当前位置: 首页 > 知识库问答 >
问题:

覆盖Prestashop模块控制器:在哪里放置php文件?

丁长卿
2023-03-14

我试图覆盖Prestashop中的一个模块。我已成功覆盖模块的模板,但无法成功覆盖模块的控制器。

新的控制器类文件应该放在哪里?

我尝试了以下位置,但它们没有添加新行为(更改任何内容):

#########################################################################################################################

根据我之前的问题,我可以通过编辑核心类(由u/Sergii P善意建议)来完成,但我确信有一种标准的方法可以做到这一点,而不涉及编辑核心类?

供参考;这是我的愿望清单的内容。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='displayexporttocscolumn'mod='myCustomModule'}
  • 创建一个自定义模块,该模块注册新挂钩,具有一个呈现表列和按钮的方法,以及一个生成CSV文件的方法
  • 大问题:你能在一个模块里有一个模块吗?我正在编辑的模板文件位于模块BlockWishlist(~/themes/MY_THEME/modules/BlockWishlist/controllers/front/mywishlist.php)中,然后我的钩子将调用我的自定义模块。这可能吗

共有2个答案

沈树
2023-03-14

嘿,我也一直在努力解决这个问题。我最终在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/classes目录

在此之后,可以通过将覆盖文件放入以下位置来覆盖模块控制器:

override/modules/{moduleName}/controllers/{front/admin}/{filename}。php

在这个文件中,您必须定义一个与要覆盖的类名称完全相同的类,并在类名称的末尾附加“override”。

我希望这能有所帮助

谢诚
2023-03-14

据我所知,您目前无法覆盖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//控制器/目录。您不能重写ModuleFrontController类,但是如果您足够聪明,您可以重写Dispatcher类并使其扫描ModuleFrontController的重写。

通常有一种方法可以通过钩子改变您想要的东西,最坏的情况是通过钩子注入javascript并改变内容。

 类似资料:
  • controllers/admin/adminPageController.php: 管理\主题\默认\模板\控制器\页面\Content.tpl 在Backoffice->管理->菜单->我以Home作为父级创建了控制器的菜单。 为什么不显示表?我做错了什么? Thanx

  • 谷歌眼镜开发套件昨日发布。但是,我找不到任何模拟器。它在哪?有没有类似android模拟器的模拟器,我们可以在那里测试这些原生的google glass应用程序?

  • > 我有两个控制器(ControllerA和ControllerB) 两个控制器都调用一个服务(MyService)。 MyService调用名为MyRepository的接口,该接口有两个实现(FirstRepository和SecondRepository)。 如何可能在从ControllerA调用服务(MyService)时使用FirstRepository而在调用来自ControllerB

  • 这应该是一个简单的过程,但还没有到目前为止。我一直在与vert合作。x 2表示一位,并切换到垂直。x 3最近。我想我应该尝试一个简单的vertx web示例,但无法通过一个简单的静态文件服务。 My server类包含以下代码段: 我正在使用Eclipse,但也一直在尝试从命令行运行vertx。我也在使用Maven。我有三个webroot文件夹,和垂直。x无法找到以下各项: 每个“webroot”

  • 从IDEA 2018.2.1开始,IDE从模块化的依赖项中启动“不在模块图中”的错误突出显示包。我添加了一个文件到我的项目,并添加了必要的语句,但是我现在无法访问我的目录中的资源文件。 (有关完整示例,请参见此GitHub项目。) 当我使用或生成的包装器脚本时,我能够读取资源文件,但是当我从IDE运行我的应用程序时,我不能。 我向JetBrains提交了一个问题,我了解到IDEA正在使用模块路径,