Events 如何触发监视的无控制器核心Magento模块<;控制器\u动作\u预喷>;在<;前端>;在外部脚本的config.xml中
作为背景参考 见: 我想问,从外部脚本“复制”前端控制器操作的首选方法是什么。我正在为Magento EE 1.12创建外部SSO登录 我的代码存在于php文件中,如下所示。您可以通过创建test.php并用您的用户ID替换我的用户(185)来测试它。导航到该页,然后重试。您会注意到您已登录和注销,但在管理中它不会显示您处于联机状态。继续读Events 如何触发监视的无控制器核心Magento模块<;控制器\u动作\u预喷>;在<;前端>;在外部脚本的config.xml中,events,magento,controller,external,observers,Events,Magento,Controller,External,Observers,作为背景参考 见: 我想问,从外部脚本“复制”前端控制器操作的首选方法是什么。我正在为Magento EE 1.12创建外部SSO登录 我的代码存在于php文件中,如下所示。您可以通过创建test.php并用您的用户ID替换我的用户(185)来测试它。导航到该页,然后重试。您会注意到您已登录和注销,但在管理中它不会显示您处于联机状态。继续读 <?php umask(0); require_once 'app/Mage.php'; Mage::app("defau
<?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事件的控制器,则不会触发Mage_Log、Mage_Persistent或任何其他模块
Mage_Log是这种情况的一个完美例子,它监视customer_登录并启动bindCustomerLogin()函数(因为我使用的是上面Alan Storm的建议),但控制器调度没有启动,导致模块无法正常工作
外部脚本(或观察控制器前端初始化路由器事件的全局观察者)如何触发这些其他模块
编辑:解决方案
下面是上面benmarks建议的最终结果。。。我正在模拟Mage_客户控制器。下面的脚本演示如何执行完整的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();
}
公共函数autoMageLogin(){
//包括控制器本身,以便可以使用对象
包括('/var/www/app/code/core/Mage/Customer/controllers/AccountController.php');
//将Magento配置为使用前端进行思考
Mage::getSingleton(“核心/会话”,数组(“名称”=>“前端”);
Mage::getConfig()->init();
Mage::getConfig()->LoadEventObservators('frontend');
Mage::app()->addEventArea('frontend');
Mage::app()->loadArea(Mage_Core_Model_app_Area::Area_FRONTEND);
//准备请求,就好像它来自特定的
//控制器(我选择了Mage_客户作为我选择的控制器
//在php代码中“模拟”
$request=Mage::app()->getRequest();
$request->setRouteName(“客户”);
$request->setControllerModule('Mage_Customer');
$request->setRoutingInfo(“”);
$request->setModuleName(“客户”);
$request->setControllerName('account');
$request->setModuleKey('module');
$request->setControllerKey('account');
$request->setActionName('loginPost');
$request->setActionKey('action');
$response=Mage::app()->getResponse();
//使用修改后的请求实例化新的AccountController对象
//以及修改后的响应(请参见上面的include()
$accountControl=新的Mage\U Customer\U accountControl($request,$response);
//调度与控制器关联的事件
Mage::dispatchEvent('controller\u action\u predispatch',数组('controller\u action'=>$accountControl));
Mage::dispatchEvent('controller\u action\u predispatch\u customer',数组('controller\u action'=>$accountControl));
Mage::dispatchEvent('controller\u action\u predispatch\u customer\u account\u loginPost',数组('controller\u action'=>$accountControl));
//加载当前用户
$user=Mage::getModel('customer/customer')->load(185)->setWebsiteId(Mage::app()->getStore()->getWebsiteId());
//抓取当前会话
$session=Mage::getSingleton('customer/session');
//从这一点开始,模拟控制器动作
如果(!$session->isLoggedIn()){
试一试{
$session->setCustomerAsLoggedIn($user);
$session->renewSession();
回显“已登录
”;
}捕获(法师核心例外$e){
$message=$e->getMessage();
变量转储($message);
}
}否则{
回显“注销
”;
$session->logout();
}
//现在触发控制器后操作事件
Mage::dispatchEvent('controller\u action\u postdispatch\u customer\u account\u loginPost',数组('controller\u action'=>$accountControl));
Mage::dispatchEvent('controller\u action\u postdispatch\u customer',数组('controller\u action'=>$accountControl));
Mage::dispatchEvent('controller\u action\u postdispatch',数组('controller\u action'=>$accountControl));
//登录到屏幕并完成
变量转储($session->getCustomer());
echo$session->isLoggedIn()?$session->getCustomer()->getName()。“已联机!”:“未登录”;
模具();
}
您需要使用原始参数手动调度事件,例如
Mage::dispatchEvent(
'controller_action_predispatch',
array('controller_action',Mage::app()->getRequest()
);
有关更多信息,请参阅。请注意,调度前和调度后方法基于routename参数调度动态事件,这可能是个问题,也可能不是个问题。如果您将外部脚本重写为自定义控制器和操作,则所有事件都将自然触发。但是,您必须首先有理由将其设置为外部。I你认为ab吗