[英]Override Prestashop Module Controller: Where to place php file?
我试图覆盖Prestashop中的模块。 我已经成功覆盖了模块的模板,但是无法成功覆盖模块的控制器。
新的控制器类文件应放在何处?
我尝试了以下位置,但它们未添加新行为(更改任何内容):
〜/ overrides / modules / blockwishlist / controllers / front / mywishlist.php
〜/ themes / MY_THEME / modules / blockwishlist / controllers / front / mywishlist.php
根据我之前的问题,我可以通过编辑核心类(由u / Sergii P推荐)来做到这一点,但是我确定有一种标准方法可以实现,而无需编辑核心类?
以供参考; 这是mywishlist.php
的内容:
<?php
if (!defined('_CAN_LOAD_FILES_'))
exit;
//class BlockWishListMyWishListModuleFrontController extends BlockWishListMyWishListModuleFrontControllerCore // extends ModuleFrontController
class BlockWishListMyWishListModuleFrontControllerOverride extends BlockWishListMyWishListModuleFrontController
{
public function __construct()
{
parent::__construct();
}
/**
* Assign wishlist template
*/
public function assign()
{
$errors = array();
....
$this->setTemplate('mywishlist.tpl');
}
}
编辑:我有一个可能的解决方法,无法覆盖ModuleFrontController
类。 目的是在“我的愿望清单”页面上添加一个“导出到CSV”按钮,单击该按钮时,服务器将生成一个包含该愿望清单中所有产品的CSV文件。 在我完成所有工作之前,您能否提供关于是否可行的建议?
{hook h='displayExportToCsvColumn' mod='myCustomModule'}
BlockWishlist
( 〜/ themes / MY_THEME / modules / blockwishlist / controllers / front / mywishlist.php ),然后我的钩子将调用我的自定义模块。 这可能吗? 据我ModuleFrontController
,您目前无法覆盖ModuleFrontController
(对不起)。 线索位于Dispatcher::dispatch()
:
case self::FC_MODULE :
$module_name = Validate::isModuleName(Tools::getValue('module')) ? Tools::getValue('module') : '';
$module = Module::getInstanceByName($module_name);
$controller_class = 'PageNotFoundController';
if (Validate::isLoadedObject($module) && $module->active) {
$controllers = Dispatcher::getControllers(_PS_MODULE_DIR_.$module_name.'/controllers/front/');
if (isset($controllers[strtolower($this->controller)])) {
include_once(_PS_MODULE_DIR_.$module_name.'/controllers/front/'.$this->controller.'.php');
$controller_class = $module_name.$this->controller.'ModuleFrontController';
}
}
$params_hook_action_dispatcher = array('controller_type' => self::FC_FRONT, 'controller_class' => $controller_class, 'is_module' => 1);
break;
它仅检查/modules/?/controllers/
目录。 您不能覆盖ModuleFrontController
类,但是如果您足够聪明,则可以覆盖Dispatcher
类并使它扫描ModuleFrontController
覆盖。
通常,在最坏的情况下,有一种方法可以用钩子来更改所需的东西-通过钩子注入javascript并更改内容。
嘿,我也在这个问题上苦苦挣扎。 我最终在prestashop论坛上发现了一个解决方案: https : //www.prestashop.com/forums/topic/480523-override-front-controller-of-modules/
用户Alex已为Dispatcher创建一个替代,它将检查是否有任何模块控制器替代。
该文件似乎不再在论坛上可用,但是您仍然可以在这里找到它,以及有关其工作原理的一些解释: http : //nemops.com/overriding-modules-controllers-in-prestashop-1-6/ #.XDR7HHX0muU
如果这些都不起作用,则代码如下:
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class Dispatcher extends DispatcherCore
{
public function dispatch()
{
$controller_class = '';
// Get current controller
$this->getController();
if (!$this->controller) {
$this->controller = $this->useDefaultController();
}
// Dispatch with right front controller
switch ($this->front_controller) {
// Dispatch front office controller
case self::FC_FRONT :
$controllers = Dispatcher::getControllers(
array(_PS_FRONT_CONTROLLER_DIR_, _PS_OVERRIDE_DIR_.'controllers/front/')
);
$controllers['index'] = 'IndexController';
if (isset($controllers['auth'])) {
$controllers['authentication'] = $controllers['auth'];
}
if (isset($controllers['compare'])) {
$controllers['productscomparison'] = $controllers['compare'];
}
if (isset($controllers['contact'])) {
$controllers['contactform'] = $controllers['contact'];
}
if (!isset($controllers[strtolower($this->controller)])) {
$this->controller = $this->controller_not_found;
}
$controller_class = $controllers[strtolower($this->controller)];
$params_hook_action_dispatcher = array(
'controller_type' => self::FC_FRONT,
'controller_class' => $controller_class,
'is_module' => 0,
);
break;
// Dispatch module controller for front office
case self::FC_MODULE :
$module_name = Validate::isModuleName(Tools::getValue('module')) ? Tools::getValue('module') : '';
$module = Module::getInstanceByName($module_name);
$controller_class = 'PageNotFoundController';
if (Validate::isLoadedObject($module) && $module->active) {
$controllers = Dispatcher::getControllers(_PS_MODULE_DIR_.$module_name.'/controllers/front/');
if (isset($controllers[strtolower($this->controller)])) {
include_once(_PS_MODULE_DIR_.$module_name.'/controllers/front/'.$this->controller.'.php');
if (file_exists(
_PS_OVERRIDE_DIR_.'modules/'.$module_name.'/controllers/front/'.$this->controller.'.php'
)) {
include_once(_PS_OVERRIDE_DIR_.'modules/'.$module_name.'/controllers/front/'.$this->controller.'.php');
$controller_class = $module_name.$this->controller.'ModuleFrontControllerOverride';
} else {
$controller_class = $module_name.$this->controller.'ModuleFrontController';
}
}
}
$params_hook_action_dispatcher = array(
'controller_type' => self::FC_FRONT,
'controller_class' => $controller_class,
'is_module' => 1,
);
break;
// Dispatch back office controller + module back office controller
case self::FC_ADMIN :
if ($this->use_default_controller && !Tools::getValue('token') && Validate::isLoadedObject(
Context::getContext()->employee
) && Context::getContext()->employee->isLoggedBack()) {
Tools::redirectAdmin(
'index.php?controller='.$this->controller.'&token='.Tools::getAdminTokenLite($this->controller)
);
}
$tab = Tab::getInstanceFromClassName($this->controller, Configuration::get('PS_LANG_DEFAULT'));
$retrocompatibility_admin_tab = null;
if ($tab->module) {
if (file_exists(_PS_MODULE_DIR_.$tab->module.'/'.$tab->class_name.'.php')) {
$retrocompatibility_admin_tab = _PS_MODULE_DIR_.$tab->module.'/'.$tab->class_name.'.php';
} else {
$controllers = Dispatcher::getControllers(_PS_MODULE_DIR_.$tab->module.'/controllers/admin/');
if (!isset($controllers[strtolower($this->controller)])) {
$this->controller = $this->controller_not_found;
$controller_class = 'AdminNotFoundController';
} else {
// Controllers in modules can be named AdminXXX.php or AdminXXXController.php
include_once(_PS_MODULE_DIR_.$tab->module.'/controllers/admin/'.$controllers[strtolower(
$this->controller
)].'.php');
$controller_class = $controllers[strtolower($this->controller)].(strpos(
$controllers[strtolower($this->controller)],
'Controller'
) ? '' : 'Controller');
}
}
$params_hook_action_dispatcher = array(
'controller_type' => self::FC_ADMIN,
'controller_class' => $controller_class,
'is_module' => 1,
);
} else {
$controllers = Dispatcher::getControllers(
array(
_PS_ADMIN_DIR_.'/tabs/',
_PS_ADMIN_CONTROLLER_DIR_,
_PS_OVERRIDE_DIR_.'controllers/admin/',
)
);
if (!isset($controllers[strtolower($this->controller)])) {
// If this is a parent tab, load the first child
if (Validate::isLoadedObject($tab) && $tab->id_parent == 0 && ($tabs = Tab::getTabs(
Context::getContext()->language->id,
$tab->id
)) && isset($tabs[0])) {
Tools::redirectAdmin(Context::getContext()->link->getAdminLink($tabs[0]['class_name']));
}
$this->controller = $this->controller_not_found;
}
$controller_class = $controllers[strtolower($this->controller)];
$params_hook_action_dispatcher = array(
'controller_type' => self::FC_ADMIN,
'controller_class' => $controller_class,
'is_module' => 0,
);
if (file_exists(_PS_ADMIN_DIR_.'/tabs/'.$controller_class.'.php')) {
$retrocompatibility_admin_tab = _PS_ADMIN_DIR_.'/tabs/'.$controller_class.'.php';
}
}
// @retrocompatibility with admin/tabs/ old system
if ($retrocompatibility_admin_tab) {
include_once($retrocompatibility_admin_tab);
include_once(_PS_ADMIN_DIR_.'/functions.php');
runAdminTab($this->controller, !empty($_REQUEST['ajaxMode']));
return;
}
break;
default :
throw new PrestaShopException('Bad front controller chosen');
}
// Instantiate controller
try {
// Loading controller
$controller = Controller::getController($controller_class);
// Execute hook dispatcher
if (isset($params_hook_action_dispatcher)) {
Hook::exec('actionDispatcher', $params_hook_action_dispatcher);
}
// Running controller
$controller->run();
} catch (PrestaShopException $e) {
$e->displayMessage();
}
}
}
此后,可以通过将替代文件放入以下位置来替代模块控制器:
override/modules/{moduleName}/controllers/{front/admin}/{filename}.php
在此文件中,您必须定义一个名称与要覆盖的类完全相同的类,并在类名的末尾附加“ Override”。
我希望这有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.