diff --git a/app/code/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewrite.php b/app/code/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewrite.php new file mode 100644 index 0000000000000000000000000000000000000000..82a25531757a2fb3cd90da751467d69fe6037cfe --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewrite.php @@ -0,0 +1,83 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogUrlRewrite\Plugin\Eav\AttributeSetRepository; + +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Eav\Api\AttributeSetRepositoryInterface; +use Magento\Eav\Api\Data\AttributeSetInterface; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; + +/** + * Remove url rewrites for products with given attribute set. + */ +class RemoveProductUrlRewrite +{ + /** + * @var int + */ + private $chunkSize = 1000; + + /** + * @var UrlPersistInterface + */ + private $urlPersist; + + /** + * @var CollectionFactory + */ + private $collectionFactory; + + /** + * ProductUrlRewriteProcessor constructor. + * + * @param UrlPersistInterface $urlPersist + * @param CollectionFactory $collectionFactory + */ + public function __construct(UrlPersistInterface $urlPersist, CollectionFactory $collectionFactory) + { + $this->urlPersist = $urlPersist; + $this->collectionFactory = $collectionFactory; + } + + /** + * Remove url rewrites for products with given attribute set. + * + * @param AttributeSetRepositoryInterface $subject + * @param \Closure $proceed + * @param AttributeSetInterface $attributeSet + * @return bool + * + * @SuppressWarnings(PHPMD.UnusedFormalParameter) + */ + public function aroundDelete( + AttributeSetRepositoryInterface $subject, + \Closure $proceed, + AttributeSetInterface $attributeSet + ) { + /** @var Collection $productCollection */ + $productCollection = $this->collectionFactory->create(); + $productCollection->addFieldToFilter('attribute_set_id', ['eq' => $attributeSet->getId()]); + $productIds = $productCollection->getAllIds(); + $result = $proceed($attributeSet); + if (!empty($productIds)) { + $productIds = array_chunk($productIds, $this->chunkSize); + foreach ($productIds as $ids) { + $this->urlPersist->deleteByData( + [ + UrlRewrite::ENTITY_ID => $ids, + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + ] + ); + } + } + + return $result; + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cf2337bf7c76c76885d765c6da4fdbb634fbeb43 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Test/Unit/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php @@ -0,0 +1,113 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogUrlRewrite\Test\Unit\Plugin\Eav\AttributeSetRepository; + +use Magento\Catalog\Model\ResourceModel\Product\Collection; +use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; +use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\CatalogUrlRewrite\Plugin\Eav\AttributeSetRepository\RemoveProductUrlRewrite; +use Magento\Eav\Api\AttributeSetRepositoryInterface; +use Magento\Eav\Api\Data\AttributeSetInterface; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\UrlRewrite\Model\UrlPersistInterface; +use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; +use PHPUnit\Framework\TestCase; + +/** + * Provide tests for RemoveProductUrlRewrite plugin. + */ +class RemoveProductUrlRewriteTest extends TestCase +{ + /** + * @var RemoveProductUrlRewrite + */ + private $testSubject; + + /** + * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + private $collectionFactory; + + /** + * @var UrlPersistInterface|\PHPUnit_Framework_MockObject_MockObject + */ + private $urlPersist; + + /** + * @inheritdoc + */ + protected function setUp() + { + $objectManager = new ObjectManager($this); + $this->collectionFactory = $this->getMockBuilder(CollectionFactory::class) + ->disableOriginalConstructor() + ->setMethods(['create']) + ->getMock(); + $this->urlPersist = $this->getMockBuilder(UrlPersistInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $this->testSubject = $objectManager->getObject( + RemoveProductUrlRewrite::class, + [ + 'collectionFactory' => $this->collectionFactory, + 'urlPersist' => $this->urlPersist, + ] + ); + } + + /** + * Test plugin will delete all url rewrites for products with given attribute set. + */ + public function testAroundDelete() + { + $attributeSetId = '1'; + $productId = '1'; + + /** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collection */ + $collection = $this->getMockBuilder(Collection::class) + ->disableOriginalConstructor() + ->getMock(); + $collection->expects(self::once()) + ->method('addFieldToFilter') + ->with(self::identicalTo('attribute_set_id'), self::identicalTo(['eq' => $attributeSetId])); + $collection->expects(self::once()) + ->method('getAllIds') + ->willReturn([$productId]); + + $this->collectionFactory->expects(self::once()) + ->method('create') + ->willReturn($collection); + + $this->urlPersist->expects(self::once()) + ->method('deleteByData') + ->with(self::identicalTo( + [ + UrlRewrite::ENTITY_ID => [$productId], + UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, + ] + )); + /** @var AttributeSetRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $attributeSetRepository */ + $attributeSetRepository = $this->getMockBuilder(AttributeSetRepositoryInterface::class) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $proceed = function () { + return true; + }; + + /** @var AttributeSetInterface|\PHPUnit_Framework_MockObject_MockObject $attributeSet */ + $attributeSet = $this->getMockBuilder(AttributeSetInterface::class) + ->setMethods(['getId']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $attributeSet->expects(self::once()) + ->method('getId') + ->willReturn($attributeSetId); + + $this->testSubject->aroundDelete($attributeSetRepository, $proceed, $attributeSet); + } +} diff --git a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml index 32ecc97d0f85f0929f1f1f96d601d6899b21ff3c..ebac217df5fcbd0215a6d677e4ca13e5759a644f 100644 --- a/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml +++ b/app/code/Magento/CatalogUrlRewrite/etc/adminhtml/di.xml @@ -25,6 +25,9 @@ <type name="Magento\Catalog\Model\Category\DataProvider"> <plugin name="category_ui_form_url_key_plugin" type="Magento\CatalogUrlRewrite\Plugin\Catalog\Block\Adminhtml\Category\Tab\Attributes"/> </type> + <type name="Magento\Eav\Api\AttributeSetRepositoryInterface"> + <plugin name="attribute_set_delete_plugin" type="Magento\CatalogUrlRewrite\Plugin\Eav\AttributeSetRepository\RemoveProductUrlRewrite"/> + </type> <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool"> <arguments> <argument name="modifiers" xsi:type="array"> diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php new file mode 100644 index 0000000000000000000000000000000000000000..3791bb7894ec4ae296c02c4267c3b9f080c2bdec --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/Plugin/Eav/AttributeSetRepository/RemoveProductUrlRewriteTest.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +namespace Magento\CatalogUrlRewrite\Plugin\Eav\AttributeSetRepository; + +use Magento\Catalog\Api\ProductRepositoryInterface; +use Magento\Eav\Api\AttributeSetRepositoryInterface; +use Magento\Eav\Model\Entity\Attribute\Set; +use Magento\TestFramework\Helper\Bootstrap; +use Magento\TestFramework\Interception\PluginList; +use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory; +use PHPUnit\Framework\TestCase; + +/** + * Provide tests for RemoveProductUrlRewrite plugin. + * @magentoAppArea adminhtml + */ +class RemoveProductUrlRewriteTest extends TestCase +{ + /** + * @return void + */ + public function testRemoveProductUrlRewriteIsRegistered() + { + $pluginInfo = Bootstrap::getObjectManager()->get(PluginList::class) + ->get(AttributeSetRepositoryInterface::class, []); + self::assertSame(RemoveProductUrlRewrite::class, $pluginInfo['attribute_set_delete_plugin']['instance']); + } + + /** + * Test url rewrite will be removed for product with given attribute set, if one will be deleted. + * + * @magentoDataFixture Magento/CatalogUrlRewrite/_files/attribute_set_with_product.php + * @magentoDbIsolation disabled + */ + public function testAroundDelete() + { + $attributeSet = Bootstrap::getObjectManager()->get(Set::class); + $attributeSet->load('empty_attribute_set', 'attribute_set_name'); + + $productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class); + $product = $productRepository->get('simple'); + + $urlRewriteCollection = Bootstrap::getObjectManager()->get(UrlRewriteCollectionFactory::class)->create(); + $urlRewriteCollection->addFieldToFilter('entity_type', 'product'); + $urlRewriteCollection->addFieldToFilter('entity_id', $product->getId()); + + self::assertSame(1, $urlRewriteCollection->getSize()); + + $attributeSetRepository = Bootstrap::getObjectManager()->get(AttributeSetRepositoryInterface::class); + $attributeSetRepository->deleteById($attributeSet->getAttributeSetId()); + + $urlRewriteCollection = Bootstrap::getObjectManager()->get(UrlRewriteCollectionFactory::class)->create(); + $urlRewriteCollection->addFieldToFilter('entity_type', 'product'); + $urlRewriteCollection->addFieldToFilter('entity_id', $product->getId()); + + self::assertSame(0, $urlRewriteCollection->getSize()); + } +} diff --git a/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/attribute_set_with_product.php b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/attribute_set_with_product.php new file mode 100644 index 0000000000000000000000000000000000000000..95f277c7124bd83389452bd933e7fd0e94cac862 --- /dev/null +++ b/dev/tests/integration/testsuite/Magento/CatalogUrlRewrite/_files/attribute_set_with_product.php @@ -0,0 +1,11 @@ +<?php +/** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ + +require __DIR__ . '/../../Eav/_files/empty_attribute_set.php'; +require __DIR__ . '/../../Catalog/_files/product_simple.php'; + +$product->setAttributeSetId($attributeSet->getId()); +$product->save();