2

背景参照については、参照:Magento:オブザーバーを外部スクリプトで動作させるにはどうすればよいですか?

フロントエンドコントローラーのアクションを外部スクリプトから「複製」するための推奨される方法を尋ねたいと思いました。MagentoEE1.12の外部SSOログインを作成しています。

私のコードは、phpファイルに次のように存在します。test.phpを作成し、ユーザー(185)をユーザーIDに置き換えることで、テストできます。ページに移動してから、もう一度移動します。ログインおよびログアウトしていることに気付くでしょうが、adminではオンラインとして表示されません。読む...

<?php

    umask(0);
    require_once 'app/Mage.php';

    Mage::app("default");

    // Set the session to frontend according to many suggestions
    Mage::getSingleton("core/session", array("name" => "frontend"));

    // Alan Storm suggestion to load specific area in Magento (frontend)
    Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);

    // Load My Specific User
    $user = Mage::getModel('customer/customer')->load(185)->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

    // Get the session object
    $session = Mage::getSingleton('customer/session');

    // Make it look good for debugging
    echo "<PRE>";

    // Toggle the customer logged in / logged out upon page load
    if ($session->isLoggedIn())
    {
        try
        {
            $session->session->setCustomer($user);
            echo "LOGGED IN<br>";
            var_dump($session->getCustomer()->getIsJustConfirmed());
        } catch (Mage_Core_Exception $e) {
            $message = $e->getMessage();
            var_dump($message);
        }

    } else {
        $session->logout();
    }

    var_dump($session->getCustomer());
    echo $session->isLoggedIn() ? $user->getName().' is online!' : 'not logged in';

?>

このコードはユーザーにログインしますが、Mage_Log、Mage_Persistent、またはconfig.xmlのフロントエンド領域にアタッチされたcontroller_action_predispatchおよびcontroller_action_postdispatchイベントに依存するコントローラーのない他のモジュールは起動しません。

Mage_Logは、customer_loginを監視してbindCustomerLogin()関数を起動する(上記のAlan Stormの提案を使用しているため)が、コントローラーディスパッチが起動せず、モジュールが正しく機能しないという状況の完璧な例です。

これらの他のモジュールは、外部スクリプト(またはcontroller_front_init_routersイベントを監視しているグローバルオブザーバー)からどのようにトリガーされる可能性がありますか?

編集: 解決策これが上記のベンチマークによる提案の最終結果です...私はMage_Customerコントローラーをエミュレートしています。以下のスクリプトは、COMPLETEmagentoログインを実行する方法を示しています。広範囲にテストされていませんが、ユーザーがバックエンドにログインしていることを示しています。これは私がこれまでに見た中で最も完全なソリューションです。

public function autoMageLogin() {
                // Include the controller itself so the object can be used
                include ('/var/www/app/code/core/Mage/Customer/controllers/AccountController.php');

                // Configure Magento to think its using the frontend
                Mage::getSingleton("core/session", array("name" => "frontend"));
                Mage::getConfig()->init();
                Mage::getConfig()->loadEventObservers('frontend');
                Mage::app()->addEventArea('frontend');
                Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_FRONTEND);

                // Prepare the request as if it were coming from the specific
                // controller (I've chosed Mage_Customer as my chosen controller
                // to 'emulate' in php code
                $request = Mage::app()->getRequest();
                $request->setRouteName('customer');
                $request->setControllerModule('Mage_Customer');
                $request->setRoutingInfo('');
                $request->setModuleName('customer');
                $request->setControllerName('account');
                $request->setModuleKey('module');
                $request->setControllerKey('account');
                $request->setActionName('loginPost');
                $request->setActionKey('action');


                $response = Mage::app()->getResponse();

                // Instantiate a new AccountController object using the modified request
                // and the modified response (see the include() above)
                $accountControl = new Mage_Customer_AccountController($request, $response);

                // Dispatch events associated to the controller
                Mage::dispatchEvent('controller_action_predispatch', array('controller_action' => $accountControl));
                Mage::dispatchEvent('controller_action_predispatch_customer', array('controller_action' => $accountControl));
                Mage::dispatchEvent('controller_action_predispatch_customer_account_loginPost', array('controller_action' => $accountControl));


                // Load the current user
                $user = Mage::getModel('customer/customer')->load(185)->setWebsiteId(Mage::app()->getStore()->getWebsiteId());

                // Grab the current session
                $session = Mage::getSingleton('customer/session');

                // From this point forward, emulate the controller actions    
                if (!$session->isLoggedIn()){
                        try{

                                $session->setCustomerAsLoggedIn($user);
                                $session->renewSession();
                                echo "LOGGED IN<br>";
                        } catch (Mage_Core_Exception $e) {
                                $message = $e->getMessage();
                                var_dump($message);
                        }

                } else {
                        echo "LOGGED OUT<br>";

                        $session->logout();
                }


                    // Now fire the post controller action events
                    Mage::dispatchEvent('controller_action_postdispatch_customer_account_loginPost', array('controller_action'=>$accountControl));
                    Mage::dispatchEvent('controller_action_postdispatch_customer', array('controller_action'=>$accountControl));
                    Mage::dispatchEvent('controller_action_postdispatch', array('controller_action'=>$accountControl));


                // log to the screen and be done
                var_dump($session->getCustomer());
                echo $session->isLoggedIn() ? $session->getCustomer()->getName().' is online!' : 'not logged in';

                die();

        }
4

2 に答える 2

3

元のパラメータを使用してイベントを手動でディスパッチする必要があります。

Mage::dispatchEvent(
    'controller_action_predispatch',
    array('controller_action',Mage::app()->getRequest()
);

詳細についてはMage_Core_Controller_Varien_Action::preDispatch()、(リンク)を参照してください。ディスパッチ前およびディスパッチ後のメソッドは、ルート名パラメーターに基づいて動的イベントをディスパッチすることに注意してください。これは、問題になる場合とそうでない場合があります。

于 2013-01-07T20:26:13.713 に答える
0

外部スクリプトをカスタムコントローラーおよびアクションとして書き直すと、すべてのイベントが自然に発生します。ただし、そもそも外部にする理由が必要です。

于 2013-01-07T21:24:56.437 に答える