PrestaShop 1.6.1.24模块控制器跳转问题及Excel解析需求
PrestaShop 1.6.1.24 自定义模块问题解决方案
问题1:表单提交跳后台首页,需加Controller.php后缀才正常
核心原因
PrestaShop 1.6后台路由依赖控制器文件名/类名规范和Tab表注册,若两者不匹配,路由解析会失败并默认跳转到后台首页,且不会抛出"控制器未找到"错误。
解决步骤
规范控制器文件与类名
- 控制器文件必须放在模块的
controllers/admin/目录下,命名格式为Admin[控制器别名]Controller.php,例如AdminCustomerMatriculeController.php - 类名需与文件名完全一致,继承
ModuleAdminController:class AdminCustomerMatriculeController extends ModuleAdminController { public function __construct() { $this->bootstrap = true; $this->allow_access = true; // 确保后台用户有权限访问 parent::__construct(); } }
- 控制器文件必须放在模块的
注册控制器到后台Tab菜单
在模块主文件的install()方法中添加Tab注册逻辑(PrestaShop 1.6需手动注册):public function install() { if (!parent::install() || !$this->_registerAdminController()) { return false; } return true; } private function _registerAdminController() { $tab = new Tab(); $tab->class_name = 'AdminCustomerMatricule'; // 对应控制器别名(去掉Controller后缀) $tab->module = $this->name; $tab->id_parent = (int)Tab::getIdFromClassName('AdminCustomers'); // 设置父菜单为客户管理 $tab->icon = 'icon-user'; foreach (Language::getLanguages(true) as $lang) { $tab->name[$lang['id_lang']] = '客户Matricule管理'; } return $tab->add(); }正确生成表单提交链接
无需添加Controller.php后缀,直接使用控制器别名调用getAdminLink:$actionUrl = $this->context->link->getAdminLink('AdminCustomerMatricule', true); echo '<form action="'.$actionUrl.'" method="post" enctype="multipart/form-data">';
问题2:解析XLSX文件并为客户列表的matricule添加颜色标识
实现流程
- 引入XLSX解析库 → 2. 处理文件上传与解析 → 3. 存储标记数据 → 4. 通过钩子修改客户列表显示
具体代码实现
1. 引入PHPExcel解析库
将PHPExcel(兼容PHP 5.6,适配PrestaShop 1.6)放在模块的lib/PHPExcel/目录下。
2. 自定义控制器处理文件上传
在AdminCustomerMatriculeController.php中添加表单渲染与文件处理逻辑:
public function renderForm() { $this->fields_form = [ 'legend' => [ 'title' => $this->l('上传XLSX标记文件'), 'icon' => 'icon-upload' ], 'input' => [ [ 'type' => 'file', 'label' => $this->l('XLSX文件'), 'name' => 'xlsx_file', 'required' => true, 'desc' => $this->l('第一列为matricule,第一行为表头') ] ], 'submit' => [ 'title' => $this->l('上传并标记'), 'class' => 'btn btn-primary' ] ]; return parent::renderForm(); } public function postProcess() { if (Tools::isSubmit('submit_upload')) { if ($_FILES['xlsx_file']['error'] != UPLOAD_ERR_OK) { $this->errors[] = $this->l('文件上传失败'); return; } // 加载PHPExcel require_once _PS_MODULE_DIR_.$this->module->name.'/lib/PHPExcel/PHPExcel.php'; $reader = PHPExcel_IOFactory::createReaderForFile($_FILES['xlsx_file']['tmp_name']); $excel = $reader->load($_FILES['xlsx_file']['tmp_name']); $sheet = $excel->getActiveSheet(); $highestRow = $sheet->getHighestRow(); // 解析matricule数据 $markedMatricules = []; for ($row = 2; $row <= $highestRow; $row++) { $matricule = trim($sheet->getCell('A'.$row)->getValue()); if (!empty($matricule)) { $markedMatricules[] = pSQL($matricule); } } // 存储到模块自定义表(需先创建表) Db::getInstance()->execute('TRUNCATE TABLE `'._DB_PREFIX_.'customer_matricule_marked`'); foreach ($markedMatricules as $mat) { Db::getInstance()->insert('customer_matricule_marked', [ 'matricule' => $mat, 'color' => '#ff4444' // 默认红色,可扩展为用户选择 ]); } $this->confirmations[] = $this->l('已标记 '.count($markedMatricules).' 个matricule'); Tools::redirectAdmin($this->context->link->getAdminLink('AdminCustomerMatricule')); } parent::postProcess(); }
3. 创建模块自定义表
在模块主文件的install()方法中添加建表逻辑:
private function _createMarkedTable() { $sql = 'CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'customer_matricule_marked` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, `matricule` VARCHAR(255) NOT NULL UNIQUE, `color` VARCHAR(7) NOT NULL DEFAULT "#ff4444", PRIMARY KEY (`id`) ) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=utf8;'; return Db::getInstance()->execute($sql); } // 在install()中调用: public function install() { if (!parent::install() || !$this->_registerAdminController() || !$this->_createMarkedTable() || !$this->registerHook('actionCustomerListRender')) { return false; } return true; }
4. 通过钩子修改客户列表显示
在模块主文件中实现actionCustomerListRender钩子:
public function hookActionCustomerListRender($params) { // 获取已标记的matricule数据 $markedData = Db::getInstance()->executeS('SELECT matricule, color FROM `'._DB_PREFIX_.'customer_matricule_marked`'); $markedMap = []; foreach ($markedData as $item) { $markedMap[$item['matricule']] = $item['color']; } // 遍历客户列表,修改matricule显示样式 foreach ($params['list'] as &$customer) { $matricule = $customer['matricule']; // 假设客户表/自定义字段名为matricule if (isset($markedMap[$matricule])) { $customer['matricule'] = '<span style="color:'.$markedMap[$matricule].'; font-weight:600;">'.$matricule.'</span>'; } } }
内容的提问来源于stack exchange,提问作者Jud3v Digital
相关产品推荐
相关产品推荐

