如何在prestashop中添加自定义产品“排序依据”字段?

时间:2018-09-30 18:22:41

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

我是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行)

3 个答案:

答案 0 :(得分:3)

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

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

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

<?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)将文件Ps_FacetedsearchProductSearchProvider.php添加到文件夹override/modules/ps_facetedsearch/src中; (如果不存在,则创建文件夹)并在其中添加以下代码。

<?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文件;从class_index.phpvar/cache/dev文件夹中删除var/cache/prod文件。

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

希望有帮助!

答案 1 :(得分:0)

对于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')         ),         (新的SortOrder('product','date_add','asc'))-> setLabel(             $ this-> module-> getTranslator()-> trans('添加日期:最早开始',array(),'Modules.Facetedsearch.Shop')         ),         (新的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>

答案 2 :(得分:0)

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

  1. 在文件夹 ps_facetedsearch.php 中添加文件 override/modules/ps_facetedsearch(如果不存在则创建文件夹)并将以下代码放入此文件中。
    <?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. 在文件夹 SearchProvider.php 中添加文件 override/modules/ps_facetedsearch/src/Product/(如果不存在则创建文件夹)并在其中添加以下代码:
<?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')
            ),
        ];
    }
}