-
Notifications
You must be signed in to change notification settings - Fork 9.4k
12110: Missing cascade into attribute set deletion. #12167
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
817bc5f
5cd2757
95f11ae
14132ce
88f218d
dd4dec8
3143bbb
9df89df
c14e9e3
c7fbbcc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename plugin to RemoveProducts There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
{ | ||
/** | ||
* @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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Use after plugin instead of around There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, may be I have missed something. But, if I'll use after plugin I won't have attribute set id in results, only bool true and instance of AttributeSetRepository. And I need attribute set id in order to filter product collection. |
||
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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove products from db There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
[ | ||
UrlRewrite::ENTITY_ID => $ids, | ||
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE, | ||
] | ||
); | ||
} | ||
} | ||
|
||
return $result; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 enabled | ||
*/ | ||
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()); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?php | ||
/** | ||
* Copyright © Magento, Inc. All rights reserved. | ||
* See COPYING.txt for license details. | ||
*/ | ||
|
||
require __DIR__ . '/../../Catalog/_files/product_simple_rollback.php'; | ||
require __DIR__ . '/../../Eav/_files/empty_attribute_set_rollback.php'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move plugin to Catalog module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.