Skip to content

Commit d0cb4ad

Browse files
committed
Merge branch '2.2-develop' into MAGETWO-71215-fix
2 parents c6d8494 + c9fdb47 commit d0cb4ad

File tree

25 files changed

+896
-34
lines changed

25 files changed

+896
-34
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/MassDelete.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
namespace Magento\Catalog\Controller\Adminhtml\Product;
88

99
use Magento\Framework\Controller\ResultFactory;
10-
use Magento\Catalog\Controller\Adminhtml\Product\Builder;
1110
use Magento\Backend\App\Action\Context;
1211
use Magento\Ui\Component\MassAction\Filter;
1312
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
13+
use Magento\Catalog\Api\ProductRepositoryInterface;
1414

1515
class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product
1616
{
@@ -26,20 +26,29 @@ class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product
2626
*/
2727
protected $collectionFactory;
2828

29+
/**
30+
* @var ProductRepositoryInterface
31+
*/
32+
private $productRepository;
33+
2934
/**
3035
* @param Context $context
3136
* @param Builder $productBuilder
3237
* @param Filter $filter
3338
* @param CollectionFactory $collectionFactory
39+
* @param ProductRepositoryInterface $productRepository
3440
*/
3541
public function __construct(
3642
Context $context,
3743
Builder $productBuilder,
3844
Filter $filter,
39-
CollectionFactory $collectionFactory
45+
CollectionFactory $collectionFactory,
46+
ProductRepositoryInterface $productRepository = null
4047
) {
4148
$this->filter = $filter;
4249
$this->collectionFactory = $collectionFactory;
50+
$this->productRepository = $productRepository
51+
?: \Magento\Framework\App\ObjectManager::getInstance()->create(ProductRepositoryInterface::class);
4352
parent::__construct($context, $productBuilder);
4453
}
4554

@@ -50,8 +59,9 @@ public function execute()
5059
{
5160
$collection = $this->filter->getCollection($this->collectionFactory->create());
5261
$productDeleted = 0;
62+
/** @var \Magento\Catalog\Model\Product $product */
5363
foreach ($collection->getItems() as $product) {
54-
$product->delete();
64+
$this->productRepository->delete($product);
5565
$productDeleted++;
5666
}
5767
$this->messageManager->addSuccess(
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Model\Indexer\Product;
8+
9+
use Magento\Framework\Indexer\ActionInterface;
10+
use Magento\Framework\Indexer\IndexerRegistry;
11+
12+
/**
13+
* Reindex all relevant product indexers
14+
*/
15+
class Full implements ActionInterface
16+
{
17+
/**
18+
* @var IndexerRegistry
19+
*/
20+
private $indexerRegistry;
21+
22+
/**
23+
* @var string[]
24+
*/
25+
private $indexerList;
26+
27+
/**
28+
* Initialize dependencies
29+
*
30+
* @param IndexerRegistry $indexerRegistry
31+
* @param string[] $indexerList
32+
*/
33+
public function __construct(
34+
IndexerRegistry $indexerRegistry,
35+
array $indexerList
36+
) {
37+
$this->indexerRegistry = $indexerRegistry;
38+
$this->indexerList = $indexerList;
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function executeFull()
45+
{
46+
foreach ($this->indexerList as $indexerName) {
47+
$indexer = $this->indexerRegistry->get($indexerName);
48+
if (!$indexer->isScheduled()) {
49+
$indexer->reindexAll();
50+
}
51+
}
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function executeList(array $ids)
58+
{
59+
if (!empty($ids)) {
60+
foreach ($this->indexerList as $indexerName) {
61+
$indexer = $this->indexerRegistry->get($indexerName);
62+
if (!$indexer->isScheduled()) {
63+
$indexer->reindexList($ids);
64+
}
65+
}
66+
}
67+
}
68+
69+
/**
70+
* {@inheritDoc}
71+
*/
72+
public function executeRow($id)
73+
{
74+
if (!empty($id)) {
75+
foreach ($this->indexerList as $indexerName) {
76+
$indexer = $this->indexerRegistry->get($indexerName);
77+
if (!$indexer->isScheduled()) {
78+
$indexer->reindexRow($id);
79+
}
80+
}
81+
}
82+
}
83+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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\Model\Indexer\Product;
8+
9+
use Magento\Catalog\Model\Indexer\Product\Full;
10+
use Magento\Framework\Indexer\IndexerInterface;
11+
use PHPUnit\Framework\TestCase;
12+
use Magento\Framework\Indexer\IndexerRegistry;
13+
14+
class FullTest extends TestCase
15+
{
16+
/**
17+
* @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager
18+
*/
19+
private $objectManager;
20+
21+
/**
22+
* @var IndexerRegistry|\PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $indexerRegistryMock;
25+
26+
/**
27+
* @var Full
28+
*/
29+
private $full;
30+
31+
public function setUp()
32+
{
33+
$this->objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
34+
$this->indexerRegistryMock = $this->createMock(IndexerRegistry::class);
35+
36+
$this->full = $this->objectManager->getObject(
37+
Full::class,
38+
[
39+
'indexerRegistry' => $this->indexerRegistryMock,
40+
'indexerList' => ['catalog_indexer', 'product_indexer', 'stock_indexer', 'search_indexer']
41+
]
42+
);
43+
}
44+
45+
public function testExecuteFull()
46+
{
47+
$indexerMock = $this->getMockForAbstractClass(IndexerInterface::class, [], "", false);
48+
$indexerMock->expects($this->exactly(4))->method('isScheduled')->willReturn(false);
49+
$indexerMock->expects($this->exactly(4))->method('reindexAll');
50+
$this->indexerRegistryMock->expects($this->exactly(4))->method('get')->willReturn($indexerMock);
51+
52+
$this->full->executeFull();
53+
}
54+
55+
public function testExecuteList()
56+
{
57+
$indexerMock = $this->getMockForAbstractClass(IndexerInterface::class, [], "", false);
58+
$indexerMock->expects($this->exactly(4))->method('isScheduled')->willReturn(false);
59+
$indexerMock->expects($this->exactly(4))->method('reindexList')->with([1, 2]);
60+
$this->indexerRegistryMock->expects($this->exactly(4))->method('get')->willReturn($indexerMock);
61+
62+
$this->full->executeList([1, 2]);
63+
}
64+
65+
public function testExecuteRow()
66+
{
67+
$indexerMock = $this->getMockForAbstractClass(IndexerInterface::class, [], "", false);
68+
$indexerMock->expects($this->exactly(4))->method('isScheduled')->willReturn(false);
69+
$indexerMock->expects($this->exactly(4))->method('reindexRow')->with(1);
70+
$this->indexerRegistryMock->expects($this->exactly(4))->method('get')->willReturn($indexerMock);
71+
72+
$this->full->executeRow(1);
73+
}
74+
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,16 @@
8484
<argument name="changelog" xsi:type="object" shared="false">Magento\Framework\Mview\View\ChangelogInterface</argument>
8585
</arguments>
8686
</type>
87+
<type name="Magento\Catalog\Model\Indexer\Product\Full">
88+
<arguments>
89+
<argument name="indexerList" xsi:type="array">
90+
<item name="catalog_category_product" xsi:type="const">Magento\Catalog\Model\Indexer\Category\Product::INDEXER_ID</item>
91+
<item name="catalog_product_category" xsi:type="const">Magento\Catalog\Model\Indexer\Product\Category::INDEXER_ID</item>
92+
<item name="catalog_product_price" xsi:type="const">Magento\Catalog\Model\Indexer\Product\Price\Processor::INDEXER_ID</item>
93+
<item name="catalog_product_attribute" xsi:type="const">Magento\Catalog\Model\Indexer\Product\Eav\Processor::INDEXER_ID</item>
94+
</argument>
95+
</arguments>
96+
</type>
8797
<type name="Magento\Catalog\Model\Product\Attribute\Backend\Media\EntryConverterPool">
8898
<arguments>
8999
<argument name="mediaGalleryEntryConvertersCollection" xsi:type="array">

app/code/Magento/CatalogInventory/etc/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@
6060
<type name="Magento\Store\Model\ResourceModel\Group">
6161
<plugin name="storeGroupResourceAroundBeforeSave" type="Magento\CatalogInventory\Model\Indexer\Stock\Plugin\StoreGroup"/>
6262
</type>
63+
<type name="Magento\Catalog\Model\Indexer\Product\Full">
64+
<arguments>
65+
<argument name="indexerList" xsi:type="array">
66+
<item name="cataloginventory_stock" xsi:type="const">Magento\CatalogInventory\Model\Indexer\Stock\Processor::INDEXER_ID</item>
67+
</argument>
68+
</arguments>
69+
</type>
6370
<type name="Magento\Catalog\Block\Product\View">
6471
<plugin name="quantityValidators" type="Magento\CatalogInventory\Block\Plugin\ProductView" />
6572
</type>

app/code/Magento/CatalogSearch/etc/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,13 @@
3939
</arguments>
4040
</type>
4141
<preference for="Magento\Framework\Indexer\IndexStructureInterface" type="Magento\CatalogSearch\Model\Indexer\IndexStructureProxy" />
42+
<type name="Magento\Catalog\Model\Indexer\Product\Full">
43+
<arguments>
44+
<argument name="indexerList" xsi:type="array">
45+
<item name="catalogsearch_fulltext" xsi:type="const">Magento\CatalogSearch\Model\Indexer\Fulltext::INDEXER_ID</item>
46+
</argument>
47+
</arguments>
48+
</type>
4249
<type name="Magento\Framework\Search\Adapter\Mysql\Aggregation\DataProviderContainer">
4350
<arguments>
4451
<argument name="dataProviders" xsi:type="array">

app/code/Magento/CatalogWidget/Block/Product/ProductsList.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,14 @@ protected function getConditions()
259259
$conditions = $this->conditionsHelper->decode($conditions);
260260
}
261261

262+
foreach ($conditions as $key => $condition) {
263+
if (!empty($condition['attribute'])
264+
&& in_array($condition['attribute'], ['special_from_date', 'special_to_date'])
265+
) {
266+
$conditions[$key]['value'] = date('Y-m-d H:i:s', strtotime($condition['value']));
267+
}
268+
}
269+
262270
$this->rule->loadPost(['conditions' => $conditions]);
263271
return $this->rule->getConditions();
264272
}

app/code/Magento/CatalogWidget/Test/Unit/Block/Product/ProductsListTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ public function testCreateCollection($pagerEnable, $productsCount, $productsPerP
288288
$this->collectionFactory->expects($this->once())->method('create')->willReturn($collection);
289289
$this->productsList->setData('conditions_encoded', 'some_serialized_conditions');
290290

291+
$this->widgetConditionsHelper->expects($this->once())
292+
->method('decode')
293+
->with('some_serialized_conditions')
294+
->willReturn([]);
295+
291296
$this->builder->expects($this->once())->method('attachConditionToCollection')
292297
->with($collection, $this->getConditionsForCollection($collection))
293298
->willReturnSelf();

app/code/Magento/ConfigurableProduct/Plugin/Model/ResourceModel/Product.php

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,34 @@
77
namespace Magento\ConfigurableProduct\Plugin\Model\ResourceModel;
88

99
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
10+
use Magento\Framework\Indexer\ActionInterface;
1011

1112
class Product
1213
{
14+
/**
15+
* @var Configurable
16+
*/
17+
private $configurable;
18+
19+
/**
20+
* @var ActionInterface
21+
*/
22+
private $productIndexer;
23+
24+
/**
25+
* Initialize Product dependencies.
26+
*
27+
* @param Configurable $configurable
28+
* @param ActionInterface $productIndexer
29+
*/
30+
public function __construct(
31+
Configurable $configurable,
32+
ActionInterface $productIndexer
33+
) {
34+
$this->configurable = $configurable;
35+
$this->productIndexer = $productIndexer;
36+
}
37+
1338
/**
1439
* We need reset attribute set id to attribute after related simple product was saved
1540
*
@@ -28,4 +53,25 @@ public function beforeSave(
2853
$object->getTypeInstance()->getSetAttributes($object);
2954
}
3055
}
56+
57+
/**
58+
* Gather configurable parent ids of product being deleted and reindex after delete is complete.
59+
*
60+
* @param \Magento\Catalog\Model\ResourceModel\Product $subject
61+
* @param \Closure $proceed
62+
* @param \Magento\Catalog\Model\Product $product
63+
* @return \Magento\Catalog\Model\ResourceModel\Product
64+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
65+
*/
66+
public function aroundDelete(
67+
\Magento\Catalog\Model\ResourceModel\Product $subject,
68+
\Closure $proceed,
69+
\Magento\Catalog\Model\Product $product
70+
) {
71+
$configurableProductIds = $this->configurable->getParentIdsByChild($product->getId());
72+
$result = $proceed($product);
73+
$this->productIndexer->executeList($configurableProductIds);
74+
75+
return $result;
76+
}
3177
}

0 commit comments

Comments
 (0)