产品分类页面URL ?skus=OPB-P112D,OPB-P206DN 指定sku显示在最前面
/etc/di.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Elasticsearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplier" type="Maijindou\Catalog\Plugin\Model\ResourceModel\Fulltext\Collection\SearchResultApplier" /> </config>
Plugin\Model\ResourceModel\Fulltext\Collection
<?php namespace Maijindou\Catalog\Plugin\Model\ResourceModel\Fulltext\Collection; use Magento\Catalog\Model\Product; use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierInterface; use Magento\Framework\Api\Search\SearchResultInterface; use Magento\Framework\Data\Collection; class SearchResultApplier implements SearchResultApplierInterface { /** * @var Collection|\Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection */ private $collection; /** * @var SearchResultInterface */ private $searchResult; /** * @var int */ private $size; /** * @var int */ private $currentPage; private $request; private $product; /** * @param Collection $collection * @param SearchResultInterface $searchResult * @param int $size * @param int $currentPage */ public function __construct( Collection $collection, \Magento\Framework\App\RequestInterface $request, SearchResultInterface $searchResult, Product $product, int $size, int $currentPage ) { $this->product = $product; $this->request = $request; $this->collection = $collection; $this->searchResult = $searchResult; $this->size = $size; $this->currentPage = $currentPage; } /** * @inheritdoc */ public function apply() { if (empty($this->searchResult->getItems())) { $this->collection->getSelect()->where('NULL'); return; } $items = $this->sliceItems($this->searchResult->getItems(), $this->size, $this->currentPage); $ids = []; foreach ($items as $item) { $ids[] = (int)$item->getId(); } $skus = $this->request->getParam('skus'); $arr_sku = explode(',',$skus); $new_ids = []; foreach($arr_sku as $str){ $product_id = $this->product->getIdBySku($str); $new_ids[] = $product_id; if(in_array($product_id,$ids)){ array_unshift($ids,$product_id); } } $ids = array_unique($ids); $this->collection->getSelect() ->where('e.entity_id IN (?)', $ids) ->reset(\Magento\Framework\DB\Select::ORDER); $sortOrder = $this->searchResult->getSearchCriteria() ->getSortOrders(); if (!empty($sortOrder['price']) && $this->collection->getLimitationFilters()->isUsingPriceIndex()) { $sortDirection = $sortOrder['price']; $this->collection->getSelect() ->order( new \Zend_Db_Expr("price_index.min_price = 0, price_index.min_price {$sortDirection}") ); } else { $orderList = join(',', $ids); $this->collection->getSelect() ->order(new \Zend_Db_Expr("FIELD(e.entity_id,$orderList)")); } } /** * Slice current items * * @param array $items * @param int $size * @param int $currentPage * @return array */ private function sliceItems(array $items, int $size, int $currentPage): array { if ($size !== 0) { // Check that current page is in a range of allowed page numbers, based on items count and items per page, // than calculate offset for slicing items array. $itemsCount = count($items); $maxAllowedPageNumber = ceil($itemsCount/$size); if ($currentPage < 1) { $currentPage = 1; } if ($currentPage > $maxAllowedPageNumber) { $currentPage = $maxAllowedPageNumber; } $offset = $this->getOffset($currentPage, $size); $items = array_slice($items, $offset, $size); } return $items; } /** * Get offset for given page. * * @param int $pageNumber * @param int $pageSize * @return int */ private function getOffset(int $pageNumber, int $pageSize): int { return ($pageNumber - 1) * $pageSize; } }