diff --git a/vendor/magento/module-configurable-product/Plugin/CatalogWidget/Block/Product/ProductsListPlugin.php b/vendor/magento/module-configurable-product/Plugin/CatalogWidget/Block/Product/ProductsListPlugin.php index 782bce8772c7c..8f1afbb6b955a 100644 --- a/vendor/magento/module-configurable-product/Plugin/CatalogWidget/Block/Product/ProductsListPlugin.php +++ b/vendor/magento/module-configurable-product/Plugin/CatalogWidget/Block/Product/ProductsListPlugin.php @@ -1,13 +1,14 @@ productCollectionFactory = $productCollectionFactory; $this->catalogProductVisibility = $catalogProductVisibility; $this->resource = $resource; $this->metadataPool = $metadataPool; + $this->storeManager = $storeManager; + $this->config = $config; } /** * Adds configurable products to the item list if child products are already part of the collection * + * Configurable products are only added if the child products are not visible individually + * * @param ProductsList $subject * @param Collection $result * @return Collection @@ -70,36 +90,82 @@ public function afterCreateCollection(ProductsList $subject, Collection $result) { $notVisibleCollection = $subject->getBaseCollection(); $currentIds = $result->getAllIds(); - $searchProducts = array_merge($currentIds, $notVisibleCollection->getAllIds()); - - if (!empty($searchProducts)) { - $linkField = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class) - ->getLinkField(); - $connection = $this->resource->getConnection(); - $productIds = $connection->fetchCol( - $connection - ->select() - ->from(['e' => $this->resource->getTableName('catalog_product_entity')], ['link_table.parent_id']) - ->joinInner( - ['link_table' => $this->resource->getTableName('catalog_product_super_link')], - 'link_table.product_id = e.' . $linkField, - [] - ) - ->where('link_table.product_id IN (?)', $searchProducts) - ); - - $configurableProductCollection = $this->productCollectionFactory->create(); - $configurableProductCollection->setVisibility($this->catalogProductVisibility->getVisibleInCatalogIds()); - $configurableProductCollection->addIdFilter($productIds); - - /** @var Product $item */ - foreach ($configurableProductCollection->getItems() as $item) { - if (false === in_array($item->getId(), $currentIds)) { - $result->addItem($item->load($item->getId())); - } - } + $searchProducts = array_unique(array_merge($currentIds, $notVisibleCollection->getAllIds())); + + if (empty($searchProducts)) { + return $result; } - return $result; + $linkField = $this->metadataPool->getMetadata(ProductInterface::class) + ->getLinkField(); + $connection = $this->resource->getConnection(); + $visibilityAttributeId = $this->config->getAttribute(Product::ENTITY, 'visibility')->getId(); + $storeId = $this->storeManager->getStore()->getId(); + + $select = $connection->select() + ->from( + ['e' => $this->resource->getTableName('catalog_product_entity')], + [] + ) + ->joinInner( + ['link_table' => $this->resource->getTableName('catalog_product_super_link')], + 'link_table.product_id = e.entity_id', + [] + ) + ->joinInner( + ['entity_table' => $this->resource->getTableName('catalog_product_entity')], + 'entity_table.' . $linkField . ' = link_table.parent_id', + ['entity_table.entity_id'] + ) + ->joinInner( + ['visibility_default' => $this->resource->getTableName('catalog_product_entity_int')], + implode(' AND ', [ + 'visibility_default.' . $linkField . ' = e.' . $linkField, + $connection->quoteInto('visibility_default.attribute_id = ?', $visibilityAttributeId), + 'visibility_default.store_id = 0', + ]), + [] + ) + ->joinLeft( + ['visibility_store' => $this->resource->getTableName('catalog_product_entity_int')], + implode(' AND ', [ + 'visibility_store.' . $linkField . ' = e.' . $linkField, + $connection->quoteInto('visibility_store.attribute_id = ?', $visibilityAttributeId), + $connection->quoteInto('visibility_store.store_id = ?', $storeId), + ]), + [] + ) + ->where('link_table.product_id IN (?)', $searchProducts); + $visibilityExpr = $connection->getCheckSql( + 'visibility_store.value IS NULL', + 'visibility_default.value', + 'visibility_store.value' + ); + $select->where( + $visibilityExpr . ' = ?', + Visibility::VISIBILITY_NOT_VISIBLE + ); + + $productIds = $connection->fetchCol($select); + + if (empty($productIds)) { + return $result; + } + + $visibleCatalogIds = $this->catalogProductVisibility->getVisibleInCatalogIds(); + $configurableProductCollection = $this->productCollectionFactory->create(); + $configurableProductCollection->setVisibility($visibleCatalogIds); + $configurableProductCollection->addIdFilter($productIds); + + $configurableEntityIds = $configurableProductCollection->getAllIds(); + if (empty($configurableEntityIds)) { + return $result; + } + + $filteredCollection = $subject->getBaseCollection(); + $filteredCollection->setVisibility($visibleCatalogIds); + $filteredCollection->getSelect()->orWhere('e.entity_id IN (?)', $configurableEntityIds); + + return $filteredCollection; } }