Skip to content

Commit

Permalink
Merge branch '2.2-develop' of github.com:magento-engcom/magento2ce in…
Browse files Browse the repository at this point in the history
…to MAGETWO-85291-magento-engcom-magento2ce-963
  • Loading branch information
ishakhsuvarov committed Dec 12, 2017
2 parents 10fb80e + b9ab1ea commit 04305a9
Show file tree
Hide file tree
Showing 437 changed files with 6,863 additions and 5,357 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ public function testBeforeSave($value, $errorMessage = null)
\Magento\Backend\Model\Config\SessionLifetime\BackendModel::class
);
if ($errorMessage !== null) {
$this->expectException(\Magento\Framework\Exception\LocalizedException::class, $errorMessage);
$this->expectException(\Magento\Framework\Exception\LocalizedException::class);
$this->expectExceptionMessage($errorMessage);
}
$model->setValue($value);
$object = $model->beforeSave();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ public function getWidgetOptionsJson(array $customOptions = [])
'limit' => ToolbarModel::LIMIT_PARAM_NAME,
'modeDefault' => $defaultMode,
'directionDefault' => $this->_direction ?: ProductList::DEFAULT_SORT_DIRECTION,
'orderDefault' => $this->_productListHelper->getDefaultSortField(),
'orderDefault' => $this->getOrderField(),
'limitDefault' => $this->_productListHelper->getDefaultLimitPerPageValue($defaultMode),
'url' => $this->getPagerUrl(),
];
Expand Down
7 changes: 5 additions & 2 deletions app/code/Magento/Catalog/Model/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -943,8 +943,11 @@ public function getAnchorsAbove()
*/
public function getProductCount()
{
$count = $this->_getResource()->getProductCount($this);
$this->setData(self::KEY_PRODUCT_COUNT, $count);
if (!$this->hasData(self::KEY_PRODUCT_COUNT)) {
$count = $this->_getResource()->getProductCount($this);
$this->setData(self::KEY_PRODUCT_COUNT, $count);
}

return $this->getData(self::KEY_PRODUCT_COUNT);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@

namespace Magento\Catalog\Model\Indexer\Category\Product;

use Magento\Framework\DB\Query\Generator as QueryGenerator;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Query\Generator as QueryGenerator;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Store\Model\Store;

/**
* Class AbstractAction
Expand Down Expand Up @@ -45,21 +50,21 @@ abstract class AbstractAction
/**
* Cached non anchor categories select by store id
*
* @var \Magento\Framework\DB\Select[]
* @var Select[]
*/
protected $nonAnchorSelects = [];

/**
* Cached anchor categories select by store id
*
* @var \Magento\Framework\DB\Select[]
* @var Select[]
*/
protected $anchorSelects = [];

/**
* Cached all product select by store id
*
* @var \Magento\Framework\DB\Select[]
* @var Select[]
*/
protected $productsSelects = [];

Expand Down Expand Up @@ -119,19 +124,21 @@ abstract class AbstractAction
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
* @param \Magento\Catalog\Model\Config $config
* @param QueryGenerator $queryGenerator
* @param MetadataPool|null $metadataPool
*/
public function __construct(
\Magento\Framework\App\ResourceConnection $resource,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Catalog\Model\Config $config,
QueryGenerator $queryGenerator = null
QueryGenerator $queryGenerator = null,
MetadataPool $metadataPool = null
) {
$this->resource = $resource;
$this->connection = $resource->getConnection();
$this->storeManager = $storeManager;
$this->config = $config;
$this->queryGenerator = $queryGenerator ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(QueryGenerator::class);
$this->queryGenerator = $queryGenerator ?: ObjectManager::getInstance()->get(QueryGenerator::class);
$this->metadataPool = $metadataPool ?: ObjectManager::getInstance()->get(MetadataPool::class);
}

/**
Expand Down Expand Up @@ -188,9 +195,9 @@ protected function getMainTable()
*/
protected function getMainTmpTable()
{
return $this->useTempTable ? $this->getTable(
self::MAIN_INDEX_TABLE . self::TEMPORARY_TABLE_SUFFIX
) : $this->getMainTable();
return $this->useTempTable
? $this->getTable(self::MAIN_INDEX_TABLE . self::TEMPORARY_TABLE_SUFFIX)
: $this->getMainTable();
}

/**
Expand Down Expand Up @@ -218,24 +225,25 @@ protected function getPathFromCategoryId($categoryId)
/**
* Retrieve select for reindex products of non anchor categories
*
* @param \Magento\Store\Model\Store $store
* @return \Magento\Framework\DB\Select
* @param Store $store
* @return Select
* @throws \Exception when metadata not found for ProductInterface
*/
protected function getNonAnchorCategoriesSelect(\Magento\Store\Model\Store $store)
protected function getNonAnchorCategoriesSelect(Store $store)
{
if (!isset($this->nonAnchorSelects[$store->getId()])) {
$statusAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Product::ENTITY,
Product::ENTITY,
'status'
)->getId();
$visibilityAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Product::ENTITY,
Product::ENTITY,
'visibility'
)->getId();

$rootPath = $this->getPathFromCategoryId($store->getRootCategoryId());

$metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();
$select = $this->connection->select()->from(
['cc' => $this->getTable('catalog_category_entity')],
Expand Down Expand Up @@ -304,12 +312,65 @@ protected function getNonAnchorCategoriesSelect(\Magento\Store\Model\Store $stor
]
);

$this->addFilteringByChildProductsToSelect($select, $store);

$this->nonAnchorSelects[$store->getId()] = $select;
}

return $this->nonAnchorSelects[$store->getId()];
}

/**
* Add filtering by child products to select
*
* It's used for correct handling of composite products.
* This method makes assumption that select already joins `catalog_product_entity` as `cpe`.
*
* @param Select $select
* @param Store $store
* @return void
* @throws \Exception when metadata not found for ProductInterface
*/
private function addFilteringByChildProductsToSelect(Select $select, Store $store)
{
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();

$statusAttributeId = $this->config->getAttribute(Product::ENTITY, 'status')->getId();

$select->joinLeft(
['relation' => $this->getTable('catalog_product_relation')],
'cpe.' . $linkField . ' = relation.parent_id',
[]
)->joinLeft(
['relation_product_entity' => $this->getTable('catalog_product_entity')],
'relation.child_id = relation_product_entity.entity_id',
[]
)->joinLeft(
['child_cpsd' => $this->getTable('catalog_product_entity_int')],
'child_cpsd.' . $linkField . ' = '. 'relation_product_entity.' . $linkField
. ' AND child_cpsd.store_id = 0'
. ' AND child_cpsd.attribute_id = ' . $statusAttributeId,
[]
)->joinLeft(
['child_cpss' => $this->getTable('catalog_product_entity_int')],
'child_cpss.' . $linkField . ' = '. 'relation_product_entity.' . $linkField . ''
. ' AND child_cpss.attribute_id = child_cpsd.attribute_id'
. ' AND child_cpss.store_id = ' . $store->getId(),
[]
)->where(
'relation.child_id IS NULL OR '
. $this->connection->getIfNullSql('child_cpss.value', 'child_cpsd.value') . ' = ?',
\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED
)->group(
[
'cc.entity_id',
'ccp.product_id',
'visibility'
]
);
}

/**
* Check whether select ranging is needed
*
Expand All @@ -323,16 +384,13 @@ protected function isRangingNeeded()
/**
* Return selects cut by min and max
*
* @param \Magento\Framework\DB\Select $select
* @param Select $select
* @param string $field
* @param int $range
* @return \Magento\Framework\DB\Select[]
* @return Select[]
*/
protected function prepareSelectsByRange(
\Magento\Framework\DB\Select $select,
$field,
$range = self::RANGE_CATEGORY_STEP
) {
protected function prepareSelectsByRange(Select $select, $field, $range = self::RANGE_CATEGORY_STEP)
{
if ($this->isRangingNeeded()) {
$iterator = $this->queryGenerator->generate(
$field,
Expand All @@ -353,10 +411,10 @@ protected function prepareSelectsByRange(
/**
* Reindex products of non anchor categories
*
* @param \Magento\Store\Model\Store $store
* @param Store $store
* @return void
*/
protected function reindexNonAnchorCategories(\Magento\Store\Model\Store $store)
protected function reindexNonAnchorCategories(Store $store)
{
$selects = $this->prepareSelectsByRange($this->getNonAnchorCategoriesSelect($store), 'entity_id');
foreach ($selects as $select) {
Expand All @@ -374,43 +432,44 @@ protected function reindexNonAnchorCategories(\Magento\Store\Model\Store $store)
/**
* Check if anchor select isset
*
* @param \Magento\Store\Model\Store $store
* @param Store $store
* @return bool
*/
protected function hasAnchorSelect(\Magento\Store\Model\Store $store)
protected function hasAnchorSelect(Store $store)
{
return isset($this->anchorSelects[$store->getId()]);
}

/**
* Create anchor select
*
* @param \Magento\Store\Model\Store $store
* @return \Magento\Framework\DB\Select
* @param Store $store
* @return Select
* @throws \Exception when metadata not found for ProductInterface or CategoryInterface
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
protected function createAnchorSelect(\Magento\Store\Model\Store $store)
protected function createAnchorSelect(Store $store)
{
$isAnchorAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Category::ENTITY,
'is_anchor'
)->getId();
$statusAttributeId = $this->config->getAttribute(\Magento\Catalog\Model\Product::ENTITY, 'status')->getId();
$statusAttributeId = $this->config->getAttribute(Product::ENTITY, 'status')->getId();
$visibilityAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Product::ENTITY,
Product::ENTITY,
'visibility'
)->getId();
$rootCatIds = explode('/', $this->getPathFromCategoryId($store->getRootCategoryId()));
array_pop($rootCatIds);

$temporaryTreeTable = $this->makeTempCategoryTreeIndex();

$productMetadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
$categoryMetadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class);
$productMetadata = $this->metadataPool->getMetadata(ProductInterface::class);
$categoryMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class);
$productLinkField = $productMetadata->getLinkField();
$categoryLinkField = $categoryMetadata->getLinkField();

return $this->connection->select()->from(
$select = $this->connection->select()->from(
['cc' => $this->getTable('catalog_category_entity')],
[]
)->joinInner(
Expand Down Expand Up @@ -492,6 +551,10 @@ protected function createAnchorSelect(\Magento\Store\Model\Store $store)
'visibility' => new \Zend_Db_Expr($this->connection->getIfNullSql('cpvs.value', 'cpvd.value')),
]
);

$this->addFilteringByChildProductsToSelect($select, $store);

return $select;
}

/**
Expand Down Expand Up @@ -586,10 +649,10 @@ protected function fillTempCategoryTreeIndex($temporaryName)
/**
* Retrieve select for reindex products of non anchor categories
*
* @param \Magento\Store\Model\Store $store
* @return \Magento\Framework\DB\Select
* @param Store $store
* @return Select
*/
protected function getAnchorCategoriesSelect(\Magento\Store\Model\Store $store)
protected function getAnchorCategoriesSelect(Store $store)
{
if (!$this->hasAnchorSelect($store)) {
$this->anchorSelects[$store->getId()] = $this->createAnchorSelect($store);
Expand All @@ -600,10 +663,10 @@ protected function getAnchorCategoriesSelect(\Magento\Store\Model\Store $store)
/**
* Reindex products of anchor categories
*
* @param \Magento\Store\Model\Store $store
* @param Store $store
* @return void
*/
protected function reindexAnchorCategories(\Magento\Store\Model\Store $store)
protected function reindexAnchorCategories(Store $store)
{
$selects = $this->prepareSelectsByRange($this->getAnchorCategoriesSelect($store), 'entity_id');

Expand All @@ -622,22 +685,23 @@ protected function reindexAnchorCategories(\Magento\Store\Model\Store $store)
/**
* Get select for all products
*
* @param \Magento\Store\Model\Store $store
* @return \Magento\Framework\DB\Select
* @param Store $store
* @return Select
* @throws \Exception when metadata not found for ProductInterface
*/
protected function getAllProducts(\Magento\Store\Model\Store $store)
protected function getAllProducts(Store $store)
{
if (!isset($this->productsSelects[$store->getId()])) {
$statusAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Product::ENTITY,
Product::ENTITY,
'status'
)->getId();
$visibilityAttributeId = $this->config->getAttribute(
\Magento\Catalog\Model\Product::ENTITY,
Product::ENTITY,
'visibility'
)->getId();

$metadata = $this->getMetadataPool()->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class);
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
$linkField = $metadata->getLinkField();

$select = $this->connection->select()->from(
Expand Down Expand Up @@ -726,10 +790,10 @@ protected function isIndexRootCategoryNeeded()
/**
* Reindex all products to root category
*
* @param \Magento\Store\Model\Store $store
* @param Store $store
* @return void
*/
protected function reindexRootCategory(\Magento\Store\Model\Store $store)
protected function reindexRootCategory(Store $store)
{
if ($this->isIndexRootCategoryNeeded()) {
$selects = $this->prepareSelectsByRange(
Expand All @@ -750,16 +814,4 @@ protected function reindexRootCategory(\Magento\Store\Model\Store $store)
}
}
}

/**
* @return \Magento\Framework\EntityManager\MetadataPool
*/
private function getMetadataPool()
{
if (null === $this->metadataPool) {
$this->metadataPool = \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Framework\EntityManager\MetadataPool::class);
}
return $this->metadataPool;
}
}
Loading

0 comments on commit 04305a9

Please sign in to comment.