Skip to content

Commit

Permalink
Merge pull request #1088 from magento-performance/MAGETWO-62691
Browse files Browse the repository at this point in the history
[Performance] EAV attributes caching optimization
  • Loading branch information
kandy authored May 11, 2017
2 parents f14f886 + e746bb0 commit 541e139
Show file tree
Hide file tree
Showing 28 changed files with 311 additions and 298 deletions.
3 changes: 1 addition & 2 deletions app/code/Magento/Catalog/Model/Product/Type/AbstractType.php
Original file line number Diff line number Diff line change
Expand Up @@ -723,8 +723,7 @@ public function save($product)
protected function _removeNotApplicableAttributes($product)
{
$entityType = $product->getResource()->getEntityType();
foreach ($this->_eavConfig->getEntityAttributeCodes($entityType, $product) as $attributeCode) {
$attribute = $this->_eavConfig->getAttribute($entityType, $attributeCode);
foreach ($this->_eavConfig->getEntityAttributes($entityType, $product) as $attribute) {
$applyTo = $attribute->getApplyTo();
if (is_array($applyTo) && count($applyTo) > 0 && !in_array($product->getTypeId(), $applyTo)) {
$product->unsetData($attribute->getAttributeCode());
Expand Down
4 changes: 1 addition & 3 deletions app/code/Magento/Catalog/Model/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,7 @@ public function getList(\Magento\Framework\Api\SearchCriteriaInterface $searchCr
$collection = $this->collectionFactory->create();
$this->extensionAttributesJoinProcessor->process($collection);

foreach ($this->metadataService->getList($this->searchCriteriaBuilder->create())->getItems() as $metadata) {
$collection->addAttributeToSelect($metadata->getAttributeCode());
}
$collection->addAttributeToSelect('*');
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');

Expand Down
11 changes: 10 additions & 1 deletion app/code/Magento/Catalog/Model/ResourceModel/Category.php
Original file line number Diff line number Diff line change
Expand Up @@ -1011,7 +1011,16 @@ public function countVisible()
public function load($object, $entityId, $attributes = [])
{
$this->_attributes = [];
$this->loadAttributesMetadata($attributes);
$select = $this->_getLoadRowSelect($object, $entityId);
$row = $this->getConnection()->fetchRow($select);

if (is_array($row)) {
$object->addData($row);
} else {
$object->isObjectNew(true);
}

$this->loadAttributesForObject($attributes, $object);
$object = $this->getEntityManager()->load($object, $entityId);
if (!$this->getEntityManager()->has($object)) {
$object->isObjectNew(true);
Expand Down
11 changes: 10 additions & 1 deletion app/code/Magento/Catalog/Model/ResourceModel/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,16 @@ public function validate($object)
*/
public function load($object, $entityId, $attributes = [])
{
$this->loadAttributesMetadata($attributes);
$select = $this->_getLoadRowSelect($object, $entityId);
$row = $this->getConnection()->fetchRow($select);

if (is_array($row)) {
$object->addData($row);
} else {
$object->isObjectNew(true);
}

$this->loadAttributesForObject($attributes, $object);
$this->getEntityManager()->load($object, $entityId);
return $this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public function testValidate($value)
$attributeCode = 'attr_code';
$attribute = $this->getMock(
\Magento\Eav\Model\Entity\Attribute::class,
['getAttributeCode', 'getIsRequired', 'isValueEmpty', 'getIsUnique', 'getEntityType', '__wakeup'],
['getAttributeCode', 'getIsRequired', 'isValueEmpty', 'getIsUnique', 'getEntity', '__wakeup'],
[],
'',
false
Expand All @@ -178,7 +178,7 @@ public function testValidate($value)
$attribute->expects($this->any())->method('getIsRequired')->will($this->returnValue(true));
$attribute->expects($this->any())->method('isValueEmpty')->will($this->returnValue($value));
$attribute->expects($this->any())->method('getIsUnique')->will($this->returnValue(true));
$attribute->expects($this->any())->method('getEntityType')->will($this->returnValue($attributeEntity));
$attribute->expects($this->any())->method('getEntity')->will($this->returnValue($attributeEntity));
$attributeEntity->expects($this->any())->method('checkAttributeUniqueValue')->will($this->returnValue(true));

$this->attributeRepository->expects($this->once())
Expand Down
23 changes: 2 additions & 21 deletions app/code/Magento/Catalog/Test/Unit/Model/ProductRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -707,36 +707,17 @@ public function testDeleteById()
public function testGetList()
{
$searchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteriaInterface::class, [], [], '', false);
$attributeCode = 'attribute_code';
$collectionMock = $this->getMock(
\Magento\Catalog\Model\ResourceModel\Product\Collection::class,
[],
[],
'',
false
);
$extendedSearchCriteriaMock = $this->getMock(\Magento\Framework\Api\SearchCriteria::class, [], [], '', false);
$productAttributeSearchResultsMock = $this->getMockBuilder(ProductAttributeInterface::class)
->disableOriginalConstructor()
->setMethods(['getItems'])
->getMockForAbstractClass();
$productAttributeMock = $this->getMock(
\Magento\Catalog\Api\Data\ProductAttributeInterface::class,
[],
[],
'',
false
);

$this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($collectionMock);
$this->searchCriteriaBuilderMock->expects($this->once())->method('create')
->willReturn($extendedSearchCriteriaMock);
$this->metadataServiceMock->expects($this->once())->method('getList')->with($extendedSearchCriteriaMock)
->willReturn($productAttributeSearchResultsMock);
$productAttributeSearchResultsMock->expects($this->once())->method('getItems')
->willReturn([$productAttributeMock]);
$productAttributeMock->expects($this->once())->method('getAttributeCode')->willReturn($attributeCode);
$collectionMock->expects($this->once())->method('addAttributeToSelect')->with($attributeCode);

$collectionMock->expects($this->once())->method('addAttributeToSelect')->with('*');
$collectionMock->expects($this->exactly(2))->method('joinAttribute')->withConsecutive(
['status', 'catalog_product/status', 'entity_id', null, 'inner'],
['visibility', 'catalog_product/visibility', 'entity_id', null, 'inner']
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public function __construct(
public function validateValue($value)
{
$attribute = $this->getAttribute();
$label = __($attribute->getStoreLabel());

$countryId = $this->getExtractedData('country_id');
if ($this->directoryHelper->isZipCodeOptional($countryId)) {
Expand All @@ -58,6 +57,7 @@ public function validateValue($value)

$errors = [];
if (empty($value) && $value !== '0') {
$label = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $label);
}
if (count($errors) == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public function createMetadataAttribute($attribute)
}
}
$validationRules = [];
foreach ($attribute->getValidateRules() as $name => $value) {
foreach ((array)$attribute->getValidateRules() as $name => $value) {
$validationRule = $this->validationRuleFactory->create()
->setName($name)
->setValue($value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected function setUp()
public function testValidateValue($value, $expected, $countryId, $isOptional)
{
$storeLabel = 'Zip/Postal Code';
$this->attributeMock->expects($this->once())
$this->attributeMock->expects($this->any())
->method('getStoreLabel')
->willReturn($storeLabel);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,9 @@ function ($value) {
$this->product->expects($this->any())->method('setLinksExist')->with($this->equalTo(false));
$this->product->expects($this->any())->method('canAffectOptions')->with($this->equalTo(true));

$eavConfigMock = $this->getMock(\Magento\Eav\Model\Config::class, ['getEntityAttributeCodes'], [], '', false);
$eavConfigMock = $this->getMock(\Magento\Eav\Model\Config::class, ['getEntityAttributes'], [], '', false);
$eavConfigMock->expects($this->any())
->method('getEntityAttributeCodes')
->method('getEntityAttributes')
->with($this->equalTo($entityTypeMock), $this->equalTo($this->product))
->will($this->returnValue([]));

Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/Eav/Model/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ public function getValidateRules()
if (is_array($rules)) {
return $rules;
} elseif (!empty($rules)) {
return $this->getSerializer()->unserialize($rules);
return (array)$this->getSerializer()->unserialize($rules);
}
return [];
}
Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/Eav/Model/Attribute/Data/AbstractData.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,10 @@ protected function _validateInputRule($value)
return true;
}

$label = $this->getAttribute()->getStoreLabel();
$validateRules = $this->getAttribute()->getValidateRules();

if (!empty($validateRules['input_validation'])) {
$label = $this->getAttribute()->getStoreLabel();
switch ($validateRules['input_validation']) {
case 'alphanumeric':
$validator = new \Zend_Validate_Alnum(true);
Expand Down
5 changes: 4 additions & 1 deletion app/code/Magento/Eav/Model/Attribute/Data/Date.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@ public function validateValue($value)
{
$errors = [];
$attribute = $this->getAttribute();
$label = $attribute->getStoreLabel();

if ($value === false) {
// try to load original value and validate it
$value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode());
}

if ($attribute->getIsRequired() && empty($value)) {
$label = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $label);
}

Expand All @@ -68,19 +68,22 @@ public function validateValue($value)
) > $validateRules['date_range_max']
) {
if (!empty($validateRules['date_range_min']) && !empty($validateRules['date_range_max'])) {
$label = __($attribute->getStoreLabel());
$errors[] = __(
'Please enter a valid date between %1 and %2 at %3.',
date('d/m/Y', $validateRules['date_range_min']),
date('d/m/Y', $validateRules['date_range_max']),
$label
);
} elseif (!empty($validateRules['date_range_min'])) {
$label = __($attribute->getStoreLabel());
$errors[] = __(
'Please enter a valid date equal to or greater than %1 at %2.',
date('d/m/Y', $validateRules['date_range_min']),
$label
);
} elseif (!empty($validateRules['date_range_max'])) {
$label = __($attribute->getStoreLabel());
$errors[] = __(
'Please enter a valid date less than or equal to %1 at %2.',
date('d/m/Y', $validateRules['date_range_max']),
Expand Down
4 changes: 2 additions & 2 deletions app/code/Magento/Eav/Model/Attribute/Data/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ public function validateValue($value)

$errors = [];
$attribute = $this->getAttribute();
$label = $attribute->getStoreLabel();

$toDelete = !empty($value['delete']) ? true : false;
$toUpload = !empty($value['tmp_name']) ? true : false;
Expand All @@ -190,6 +189,7 @@ public function validateValue($value)
}

if ($attribute->getIsRequired() && !$toUpload) {
$label = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $label);
}

Expand Down Expand Up @@ -229,7 +229,7 @@ public function compactValue($value)
}
}

$destinationFolder = $attribute->getEntity()->getEntityTypeCode();
$destinationFolder = $attribute->getEntityType()->getEntityTypeCode();

// unlink entity file
if ($toDelete) {
Expand Down
4 changes: 3 additions & 1 deletion app/code/Magento/Eav/Model/Attribute/Data/Multiline.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ public function validateValue($value)
$errors = [];
$lines = $this->processValue($value);
$attribute = $this->getAttribute();
$attributeLabel = __($attribute->getStoreLabel());

if ($attribute->getIsRequired() && empty($lines)) {
$attributeLabel = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $attributeLabel);
}

$maxAllowedLineCount = $attribute->getMultilineCount();
if (count($lines) > $maxAllowedLineCount) {
$attributeLabel = __($attribute->getStoreLabel());
$errors[] = __('"%1" cannot contain more than %2 lines.', $attributeLabel, $maxAllowedLineCount);
}

Expand Down
2 changes: 1 addition & 1 deletion app/code/Magento/Eav/Model/Attribute/Data/Select.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ public function validateValue($value)
{
$errors = [];
$attribute = $this->getAttribute();
$label = __($attribute->getStoreLabel());

if ($value === false) {
// try to load original value and validate it
$value = $this->getEntity()->getData($attribute->getAttributeCode());
}

if ($attribute->getIsRequired() && empty($value) && $value != '0') {
$label = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $label);
}

Expand Down
4 changes: 3 additions & 1 deletion app/code/Magento/Eav/Model/Attribute/Data/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ public function validateValue($value)
{
$errors = [];
$attribute = $this->getAttribute();
$label = __($attribute->getStoreLabel());

if ($value === false) {
// try to load original value and validate it
$value = $this->getEntity()->getDataUsingMethod($attribute->getAttributeCode());
}

if ($attribute->getIsRequired() && empty($value) && $value !== '0') {
$label = __($attribute->getStoreLabel());
$errors[] = __('"%1" is a required value.', $label);
}

Expand All @@ -81,10 +81,12 @@ public function validateValue($value)

$validateRules = $attribute->getValidateRules();
if (!empty($validateRules['min_text_length']) && $length < $validateRules['min_text_length']) {
$label = __($attribute->getStoreLabel());
$v = $validateRules['min_text_length'];
$errors[] = __('"%1" length must be equal or greater than %2 characters.', $label, $v);
}
if (!empty($validateRules['max_text_length']) && $length > $validateRules['max_text_length']) {
$label = __($attribute->getStoreLabel());
$v = $validateRules['max_text_length'];
$errors[] = __('"%1" length must be equal or less than %2 characters.', $label, $v);
}
Expand Down
Loading

0 comments on commit 541e139

Please sign in to comment.