diff --git a/app/code/Magento/Catalog/Model/Category.php b/app/code/Magento/Catalog/Model/Category.php index c76fc3d291ed1710f9deea86322dc07f12bdba25..87fb8d9656d122287a4a18f38776e226db54084e 100644 --- a/app/code/Magento/Catalog/Model/Category.php +++ b/app/code/Magento/Catalog/Model/Category.php @@ -25,6 +25,8 @@ use Magento\UrlRewrite\Service\V1\Data\UrlRewrite; * @method array getAffectedCategoryIds() * @method Category setUrlKey(string $urlKey) * @method Category setUrlPath(string $urlPath) + * @method Category getSkipDeleteChildren() + * @method Category setSkipDeleteChildren(boolean $value) * * @SuppressWarnings(PHPMD.LongVariable) * @SuppressWarnings(PHPMD.ExcessivePublicCount) diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php index 57bc0144704ce2c3155242206977291a4a087a7c..f0697d95648484f018b74511579f5d36009cebf4 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/AbstractAction.php @@ -9,6 +9,7 @@ namespace Magento\Catalog\Model\Indexer\Category\Flat; use Magento\Framework\App\ResourceConnection; +use Magento\Framework\Model\Entity\MetadataPool; class AbstractAction { @@ -53,6 +54,18 @@ class AbstractAction */ protected $connection; + /** + * @var \Magento\Framework\Model\Entity\EntityMetadata + */ + protected $categoryMetadata; + + /** + * Static columns to skip + * + * @var array + */ + protected $skipStaticColumns = []; + /** * @param ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager @@ -61,13 +74,17 @@ class AbstractAction public function __construct( ResourceConnection $resource, \Magento\Store\Model\StoreManagerInterface $storeManager, - \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, + MetadataPool $metadataPool, + $skipStaticColumns = [] ) { $this->resource = $resource; $this->connection = $resource->getConnection(); $this->storeManager = $storeManager; $this->resourceHelper = $resourceHelper; + $this->skipStaticColumns = $skipStaticColumns; $this->columns = array_merge($this->getStaticColumns(), $this->getEavColumns()); + $this->categoryMetadata = $metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class); } /** @@ -177,13 +194,12 @@ class AbstractAction protected function getStaticColumns() { $columns = []; - $columnsToSkip = ['entity_type_id', 'attribute_set_id']; $describe = $this->connection->describeTable( $this->connection->getTableName($this->getTableName('catalog_category_entity')) ); foreach ($describe as $column) { - if (in_array($column['COLUMN_NAME'], $columnsToSkip)) { + if (in_array($column['COLUMN_NAME'], $this->skipStaticColumns)) { continue; } $isUnsigned = ''; @@ -364,11 +380,11 @@ class AbstractAction $attributesType = ['varchar', 'int', 'decimal', 'text', 'datetime']; foreach ($attributesType as $type) { foreach ($this->getAttributeTypeValues($type, $entityIds, $storeId) as $row) { - if (isset($row['entity_id']) && isset($row['attribute_id'])) { + if (isset($row[$this->categoryMetadata->getLinkField()]) && isset($row['attribute_id'])) { $attributeId = $row['attribute_id']; if (isset($attributes[$attributeId])) { $attributeCode = $attributes[$attributeId]['attribute_code']; - $values[$row['entity_id']][$attributeCode] = $row['value']; + $values[$row[$this->categoryMetadata->getLinkField()]][$attributeCode] = $row['value']; } } } @@ -386,18 +402,24 @@ class AbstractAction */ protected function getAttributeTypeValues($type, $entityIds, $storeId) { + $linkField = $this->categoryMetadata->getLinkField(); $select = $this->connection->select()->from( [ 'def' => $this->connection->getTableName($this->getTableName('catalog_category_entity_' . $type)), ], - ['entity_id', 'attribute_id'] + [$linkField, 'attribute_id'] + )->joinLeft( + [ + 'e' => $this->connection->getTableName($this->getTableName('catalog_category_entity')) + ], + "def.{$linkField} = e.{$linkField}" )->joinLeft( [ 'store' => $this->connection->getTableName( $this->getTableName('catalog_category_entity_' . $type) ), ], - 'store.entity_id = def.entity_id AND store.attribute_id = def.attribute_id ' . + "store.{$linkField} = def.{$linkField} AND store.attribute_id = def.attribute_id " . 'AND store.store_id = ' . $storeId, [ @@ -408,7 +430,7 @@ class AbstractAction ) ] )->where( - 'def.entity_id IN (?)', + "e.entity_id IN (?)", $entityIds )->where( 'def.store_id IN (?)', diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php index 84390a23058897b899f8b3af03fe4c96dd7b61c0..204a5534a260a3d000f4b000369c2020c4e0d5cf 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Full.php @@ -68,12 +68,12 @@ class Full extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction $attributesData = $this->getAttributeValues($categoriesIdsChunk, $store->getId()); $data = []; foreach ($categories[$store->getRootCategoryId()] as $category) { - if (!isset($attributesData[$category['entity_id']])) { + if (!isset($attributesData[$category[$this->categoryMetadata->getLinkField()]])) { continue; } $category['store_id'] = $store->getId(); $data[] = $this->prepareValuesToInsert( - array_merge($category, $attributesData[$category['entity_id']]) + array_merge($category, $attributesData[$category[$this->categoryMetadata->getLinkField()]]) ); } $this->connection->insertMultiple( diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php index 88ce0ac50b363018069086ac43c8193ab9af8a10..4d5961809e61b44707c09b87bd0a4e92dba1fad6 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Flat/Action/Rows.php @@ -7,6 +7,7 @@ namespace Magento\Catalog\Model\Indexer\Category\Flat\Action; use Magento\Catalog\Api\CategoryRepositoryInterface; use Magento\Framework\Exception\NoSuchEntityException; +use Magento\Framework\Model\Entity\MetadataPool; class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction { @@ -19,16 +20,20 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper + * @param MetadataPool $metadataPool + * @param array $skipStaticColumns * @param CategoryRepositoryInterface $categoryRepository */ public function __construct( \Magento\Framework\App\ResourceConnection $resource, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper, - CategoryRepositoryInterface $categoryRepository + MetadataPool $metadataPool, + CategoryRepositoryInterface $categoryRepository, + $skipStaticColumns = [] ) { $this->categoryRepository = $categoryRepository; - parent::__construct($resource, $storeManager, $resourceHelper); + parent::__construct($resource, $storeManager, $resourceHelper, $metadataPool, $skipStaticColumns); } /** @@ -122,14 +127,16 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction /** @var \Magento\Framework\DB\Select $select */ $select = $this->connection->select()->from( ['cf' => $this->getTableNameByStore($store, $useTempTable)] - )->joinLeft( - ['ce' => $this->getTableName('catalog_category_entity')], - 'cf.path = ce.path', - [] )->where( "cf.path = {$rootIdExpr} OR cf.path = {$rootCatIdExpr} OR cf.path like {$catIdExpr}" )->where( - 'ce.entity_id IS NULL' + 'cf.entity_id NOT IN (?)', + new \Zend_Db_Expr( + $this->connection->select()->from( + ['ce' => $this->getTableName('catalog_category_entity')], + ['entity_id'] + ) + ) ); $sql = $select->deleteFromSelect('cf'); @@ -157,7 +164,7 @@ class Rows extends \Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction )->where( "path = {$rootIdExpr} OR path = {$rootCatIdExpr} OR path like {$catIdExpr}" )->where( - 'entity_id IN (?)', + "entity_id IN (?)", $ids ); diff --git a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php index 5bfe8e714ba7f9a1ef9984cf9ddbe8c386ad7fd5..b764f3d642ba137919bb7f2a92dce4534b249447 100644 --- a/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php +++ b/app/code/Magento/Catalog/Model/Indexer/Category/Product/AbstractAction.php @@ -371,8 +371,11 @@ abstract class AbstractAction $rootCatIds = explode('/', $this->getPathFromCategoryId($store->getRootCategoryId())); array_pop($rootCatIds); - $metadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); - $linkField = $metadata->getLinkField(); + $productMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\ProductInterface::class); + $categoryMetadata = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class); + $productLinkField = $productMetadata->getLinkField(); + $categoryLinkField = $categoryMetadata->getLinkField(); + return $this->connection->select()->from( ['cc' => $this->getTable('catalog_category_entity')], [] @@ -399,35 +402,36 @@ abstract class AbstractAction [] )->joinInner( ['cpsd' => $this->getTable('catalog_product_entity_int')], - 'cpsd.' . $linkField . ' = cpe.' . $linkField . ' AND cpsd.store_id = 0' + 'cpsd.' . $productLinkField . ' = cpe.' . $productLinkField . ' AND cpsd.store_id = 0' . ' AND cpsd.attribute_id = ' . $statusAttributeId, [] )->joinLeft( ['cpss' => $this->getTable('catalog_product_entity_int')], - 'cpss.' . $linkField . ' = cpe.' . $linkField . ' AND cpss.attribute_id = cpsd.attribute_id' . + 'cpss.' . $productLinkField . ' = cpe.' . $productLinkField . ' AND cpss.attribute_id = cpsd.attribute_id' . ' AND cpss.store_id = ' . $store->getId(), [] )->joinInner( ['cpvd' => $this->getTable('catalog_product_entity_int')], - 'cpvd.' . $linkField . ' = cpe. ' . $linkField . ' AND cpvd.store_id = 0' . + 'cpvd.' . $productLinkField . ' = cpe. ' . $productLinkField . ' AND cpvd.store_id = 0' . ' AND cpvd.attribute_id = ' . $visibilityAttributeId, [] )->joinLeft( ['cpvs' => $this->getTable('catalog_product_entity_int')], - 'cpvs.' . $linkField . ' = cpe.' . $linkField . ' AND cpvs.attribute_id = cpvd.attribute_id ' . - 'AND cpvs.store_id = ' . + 'cpvs.' . $productLinkField . ' = cpe.' . $productLinkField . + ' AND cpvs.attribute_id = cpvd.attribute_id ' . 'AND cpvs.store_id = ' . $store->getId(), [] )->joinInner( ['ccad' => $this->getTable('catalog_category_entity_int')], - 'ccad.entity_id = cc.entity_id AND ccad.store_id = 0' . ' AND ccad.attribute_id = ' . $isAnchorAttributeId, + 'ccad.' . $categoryLinkField . ' = cc.' . $categoryLinkField . ' AND ccad.store_id = 0' . + ' AND ccad.attribute_id = ' . $isAnchorAttributeId, [] )->joinLeft( ['ccas' => $this->getTable('catalog_category_entity_int')], - 'ccas.entity_id = cc.entity_id AND ccas.attribute_id = ccad.attribute_id' . - ' AND ccas.store_id = ' . + 'ccas.' . $categoryLinkField . ' = cc.' . $categoryLinkField + . ' AND ccas.attribute_id = ccad.attribute_id AND ccas.store_id = ' . $store->getId(), [] )->where( diff --git a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php index dddca8978fc4d676dc93738298c2f72a791e87a7..b42fc677f718e3fa112be20b85447e6b88795e32 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/AbstractResource.php @@ -140,7 +140,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity $select = $this->getConnection() ->select() ->from(['attr_table' => $table], []) - ->where("attr_table.{$this->getLinkField()} = ?", $object->getId()) + ->where("attr_table.{$this->getLinkField()} = ?", $object->getData($this->getLinkField())) ->where('attr_table.store_id IN (?)', $storeIds); if ($setId) { @@ -227,13 +227,14 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity * for default store id * In this case we clear all not default values */ + $entityIdField = $this->getLinkField(); if ($this->_storeManager->hasSingleStore()) { $storeId = $this->getDefaultStoreId(); $connection->delete( $table, [ 'attribute_id = ?' => $attribute->getAttributeId(), - $this->getLinkField() . ' = ?' => $object->getId(), + "{$entityIdField} = ?" => $object->getData($entityIdField), 'store_id <> ?' => $storeId ] ); @@ -243,7 +244,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity [ 'attribute_id' => $attribute->getAttributeId(), 'store_id' => $storeId, - $this->getLinkField() => $object->getData($this->getLinkField()), + $entityIdField => $object->getData($entityIdField), 'value' => $this->_prepareValueForSave($value, $attribute), ] ); @@ -296,7 +297,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity ->from($table) ->where('attribute_id = ?', $attribute->getAttributeId()) ->where('store_id = ?', $this->getDefaultStoreId()) - ->where('entity_id = ?', $object->getId()); + ->where($this->getLinkField() . ' = ?', $object->getData($this->getLinkField())); $row = $this->getConnection()->fetchOne($select); if (!$row) { @@ -304,7 +305,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity [ 'attribute_id' => $attribute->getAttributeId(), 'store_id' => $this->getDefaultStoreId(), - 'entity_id' => $object->getId(), + $this->getLinkField() => $object->getData($this->getLinkField()), 'value' => $this->_prepareValueForSave($value, $attribute), ] ); @@ -563,7 +564,7 @@ abstract class AbstractResource extends \Magento\Eav\Model\Entity\AbstractEntity ['e' => $this->getTable('catalog_product_entity')], 'e.' . $this->getLinkField() . ' = ' . $staticTable . '.' . $this->getLinkField() )->where( - 'e.entity_id = :entity_id' + 'e.entity_id = :entity_id' ); $attributesData = $connection->fetchRow($select, ['entity_id' => $entityId]); } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category.php b/app/code/Magento/Catalog/Model/ResourceModel/Category.php index c7f00697fbf392557eb1c6e4143e847c6929aac9..57492bf78b705c1a7539bdba898eff168a6ad8a1 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category.php @@ -11,6 +11,9 @@ */ namespace Magento\Catalog\Model\ResourceModel; +use Magento\Framework\Model\EntityManager; +use Magento\Catalog\Api\Data\CategoryInterface; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -66,12 +69,19 @@ class Category extends AbstractResource protected $_categoryTreeFactory; /** + * @var EntityManager + */ + protected $entityManager; + + /** + * Category constructor. * @param \Magento\Eav\Model\Entity\Context $context * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\Factory $modelFactory * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param Category\TreeFactory $categoryTreeFactory * @param Category\CollectionFactory $categoryCollectionFactory + * @param EntityManager $entityManager * @param array $data */ public function __construct( @@ -81,6 +91,7 @@ class Category extends AbstractResource \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\ResourceModel\Category\TreeFactory $categoryTreeFactory, \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory, + EntityManager $entityManager, $data = [] ) { parent::__construct( @@ -92,6 +103,7 @@ class Category extends AbstractResource $this->_categoryTreeFactory = $categoryTreeFactory; $this->_categoryCollectionFactory = $categoryCollectionFactory; $this->_eventManager = $eventManager; + $this->entityManager = $entityManager; $this->connectionName = 'catalog'; } @@ -196,20 +208,16 @@ class Category extends AbstractResource */ public function deleteChildren(\Magento\Framework\DataObject $object) { - $connection = $this->getConnection(); - $pathField = $connection->quoteIdentifier('path'); - - $select = $connection->select()->from( - $this->getEntityTable(), - ['entity_id'] - )->where( - $pathField . ' LIKE :c_path' - ); - - $childrenIds = $connection->fetchCol($select, ['c_path' => $object->getPath() . '/%']); + if ($object->getSkipDeleteChildren()) { + return $this; + } - if (!empty($childrenIds)) { - $connection->delete($this->getEntityTable(), ['entity_id IN (?)' => $childrenIds]); + $categories = $this->_categoryCollectionFactory->create(); + $categories->addAttributeToFilter('path', ['like' => $object->getPath() . '/%']); + $childrenIds = $categories->getAllIds(); + foreach ($categories as $category) { + $category->setSkipDeleteChildren(true); + $category->delete(); } /** @@ -524,7 +532,7 @@ class Category extends AbstractResource $table = $this->getTable([$this->getEntityTablePrefix(), 'int']); $connection = $this->getConnection(); $checkSql = $connection->getCheckSql('c.value_id > 0', 'c.value', 'd.value'); - + $linkField = $this->getLinkField(); $bind = [ 'attribute_id' => $attributeId, 'store_id' => $storeId, @@ -536,11 +544,11 @@ class Category extends AbstractResource ['COUNT(m.entity_id)'] )->joinLeft( ['d' => $table], - 'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = m.entity_id', + "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = m.{$linkField}", [] )->joinLeft( ['c' => $table], - "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = m.entity_id", + "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = m.{$linkField}", [] )->where( 'm.path LIKE :c_path' @@ -576,20 +584,22 @@ class Category extends AbstractResource */ public function findWhereAttributeIs($entityIdsFilter, $attribute, $expectedValue) { + $linkField = $this->getLinkField(); $bind = ['attribute_id' => $attribute->getId(), 'value' => $expectedValue]; - $select = $this->getConnection()->select()->from( - $attribute->getBackend()->getTable(), + $selectEntities = $this->getConnection()->select()->from( + ['ce' => $this->getTable('catalog_category_entity')], ['entity_id'] + )->joinLeft( + ['ci' => $attribute->getBackend()->getTable()], + "ci.{$linkField} = ce.{$linkField} AND attribute_id = :attribute_id", + ['value'] )->where( - 'attribute_id = :attribute_id' - )->where( - 'value = :value' + 'ci.value = :value' )->where( - 'entity_id IN(?)', + 'ce.entity_id IN (?)', $entityIdsFilter ); - - return $this->getConnection()->fetchCol($select, $bind); + return $this->getConnection()->fetchCol($selectEntities, $bind); } /** @@ -745,10 +755,12 @@ class Category extends AbstractResource */ public function getChildren($category, $recursive = true) { + $linkField = $this->getLinkField(); $attributeId = $this->getIsActiveAttributeId(); $backendTable = $this->getTable([$this->getEntityTablePrefix(), 'int']); $connection = $this->getConnection(); $checkSql = $connection->getCheckSql('c.value_id > 0', 'c.value', 'd.value'); + $linkField = $this->getLinkField(); $bind = [ 'attribute_id' => $attributeId, 'store_id' => $category->getStoreId(), @@ -760,11 +772,11 @@ class Category extends AbstractResource 'entity_id' )->joinLeft( ['d' => $backendTable], - 'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = m.entity_id', + "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = m.{$linkField}", [] )->joinLeft( ['c' => $backendTable], - 'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = m.entity_id', + "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = m.{$linkField}", [] )->where( $checkSql . ' = :scope' @@ -979,4 +991,137 @@ class Category extends AbstractResource $select->from($this->getEntityTable(), 'COUNT(*)')->where('parent_id != ?', 0); return (int)$connection->fetchOne($select); } + + /** + * Reset firstly loaded attributes + * + * @param \Magento\Framework\DataObject $object + * @param integer $entityId + * @param array|null $attributes + * @return $this + */ + public function load($object, $entityId, $attributes = []) + { + $this->_attributes = []; + \Magento\Framework\Profiler::start('EAV:load_entity'); + /** + * Load object base row data + */ + $this->entityManager->load(CategoryInterface::class, $object, $entityId); + + + if (!$this->entityManager->has(\Magento\Catalog\Api\Data\CategoryInterface::class, $entityId)) { + $object->isObjectNew(true); + } + + $this->loadAttributesMetadata($attributes); + + $this->_loadModelAttributes($object); + + $object->setOrigData(); + + $this->_afterLoad($object); + + \Magento\Framework\Profiler::stop('EAV:load_entity'); + return $this; + } + + /** + * Save object collected data + * + * @param array $saveData array('newObject', 'entityRow', 'insert', 'update', 'delete') + * @return $this + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) + */ + protected function _processSaveData($saveData) + { + extract($saveData, EXTR_SKIP); + /** + * Import variables into the current symbol table from save data array + * + * @see \Magento\Eav\Model\Entity\AbstractEntity::_collectSaveData() + * + * @var array $entityRow + * @var \Magento\Framework\Model\AbstractModel $newObject + * @var array $insert + * @var array $update + * @var array $delete + */ + + /** + * Process base row + */ + $this->entityManager->save(CategoryInterface::class, $newObject); + + /** + * insert attribute values + */ + if (!empty($insert)) { + foreach ($insert as $attributeId => $value) { + $attribute = $this->getAttribute($attributeId); + $this->_insertAttribute($newObject, $attribute, $value); + } + } + + /** + * update attribute values + */ + if (!empty($update)) { + foreach ($update as $attributeId => $v) { + $attribute = $this->getAttribute($attributeId); + $this->_updateAttribute($newObject, $attribute, $v['value_id'], $v['value']); + } + } + + /** + * delete empty attribute values + */ + if (!empty($delete)) { + foreach ($delete as $table => $values) { + $this->_deleteAttributes($newObject, $table, $values); + } + } + + $this->_processAttributeValues(); + + $newObject->isObjectNew(false); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function delete($object) + { + try { + $this->transactionManager->start($this->getConnection()); + if (is_numeric($object)) { + } elseif ($object instanceof \Magento\Framework\Model\AbstractModel) { + $object->beforeDelete(); + } + $this->_beforeDelete($object); + $this->entityManager->delete(\Magento\Catalog\Api\Data\CategoryInterface::class, $object); + + $this->_afterDelete($object); + + if ($object instanceof \Magento\Framework\Model\AbstractModel) { + $object->isDeleted(true); + $object->afterDelete(); + } + $this->transactionManager->commit(); + if ($object instanceof \Magento\Framework\Model\AbstractModel) { + $object->afterDeleteCommit(); + } + } catch (\Exception $e) { + $this->transactionManager->rollBack(); + throw $e; + } + $this->_eventManager->dispatch( + 'catalog_category_delete_after_done', + ['product' => $object] + ); + return $this; + } } diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php b/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php index 0847a8e35e677c5748d1f13cabf640f64f4459fb..9d4cb16f18ceae3149e1f3cf69bd6d4e8595f64a 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Category/Tree.php @@ -5,6 +5,9 @@ */ namespace Magento\Catalog\Model\ResourceModel\Category; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Framework\Model\Entity\MetadataPool; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -88,15 +91,20 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp protected $_catalogCategory; /** - * Construct - * + * @var MetadataPool + */ + protected $metadataPool; + + /** + * Tree constructor. * @param \Magento\Catalog\Model\ResourceModel\Category $catalogCategory * @param \Magento\Framework\App\CacheInterface $cache * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Framework\Event\ManagerInterface $eventManager * @param \Magento\Catalog\Model\Attribute\Config $attributeConfig - * @param \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory + * @param Collection\Factory $collectionFactory + * @param MetadataPool $metadataPool */ public function __construct( \Magento\Catalog\Model\ResourceModel\Category $catalogCategory, @@ -105,7 +113,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp \Magento\Framework\App\ResourceConnection $resource, \Magento\Framework\Event\ManagerInterface $eventManager, \Magento\Catalog\Model\Attribute\Config $attributeConfig, - \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory + \Magento\Catalog\Model\ResourceModel\Category\Collection\Factory $collectionFactory, + MetadataPool $metadataPool ) { $this->_catalogCategory = $catalogCategory; $this->_cache = $cache; @@ -124,6 +133,7 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp $this->_eventManager = $eventManager; $this->_attributeConfig = $attributeConfig; $this->_collectionFactory = $collectionFactory; + $this->metadataPool = $metadataPool; } /** @@ -297,31 +307,35 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp */ protected function _getInactiveItemIds($collection, $storeId) { - $filter = $collection->getAllIdsSql(); - $attributeId = $this->_catalogCategory->getIsActiveAttributeId(); - - $conditionSql = $this->_conn->getCheckSql('c.value_id > 0', 'c.value', 'd.value'); - $table = $this->_coreResource->getTableName('catalog_category_entity_int'); - $bind = ['attribute_id' => $attributeId, 'store_id' => $storeId, 'zero_store_id' => 0, 'cond' => 0]; - $select = $this->_conn->select()->from( - ['d' => $table], - ['d.entity_id'] - )->where( - 'd.attribute_id = :attribute_id' - )->where( - 'd.store_id = :zero_store_id' - )->where( - 'd.entity_id IN (?)', - new \Zend_Db_Expr($filter) - )->joinLeft( - ['c' => $table], - 'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = d.entity_id', - [] - )->where( - $conditionSql . ' = :cond' - ); + $linkField = $this->metadataPool->getMetadata(CategoryInterface::class)->getLinkField(); + $intTable = $this->_coreResource->getTableName('catalog_category_entity_int'); + + $select = $collection->getAllIdsSql() + ->joinInner( + ['d' => $intTable], + "e.{$linkField} = d.{$linkField}", + [] + )->joinLeft( + ['c' => $intTable], + "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = d.{$linkField}", + [] + )->where( + 'd.attribute_id = :attribute_id' + )->where( + 'd.store_id = :zero_store_id' + )->where( + $this->_conn->getCheckSql('c.value_id > 0', 'c.value', 'd.value') . ' = :cond' + ); - return $this->_conn->fetchCol($select, $bind); + return $this->_conn->fetchCol( + $select, + [ + 'attribute_id' => $this->_catalogCategory->getIsActiveAttributeId(), + 'store_id' => $storeId, + 'zero_store_id' => 0, + 'cond' => 0 + ] + ); } /** @@ -567,6 +581,9 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp */ protected function _createCollectionDataSelect($sorted = true, $optionalAttributes = []) { + $meta = $this->metadataPool->getMetadata(CategoryInterface::class); + $linkField = $meta->getLinkField(); + $select = $this->_getDefaultCollection($sorted ? $this->_orderField : false)->getSelect(); // add attributes to select $attributes = ['name', 'is_active', 'is_anchor']; @@ -590,7 +607,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp $select->joinLeft( [$tableDefault => $attribute->getBackend()->getTable()], sprintf( - '%1$s.entity_id=e.entity_id AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', + '%1$s.' . $linkField . '=e.' . $linkField . + ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', $tableDefault, $attribute->getId(), \Magento\Store\Model\Store::DEFAULT_STORE_ID @@ -599,7 +617,8 @@ class Tree extends \Magento\Framework\Data\Tree\Dbp )->joinLeft( [$tableStore => $attribute->getBackend()->getTable()], sprintf( - '%1$s.entity_id=e.entity_id AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', + '%1$s.' . $linkField . '=e.' . $linkField . + ' AND %1$s.attribute_id=%2$d AND %1$s.store_id=%3$d', $tableStore, $attribute->getId(), $this->getStoreId() diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php index 01abfa03a6ab5cb9344ff6bc1f2ba5d0a4b36d41..8dcba6547cd14f61e1ff91b605070824f5084244 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Collection/AbstractCollection.php @@ -71,6 +71,17 @@ class AbstractCollection extends \Magento\Eav\Model\Entity\Collection\AbstractCo ); } + /** + * Retrieve Entity Primary Key + * + * @param \Magento\Eav\Model\Entity\AbstractEntity $entity + * @return string + */ + protected function getEntityPkName(\Magento\Eav\Model\Entity\AbstractEntity $entity) + { + return $entity->getLinkField(); + } + /** * Set store scope * diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php index fc6db7a099b7d824d01e532b7e7abc3dbd199113..9f6f6dbf73712655a9f321a58f95be4e837b8b2c 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Collection.php @@ -13,6 +13,8 @@ use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; use Magento\Customer\Api\GroupManagementInterface; use Magento\Framework\DB\Select; use Magento\Store\Model\Store; +use Magento\Framework\Model\Entity\MetadataPool; +use Magento\Catalog\Api\Data\CategoryInterface; /** * Product collection @@ -1999,7 +2001,10 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Collection\Abstrac $conditions = [ 'cat_pro.product_id=e.entity_id', - $this->getConnection()->quoteInto('cat_pro.category_id=?', $filters['category_id']), + $this->getConnection()->quoteInto( + 'cat_pro.category_id=?', + $filters['category_id'] + ), ]; $joinCond = join(' AND ', $conditions); diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php index 21389703ce94bfe22a4f4627477da3c300702a1e..ed40914f76a67652e7f099c35123779f4fc29b4e 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Product/Compare/Item/Collection.php @@ -50,6 +50,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection protected $_catalogProductCompareItem; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/Catalog/Model/ResourceModel/Url.php b/app/code/Magento/Catalog/Model/ResourceModel/Url.php index 157edc0b176c0a9fd3d8bf233cda4d10b4aaa903..bff384d42defb4c0bfbec3047db67462f1b0db33 100644 --- a/app/code/Magento/Catalog/Model/ResourceModel/Url.php +++ b/app/code/Magento/Catalog/Model/ResourceModel/Url.php @@ -11,7 +11,15 @@ namespace Magento\Catalog\Model\ResourceModel; * @author Magento Core Team <core@magentocommerce.com> */ use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Framework\Model\Entity\MetadataPool; +/** + * Class Url + * @package Magento\Catalog\Model\ResourceModel + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { /** @@ -88,13 +96,20 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb protected $productResource; /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * Url constructor. * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Eav\Model\Config $eavConfig * @param Product $productResource * @param \Magento\Catalog\Model\Category $catalogCategory * @param \Psr\Log\LoggerInterface $logger - * @param string $connectionName + * @param MetadataPool $metadataPool + * @param null $connectionName */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, @@ -103,6 +118,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb Product $productResource, \Magento\Catalog\Model\Category $catalogCategory, \Psr\Log\LoggerInterface $logger, + MetadataPool $metadataPool, $connectionName = null ) { $this->_storeManager = $storeManager; @@ -110,6 +126,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $this->productResource = $productResource; $this->_catalogCategory = $catalogCategory; $this->_logger = $logger; + $this->metadataPool = $metadataPool; parent::__construct($context, $connectionName); } @@ -150,6 +167,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected function _getCategoryAttribute($attributeCode, $categoryIds, $storeId) { + $linkField = $this->metadataPool->getMetadata(CategoryInterface::class)->getLinkField(); + $identifierFiled = $this->metadataPool->getMetadata(CategoryInterface::class)->getIdentifierField(); + $connection = $this->getConnection(); if (!isset($this->_categoryAttributes[$attributeCode])) { $attribute = $this->_catalogCategory->getResource()->getAttribute($attributeCode); @@ -181,26 +201,35 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb ); } elseif ($this->_categoryAttributes[$attributeCode]['is_global'] || $storeId == 0) { $select->from( - $attributeTable, - ['entity_id', 'value'] + ['t1' =>$this->getTable('catalog_category_entity')], + [$identifierFiled] + )->joinLeft( + ['e' => $attributeTable], + "t1.{$linkField} = e.{$linkField}", + ['value'] )->where( - 'attribute_id = :attribute_id' + "t1.{$identifierFiled} IN(?)", + $categoryIds )->where( - 'store_id = ?', - 0 + 'e.attribute_id = :attribute_id' )->where( - 'entity_id IN(?)', - $categoryIds + 'e.store_id = ?', + 0 ); + $bind['attribute_id'] = $this->_categoryAttributes[$attributeCode]['attribute_id']; } else { $valueExpr = $connection->getCheckSql('t2.value_id > 0', 't2.value', 't1.value'); $select->from( ['t1' => $attributeTable], - ['entity_id', 'value' => $valueExpr] + [$identifierFiled => 'e.'.$identifierFiled, 'value' => $valueExpr] )->joinLeft( ['t2' => $attributeTable], - 't1.entity_id = t2.entity_id AND t1.attribute_id = t2.attribute_id AND t2.store_id = :store_id', + "t1.{$linkField} = t2.{$linkField} AND t1.attribute_id = t2.attribute_id AND t2.store_id = :store_id", + [] + )->joinLeft( + ['e' => $this->getTable('catalog_category_entity')], + "e.{$linkField} = t1.{$linkField}", [] )->where( 't1.store_id = ?', @@ -208,9 +237,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb )->where( 't1.attribute_id = :attribute_id' )->where( - 't1.entity_id IN(?)', + "e.entity_id IN(?)", $categoryIds - ); + )->group('e.entity_id'); $bind['attribute_id'] = $this->_categoryAttributes[$attributeCode]['attribute_id']; $bind['store_id'] = $storeId; @@ -220,7 +249,7 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $attributes = []; foreach ($rowSet as $row) { - $attributes[$row['entity_id']] = $row['value']; + $attributes[$row[$identifierFiled]] = $row['value']; } unset($rowSet); foreach ($categoryIds as $categoryId) { @@ -374,6 +403,9 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $categories = []; $connection = $this->getConnection(); + $meta = $this->metadataPool->getMetadata(CategoryInterface::class); + $linkField = $meta->getLinkField(); + if (!is_array($categoryIds)) { $categoryIds = [$categoryIds]; } @@ -403,11 +435,11 @@ class Url extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $table = $this->getTable('catalog_category_entity_int'); $select->joinLeft( ['d' => $table], - 'd.attribute_id = :attribute_id AND d.store_id = 0 AND d.entity_id = main_table.entity_id', + "d.attribute_id = :attribute_id AND d.store_id = 0 AND d.{$linkField} = main_table.{$linkField}", [] )->joinLeft( ['c' => $table], - 'c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.entity_id = main_table.entity_id', + "c.attribute_id = :attribute_id AND c.store_id = :store_id AND c.{$linkField} = main_table.{$linkField}", [] ); diff --git a/app/code/Magento/Catalog/Setup/InstallSchema.php b/app/code/Magento/Catalog/Setup/InstallSchema.php index 69761bbe12c984d98e2b62b685df81fcace59df0..ba07738dd423a89c97472fcc7cda9d10f36878f9 100644 --- a/app/code/Magento/Catalog/Setup/InstallSchema.php +++ b/app/code/Magento/Catalog/Setup/InstallSchema.php @@ -1233,18 +1233,6 @@ class InstallSchema implements InstallSchemaInterface $installer->getIdxName('catalog_category_product', ['product_id']), ['product_id'] ) - ->addForeignKey( - $installer->getFkName( - 'catalog_category_product', - 'category_id', - 'catalog_category_entity', - 'entity_id' - ), - 'category_id', - $installer->getTable('catalog_category_entity'), - 'entity_id', - \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE - ) ->addForeignKey( $installer->getFkName('catalog_category_product', 'product_id', 'catalog_product_entity', 'entity_id'), 'product_id', diff --git a/app/code/Magento/Catalog/Setup/Recurring.php b/app/code/Magento/Catalog/Setup/Recurring.php new file mode 100644 index 0000000000000000000000000000000000000000..c5a3f6972b4192583b4c09a8f42bfbe244dc0fb4 --- /dev/null +++ b/app/code/Magento/Catalog/Setup/Recurring.php @@ -0,0 +1,61 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Catalog\Setup; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Framework\Model\Entity\MetadataPool; +use Magento\Framework\Setup\ExternalFKSetup; +use Magento\Framework\Setup\InstallSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * Catalog recurring setup + */ +class Recurring implements InstallSchemaInterface +{ + /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * @var ExternalFKSetup + */ + protected $externalFKSetup; + + /** + * @param MetadataPool $metadataPool + * @param ExternalFKSetup $externalFKSetup + */ + public function __construct( + MetadataPool $metadataPool, + ExternalFKSetup $externalFKSetup + ) { + $this->metadataPool = $metadataPool; + $this->externalFKSetup = $externalFKSetup; + } + + /** + * {@inheritdoc} + */ + public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $installer = $setup; + $installer->startSetup(); + + $metadata = $this->metadataPool->getMetadata(CategoryInterface::class); + $this->externalFKSetup->install( + $installer, + $metadata->getEntityTable(), + $metadata->getIdentifierField(), + 'catalog_category_product', + 'category_id' + ); + + $installer->endSetup(); + } +} diff --git a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php index de82e728cc6c7e5bb2500640c15116b457984969..6073db335fe533c8a442ba7ec9d4debe98cb4b34 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Category/TreeTest.php @@ -8,6 +8,10 @@ namespace Magento\Catalog\Test\Unit\Model\ResourceModel\Category; +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\Framework\Model\Entity\EntityMetadata; +use Magento\Framework\Model\Entity\MetadataPool; + class TreeTest extends \PHPUnit_Framework_TestCase { /** @@ -30,6 +34,14 @@ class TreeTest extends \PHPUnit_Framework_TestCase */ protected $_collectionFactory; + /** + * @var MetadataPool|\PHPUnit_Framework_MockObject_MockObject + */ + protected $metadataPoolMock; + + /** + * {@inheritdoc} + */ protected function setUp() { $objectHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this); @@ -71,13 +83,19 @@ class TreeTest extends \PHPUnit_Framework_TestCase '', false ); + + $this->metadataPoolMock = $this->getMockBuilder(MetadataPool::class) + ->disableOriginalConstructor() + ->getMock(); + $this->_model = $objectHelper->getObject( 'Magento\Catalog\Model\ResourceModel\Category\Tree', [ 'resource' => $this->_resource, 'eventManager' => $eventManager, 'attributeConfig' => $this->_attributeConfig, - 'collectionFactory' => $this->_collectionFactory + 'collectionFactory' => $this->_collectionFactory, + 'metadataPool' => $this->metadataPoolMock, ] ); } @@ -134,6 +152,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase $select = $this->getMock('Magento\Framework\DB\Select', [], [], '', false); $select->expects($this->any())->method('from')->will($this->returnSelf()); $select->expects($this->any())->method('join')->will($this->returnSelf()); + $select->expects($this->any())->method('joinInner')->will($this->returnSelf()); $select->expects($this->any())->method('joinLeft')->will($this->returnSelf()); $select->expects($this->any())->method('where')->will($this->returnSelf()); @@ -167,6 +186,7 @@ class TreeTest extends \PHPUnit_Framework_TestCase $collection = $this->getMock('Magento\Catalog\Model\ResourceModel\Category\Collection', [], [], '', false); $collection->expects($this->never())->method('getAllIds')->will($this->returnValue([])); + $collection->expects($this->once())->method('getAllIdsSql')->will($this->returnValue($select)); $collectionFactory = $this->getMock( 'Magento\Catalog\Model\ResourceModel\Category\Collection\Factory', [], @@ -182,6 +202,18 @@ class TreeTest extends \PHPUnit_Framework_TestCase $storeManager = $this->getMockForAbstractClass('Magento\Store\Model\StoreManagerInterface'); $storeManager->expects($this->any())->method('getStore')->will($this->returnValue($store)); + $categoryMetadataMock = $this->getMockBuilder(EntityMetadata::class) + ->disableOriginalConstructor() + ->getMock(); + $categoryMetadataMock->expects($this->any()) + ->method('getLinkField') + ->willReturn('id'); + $this->metadataPoolMock + ->expects($this->any()) + ->method('getMetadata') + ->with(CategoryInterface::class) + ->willReturn($categoryMetadataMock); + $model = $objectHelper->getObject( 'Magento\Catalog\Model\ResourceModel\Category\Tree', [ @@ -189,7 +221,8 @@ class TreeTest extends \PHPUnit_Framework_TestCase 'resource' => $resource, 'eventManager' => $eventManager, 'attributeConfig' => $attributeConfig, - 'collectionFactory' => $collectionFactory + 'collectionFactory' => $collectionFactory, + 'metadataPool' => $this->metadataPoolMock ] ); diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml index 7e4742bd14d1eee1955cae44163a26e443271fcd..c3fb3dc30cd779087705e166b6f6a3df153cee32 100644 --- a/app/code/Magento/Catalog/etc/di.xml +++ b/app/code/Magento/Catalog/etc/di.xml @@ -561,6 +561,14 @@ <item name="store_id" xsi:type="string">store_id</item> </item> </item> + <item name="Magento\Catalog\Api\Data\CategoryInterface" xsi:type="array"> + <item name="entityTableName" xsi:type="string">catalog_category_entity</item> + <item name="eavEntityType" xsi:type="string">catalog_category</item> + <item name="identifierField" xsi:type="string">entity_id</item> + <item name="entityContext" xsi:type="array"> + <item name="store_id" xsi:type="string">store_id</item> + </item> + </item> </argument> </arguments> </type> @@ -584,4 +592,12 @@ </argument> </arguments> </type> + <type name="Magento\Catalog\Model\Indexer\Category\Flat\AbstractAction"> + <arguments> + <argument name="skipStaticColumns" xsi:type="array"> + <item name="entity_type_id" xsi:type="string">entity_type_id</item> + <item name="attribute_set_id" xsi:type="string">attribute_set_id</item> + </argument> + </arguments> + </type> </config> diff --git a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php index 6220d75179e7ed252f5b2f32e3c1693b0f279b6d..38c87413b2b410f375a4c58156e4fbe143f27b35 100644 --- a/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php +++ b/app/code/Magento/CatalogSearch/Model/Adapter/Mysql/Plugin/Aggregation/Category/DataProvider.php @@ -34,6 +34,7 @@ class DataProvider protected $categoryFactory; /** + * DataProvider constructor. * @param ResourceConnection $resource * @param ScopeResolverInterface $scopeResolver * @param Resolver $layerResolver diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php index 1a43b5b7e2ad703bbf1169df697dd092a42a5a2d..37bc592d595fb11633411ff0a5aa1e81e290425e 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Advanced/Collection.php @@ -38,6 +38,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection private $temporaryStorageFactory; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php index 5338eaddbd12d20af3b93c5e0c57aa85c4dd0db1..5b11136822a8000e75f44ea4d4c4662e2b465f9c 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Fulltext/Collection.php @@ -7,9 +7,7 @@ namespace Magento\CatalogSearch\Model\ResourceModel\Fulltext; use Magento\Framework\DB\Select; use Magento\Framework\Exception\StateException; -use Magento\Framework\Search\Adapter\Mysql\Adapter; use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage; -use Magento\Framework\Search\Response\Aggregation\Value; use Magento\Framework\Search\Response\QueryResponse; /** @@ -38,13 +36,19 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection */ private $searchEngine; - /** @var string */ + /** + * @var string + */ private $queryText; - /** @var string|null */ + /** + * @var string|null + */ private $order = null; - /** @var string */ + /** + * @var string + */ private $searchRequestName; /** diff --git a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php index 82d1b2623550529931f7210cd136aea49ac03ec9..80c85edcce765a88ee7ed8df50ef45fbc74096b6 100644 --- a/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php +++ b/app/code/Magento/CatalogSearch/Model/ResourceModel/Search/Collection.php @@ -37,6 +37,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection protected $_attributeCollectionFactory; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php index 19a96e41cf3cd1ce41b36d7f38a1dfd2b79931fd..ecd1d8f822cd3c2f91f9ccea2d829feeb3817d2b 100644 --- a/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php +++ b/app/code/Magento/CatalogUrlRewrite/Setup/InstallSchema.php @@ -59,13 +59,6 @@ class InstallSchema implements InstallSchemaInterface 'entity_id', \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE ) - ->addForeignKey( - $installer->getFkName($tableName, 'category_id', 'catalog_category_entity', 'entity_id'), - 'category_id', - $installer->getTable('catalog_category_entity'), - 'entity_id', - \Magento\Framework\DB\Ddl\Table::ACTION_CASCADE - ) ->addForeignKey( $installer->getFkName($tableName, 'url_rewrite_id', 'url_rewrite', 'url_rewrite_id'), 'url_rewrite_id', @@ -77,6 +70,5 @@ class InstallSchema implements InstallSchemaInterface $installer->getConnection()->createTable($table); $installer->endSetup(); - } } diff --git a/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php b/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php new file mode 100644 index 0000000000000000000000000000000000000000..1fc00f70d08b60a0674890557e53cbe7d43e9c57 --- /dev/null +++ b/app/code/Magento/CatalogUrlRewrite/Setup/Recurring.php @@ -0,0 +1,62 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\CatalogUrlRewrite\Setup; + +use Magento\Catalog\Api\Data\CategoryInterface; +use Magento\CatalogUrlRewrite\Model\ResourceModel\Category\Product as ResourceProduct; +use Magento\Framework\Model\Entity\MetadataPool; +use Magento\Framework\Setup\ExternalFKSetup; +use Magento\Framework\Setup\InstallSchemaInterface; +use Magento\Framework\Setup\ModuleContextInterface; +use Magento\Framework\Setup\SchemaSetupInterface; + +/** + * CatalogUrlRewrite recurring setup + */ +class Recurring implements InstallSchemaInterface +{ + /** + * @var MetadataPool + */ + protected $metadataPool; + + /** + * @var ExternalFKSetup + */ + protected $externalFKSetup; + + /** + * @param MetadataPool $metadataPool + * @param ExternalFKSetup $externalFKSetup + */ + public function __construct( + MetadataPool $metadataPool, + ExternalFKSetup $externalFKSetup + ) { + $this->metadataPool = $metadataPool; + $this->externalFKSetup = $externalFKSetup; + } + + /** + * {@inheritdoc} + */ + public function install(SchemaSetupInterface $setup, ModuleContextInterface $context) + { + $installer = $setup; + $installer->startSetup(); + + $metadata = $this->metadataPool->getMetadata(CategoryInterface::class); + $this->externalFKSetup->install( + $installer, + $metadata->getEntityTable(), + $metadata->getIdentifierField(), + ResourceProduct::TABLE_NAME, + 'category_id' + ); + + $installer->endSetup(); + } +} diff --git a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php index 53b4ec285dd28202a083c1487c27c8e577f0beb2..ff50734d1b8348fbf7636e7274a9518a1477918f 100644 --- a/app/code/Magento/Eav/Model/Entity/AbstractEntity.php +++ b/app/code/Magento/Eav/Model/Entity/AbstractEntity.php @@ -1709,7 +1709,7 @@ abstract class AbstractEntity extends AbstractResource implements EntityInterfac { $data = [ 'attribute_id' => $attribute->getId(), - $this->getLinkField() => $object->getData($this->getLinkField()), + $entity->getLinkField() => $object->getData($entity->getLinkField()), ]; if (!$this->getEntityTable()) { diff --git a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php index c2f390e90e5d6e5330ca2f3db99bb80074da12a7..a608dc3809e2f77360430f31dca8869eed8022df 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php +++ b/app/code/Magento/Eav/Model/ResourceModel/UpdateHandler.php @@ -133,7 +133,7 @@ class UpdateHandler } if ((!array_key_exists($attribute->getAttributeCode(), $snapshot) || $snapshot[$attribute->getAttributeCode()] === false) - && array_key_exists($attribute->getAttributeCode(), $data) + && !empty($data[$attribute->getAttributeCode()]) && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()]) ) { $this->attributePersistor->registerInsert( @@ -146,7 +146,7 @@ class UpdateHandler } if (array_key_exists($attribute->getAttributeCode(), $snapshot) && $snapshot[$attribute->getAttributeCode()] !== false - && array_key_exists($attribute->getAttributeCode(), $data) + && !empty($data[$attribute->getAttributeCode()]) && $snapshot[$attribute->getAttributeCode()] != $data[$attribute->getAttributeCode()] && !$attribute->isValueEmpty($data[$attribute->getAttributeCode()]) ) { diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php index 65ecfee83f4f36e6c0216871b8c91d588ab4c17b..db2598df93ba2c50381ccb2fbfde621475b73e76 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Collection.php @@ -62,6 +62,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection protected $quoteResource; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php index 87100f307850e71235f35f7121397ebb0a866ffd..3344cca8eddef29015101596eac107e426427d98 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Index/Collection/AbstractCollection.php @@ -29,6 +29,7 @@ abstract class AbstractCollection extends \Magento\Catalog\Model\ResourceModel\P protected $_customerVisitor; /** + * AbstractCollection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php index 171a909702ef7cdd7416fab8e440584075a6c123..51199806dde789353c4b2d771455d200b10663d8 100644 --- a/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php +++ b/app/code/Magento/Reports/Model/ResourceModel/Product/Lowstock/Collection.php @@ -46,6 +46,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection protected $_itemResource; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy @@ -72,7 +73,7 @@ class Collection extends \Magento\Reports\Model\ResourceModel\Product\Collection * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry * @param \Magento\CatalogInventory\Api\StockConfigurationInterface $stockConfiguration * @param \Magento\CatalogInventory\Model\ResourceModel\Stock\Item $itemResource - * @param mixed $connection + * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection * * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ diff --git a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php index d7d8aebfdf0c4cc897058d51eb84067878e99c75..a202444afac72a49b0495a9fc5843eb39d17507e 100644 --- a/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php +++ b/app/code/Magento/Review/Model/ResourceModel/Review/Product/Collection.php @@ -59,6 +59,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection protected $_voteFactory; /** + * Collection constructor. * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy diff --git a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php index 75e853c13c6024ec0969a2a163d00fce5eafde9d..dc71b469f39a04063d10cbd219251cc9a6ae217c 100644 --- a/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php +++ b/app/code/Magento/Sitemap/Model/ResourceModel/Catalog/Category.php @@ -38,21 +38,29 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected $_categoryResource; + /** + * @var \Magento\Framework\Model\Entity\MetadataPool + */ + protected $metadataPool; + /** * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Magento\Store\Model\StoreManagerInterface $storeManager * @param \Magento\Catalog\Model\ResourceModel\Category $categoryResource + * @param \Magento\Framework\Model\Entity\MetadataPool $metadataPool * @param string $connectionName */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\ResourceModel\Category $categoryResource, + \Magento\Framework\Model\Entity\MetadataPool $metadataPool, $connectionName = null ) { $this->_storeManager = $storeManager; $this->_categoryResource = $categoryResource; parent::__construct($context, $connectionName); + $this->metadataPool = $metadataPool; } /** @@ -147,6 +155,9 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb */ protected function _addFilter($storeId, $attributeCode, $value, $type = '=') { + $meta = $this->metadataPool->getMetadata(\Magento\Catalog\Api\Data\CategoryInterface::class); + $linkField = $meta->getLinkField(); + if (!$this->_select instanceof \Magento\Framework\DB\Select) { return false; } @@ -181,7 +192,8 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb } else { $this->_select->join( ['t1_' . $attributeCode => $attribute['table']], - 'e.entity_id = t1_' . $attributeCode . '.entity_id AND t1_' . $attributeCode . '.store_id = 0', + 'e.' . $linkField . ' = t1_' . $attributeCode . '.' . $linkField . + ' AND t1_' . $attributeCode . '.store_id = 0', [] )->where( 't1_' . $attributeCode . '.attribute_id=?', @@ -201,9 +213,9 @@ class Category extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb $this->getConnection()->quoteInto( 't1_' . $attributeCode . - '.entity_id = t2_' . + '.' . $linkField . ' = t2_' . $attributeCode . - '.entity_id AND t1_' . + '.' . $linkField . ' AND t1_' . $attributeCode . '.attribute_id = t2_' . $attributeCode . diff --git a/composer.lock b/composer.lock index 5a1312bc6f83baaba2ecc0aebea91dd2a07223e3..d7525677fdd8f1118add45701b401ebbc9dcc361 100644 --- a/composer.lock +++ b/composer.lock @@ -277,7 +277,7 @@ "type": "zip", "url": "https://api.github.com/repos/magento/composer/zipball/1be267e71debac6e0d9fae4e5144f6095cffbe89", "reference": null, - "shasum": "79156c3e7317af1ff64a482ba90ec81c66b82c73" + "shasum": "6bfdbff4c23aace1e6d14ab598c81c790375aba0" }, "require": { "composer/composer": "1.0.0-alpha10", @@ -381,12 +381,12 @@ "source": { "type": "git", "url": "https://github.com/magento/zf1.git", - "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f" + "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10" }, "dist": { "type": "zip", "url": "https://api.github.com/repos/magento/zf1/zipball/c9d607bfd9454bc18b9deff737ccd5d044e2ab10", - "reference": "dbdf178992bfa52d6e978e62131162301ff6b76f", + "reference": "c9d607bfd9454bc18b9deff737ccd5d044e2ab10", "shasum": "" }, "require": { @@ -420,7 +420,7 @@ "ZF1", "framework" ], - "time": "2015-09-30 13:04:03" + "time": "2015-10-29 14:34:55" }, { "name": "monolog/monolog", diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php index d34428003efc501bfa3b952acb78e3e59f620b71..2a82b359c5a8b923d5a621014fac5d91143dac1e 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Category/Checkboxes/TreeTest.php @@ -7,6 +7,8 @@ namespace Magento\Catalog\Block\Adminhtml\Category\Checkboxes; /** * @magentoAppArea adminhtml + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class TreeTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php index eb685c327577e3515c22a6f16d8d925b0de8d637..4a3c8d48a4f71ddf494343bd434eeb983b099c29 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Controller/Adminhtml/CategoryTest.php @@ -152,7 +152,7 @@ class CategoryTest extends \Magento\TestFramework\TestCase\AbstractBackendContro 'id' => '2', 'path' => '1/2', 'url_key' => 'default-category', - 'is_anchor' => '0', + 'is_anchor' => 'false', 'use_default' => [ 'name' => 1, 'is_active' => 1, diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php index 7255a16fb29b64e0b45da60964787a8ddaa822d1..c425072dc6bf8034c5ec13284883471ac860fa9f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/CategoryTest.php @@ -5,6 +5,13 @@ */ namespace Magento\Catalog\Helper; +/** + * Class CategoryTest + * @package Magento\Catalog\Helper + * + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled + */ class CategoryTest extends \PHPUnit_Framework_TestCase { /** diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php index 4cba91301d9169f6960e67df239d08beeea24837..c41c5ad2d2520f12f21b64388c673c8dd74bb29f 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/DataTest.php @@ -83,6 +83,8 @@ class DataTest extends \PHPUnit_Framework_TestCase /** * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ public function testGetBreadcrumbPath() { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php index 6a1cb185479a8951978233509f55ca9b3c2b19c7..762b7d17ff45a64fe88b59f8c0283933cb6f65bc 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Helper/ProductTest.php @@ -191,6 +191,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase /** * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled * @magentoAppIsolation enabled */ public function testInitProduct() diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php index f47f8af6ff8d217aa40e2b44c4ec710615686cc6..9097bd400b368f5d0b0948b2121fbf99102f427b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTest.php @@ -11,6 +11,7 @@ namespace Magento\Catalog\Model; * * @see \Magento\Catalog\Model\CategoryTreeTest * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled * @magentoAppIsolation enabled */ class CategoryTest extends \PHPUnit_Framework_TestCase @@ -274,6 +275,30 @@ class CategoryTest extends \PHPUnit_Framework_TestCase $this->assertEquals('5', $category->getPosition()); } + /** + * @magentoAppArea adminhtml + */ + public function testDeleteChildren() + { + $this->_model->unsetData(); + $this->_model->load(4); + $this->_model->setSkipDeleteChildren(true); + $this->_model->delete(); + + $this->_model->unsetData(); + $this->_model->load(5); + $this->assertEquals($this->_model->getId(), 5); + + $this->_model->unsetData(); + $this->_model->load(3); + $this->assertEquals($this->_model->getId(), 3); + $this->_model->delete(); + + $this->_model->unsetData(); + $this->_model->load(5); + $this->assertEquals($this->_model->getId(), null); + } + protected function getCategoryByName($categoryName) { /* @var \Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php index 3b12d91a0fd298122f1de25f8c4453cdd7516cf6..46a36dbf0a0230214c77a0daadb096387390a985 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/CategoryTreeTest.php @@ -11,6 +11,8 @@ namespace Magento\Catalog\Model; * * @see \Magento\Catalog\Model\CategoryTest * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ class CategoryTreeTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php index 6df6b1f6753204ad2ca09516d202832fcc0c167f..edc07a3d7ccf609727592183394e3b87e48576a7 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/FlatTest.php @@ -109,7 +109,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase 2 ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource()); $result = $category->getAllChildren(true); $this->assertNotEmpty($result); @@ -174,7 +174,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase 2 ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource()); $result = $category->getAllChildren(true); $this->assertNotEmpty($result); @@ -188,7 +188,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase self::$categoryOne ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $categoryOne->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $categoryOne->getResource()); $result = $categoryOne->getAllChildren(true); $this->assertNotEmpty($result); @@ -198,12 +198,12 @@ class FlatTest extends \PHPUnit_Framework_TestCase /** @var \Magento\Catalog\Model\Category $categoryTwo */ $categoryTwo = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create( - 'Magento\Catalog\Model\Category' + \Magento\Catalog\Model\Category::class )->load( self::$categoryTwo ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $categoryTwo->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $categoryTwo->getResource()); $this->assertEquals(self::$categoryOne, $categoryTwo->getParentId()); $this->checkCategoryData($categoryTwo); @@ -264,7 +264,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase 2 ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource()); $this->checkCategoryData($category); @@ -332,7 +332,7 @@ class FlatTest extends \PHPUnit_Framework_TestCase 2 ); - $this->assertInstanceOf('Magento\Catalog\Model\ResourceModel\Category\Flat', $category->getResource()); + $this->assertInstanceOf(\Magento\Catalog\Model\ResourceModel\Category\Flat::class, $category->getResource()); $result = $category->getAllChildren(true); $this->assertNotEmpty($result); diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php index 940a4af8a59ae123847788603d1a437304d87e8b..e253f7e4b3a23768bf1ec9ee946faeb8325aa479 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/CategoryTest.php @@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer; * Test class for \Magento\Catalog\Model\Layer. * * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ class CategoryTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php index 704e08df7e588f5cc7bbf3ce7e70e5266d7b46cc..2a2f4c6c1da25765fc81ed1a93e511589b575da9 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/CategoryTest.php @@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer\Filter; * Test class for \Magento\Catalog\Model\Layer\Filter\Category. * * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ class CategoryTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php index dc3ef94d5dbc87483401ce1df0dedfda73208c5b..59bccfb1d2bb02c22e3c6519867d639a364db1a6 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DataProvider/PriceTest.php @@ -10,6 +10,8 @@ namespace Magento\Catalog\Model\Layer\Filter\DataProvider; * Test class for \Magento\Catalog\Model\Layer\Filter\DataProvider\Price. * * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ class PriceTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php index 08aa17f97530c3fe8ab06610be8a5ebc3635b159..10c3252f6643e4c236d982c1c48faa7fd2f185fb 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/DecimalTest.php @@ -10,6 +10,8 @@ namespace Magento\Catalog\Model\Layer\Filter; * * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_weight_filterable.php * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class DecimalTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php index a4ad1e6c5f84a23d436a40fb61eedd47644e7bd4..2fff101b743b59d5663e0d32f6172e6a58e55787 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Layer/Filter/PriceTest.php @@ -9,6 +9,8 @@ namespace Magento\Catalog\Model\Layer\Filter; * Test class for \Magento\Catalog\Model\Layer\Filter\Price. * * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class PriceTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php index db598982a1b40605e6433896089d0a5fbd44865a..c87b553e18f8b4772ef7a5d562161cafa2508d21 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductExternalTest.php @@ -12,6 +12,8 @@ namespace Magento\Catalog\Model; * @see \Magento\Catalog\Model\ProductTest * @see \Magento\Catalog\Model\ProductPriceTest * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoAppIsolation enabled + * @magentoDbIsolation enabled */ class ProductExternalTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php index 561f099ad9e0a4e95c365c347dcf94a1feb369e1..0359a76e286cc4dd3f8ecd0ddfe3609613ba548d 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductGettersTest.php @@ -14,6 +14,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; * @see \Magento\Catalog\Model\ProductExternalTest * @see \Magento\Catalog\Model\ProductPriceTest * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class ProductGettersTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php index a7aba33c83e008ab021f15a955b8a70a4f6da34f..e3e6c2588736c9c073def5dd495c80f4cbc9658b 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/ProductTest.php @@ -14,6 +14,8 @@ use Magento\Framework\App\Filesystem\DirectoryList; * @see \Magento\Catalog\Model\ProductExternalTest * @see \Magento\Catalog\Model\ProductPriceTest * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class ProductTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php index 115978c8439f6b7863e0aa598655f719af8e74ee..e114f71d09d0c1657799cbba5e1eb1e7a0b88508 100644 --- a/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php +++ b/dev/tests/integration/testsuite/Magento/Catalog/_files/categories_rollback.php @@ -28,10 +28,10 @@ foreach ($productsToDelete as $sku) { //Remove categories /** @var Magento\Catalog\Model\ResourceModel\Category\Collection $collection */ $collection = $objectManager->create('Magento\Catalog\Model\ResourceModel\Category\Collection'); -$collection - ->addAttributeToFilter('level', 2) - ->load() - ->delete(); +foreach ($collection->addAttributeToFilter('level', ['in' => [2, 3, 4]]) as $category) { + /** @var \Magento\Catalog\Model\Category $category */ + $category->delete(); +} $registry->unregister('isSecureArea'); $registry->register('isSecureArea', false); diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php index c1c6686f1574f3cb6fef7fed2dc1a89c5c0f2b6a..266f4e038570e4834cc5a3e28cc37b9dc4b3c300 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest.php @@ -764,6 +764,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase * @magentoDataFixture Magento/Store/_files/core_fixturestore.php * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_with_option.php * @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_attribute.php + * @magentoDbIsolation enabled * @magentoAppIsolation enabled */ public function testProductsWithMultipleStores() diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php index 322c802e6281b0ae9250ea62089fddff5bb1309a..52931492226fd0accba927552a97474c3d1adfe1 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/CategoryTest.php @@ -11,7 +11,7 @@ namespace Magento\CatalogSearch\Model\Layer\Filter; /** * Test class for \Magento\CatalogSearch\Model\Layer\Filter\Category. * - * @magentoDbIsolation disabled + * @magentoDbIsolation enabled * @magentoAppIsolation enabled * @magentoDataFixture Magento/Catalog/_files/categories.php */ diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php index 1f8ba6aef0710512f3303700b73ed83938dc4a4f..3b2356fc756c9c9a538f2472e3238d50a12eabff 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/DecimalTest.php @@ -11,6 +11,8 @@ namespace Magento\CatalogSearch\Model\Layer\Filter; * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/_files/attribute_weight_filterable.php * @magentoDataFixture Magento/Catalog/_files/categories.php * @magentoDataFixture Magento/Catalog/Model/Layer/Filter/Price/_files/products_base.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class DecimalTest extends \PHPUnit_Framework_TestCase { diff --git a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php index 003b558aa42adbc47e6716eafc4db7e20d9d1ca9..ce292c06f02e169e62d80dfa0e51eeb0f85ad01a 100644 --- a/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php +++ b/dev/tests/integration/testsuite/Magento/CatalogSearch/Model/Layer/Filter/PriceTest.php @@ -9,6 +9,8 @@ namespace Magento\CatalogSearch\Model\Layer\Filter; * Test class for \Magento\CatalogSearch\Model\Layer\Filter\Price. * * @magentoDataFixture Magento/Catalog/_files/categories.php + * @magentoDbIsolation enabled + * @magentoAppIsolation enabled */ class PriceTest extends \PHPUnit_Framework_TestCase { diff --git a/lib/internal/Magento/Framework/Model/EntityManager.php b/lib/internal/Magento/Framework/Model/EntityManager.php index 140fbd041cde13920b00c42500fd2f8d90f52afb..82d3fa02873a7da9e73db7256211668d81cd3fe4 100644 --- a/lib/internal/Magento/Framework/Model/EntityManager.php +++ b/lib/internal/Magento/Framework/Model/EntityManager.php @@ -70,6 +70,19 @@ class EntityManager return $operation->execute($entityType, $entity); } + /** + * Is entity exists in Entity Manager + * + * @param string $entityType + * @param string $identifier + * @return bool + * @throws \Exception + */ + public function has($entityType, $identifier) + { + return $this->metadataPool->getMetadata($entityType)->checkIsEntityExists($identifier); + } + /** * @param string $entityType * @param object $entity diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php index 22bf6a7e96fb2bcceb8ef5d303b0b1ac0f72310d..0886a9c0611d36b480b988c072e30e99488007df 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/Entity/MetadataPoolTest.php @@ -151,8 +151,7 @@ class MetadataPoolTest extends \PHPUnit_Framework_TestCase 'entityContext' => ['store_id'] ] ] - ] - , + ], [ 'SomeNameSpace\TestInterface', [ diff --git a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php index 086d3c44dda1a490f0ad09bd68cdd7bef97e2f6f..be0f86d547589ad922b8c3819c5cf78a2bb2dd22 100644 --- a/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php +++ b/lib/internal/Magento/Framework/Model/Test/Unit/ResourceModel/Db/ExtensionPoolTest.php @@ -22,6 +22,9 @@ class ExtensionPoolTest extends \PHPUnit_Framework_TestCase */ protected $objectManager; + /** + * {@inheritdoc} + */ protected function setUp() { $this->objectManager = $this->getMockForAbstractClass( @@ -61,14 +64,41 @@ class ExtensionPoolTest extends \PHPUnit_Framework_TestCase ); } - public function testExecute() + /** + * @dataProvider executeDataProvider + * + * @param array $expected + * @param string $entityType + * @param string $actionName + * @return void + */ + public function testExecute(array $expected, $entityType, $actionName) { $this->assertEquals( + $expected, + $this->subject->getActions($entityType, $actionName) + ); + } + + /** + * @return array + */ + public function executeDataProvider() + { + return [ [ - 'test_extension_1' => 'Test\Extension1\Entity\ReadHandler', - 'test_extension_2' => 'Test\Extension2\Default\CreateHandler' + [ + 'test_extension_1' => 'Test\Extension1\Entity\ReadHandler', + 'test_extension_2' => 'Test\Extension2\Default\CreateHandler' + ], + 'Test\First\Entity', + 'read' ], - $this->subject->getActions('Test\First\Entity', 'read') - ); + [ + [], + 'Test\First\Entity', + 'delete' + ] + ]; } } diff --git a/lib/internal/Magento/Framework/Mview/Config/Converter.php b/lib/internal/Magento/Framework/Mview/Config/Converter.php index df06fde50c38305c9b2b9939659cb8ba38fb9e60..bdd814f018dfe1e5faeea1ac16632b307233133a 100644 --- a/lib/internal/Magento/Framework/Mview/Config/Converter.php +++ b/lib/internal/Magento/Framework/Mview/Config/Converter.php @@ -5,6 +5,9 @@ */ namespace Magento\Framework\Mview\Config; +use Magento\Framework\Exception\LocalizedException; +use Magento\Framework\Mview\View\SubscriptionInterface; + class Converter implements \Magento\Framework\Config\ConverterInterface { /** @@ -73,7 +76,22 @@ class Converter implements \Magento\Framework\Config\ConverterInterface } $name = $this->getAttributeValue($subscription, 'name'); $column = $this->getAttributeValue($subscription, 'entity_column'); - $data['subscriptions'][$name] = ['name' => $name, 'column' => $column]; + $subscriptionModel = $this->getAttributeValue($subscription, 'subscription_model'); + if (!empty($subscriptionModel) + && !in_array( + SubscriptionInterface::class, + class_implements(ltrim($subscriptionModel, '\\')) + ) + ) { + throw new \InvalidArgumentException( + 'Subscription model must implement ' . SubscriptionInterface::class + ); + } + $data['subscriptions'][$name] = [ + 'name' => $name, + 'column' => $column, + 'subscription_model' => $subscriptionModel + ]; } break; } diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php index 632a112975e73a28fb49563c28f143818d91d7a6..dde9a3938cb4c066ee2d0c290b7acfad235e40c7 100644 --- a/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php +++ b/lib/internal/Magento/Framework/Mview/Test/Unit/ViewTest.php @@ -232,7 +232,7 @@ class ViewTest extends \PHPUnit_Framework_TestCase $this->changelogMock->expects($this->once()) ->method('drop'); $subscriptionMock = $this->getMock( - 'Magento\Framework\Mview\View\Subscription', + \Magento\Framework\Mview\View\Subscription::class, ['remove'], [], '', diff --git a/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php b/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php index 0f9ee70ac637804de2461555d2800e2d2c3419fb..158383f5154bf6e449fbdf8696afa9bd8247ea52 100644 --- a/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php +++ b/lib/internal/Magento/Framework/Mview/Test/Unit/_files/mview_config.php @@ -15,8 +15,16 @@ return [ 'action_class' => 'Ogogo\Class\One', 'group' => 'some_view_group', 'subscriptions' => [ - 'some_entity' => ['name' => 'some_entity', 'column' => 'entity_id'], - 'some_product_relation' => ['name' => 'some_product_relation', 'column' => 'product_id'], + 'some_entity' => [ + 'name' => 'some_entity', + 'column' => 'entity_id', + 'subscription_model' => null + ], + 'some_product_relation' => [ + 'name' => 'some_product_relation', + 'column' => 'product_id', + 'subscription_model' => null + ], ], ], ] diff --git a/lib/internal/Magento/Framework/Mview/View.php b/lib/internal/Magento/Framework/Mview/View.php index 6026a28c83470d55072bd0c5ecdb9853bc905f7b..a0a89bce998cc6165ee200e98d2bd198474b54c8 100644 --- a/lib/internal/Magento/Framework/Mview/View.php +++ b/lib/internal/Magento/Framework/Mview/View.php @@ -8,6 +8,8 @@ namespace Magento\Framework\Mview; +use Magento\Framework\Mview\View\SubscriptionFactory; + /** * @SuppressWarnings(PHPMD.CouplingBetweenObjects) */ @@ -48,7 +50,7 @@ class View extends \Magento\Framework\DataObject implements ViewInterface * @param ActionFactory $actionFactory * @param View\StateInterface $state * @param View\ChangelogInterface $changelog - * @param View\SubscriptionFactory $subscriptionFactory + * @param SubscriptionFactory $subscriptionFactory * @param array $data */ public function __construct( @@ -56,7 +58,7 @@ class View extends \Magento\Framework\DataObject implements ViewInterface ActionFactory $actionFactory, View\StateInterface $state, View\ChangelogInterface $changelog, - View\SubscriptionFactory $subscriptionFactory, + SubscriptionFactory $subscriptionFactory, array $data = [] ) { $this->config = $config; @@ -175,16 +177,19 @@ class View extends \Magento\Framework\DataObject implements ViewInterface $this->getChangelog()->create(); // Create subscriptions - foreach ($this->getSubscriptions() as $subscription) { + foreach ($this->getSubscriptions() as $subscriptionConfig) { /** @var \Magento\Framework\Mview\View\SubscriptionInterface $subscription */ - $subscription = $this->subscriptionFactory->create( + $subscriptionInstance = $this->subscriptionFactory->create( [ 'view' => $this, - 'tableName' => $subscription['name'], - 'columnName' => $subscription['column'], + 'tableName' => $subscriptionConfig['name'], + 'columnName' => $subscriptionConfig['column'], + 'subscriptionModel' => !empty($subscriptionConfig['subscription_model']) + ? $subscriptionConfig['subscription_model'] + : SubscriptionFactory::INSTANCE_NAME, ] ); - $subscription->create(); + $subscriptionInstance->create(); } // Update view state @@ -208,16 +213,19 @@ class View extends \Magento\Framework\DataObject implements ViewInterface if ($this->getState()->getMode() != View\StateInterface::MODE_DISABLED) { try { // Remove subscriptions - foreach ($this->getSubscriptions() as $subscription) { + foreach ($this->getSubscriptions() as $subscriptionConfig) { /** @var \Magento\Framework\Mview\View\SubscriptionInterface $subscription */ - $subscription = $this->subscriptionFactory->create( + $subscriptionInstance = $this->subscriptionFactory->create( [ 'view' => $this, - 'tableName' => $subscription['name'], - 'columnName' => $subscription['column'], + 'tableName' => $subscriptionConfig['name'], + 'columnName' => $subscriptionConfig['column'], + 'subscriptionModel' => !empty($subscriptionConfig['subscriptionModel']) + ? $subscriptionConfig['subscriptionModel'] + : SubscriptionFactory::INSTANCE_NAME, ] ); - $subscription->remove(); + $subscriptionInstance->remove(); } // Drop changelog table diff --git a/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php b/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php index fc31a8f25ceab49e6189934d7c4cef3e25b50d4e..7a27338878d4a7f99a0fdfe72404cfe7b99e71dd 100644 --- a/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php +++ b/lib/internal/Magento/Framework/Mview/View/SubscriptionFactory.php @@ -5,10 +5,26 @@ */ namespace Magento\Framework\Mview\View; +/** + * Class SubscriptionFactory + * @package Magento\Framework\Mview\View + * + */ class SubscriptionFactory extends AbstractFactory { /** * Instance name */ - const INSTANCE_NAME = 'Magento\Framework\Mview\View\SubscriptionInterface'; + const INSTANCE_NAME = SubscriptionInterface::class; + + /** + * @param array $data + * @return SubscriptionInterface + */ + public function create(array $data = []) + { + $instanceName = isset($data['subscriptionModel']) ? $data['subscriptionModel'] : self::INSTANCE_NAME; + unset($data['subscriptionModel']); + return $this->objectManager->create($instanceName, $data); + } } diff --git a/lib/internal/Magento/Framework/Mview/etc/mview.xsd b/lib/internal/Magento/Framework/Mview/etc/mview.xsd index 320a57a0af46e2551077f08d2f73c5ebea308c0a..cda0b197095bc7f1942d1738844c1e1800c59d95 100644 --- a/lib/internal/Magento/Framework/Mview/etc/mview.xsd +++ b/lib/internal/Magento/Framework/Mview/etc/mview.xsd @@ -78,6 +78,7 @@ </xs:annotation> <xs:attribute name="name" type="tableNameType" use="required" /> <xs:attribute name="entity_column" type="entityColumnType" use="required" /> + <xs:attribute name="subscription_model" type="subscriptionModelType" /> </xs:complexType> <xs:simpleType name="entityColumnType"> @@ -101,4 +102,15 @@ <xs:pattern value="[a-z_]+" /> </xs:restriction> </xs:simpleType> + + <xs:simpleType name="subscriptionModelType"> + <xs:annotation> + <xs:documentation> + Subscription model must be a valid PHP class or interface name. + </xs:documentation> + </xs:annotation> + <xs:restriction base="xs:string"> + <xs:pattern value="[a-zA-Z_][a-zA-Z0-9\\]*" /> + </xs:restriction> + </xs:simpleType> </xs:schema>