12

Magentoメッセージに問題があります。私は、理論的にはストアの一部へのアクセスを制限できるはずのカスタムモジュールを構築しています。イベントにフックし controller_action_predispatchて、ユーザーが現在のリクエストにアクセスできるかどうかを確認するオブザーバーを作成しました。アクションにアクセスできない場合、オブザーバーはユーザーをリダイレクトし、エラー情報を設定します。ショップ全体をクリックしないように、リダイレクトURLを顧客がアクセスしているページに設定したいと思います。を見て、HTTP_REFERER設定されている場合は使用します。設定されていない場合は、顧客をホームページにリダイレクトします。問題は、後者の場合(ホームページのリダイレクト)はすべてうまく機能しますが、リファラーに基づいてURLを設定すると、メッセージボックスにエラーメッセージが表示されないことです。

オブザーバーからのコード($name変数は文字列です):

Mage::getSingleton('core/session')->addError('Acces to '.$name.' section is denied');
$url = Mage::helper('core/http')->getHttpReferer() ? Mage::helper('core/http')->getHttpReferer()  : Mage::getUrl();
Mage::app()->getResponse()->setRedirect($url);

私が興味深いと思ったのは、オブザーバーファイルに変更を加えて保存すると、失敗してリファラーURLにリダイレクトされる次のリクエストにはエラー情報が表示されますが、それ以降はメッセージが失われることです。

問題は完全なURLとローカルインストール(.localドメインを使用しています)にあると思っていたので、追加してみました

$url = str_replace(Mage::getBaseUrl(), '/', $url);

しかし、これは役に立ちませんでした。

また、phpheader()関数を使用してリダイレクトを試みましたが、結果はありませんでした。

すべてのキャッシュが無効になります。問題を引き起こすワークフローは次のとおりです。

  1. アクセス可能なページ(たとえば、/ customer / account)に移動します
  2. カートのリンクをクリックします(このアカウントのカートは無効になっています)
  3. / customer / accountに戻ると、エラーメッセージが表示されます
  4. カートのリンクをもう一度クリックします
  5. / customer / accountに戻りますが、エラーメッセージは表示されません

どこを見ればよいかについてのヒントをいただければ幸いです。

4

3 に答える 3

24
//A Success Message
Mage::getSingleton('core/session')->addSuccess("Some success message");

//A Error Message
Mage::getSingleton('core/session')->addError("Some error message");

//A Info Message (See link below)
Mage::getSingleton('core/session')->addNotice("This is just a FYI message...");

//These lines are required to get it to work
session_write_close(); //THIS LINE IS VERY IMPORTANT!
$this->_redirect('module/controller/action');

// or
$url = 'path/to/your/page';
$this->_redirectUrl($url);

これはコントローラーで機能しますが、出力が既に送信された後にリダイレクトしようとしている場合は、javascriptを介してのみ行うことができます。

<script language=”javascript” type=”text/javascript”&gt;
window.location.href=”module/controller/action/getparam1/value1/etc";
</script>    
于 2013-02-21T10:03:48.037 に答える
4

でリダイレクトに不利な方法を使用しているため、メッセージが失われますcontroller_action_predispatch。あなたの解決策は、一方では「メッセージが失われた」原因となり、他方ではサーバーの処理能力を浪費します。

Mage_Core_Controller_Varien_Action::dispatch()見ると、ソリューションが現在のアクションの実行を停止しないことがわかりますが、リダイレクトを使用して停止する必要があります。代わりに、Magentoは、以前に追加したメッセージのレンダリングを含め、現在のアクションを最後まで実行します。したがって、次のクライアント要求でメッセージが失われるのも不思議ではありません。Magentoは、リダイレクトを含むサーバー応答を使用して、以前にメッセージを既にレンダリングしていました。

さらにMage_Core_Controller_Varien_Action::dispatch()、現在のアクションの実行を停止し、428行目にあるリダイレクトに直接スキップする可能性が1つだけありますcatch (Mage_Core_Controller_Varien_Exception $e) [...]。したがってMage_Core_Controller_Varien_Exception、非常に人気のないものを使用する必要がありますが、目的に適した唯一のソリューションです。唯一の問題は、このクラスにはMagento1.3.2で導入されてからのバグがあることです。しかし、これは簡単に修正できます。

から派生した独自のクラスを作成するだけですMage_Core_Controller_Varien_Exception

/**
 * Controller exception that can fork different actions, 
 * cause forward or redirect
 */
class Your_Module_Controller_Varien_Exception 
    extends Mage_Core_Controller_Varien_Exception
{
    /**
     * Bugfix
     * 
     * @see Mage_Core_Controller_Varien_Exception::prepareRedirect()
     */
    public function prepareRedirect($path, $arguments = array())
    {
        $this->_resultCallback = self::RESULT_REDIRECT;
        $this->_resultCallbackParams = array($path, $arguments);
        return $this;
    }
}

これで、ソリューションを本当にクリーンに実装できます。

/**
 * Your observer
 */
class Your_Module_Model_Observer
{
    /**
     * Called before frontend action dispatch
     * (controller_action_predispatch)
     * 
     * @param Varien_Event_Observer $observer
     */
    public function onFrontendActionDispatch($observer)
    {
        // [...]

        /* @var $action Mage_Core_Model_Session */
        $session = Mage::getSingleton('core/session');
        /* @var $helper Mage_Core_Helper_Http */
        $helper = Mage::helper('core/http');
        // puts your message in the session
        $session->addError('Your message');
        // prepares the redirect url
        $params = array();
        $params['_direct'] = $helper->getHttpReferer() 
            ? $helper->getHttpReferer() : Mage::getHomeUrl();
        // force the redirect
        $exception = new Your_Module_Controller_Varien_Exception();
        $exception->prepareRedirect('', $params);
        throw $exception;
    }
}
于 2013-03-21T03:34:23.933 に答える
0

これは機能するので、試してみてください。

$url = 'path/to/your/page';
$this->_redirectUrl($url);
return false;

これは、他の実行を再度許可しないことを意味します。

于 2016-12-16T07:09:48.003 に答える