events - 如何从外部脚本触发在 config.xml 中的 <frontend> 中监视 <controller_action_predispatch> 的无 Controller 核心 Magento 模块

标签 events magento controller external observers

供背景引用 请参阅:Magento: How do I get observers to work in an external script?

我想问从外部脚本“复制”前端 Controller 操作的首选方法是什么。我正在为 Magento EE 1.12 创建外部 SSO 登录。

我的代码存在于 php 文件中,如下所示。您可以通过创建 test.php 并将我的用户 (185) 替换为您的用户 ID 来测试它。导航到该页面,然后再次导航。您会注意到您已登录和退出,但在管理中它不会显示您在线。继续阅读...

<?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';

?>

此代码会登录用户,但是如果没有依赖于附加到 config.xml 中前端区域的controller_action_predispatch 和controller_action_postdispatch 事件的 Controller ,Mage_Log、Mage_Persistent 或任何其他模块都不会登录。曾经火过。

Mage_Log 是这种情况的一个完美示例,它监视 customer_login 并触发 bindCustomerLogin() 函数(因为我使用了上面 Alan Storm 的建议),但 Controller 调度没有触发,导致模块无法正常工作.

这些其他模块如何可能从外部脚本(或监视controller_front_init_routers事件的全局观察者)触发?

编辑:解决方案 这是上面基准建议的最终结果...我正在模拟 Mage_Customer Controller 。下面的脚本演示了如何执行完整的 magento 登录。它没有经过广泛的测试,但它确实显示用户已在后端登录。这是迄今为止我见过的最完整的解决方案。

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();

        }

最佳答案

您需要使用原始参数手动分派(dispatch)事件,例如

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

参见Mage_Core_Controller_Varien_Action::preDispatch() (link)了解更多信息。请注意,预调度和后调度方法根据路由名称参数调度动态事件,这可能是也可能不是问题。

关于events - 如何从外部脚本触发在 config.xml 中的 <frontend> 中监视 <controller_action_predispatch> 的无 Controller 核心 Magento 模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14201677/

相关文章:

javascript - 如何在 Angular 2 中设置事件目标的样式?

mysql - Magento 在安装脚本中包含 .sql 文件

java - Angularjs $http Spring Rest Controller - 404 错误

objective-c - 尝试在 XCode 中将数据 Controller 分配给 UICollectionViewController 时出现错误

sql - 在哪里可以查看 SQL Server 启动/停止日志?

actionscript-3 - 记录调度自定义事件(在 ActionScript 3 中)

magento - 多个商店和多个具有不同角色的管理员

magento - 如何在 magento 1.4.1.1 中将自定义上传的图像添加到购物车?

flutter - Flutter 中的 PageView 模块中的 PageController 未正确设置。弹出位置非空错误

javascript - 更改鼠标键码 - jquery