diff --git a/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php b/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php new file mode 100644 index 0000000000000..499f0cd2ca9c5 --- /dev/null +++ b/app/code/Magento/Bundle/Model/Plugin/Frontend/Product.php @@ -0,0 +1,48 @@ +type = $type; + } + + /** + * Add child identities to product identities + * + * @param CatalogProduct $product + * @param array $identities + * @return array + */ + public function afterGetIdentities(CatalogProduct $product, array $identities): array + { + foreach ($this->type->getChildrenIds($product->getEntityId()) as $childIds) { + foreach ($childIds as $childId) { + $identities[] = CatalogProduct::CACHE_TAG . '_' . $childId; + } + } + + return array_unique($identities); + } +} diff --git a/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php new file mode 100644 index 0000000000000..ee08618eab5dd --- /dev/null +++ b/app/code/Magento/Bundle/Test/Unit/Model/Plugin/Frontend/ProductTest.php @@ -0,0 +1,73 @@ +product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getEntityId']) + ->getMock(); + + $this->type = $this->getMockBuilder(Type::class) + ->disableOriginalConstructor() + ->setMethods(['getChildrenIds']) + ->getMock(); + + $this->plugin = new ProductPlugin($this->type); + } + + public function testAfterGetIdentities() + { + $baseIdentities = [ + 'SomeCacheId', + 'AnotherCacheId', + ]; + $id = 12345; + $childIds = [ + 1 => [1, 2, 5, 100500], + 12 => [7, 22, 45, 24612] + ]; + $expectedIdentities = [ + 'SomeCacheId', + 'AnotherCacheId', + Product::CACHE_TAG . '_' . 1, + Product::CACHE_TAG . '_' . 2, + Product::CACHE_TAG . '_' . 5, + Product::CACHE_TAG . '_' . 100500, + Product::CACHE_TAG . '_' . 7, + Product::CACHE_TAG . '_' . 22, + Product::CACHE_TAG . '_' . 45, + Product::CACHE_TAG . '_' . 24612, + ]; + $this->product->expects($this->once()) + ->method('getEntityId') + ->will($this->returnValue($id)); + $this->type->expects($this->once()) + ->method('getChildrenIds') + ->with($id) + ->will($this->returnValue($childIds)); + $identities = $this->plugin->afterGetIdentities($this->product, $baseIdentities); + $this->assertEquals($expectedIdentities, $identities); + } +} diff --git a/app/code/Magento/Bundle/etc/frontend/di.xml b/app/code/Magento/Bundle/etc/frontend/di.xml index 54f6d3b4b0f42..fc820ff87a129 100644 --- a/app/code/Magento/Bundle/etc/frontend/di.xml +++ b/app/code/Magento/Bundle/etc/frontend/di.xml @@ -13,4 +13,7 @@ + + + diff --git a/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php b/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php new file mode 100644 index 0000000000000..92b7ab0d88ea8 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtender.php @@ -0,0 +1,48 @@ +configurableType = $configurableType; + } + + /** + * Add child identities to product identities + * + * @param Product $subject + * @param array $identities + * @return array + */ + public function afterGetIdentities(Product $subject, array $identities): array + { + foreach ($this->configurableType->getChildrenIds($subject->getId()) as $childIds) { + foreach ($childIds as $childId) { + $identities[] = Product::CACHE_TAG . '_' . $childId; + } + } + + return array_unique($identities); + } +} diff --git a/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php new file mode 100644 index 0000000000000..b4fb5ccfaa558 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Unit/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php @@ -0,0 +1,77 @@ +product = $this->getMockBuilder(Product::class) + ->disableOriginalConstructor() + ->setMethods(['getId']) + ->getMock(); + + $this->configurableTypeMock = $this->getMockBuilder(Configurable::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->plugin = new ProductIdentitiesExtender($this->configurableTypeMock); + } + + public function testAfterGetIdentities() + { + $identities = [ + 'SomeCacheId', + 'AnotherCacheId', + ]; + $productId = 12345; + $childIdentities = [ + 0 => [1, 2, 5, 100500] + ]; + $expectedIdentities = [ + 'SomeCacheId', + 'AnotherCacheId', + Product::CACHE_TAG . '_' . 1, + Product::CACHE_TAG . '_' . 2, + Product::CACHE_TAG . '_' . 5, + Product::CACHE_TAG . '_' . 100500, + ]; + + $this->product->expects($this->once()) + ->method('getId') + ->willReturn($productId); + + $this->configurableTypeMock->expects($this->once()) + ->method('getChildrenIds') + ->with($productId) + ->willReturn($childIdentities); + + $productIdentities = $this->plugin->afterGetIdentities($this->product, $identities); + $this->assertEquals($expectedIdentities, $productIdentities); + } +} diff --git a/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml b/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml index bb830c36b929d..df96829b354c8 100644 --- a/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml +++ b/app/code/Magento/ConfigurableProduct/etc/frontend/di.xml @@ -10,4 +10,7 @@ + + + diff --git a/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php b/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php new file mode 100644 index 0000000000000..91dcd5f3e8d5b --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/Bundle/Model/Plugin/Frontend/ProductTest.php @@ -0,0 +1,71 @@ +get(PluginList::class) + ->get(\Magento\Catalog\Model\Product::class, []); + $this->assertSame(Product::class, $pluginInfo['bundle']['instance']); + } + + /** + * Check plugin will add children ids to bundle product identities on storefront. + * + * @magentoDataFixture Magento/Bundle/_files/product.php + * @magentoAppArea frontend + * @return void + */ + public function testGetIdentitiesForBundleProductOnStorefront(): void + { + $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $bundleProduct = $productRepository->get('bundle-product'); + $simpleProduct = $productRepository->get('simple'); + $expectedIdentities = [ + 'cat_p_' . $bundleProduct->getId(), + 'cat_p', + 'cat_p_' . $simpleProduct->getId(), + + ]; + $this->assertEquals($expectedIdentities, $bundleProduct->getIdentities()); + } + + /** + * Check plugin won't add children ids to bundle product identities in admin area. + * + * @magentoDataFixture Magento/Bundle/_files/product.php + * @magentoAppArea adminhtml + * @return void + */ + public function testGetIdentitiesForBundleProductInAdminArea(): void + { + $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $bundleProduct = $productRepository->get('bundle-product'); + $expectedIdentities = [ + 'cat_p_' . $bundleProduct->getId(), + ]; + $this->assertEquals($expectedIdentities, $bundleProduct->getIdentities()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php new file mode 100644 index 0000000000000..1fffd701c509f --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Plugin/Frontend/ProductIdentitiesExtenderTest.php @@ -0,0 +1,73 @@ +get(PluginList::class) + ->get(\Magento\Catalog\Model\Product::class, []); + $this->assertSame(ProductIdentitiesExtender::class, $pluginInfo['product_identities_extender']['instance']); + } + + /** + * Check plugin will add children ids to configurable product identities on storefront. + * + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * @magentoAppArea frontend + * @return void + */ + public function testGetIdentitiesForConfigurableProductOnStorefront(): void + { + $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $configurableProduct = $productRepository->get('configurable'); + $simpleProduct1 = $productRepository->get('simple_10'); + $simpleProduct2 = $productRepository->get('simple_20'); + $expectedIdentities = [ + 'cat_p_' . $configurableProduct->getId(), + 'cat_p', + 'cat_p_' . $simpleProduct1->getId(), + 'cat_p_' . $simpleProduct2->getId(), + + ]; + $this->assertEquals($expectedIdentities, $configurableProduct->getIdentities()); + } + + /** + * Check plugin won't add children ids to configurable product identities in admin area. + * + * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php + * @magentoAppArea adminhtml + * @return void + */ + public function testGetIdentitiesForConfigurableProductInAdminArea(): void + { + $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $configurableProduct = $productRepository->get('configurable'); + $expectedIdentities = [ + 'cat_p_' . $configurableProduct->getId(), + ]; + $this->assertEquals($expectedIdentities, $configurableProduct->getIdentities()); + } +}