【问题标题】:How can I add a custom product "Sort by" field in prestashop?如何在 prestashop 中添加自定义产品“排序依据”字段?
【发布时间】:2019-03-05 22:56:40
【问题描述】:

我是 Prestashop 的新手,我正在尝试添加一个新的“排序依据”字段(默认情况下,您有:“相关性”、“名称,A 到 Z”、“名称,Z 到 A”、“价格,从低到高”,“价格,从高到低”)

如你们所知,该功能位于名为: “Ps_facetedsearch”,链接here

我试过了:

  • 编辑模块文件,这可行,但如果我想保留该功能,我无法再升级模块。
  • 覆盖,但似乎无法使其工作,它仍然使用相同的旧模块,而不是被覆盖的模块。

所以我的问题是:

  1. 如何以最优雅/最简单的方式在产品列表(前面)中添加额外的“排序依据”字段?我很想听听解决此问题的任何其他方法。
  2. 如果您购买了另一个覆盖主模块的模块(“Ps_facetedsearch”,这样两个覆盖不会发生冲突),您能否在不使用覆盖的情况下执行此操作

感谢任何提示!!!

PrestaShop 版本:1.7.4.2

为了添加额外的“排序依据”字段,我需要复制/粘贴 Ps_facetedsearch 模块中的行:

private function getAvailableSortOrders()
{
    return [
        (new SortOrder('product', 'position', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Relevance', array(), 'Modules.Facetedsearch.Shop')
        ),
        (new SortOrder('product', 'name', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Name, A to Z', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'name', 'desc'))->setLabel(
            $this->module->getTranslator()->trans('Name, Z to A', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'price', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Price, low to high', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'price', 'desc'))->setLabel(
            $this->module->getTranslator()->trans('Price, high to low', array(), 'Shop.Theme.Catalog')
        )
        // copy and paste here for another one, but lose the upgradability
       // of a module.
    ];

}

在 Ps_FacetedsearchProductSearchProvider.php 中找到 (第 117-136 行)

【问题讨论】:

  • 可能可以在覆盖的帮助下完成

标签: php symfony model-view-controller prestashop prestashop-1.7


【解决方案1】:

由于ps_facetedsearch 模块最近发生了一些变化,这里是最新 PS 1.7.7.1 版本的版本,基于@Divjesh 回答:

  1. 在文件夹override/modules/ps_facetedsearch 中添加文件ps_facetedsearch.php(如果不存在则创建文件夹)并将以下代码放入此文件中。
    <?php
    if (!defined('_PS_VERSION_')) {
        exit;
    }
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, 'src', 'Product', 'SearchProvider.php',
    ));
    
    use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
    use PrestaShop\Module\FacetedSearch\URLSerializer;
    use PrestaShop\Module\FacetedSearch\Filters\Converter;
    
    class Ps_FacetedsearchOverride extends Ps_Facetedsearch
    {
        public function hookProductSearchProvider($params)
        {
            $query = $params['query'];
             if ($query->getIdCategory()) {
                $urlSerializer = new URLSerializer();
                return new SearchProviderOverride(
                    $this,
                    new Converter(
                        $this->getContext(),
                        $this->getDatabase(),
                        $urlSerializer
                    ),
                    $urlSerializer
                );
            } else {
                return null;
            }
        }
    }
  1. 在文件夹override/modules/ps_facetedsearch/src/Product/ 中添加文件SearchProvider.php(如果不存在则创建文件夹)并在其中添加以下代码:
<?php

use PrestaShop\Module\FacetedSearch\Filters;
use PrestaShop\Module\FacetedSearch\URLSerializer;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;

use PrestaShop\Module\FacetedSearch\Product\SearchProvider;

class SearchProviderOverride extends SearchProvider
{
    private $_module;
    
    public function __construct(
        Ps_Facetedsearch $module,
        Filters\Converter $converter,
        URLSerializer $serializer,
        SearchFactory $searchFactory = null
    ) {
        parent::__construct($module, $converter, $serializer, $searchFactory);
        $this->_module = $module;
    }   
    
    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        $result = parent::runQuery($context, $query);
        $result->setAvailableSortOrders($this->getMyAvailableSortOrders());
        return $result;
    }
    
    private function getMyAvailableSortOrders()
    {
        // define your SortOrders here for example:
        $sortDateDesc = new SortOrder('product', 'date_add', 'desc');
        $translator = $this->_module->getTranslator();
        return [
            $sortDateDesc->setLabel(
                $translator->trans('Newest', [], 'Modules.Facetedsearch.Shop')
            ),
        ];
    }
}

【讨论】:

    【解决方案2】:

    对于 1.7.4.x

    • 转到 /modules/ps_facetedsearch/src
    • 打开 Ps_FacetedsearchProductSearchProvider.php
    • 找到private function getAvailableSortOrders()线
    • 并添加您想要的内容:

    (new SortOrder('product', 'date_add', 'desc'))->setLabel( $this->module->getTranslator()->trans('添加日期:最新的第一个', array(), 'Modules.Facetedsearch.Shop') ), (new SortOrder('product', 'date_add', 'asc'))->setLabel( $this->module->getTranslator()->trans('添加日期:最早的第一个', array(), 'Modules.Facetedsearch.Shop') ), (new SortOrder('product', 'position', 'asc'))->setLabel( $this->module->getTranslator()->trans('Relevance', array(), 'Modules.Facetedsearch.Shop') ),

    适用于 1.7.6.x

    您可以在 /modules/ps_facetedsearch/src/Product/SearchProvider.php 中找到该文件

    然后找到:

    private function getAvailableSortOrders()
    

    对于旧版本: - 主题/默认/product-sort.tpl - 添加喜欢:

    <option value="date_add:desc" {if $orderby eq 'date_add' AND $orderway eq 'desc'}selected="selected"{/if}>{l s='Date added: latest first'}</option>
    

    【讨论】:

    • 值得注意的是,不应修改您提到的文件,而应覆盖模块 - 请参阅使用 1.7.7.1 版本的代码
    【解决方案3】:

    您可以通过覆盖Ps_Facetedsearch 模块来添加自定义排序选项。

    您可以按照以下步骤添加自定义排序。

    1) 在文件夹override/modules/ps_facetedsearch 中添加文件ps_facetedsearch.php; (如果不存在则创建文件夹)以及此文件中的以下代码。

    <?php
    /**
     * @override Ps_Facetedsearch
     */
    
    if (!defined('_PS_VERSION_')) {
        exit;
    }
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, 'src', 'Ps_FacetedsearchProductSearchProvider.php',
    ));
    
    class Ps_FacetedsearchOverride extends Ps_Facetedsearch
    {
        public function hookProductSearchProvider($params)
        {
            $query = $params['query'];
            // do something with query,
            // e.g. use $query->getIdCategory()
            // to choose a template for filters.
            // Query is an instance of:
            // PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery
            if ($query->getIdCategory()) {
                return new Ps_FacetedsearchProductSearchProviderOverride($this);
            } else {
                return null;
            }
        }
    }
    

    2) 在文件夹override/modules/ps_facetedsearch/src 中添加文件Ps_FacetedsearchProductSearchProvider.php; (如果不存在则创建文件夹)并在其中添加以下代码。

    <?php
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchProductSearchProvider.php',
    ));
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchFiltersConverter.php',
    ));
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchFacetsURLSerializer.php',
    ));
    
    use PrestaShop\PrestaShop\Core\Product\Search\URLFragmentSerializer;
    use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;
    use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
    use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
    use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
    use PrestaShop\PrestaShop\Core\Product\Search\Facet;
    use PrestaShop\PrestaShop\Core\Product\Search\FacetCollection;
    use PrestaShop\PrestaShop\Core\Product\Search\Filter;
    use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
    
    class Ps_FacetedsearchProductSearchProviderOverride extends Ps_FacetedsearchProductSearchProvider
    {
        private $module;
    
        public function __construct(Ps_Facetedsearch $module)
        {
            $this->module = $module;
        }
    
        public function runQuery(
            ProductSearchContext $context,
            ProductSearchQuery $query
        ) {
            $facetedSearch = new Ps_FacetedsearchProductSearchProvider($this->module);
            $result = $facetedSearch->runQuery($context, $query);
    
            $sortOrders = $this->getAvailableSortOrders();
            foreach ($sortOrders as $sortOrder) {
                $result->addAvailableSortOrder($sortOrder);
            }
    
            return $result;
        }
    
        /**
         * New sort order that needs to be appended
         * 
         * @return array
         */
        private function getAvailableSortOrders()
        {
            return [
                // add your custom sort by orders here;
            ];
        }
    }
    

    3) 确保在后端启用overrides;来自 高级参数 > 性能

    4) 要加载您的覆盖,您需要 re-index 自动加载,为此您需要删除 class_index.php 文件;从var/cache/devvar/cache/prod 文件夹中删除class_index.php 文件。

    5) 检查您的商店;将添加新的自定义排序顺序。

    希望对你有帮助!

    【讨论】:

    • 嗨,我也需要在产品搜索中包含 Facetedsearch。所以删除了if ($query-&gt;getIdCategory()) {} 条件。但是,这对我不起作用。你能给我一个建议吗。:-@Divyesh Prajapathi
    • @Divyesh Prajapathi 感谢您的启发。我刚刚发布了最新 1.7.7.1 版本的 ps_facetedsearch 覆盖代码
    猜你喜欢
    • 2016-04-08
    • 1970-01-01
    • 2017-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多