Skip to content

Commit a50843f

Browse files
Merge pull request #1810 from magento-engcom/develop-prs
[EngCom] Public Pull Requests - develop - MAGETWO-85026: [Backport 2.3] #12450: Set Current Store from Store Code if isUseStoreInUrl #12545 - MAGETWO-85016: 12111: Missing cascade into attribute set deletion.[port] #12538 - MAGETWO-84980: Trying to get data from non existent products #12540 - MAGETWO-84933: PR #12466 [BACKPORT 2.3] #12523
2 parents f93b914 + b4651a9 commit a50843f

File tree

13 files changed

+276
-8
lines changed

13 files changed

+276
-8
lines changed

app/code/Magento/Catalog/Block/Product/ListProduct.php

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,21 @@ public function prepareSortableFieldsByCategory($category)
265265
public function getIdentities()
266266
{
267267
$identities = [];
268-
foreach ($this->_getProductCollection() as $item) {
269-
$identities = array_merge($identities, $item->getIdentities());
270-
}
268+
271269
$category = $this->getLayer()->getCurrentCategory();
272270
if ($category) {
273271
$identities[] = Product::CACHE_PRODUCT_CATEGORY_TAG . '_' . $category->getId();
274272
}
273+
274+
//Check if category page shows only static block (No products)
275+
if ($category->getData('display_mode') == Category::DM_PAGE) {
276+
return $identities;
277+
}
278+
279+
foreach ($this->_getProductCollection() as $item) {
280+
$identities = array_merge($identities, $item->getIdentities());
281+
}
282+
275283
return $identities;
276284
}
277285

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Plugin\Model\AttributeSetRepository;
8+
9+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
10+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
11+
use Magento\Eav\Api\AttributeSetRepositoryInterface;
12+
use Magento\Eav\Api\Data\AttributeSetInterface;
13+
14+
/**
15+
* Delete related products after attribute set successfully removed.
16+
*/
17+
class RemoveProducts
18+
{
19+
/**
20+
* Retrieve products related to specific attribute set.
21+
*
22+
* @var CollectionFactory
23+
*/
24+
private $collectionFactory;
25+
26+
/**
27+
* RemoveProducts constructor.
28+
*
29+
* @param CollectionFactory $collectionFactory
30+
*/
31+
public function __construct(CollectionFactory $collectionFactory)
32+
{
33+
$this->collectionFactory = $collectionFactory;
34+
}
35+
36+
/**
37+
* Delete related to specific attribute set products, if attribute set was removed successfully.
38+
*
39+
* @param AttributeSetRepositoryInterface $subject
40+
* @param bool $result
41+
* @param AttributeSetInterface $attributeSet
42+
* @return bool
43+
*
44+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
45+
*/
46+
public function afterDelete(
47+
AttributeSetRepositoryInterface $subject,
48+
bool $result,
49+
AttributeSetInterface $attributeSet
50+
) {
51+
/** @var Collection $productCollection */
52+
$productCollection = $this->collectionFactory->create();
53+
$productCollection->addFieldToFilter('attribute_set_id', ['eq' => $attributeSet->getId()]);
54+
$productCollection->delete();
55+
56+
return $result;
57+
}
58+
}

app/code/Magento/Catalog/Setup/UpgradeSchema.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class UpgradeSchema implements UpgradeSchemaInterface
2121
/**
2222
* {@inheritdoc}
2323
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
24+
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
25+
* @SuppressWarnings(PHPMD.NPathComplexity)
2426
*/
2527
public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)
2628
{
@@ -126,6 +128,10 @@ public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $con
126128
$this->fixCustomerGroupIdColumn($setup);
127129
}
128130

131+
if (version_compare($context->getVersion(), '2.2.4', '<')) {
132+
$this->removeAttributeSetRelation($setup);
133+
}
134+
129135
$setup->endSetup();
130136
}
131137

@@ -699,4 +705,20 @@ private function addReplicaTable(SchemaSetupInterface $setup, $existingTable, $r
699705
);
700706
$setup->getConnection()->query($sql);
701707
}
708+
709+
/**
710+
* Remove foreign key between catalog_product_entity and eav_attribute_set tables.
711+
* Drop foreign key to delegate cascade on delete to plugin.
712+
* @see \Magento\Catalog\Plugin\Model\AttributeSetRepository\RemoveProducts
713+
*
714+
* @param SchemaSetupInterface $setup
715+
* @return void
716+
*/
717+
private function removeAttributeSetRelation(SchemaSetupInterface $setup)
718+
{
719+
$setup->getConnection()->dropForeignKey(
720+
$setup->getTable('catalog_product_entity'),
721+
$setup->getFkName('catalog_product_entity', 'attribute_set_id', 'eav_attribute_set', 'attribute_set_id')
722+
);
723+
}
702724
}

app/code/Magento/Catalog/Test/Unit/Block/Product/ListProductTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public function testGetIdentities()
192192
->will($this->returnValue($this->toolbarMock));
193193

194194
$this->assertEquals(
195-
[$productTag, $categoryTag],
195+
[$categoryTag, $productTag],
196196
$this->block->getIdentities()
197197
);
198198
$this->assertEquals(
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Plugin\Model\AttributeSetRepository;
8+
9+
use Magento\Catalog\Model\ResourceModel\Product\Collection;
10+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
11+
use Magento\Catalog\Plugin\Model\AttributeSetRepository\RemoveProducts;
12+
use Magento\Eav\Api\AttributeSetRepositoryInterface;
13+
use Magento\Eav\Api\Data\AttributeSetInterface;
14+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
15+
use PHPUnit\Framework\TestCase;
16+
17+
/**
18+
* Provide tests for RemoveProducts plugin.
19+
*/
20+
class RemoveProductsTest extends TestCase
21+
{
22+
/**
23+
* @var RemoveProducts
24+
*/
25+
private $testSubject;
26+
27+
/**
28+
* @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
29+
*/
30+
private $collectionFactory;
31+
32+
/**
33+
* @inheritdoc
34+
*/
35+
protected function setUp()
36+
{
37+
$objectManager = new ObjectManager($this);
38+
$this->collectionFactory = $this->getMockBuilder(CollectionFactory::class)
39+
->disableOriginalConstructor()
40+
->setMethods(['create'])
41+
->getMock();
42+
$this->testSubject = $objectManager->getObject(
43+
RemoveProducts::class,
44+
[
45+
'collectionFactory' => $this->collectionFactory,
46+
]
47+
);
48+
}
49+
50+
/**
51+
* Test plugin will delete all related products for given attribute set.
52+
*/
53+
public function testAfterDelete()
54+
{
55+
$attributeSetId = '1';
56+
57+
/** @var Collection|\PHPUnit_Framework_MockObject_MockObject $collection */
58+
$collection = $this->getMockBuilder(Collection::class)
59+
->disableOriginalConstructor()
60+
->getMock();
61+
$collection->expects(self::once())
62+
->method('addFieldToFilter')
63+
->with(self::identicalTo('attribute_set_id'), self::identicalTo(['eq' => $attributeSetId]));
64+
$collection->expects(self::once())
65+
->method('delete');
66+
67+
$this->collectionFactory->expects(self::once())
68+
->method('create')
69+
->willReturn($collection);
70+
71+
/** @var AttributeSetRepositoryInterface|\PHPUnit_Framework_MockObject_MockObject $attributeSetRepository */
72+
$attributeSetRepository = $this->getMockBuilder(AttributeSetRepositoryInterface::class)
73+
->disableOriginalConstructor()
74+
->getMockForAbstractClass();
75+
76+
/** @var AttributeSetInterface|\PHPUnit_Framework_MockObject_MockObject $attributeSet */
77+
$attributeSet = $this->getMockBuilder(AttributeSetInterface::class)
78+
->setMethods(['getId'])
79+
->disableOriginalConstructor()
80+
->getMockForAbstractClass();
81+
$attributeSet->expects(self::once())
82+
->method('getId')
83+
->willReturn($attributeSetId);
84+
85+
self::assertTrue($this->testSubject->afterDelete($attributeSetRepository, true, $attributeSet));
86+
}
87+
}

app/code/Magento/Catalog/etc/adminhtml/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,7 @@
184184
<argument name="scopeOverriddenValue" xsi:type="object">Magento\Catalog\Model\Attribute\ScopeOverriddenValue</argument>
185185
</arguments>
186186
</type>
187+
<type name="Magento\Eav\Api\AttributeSetRepositoryInterface">
188+
<plugin name="remove_products" type="Magento\Catalog\Plugin\Model\AttributeSetRepository\RemoveProducts"/>
189+
</type>
187190
</config>

app/code/Magento/Catalog/etc/module.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
-->
88
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
9-
<module name="Magento_Catalog" setup_version="2.2.3">
9+
<module name="Magento_Catalog" setup_version="2.2.4">
1010
<sequence>
1111
<module name="Magento_Eav"/>
1212
<module name="Magento_Cms"/>

app/code/Magento/Reports/Model/ResourceModel/Quote/Item/Collection.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,10 @@ protected function _afterLoad()
220220
$orderData = $this->getOrdersData($productIds);
221221
foreach ($items as $item) {
222222
$item->setId($item->getProductId());
223-
$item->setPrice($productData[$item->getProductId()]['price'] * $item->getBaseToGlobalRate());
224-
$item->setName($productData[$item->getProductId()]['name']);
223+
if (isset($productData[$item->getProductId()])) {
224+
$item->setPrice($productData[$item->getProductId()]['price'] * $item->getBaseToGlobalRate());
225+
$item->setName($productData[$item->getProductId()]['name']);
226+
}
225227
$item->setOrders(0);
226228
if (isset($orderData[$item->getProductId()])) {
227229
$item->setOrders($orderData[$item->getProductId()]['orders']);

app/code/Magento/Store/App/Request/PathInfoProcessor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function process(\Magento\Framework\App\RequestInterface $request, $pathI
4343

4444
if ($store->isUseStoreInUrl()) {
4545
if (!$request->isDirectAccessFrontendName($storeCode)) {
46-
$this->storeManager->setCurrentStore($storeCode);
46+
$this->storeManager->setCurrentStore($store->getCode());
4747
$pathInfo = '/' . (isset($pathParts[1]) ? $pathParts[1] : '');
4848
return $pathInfo;
4949
} elseif (!empty($storeCode)) {

app/code/Magento/Store/Test/Unit/App/Request/PathInfoProcessorTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ public function testProcessIfStoreExistsAndIsNotDirectAcccessToFrontName()
4747
)->with(
4848
'storeCode'
4949
)->willReturn($store);
50+
$store->expects($this->once())->method('getCode')->will($this->returnValue('storeCode'));
5051
$store->expects($this->once())->method('isUseStoreInUrl')->will($this->returnValue(true));
5152
$this->_requestMock->expects(
5253
$this->once()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Plugin\Model\AttributeSetRepository;
8+
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
11+
use Magento\Eav\Api\AttributeSetRepositoryInterface;
12+
use Magento\Eav\Model\Entity\Attribute\Set;
13+
use Magento\TestFramework\Helper\Bootstrap;
14+
use Magento\TestFramework\Interception\PluginList;
15+
use Magento\UrlRewrite\Model\ResourceModel\UrlRewriteCollectionFactory;
16+
use PHPUnit\Framework\TestCase;
17+
18+
/**
19+
* Provide tests for RemoveProducts plugin.
20+
* @magentoAppArea adminhtml
21+
*/
22+
class RemoveProductsTest extends TestCase
23+
{
24+
/**
25+
* @return void
26+
*/
27+
public function testRemoveProductsIsRegistered()
28+
{
29+
$pluginInfo = Bootstrap::getObjectManager()->get(PluginList::class)
30+
->get(AttributeSetRepositoryInterface::class, []);
31+
self::assertSame(RemoveProducts::class, $pluginInfo['remove_products']['instance']);
32+
}
33+
34+
/**
35+
* Test related to given attribute set products will be removed, if attribute set will be deleted.
36+
*
37+
* @magentoDataFixture Magento/Catalog/_files/attribute_set_with_product.php
38+
*/
39+
public function testAfterDelete()
40+
{
41+
$attributeSet = Bootstrap::getObjectManager()->get(Set::class);
42+
$attributeSet->load('empty_attribute_set', 'attribute_set_name');
43+
44+
$productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
45+
$product = $productRepository->get('simple');
46+
47+
$productCollection = Bootstrap::getObjectManager()->get(CollectionFactory::class)->create();
48+
$productCollection->addIdFilter($product->getId());
49+
$urlRewriteCollection = Bootstrap::getObjectManager()->get(UrlRewriteCollectionFactory::class)->create();
50+
$urlRewriteCollection->addFieldToFilter('entity_type', 'product');
51+
$urlRewriteCollection->addFieldToFilter('entity_id', $product->getId());
52+
53+
self::assertSame(1, $urlRewriteCollection->getSize());
54+
self::assertSame(1, $productCollection->getSize());
55+
56+
$attributeSetRepository = Bootstrap::getObjectManager()->get(AttributeSetRepositoryInterface::class);
57+
$attributeSetRepository->deleteById($attributeSet->getAttributeSetId());
58+
59+
$productCollection = Bootstrap::getObjectManager()->get(CollectionFactory::class)->create();
60+
$productCollection->addIdFilter($product->getId());
61+
$urlRewriteCollection = Bootstrap::getObjectManager()->get(UrlRewriteCollectionFactory::class)->create();
62+
$urlRewriteCollection->addFieldToFilter('entity_type', 'product');
63+
$urlRewriteCollection->addFieldToFilter('entity_id', $product->getId());
64+
65+
self::assertSame(0, $urlRewriteCollection->getSize());
66+
self::assertSame(0, $productCollection->getSize());
67+
}
68+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require __DIR__ . '/../../Eav/_files/empty_attribute_set.php';
8+
require __DIR__ . '/../../Catalog/_files/product_simple.php';
9+
10+
$product->setAttributeSetId($attributeSet->getId());
11+
$product->save();
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
require __DIR__ . '/../../Catalog/_files/product_simple_rollback.php';
8+
require __DIR__ . '/../../Eav/_files/empty_attribute_set_rollback.php';

0 commit comments

Comments
 (0)