Skip to content

Commit

Permalink
Merge pull request #1581 from magento-tango/MAGETWO-71554
Browse files Browse the repository at this point in the history
Bug
- MAGETWO-71554 Visual Merchandiser category edit performance issue - for 2.2
  • Loading branch information
VladimirZaets authored Oct 11, 2017
2 parents fb05546 + 833cfa3 commit ba4b975
Show file tree
Hide file tree
Showing 12 changed files with 441 additions and 61 deletions.
2 changes: 2 additions & 0 deletions app/code/Magento/Catalog/Model/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
* @method Category setUrlPath(string $urlPath)
* @method Category getSkipDeleteChildren()
* @method Category setSkipDeleteChildren(boolean $value)
* @method Category setChangedProductIds(array $categoryIds) Set products ids that inserted or deleted for category
* @method array getChangedProductIds() Get products ids that inserted or deleted for category
*
* @SuppressWarnings(PHPMD.LongVariable)
* @SuppressWarnings(PHPMD.ExcessivePublicCount)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Catalog\Model\Category\Product;

/**
* Resolver to get product positions by ids assigned to specific category
*/
class PositionResolver extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
{
/**
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
* @param string $connectionName
*/
public function __construct(
\Magento\Framework\Model\ResourceModel\Db\Context $context,
$connectionName = null
) {
parent::__construct($context, $connectionName);
}

/**
* Initialize resource model
*
* @return void
*/
protected function _construct()
{
$this->_init('catalog_product_entity', 'entity_id');
}

/**
* Get category product positions
*
* @param int $categoryId
* @return array
*/
public function getPositions(int $categoryId)
{
$connection = $this->getConnection();

$select = $connection->select()->from(
['cpe' => $this->getTable('catalog_product_entity')],
'entity_id'
)->joinLeft(
['ccp' => $this->getTable('catalog_category_product')],
'ccp.product_id=cpe.entity_id'
)->where(
'ccp.category_id = ?',
$categoryId
)->order(
'ccp.position ' . \Magento\Framework\DB\Select::SQL_ASC
);

return array_flip($connection->fetchCol($select));
}
}
15 changes: 13 additions & 2 deletions app/code/Magento/Catalog/Model/ResourceModel/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -410,9 +410,18 @@ protected function _saveCategoryProducts($category)
* Update product positions in category
*/
if (!empty($update)) {
$newPositions = [];
foreach ($update as $productId => $position) {
$where = ['category_id = ?' => (int)$id, 'product_id = ?' => (int)$productId];
$bind = ['position' => (int)$position];
$delta = $position - $oldProducts[$productId];
if (!isset($newPositions[$delta])) {
$newPositions[$delta] = [];
}
$newPositions[$delta][] = $productId;
}

foreach ($newPositions as $delta => $productIds) {
$bind = ['position' => new \Zend_Db_Expr("position + ({$delta})")];
$where = ['category_id = ?' => (int)$id, 'product_id IN (?)' => $productIds];
$connection->update($this->getCategoryProductTable(), $bind, $where);
}
}
Expand All @@ -423,6 +432,8 @@ protected function _saveCategoryProducts($category)
'catalog_category_change_products',
['category' => $category, 'product_ids' => $productIds]
);

$category->setChangedProductIds($productIds);
}

if (!empty($insert) || !empty($update) || !empty($delete)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Catalog\Test\Unit\Model\Category\Product;

use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Catalog\Model\Category\Product\PositionResolver;
use Magento\Framework\Model\ResourceModel\Db\Context;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;

class PositionResolverTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Context|\PHPUnit_Framework_MockObject_MockObject
*/
private $context;

/**
* @var ResourceConnection|\PHPUnit_Framework_MockObject_MockObject
*/
private $resources;

/**
* @var AdapterInterface|\PHPUnit_Framework_MockObject_MockObject
*/
private $connection;

/**
* @var Select|\PHPUnit_Framework_MockObject_MockObject
*/
private $select;

/**
* @var PositionResolver
*/
private $model;

/**
* @var array
*/
private $positions = [
'3' => 100,
'2' => 101,
'1' => 102
];

/**
* @var array
*/
private $flippedPositions = [
'100' => 3,
'101' => 2,
'102' => 1
];

/**
* @var int
*/
private $categoryId = 1;

protected function setUp()
{
$this->context = $this->getMockBuilder(Context::class)
->disableOriginalConstructor()
->getMock();

$this->resources = $this->getMockBuilder(ResourceConnection::class)
->disableOriginalConstructor()
->getMock();

$this->connection = $this->getMockBuilder(AdapterInterface::class)
->disableOriginalConstructor()
->getMockForAbstractClass();

$this->select = $this->getMockBuilder(Select::class)
->disableOriginalConstructor()
->getMock();

$this->model = (new ObjectManager($this))->getObject(
PositionResolver::class,
[
'context' => $this->context,
null,
'_resources' => $this->resources
]
);
}

public function testGetPositions()
{
$this->resources->expects($this->once())
->method('getConnection')
->willReturn($this->connection);

$this->connection->expects($this->once())
->method('select')
->willReturn($this->select);
$this->select->expects($this->once())
->method('from')
->willReturnSelf();
$this->select->expects($this->once())
->method('where')
->willReturnSelf();
$this->select->expects($this->once())
->method('order')
->willReturnSelf();
$this->select->expects($this->once())
->method('joinLeft')
->willReturnSelf();
$this->connection->expects($this->once())
->method('fetchCol')
->willReturn($this->positions);

$this->assertEquals($this->flippedPositions, $this->model->getPositions($this->categoryId));
}
}
Loading

0 comments on commit ba4b975

Please sign in to comment.