66
77namespace Magento \Elasticsearch \Model \ResourceModel \Fulltext \Collection ;
88
9- use Magento \Catalog \Api \Data \ProductInterface ;
10- use Magento \CatalogInventory \Model \StockStatusApplierInterface ;
11- use Magento \CatalogInventory \Model \ResourceModel \StockStatusFilterInterface ;
129use Magento \CatalogSearch \Model \ResourceModel \Fulltext \Collection \SearchResultApplierInterface ;
1310use Magento \Framework \Api \Search \SearchResultInterface ;
14- use Magento \Framework \App \Config \ScopeConfigInterface ;
15- use Magento \Framework \App \ObjectManager ;
1611use Magento \Framework \Data \Collection ;
17- use Magento \Framework \EntityManager \MetadataPool ;
1812
1913/**
2014 * Resolve specific attributes for search criteria.
21- *
22- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2315 */
2416class SearchResultApplier implements SearchResultApplierInterface
2517{
@@ -43,56 +35,22 @@ class SearchResultApplier implements SearchResultApplierInterface
4335 */
4436 private $ currentPage ;
4537
46- /**
47- * @var ScopeConfigInterface
48- */
49- private $ scopeConfig ;
50-
51- /**
52- * @var MetadataPool
53- */
54- private $ metadataPool ;
55-
56- /**
57- * @var StockStatusFilterInterface
58- */
59- private $ stockStatusFilter ;
60-
61- /**
62- * @var StockStatusApplierInterface
63- */
64- private $ stockStatusApplier ;
65-
6638 /**
6739 * @param Collection $collection
6840 * @param SearchResultInterface $searchResult
6941 * @param int $size
7042 * @param int $currentPage
71- * @param ScopeConfigInterface|null $scopeConfig
72- * @param MetadataPool|null $metadataPool
73- * @param StockStatusFilterInterface|null $stockStatusFilter
74- * @param StockStatusApplierInterface|null $stockStatusApplier
7543 */
7644 public function __construct (
7745 Collection $ collection ,
7846 SearchResultInterface $ searchResult ,
7947 int $ size ,
80- int $ currentPage ,
81- ?ScopeConfigInterface $ scopeConfig = null ,
82- ?MetadataPool $ metadataPool = null ,
83- ?StockStatusFilterInterface $ stockStatusFilter = null ,
84- ?StockStatusApplierInterface $ stockStatusApplier = null
48+ int $ currentPage
8549 ) {
8650 $ this ->collection = $ collection ;
8751 $ this ->searchResult = $ searchResult ;
8852 $ this ->size = $ size ;
8953 $ this ->currentPage = $ currentPage ;
90- $ this ->scopeConfig = $ scopeConfig ?? ObjectManager::getInstance ()->get (ScopeConfigInterface::class);
91- $ this ->metadataPool = $ metadataPool ?? ObjectManager::getInstance ()->get (MetadataPool::class);
92- $ this ->stockStatusFilter = $ stockStatusFilter
93- ?? ObjectManager::getInstance ()->get (StockStatusFilterInterface::class);
94- $ this ->stockStatusApplier = $ stockStatusApplier
95- ?? ObjectManager::getInstance ()->get (StockStatusApplierInterface::class);
9654 }
9755
9856 /**
@@ -105,13 +63,10 @@ public function apply()
10563 return ;
10664 }
10765
108- $ ids = $ this ->getProductIdsBySaleability ();
109-
110- if (count ($ ids ) == 0 ) {
111- $ items = $ this ->sliceItems ($ this ->searchResult ->getItems (), $ this ->size , $ this ->currentPage );
112- foreach ($ items as $ item ) {
113- $ ids [] = (int )$ item ->getId ();
114- }
66+ $ items = $ this ->sliceItems ($ this ->searchResult ->getItems (), $ this ->size , $ this ->currentPage );
67+ $ ids = [];
68+ foreach ($ items as $ item ) {
69+ $ ids [] = (int )$ item ->getId ();
11570 }
11671 $ orderList = implode (', ' , $ ids );
11772 $ this ->collection ->getSelect ()
@@ -160,134 +115,4 @@ private function getOffset(int $pageNumber, int $pageSize): int
160115 {
161116 return ($ pageNumber - 1 ) * $ pageSize ;
162117 }
163- /**
164- * Fetch filtered product ids sorted by the saleability and other applied sort orders
165- *
166- * @return array
167- */
168- private function getProductIdsBySaleability (): array
169- {
170- $ ids = [];
171-
172- if (!$ this ->hasShowOutOfStockStatus ()) {
173- return $ ids ;
174- }
175-
176- if ($ this ->collection ->getFlag ('has_stock_status_filter ' )
177- || $ this ->collection ->getFlag ('has_category_filter ' )) {
178- $ categoryId = null ;
179- $ searchCriteria = $ this ->searchResult ->getSearchCriteria ();
180- foreach ($ searchCriteria ->getFilterGroups () as $ filterGroup ) {
181- foreach ($ filterGroup ->getFilters () as $ filter ) {
182- if ($ filter ->getField () === 'category_ids ' ) {
183- $ categoryId = $ filter ->getValue ();
184- break 2 ;
185- }
186- }
187- }
188-
189- if ($ categoryId ) {
190- $ resultSet = $ this ->categoryProductByCustomSortOrder ($ categoryId );
191- foreach ($ resultSet as $ item ) {
192- $ ids [] = (int )$ item ['entity_id ' ];
193- }
194- }
195- }
196-
197- return $ ids ;
198- }
199-
200- /**
201- * Fetch product resultset by custom sort orders
202- *
203- * @param int $categoryId
204- * @return array
205- * @throws \Magento\Framework\Exception\LocalizedException
206- * @throws \Exception
207- */
208- private function categoryProductByCustomSortOrder (int $ categoryId ): array
209- {
210- $ storeId = $ this ->collection ->getStoreId ();
211- $ searchCriteria = $ this ->searchResult ->getSearchCriteria ();
212- $ sortOrders = $ searchCriteria ->getSortOrders () ?? [];
213- $ sortOrders = array_merge (['is_salable ' => \Magento \Framework \DB \Select::SQL_DESC ], $ sortOrders );
214- $ connection = $ this ->collection ->getConnection ();
215- $ query = clone $ connection ->select ()
216- ->reset (\Magento \Framework \DB \Select::ORDER )
217- ->reset (\Magento \Framework \DB \Select::LIMIT_COUNT )
218- ->reset (\Magento \Framework \DB \Select::LIMIT_OFFSET )
219- ->reset (\Magento \Framework \DB \Select::COLUMNS );
220- $ query ->from (
221- ['e ' => $ this ->collection ->getTable ('catalog_product_entity ' )],
222- ['e.entity_id ' ]
223- );
224- $ this ->stockStatusApplier ->setSearchResultApplier (true );
225- $ query = $ this ->stockStatusFilter ->execute ($ query , 'e ' , 'stockItem ' );
226- $ query ->join (
227- ['cat_index ' => $ this ->collection ->getTable ('catalog_category_product_index_store ' . $ storeId )],
228- 'cat_index.product_id = e.entity_id '
229- . ' AND cat_index.category_id = ' . $ categoryId
230- . ' AND cat_index.store_id = ' . $ storeId ,
231- ['cat_index.position ' ]
232- );
233-
234- $ productIds = [];
235- foreach ($ this ->searchResult ->getItems () as $ item ) {
236- $ productIds [] = $ item ->getId ();
237- }
238-
239- $ query ->where ('e.entity_id IN(?) ' , $ productIds );
240-
241- foreach ($ sortOrders as $ field => $ dir ) {
242- if ($ field === 'name ' ) {
243- $ entityTypeId = $ this ->collection ->getEntity ()->getTypeId ();
244- $ entityMetadata = $ this ->metadataPool ->getMetadata (ProductInterface::class);
245- $ linkField = $ entityMetadata ->getLinkField ();
246- $ query ->joinLeft (
247- ['product_var ' => $ this ->collection ->getTable ('catalog_product_entity_varchar ' )],
248- "product_var. {$ linkField } = e. {$ linkField } AND product_var.attribute_id =
249- (SELECT attribute_id FROM eav_attribute WHERE entity_type_id= {$ entityTypeId }
250- AND attribute_code='name') " ,
251- ['product_var.value AS name ' ]
252- );
253- } elseif ($ field === 'price ' ) {
254- $ query ->joinLeft (
255- ['price_index ' => $ this ->collection ->getTable ('catalog_product_index_price ' )],
256- 'price_index.entity_id = e.entity_id '
257- . ' AND price_index.customer_group_id = 0 '
258- . ' AND price_index.website_id = (Select website_id FROM store WHERE store_id = '
259- . $ storeId . ') ' ,
260- ['price_index.max_price AS price ' ]
261- );
262- }
263- $ columnFilters = [];
264- $ columnsParts = $ query ->getPart ('columns ' );
265- foreach ($ columnsParts as $ columns ) {
266- $ columnFilters [] = $ columns [2 ] ?? $ columns [1 ];
267- }
268- if (in_array ($ field , $ columnFilters , true )) {
269- $ query ->order (new \Zend_Db_Expr ("{$ field } {$ dir }" ));
270- }
271- }
272-
273- $ query ->limit (
274- $ searchCriteria ->getPageSize (),
275- $ searchCriteria ->getCurrentPage () * $ searchCriteria ->getPageSize ()
276- );
277-
278- return $ connection ->fetchAssoc ($ query ) ?? [];
279- }
280-
281- /**
282- * Returns if display out of stock status set or not in catalog inventory
283- *
284- * @return bool
285- */
286- private function hasShowOutOfStockStatus (): bool
287- {
288- return (bool ) $ this ->scopeConfig ->getValue (
289- \Magento \CatalogInventory \Model \Configuration::XML_PATH_SHOW_OUT_OF_STOCK ,
290- \Magento \Store \Model \ScopeInterface::SCOPE_STORE
291- );
292- }
293118}
0 commit comments