Prestashop 1.7无需query builder创建自定义Grid的方案咨询
Prestashop 1.7自定义Grid对接非数据库数据源方案
完全可以实现该需求,不需要依赖官方默认的Doctrine QueryBuilder作为数据源,只需要自定义实现GridDataFactoryInterface接口,替换官方的DoctrineGridDataFactory即可适配数组、集合、JSON等任意格式的数据源,具体实现方案如下:
实现步骤
1. 自定义Grid数据工厂类
实现PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface接口的getData和getCount两个核心方法,在方法内部自行处理数据源读取、过滤、排序、分页逻辑即可,示例代码如下:
<?php use PrestaShop\PrestaShop\Core\Grid\Data\Factory\GridDataFactoryInterface; use PrestaShop\PrestaShop\Core\Grid\Search\SearchCriteriaInterface; use PrestaShop\PrestaShop\Core\Grid\Data\GridData; class CustomArrayGridDataFactory implements GridDataFactoryInterface { // 可通过构造函数注入提供数组/JSON/集合数据的自定义服务 private $customDataSource; public function __construct($customDataSource) { $this->customDataSource = $customDataSource; } public function getData(SearchCriteriaInterface $searchCriteria) { // 1. 获取原始数据:可以是PHP数组、解析后的JSON、Doctrine集合等 $rawData = $this->customDataSource->fetchAllData(); // 如果是集合可直接调用toArray()转为数组,JSON可通过json_decode()转为数组 if ($rawData instanceof \Doctrine\Common\Collections\Collection) { $rawData = $rawData->toArray(); } elseif (is_string($rawData)) { $rawData = json_decode($rawData, true) ?? []; } // 2. 根据Grid传入的过滤条件处理数据 $filters = $searchCriteria->getFilters(); if (!empty($filters)) { $rawData = $this->applyFilters($rawData, $filters); } // 3. 根据Grid传入的排序规则处理数据 $orderBy = $searchCriteria->getOrderBy(); $orderWay = $searchCriteria->getOrderWay(); if ($orderBy) { $rawData = $this->applySorting($rawData, $orderBy, $orderWay); } // 4. 处理分页逻辑 $offset = $searchCriteria->getOffset(); $limit = $searchCriteria->getLimit(); $paginatedData = array_slice($rawData, $offset, $limit); $totalCount = count($rawData); // 返回符合Grid要求的标准数据格式 return new GridData($paginatedData, $totalCount, $searchCriteria); } public function getCount(SearchCriteriaInterface $searchCriteria) { // 返回过滤后的总数据条数即可 $rawData = $this->customDataSource->fetchAllData(); $filters = $searchCriteria->getFilters(); if (!empty($filters)) { $rawData = $this->applyFilters($rawData, $filters); } return count($rawData); } // 自定义过滤逻辑,可根据业务需求修改 private function applyFilters(array $data, array $filters): array { return array_filter($data, function ($item) use ($filters) { foreach ($filters as $field => $keyword) { if (!isset($item[$field]) || strpos($item[$field], $keyword) === false) { return false; } } return true; }); } // 自定义排序逻辑,可根据业务需求修改 private function applySorting(array $data, string $orderBy, string $orderWay): array { usort($data, function ($a, $b) use ($orderBy, $orderWay) { if ($a[$orderBy] == $b[$orderBy]) return 0; $result = $a[$orderBy] > $b[$orderBy] ? 1 : -1; return strtoupper($orderWay) === 'DESC' ? -$result : $result; }); return $data; } }
2. 修改服务配置
不需要再注册QueryBuilder相关服务,直接绑定你自定义的数据工厂即可,示例配置如下:
# 注册你自己的数据源服务,用于提供数组/JSON/集合格式的数据 your_module.custom_data_source: class: 'YourModule\Service\CustomDataSource' public: true # 注册你自定义的Grid数据工厂 your_module.grid.data.factory.custom_factory: class: 'YourModule\Grid\Data\Factory\CustomArrayGridDataFactory' arguments: - '@your_module.custom_data_source' public: true # 配置Grid时将data_factory指向你自定义的工厂服务即可 your_module.grid.definition.custom_grid: class: 'YourModule\Grid\Definition\CustomGridDefinitionFactory' parent: 'prestashop.core.grid.definition.factory.abstract_grid_definition' tags: - { name: prestashop.grid.definition_factory, grid_id: 'custom_grid' } your_module.grid.custom_grid: class: 'PrestaShop\PrestaShop\Core\Grid\Grid' factory: ['@prestashop.core.grid.factory.grid_factory', 'get'] arguments: - 'custom_grid' - '@your_module.grid.data.factory.custom_factory' public: true
注意事项
- 过滤、排序、分页逻辑完全自定义,不需要适配官方QueryBuilder的规则,灵活性更高
- 任意格式的数据源只要能转为PHP数组格式,都可以按照上述方案对接
内容的提问来源于stack exchange,提问作者Malek Ben El Ouafi
相关产品推荐
相关产品推荐

