簡體   English   中英

覆蓋Prestashop模塊控制器:哪里放置php文件?

[英]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'}
  • 創建一個注冊新鈎子的自定義模塊,創建一個呈現表列和按鈕的方法,並生成一個CSV文件。
  • 大問題:您可以在模塊內部有一個模塊嗎? 我正在編輯的模板文件位於模塊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 / classes目錄
  • 刪除cache / class_index.php文件

此后,可以通過將替代文件放入以下位置來替代模塊控制器:

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

在此文件中,您必須定義一個名稱與要覆蓋的類完全相同的類,並在類名的末尾附加“ Override”。

我希望這有幫助

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM