From 421ea4f7155dfa02ca55ed482ca577379fd7c8f2 Mon Sep 17 00:00:00 2001 From: Fabrice Creuzot Date: Sun, 15 Jan 2023 11:49:45 +0100 Subject: [PATCH 1/5] Fix getAttributeRawValue when there are no default value --- .../Mage/Catalog/Model/Resource/Abstract.php | 54 ++++++++++++------- 1 file changed, 35 insertions(+), 19 deletions(-) diff --git a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php index bbc8e9c4e34..ef78955f96a 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php @@ -632,6 +632,7 @@ public function getAttributeRawValue($entityId, $attribute, $store) * Collecting typed attributes, performing separate SQL query for each attribute type table */ if ($typedAttributes) { + if ($store instanceof Mage_Core_Model_Store) { $store = $store->getId(); } @@ -639,45 +640,60 @@ public function getAttributeRawValue($entityId, $attribute, $store) $store = (int)$store; foreach ($typedAttributes as $table => $_attributes) { - $select = $adapter->select() - ->from(['default_value' => $table], ['attribute_id']) - ->where('default_value.attribute_id IN (?)', array_keys($_attributes)) - ->where('default_value.entity_type_id = :entity_type_id') - ->where('default_value.entity_id = :entity_id') - ->where('default_value.store_id = ?', 0); - $bind = [ - 'entity_type_id' => $this->getTypeId(), - 'entity_id' => $entityId, + + $defaultJoinCondition = [ + $adapter->quoteInto('default_value.attribute_id IN (?)', array_keys($_attributes)), + 'default_value.entity_type_id = :entity_type_id_default', + 'default_value.entity_id = e.entity_id', + 'default_value.store_id = 0', ]; + $select = $adapter->select() + ->from(['e' => $this->getTable($this->getEntityTable())], []) + ->joinLeft( + ['default_value' => $table], + implode(' AND ', $defaultJoinCondition), + [] + )->where('e.entity_id = :entity_id'); + + $bind = ['entity_id' => $entityId, 'entity_type_id_default' => $this->getTypeId()]; if ($getPerStore && $store != $this->getDefaultStoreId()) { + $bind['entity_type_id_store'] = $this->getTypeId(); + $bind['store_id'] = $store; $valueExpr = $adapter->getCheckSql( 'store_value.value IS NULL', 'default_value.value', 'store_value.value' ); + $attributeIdExpr = $adapter->getCheckSql( + 'store_value.attribute_id IS NULL', + 'default_value.attribute_id', + 'store_value.attribute_id' + ); $joinCondition = [ - 'store_value.attribute_id = default_value.attribute_id', - 'store_value.entity_type_id = :entity_type_id', - 'store_value.entity_id = :entity_id', + $adapter->quoteInto('store_value.attribute_id IN (?)', array_keys($_attributes)), + 'store_value.entity_type_id = :entity_type_id_store', + 'store_value.entity_id = e.entity_id', 'store_value.store_id = :store_id', ]; - $select->joinLeft( ['store_value' => $table], implode(' AND ', $joinCondition), - ['attr_value' => $valueExpr] + ['attribute_id' => $attributeIdExpr, 'attr_value' => $valueExpr] ); - - $bind['store_id'] = $store; } else { - $select->columns(['attr_value' => 'value'], 'default_value'); + $select->columns( + ['attribute_id' => 'attribute_id', 'attr_value' => 'value'], + 'default_value' + ); } $result = $adapter->fetchPairs($select, $bind); foreach ($result as $attrId => $value) { - $attrCode = $typedAttributes[$table][$attrId]; - $attributesData[$attrCode] = $value; + if (!empty($attrId)) { + $attrCode = $typedAttributes[$table][$attrId]; + $attributesData[$attrCode] = $value; + } } } } From e70e463087807831ba8caf60b33f8522dc3f3f1c Mon Sep 17 00:00:00 2001 From: Fabrice Creuzot Date: Fri, 3 Mar 2023 22:29:49 +0100 Subject: [PATCH 2/5] Fix for PHP-CS --- app/code/core/Mage/Catalog/Model/Resource/Abstract.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php index ef78955f96a..35c75dfced8 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php @@ -632,7 +632,6 @@ public function getAttributeRawValue($entityId, $attribute, $store) * Collecting typed attributes, performing separate SQL query for each attribute type table */ if ($typedAttributes) { - if ($store instanceof Mage_Core_Model_Store) { $store = $store->getId(); } @@ -640,7 +639,6 @@ public function getAttributeRawValue($entityId, $attribute, $store) $store = (int)$store; foreach ($typedAttributes as $table => $_attributes) { - $defaultJoinCondition = [ $adapter->quoteInto('default_value.attribute_id IN (?)', array_keys($_attributes)), 'default_value.entity_type_id = :entity_type_id_default', From 35cefd51c9ae749a9ed4c766b3fd1f7fdb60f937 Mon Sep 17 00:00:00 2001 From: Fabrice Creuzot Date: Tue, 30 May 2023 20:12:39 +0200 Subject: [PATCH 3/5] Fix getAttributeRawValue when there are no default value --- .../Mage/Catalog/Model/Resource/Abstract.php | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php index 35c75dfced8..f9c95546297 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Abstract.php @@ -580,6 +580,7 @@ public function getAttributeRawValue($entityId, $attribute, $store) } $returnArray = false; + $entityId = (int)$entityId; if (!is_array($attribute)) { $attribute = [$attribute]; @@ -587,12 +588,12 @@ public function getAttributeRawValue($entityId, $attribute, $store) $returnArray = true; } - $attributesData = []; - $staticAttributes = []; - $typedAttributes = []; - $staticTable = null; - $adapter = $this->_getReadAdapter(); - $getPerStore = false; + $attributesData = []; + $staticAttributes = []; + $typedAttributes = []; + $staticTable = null; + $adapter = $this->_getReadAdapter(); + $getPerStore = false; foreach ($attribute as $_attribute) { /** @var Mage_Catalog_Model_Entity_Attribute $attribute */ @@ -638,28 +639,36 @@ public function getAttributeRawValue($entityId, $attribute, $store) $store = (int)$store; - foreach ($typedAttributes as $table => $_attributes) { - $defaultJoinCondition = [ - $adapter->quoteInto('default_value.attribute_id IN (?)', array_keys($_attributes)), - 'default_value.entity_type_id = :entity_type_id_default', - 'default_value.entity_id = e.entity_id', - 'default_value.store_id = 0', - ]; - $select = $adapter->select() - ->from(['e' => $this->getTable($this->getEntityTable())], []) - ->joinLeft( + foreach ($typedAttributes as $table => $attributes) { + // see also Mage_Catalog_Model_Resource_Collection_Abstract::_getLoadAttributesSelect() + if ($getPerStore && $store != $this->getDefaultStoreId()) { + $select = $adapter->select() + ->from(['e' => $this->getEntityTable()], []) + ->where('e.entity_id = ?', $entityId); + // attr join + $select->joinInner( + ['attr' => $table], + implode(' AND ', [ + 'attr.entity_id = e.entity_id', + $adapter->quoteInto('attr.attribute_id IN (?)', array_keys($attributes)), + 'attr.store_id IN (' . $this->getDefaultStoreId() . ', ' . $store . ')', + 'attr.entity_type_id = ' . $this->getTypeId(), + ]), + [] + ); + // default_value join + $select->joinLeft( ['default_value' => $table], - implode(' AND ', $defaultJoinCondition), + implode(' AND ', [ + 'default_value.entity_id = e.entity_id', + 'default_value.attribute_id = attr.attribute_id', + 'default_value.store_id = ' . $this->getDefaultStoreId(), + ]), [] - )->where('e.entity_id = :entity_id'); - - $bind = ['entity_id' => $entityId, 'entity_type_id_default' => $this->getTypeId()]; - - if ($getPerStore && $store != $this->getDefaultStoreId()) { - $bind['entity_type_id_store'] = $this->getTypeId(); - $bind['store_id'] = $store; + ); + // store_value join $valueExpr = $adapter->getCheckSql( - 'store_value.value IS NULL', + 'store_value.attribute_id IS NULL', 'default_value.value', 'store_value.value' ); @@ -668,25 +677,26 @@ public function getAttributeRawValue($entityId, $attribute, $store) 'default_value.attribute_id', 'store_value.attribute_id' ); - $joinCondition = [ - $adapter->quoteInto('store_value.attribute_id IN (?)', array_keys($_attributes)), - 'store_value.entity_type_id = :entity_type_id_store', - 'store_value.entity_id = e.entity_id', - 'store_value.store_id = :store_id', - ]; $select->joinLeft( ['store_value' => $table], - implode(' AND ', $joinCondition), + implode(' AND ', [ + 'store_value.entity_id = e.entity_id', + 'store_value.attribute_id = attr.attribute_id', + 'store_value.store_id = ' . $store, + ]), ['attribute_id' => $attributeIdExpr, 'attr_value' => $valueExpr] ); + $select->group('attr.attribute_id'); } else { - $select->columns( - ['attribute_id' => 'attribute_id', 'attr_value' => 'value'], - 'default_value' - ); + $select = $adapter->select() + ->from(['default_value' => $table], ['attribute_id', 'attr_value' => 'value']) + ->where('default_value.entity_id = ?', $entityId) + ->where('default_value.attribute_id IN (?)', array_keys($attributes)) + ->where('default_value.store_id = ?', $this->getDefaultStoreId()) + ->where('default_value.entity_type_id = ?', $this->getTypeId()); } - $result = $adapter->fetchPairs($select, $bind); + $result = $adapter->fetchPairs($select); foreach ($result as $attrId => $value) { if (!empty($attrId)) { $attrCode = $typedAttributes[$table][$attrId]; From 42a5682a89e24a7ab917bb527f817cd8d3ef1d46 Mon Sep 17 00:00:00 2001 From: Fabrice Creuzot Date: Tue, 30 May 2023 20:12:55 +0200 Subject: [PATCH 4/5] Fix comment --- .../Eav/Model/Entity/Collection/Abstract.php | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php b/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php index a0eb7ec0fdd..cdc5e7fbcb4 100644 --- a/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php +++ b/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php @@ -26,14 +26,14 @@ abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Col * * @var array */ - protected $_itemsById = []; + protected $_itemsById = []; /** * Entity static fields * * @var array */ - protected $_staticFields = []; + protected $_staticFields = []; /** * Entity object to define collection's attributes @@ -47,42 +47,42 @@ abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Col * * @var array */ - protected $_selectEntityTypes = []; + protected $_selectEntityTypes = []; /** * Attributes to be fetched for objects in collection * * @var array */ - protected $_selectAttributes = []; + protected $_selectAttributes = []; /** * Attributes to be filtered order sorted by * * @var array */ - protected $_filterAttributes = []; + protected $_filterAttributes = []; /** * Joined entities * * @var array */ - protected $_joinEntities = []; + protected $_joinEntities = []; /** * Joined attributes * * @var array */ - protected $_joinAttributes = []; + protected $_joinAttributes = []; /** * Joined fields data * * @var array */ - protected $_joinFields = []; + protected $_joinFields = []; /** * Use analytic function flag @@ -90,7 +90,7 @@ abstract class Mage_Eav_Model_Entity_Collection_Abstract extends Varien_Data_Col * * @var bool */ - protected $_useAnalyticFunction = false; + protected $_useAnalyticFunction = false; /** * Cast map for attribute order @@ -1181,7 +1181,7 @@ protected function _addLoadAttributesSelectValues($select, $table, $type) } /** - * Initialize entity ubject property value + * Initialize entity object property value * * $valueInfo is _getLoadAttributesSelect fetch result row * From b4cb7a40394faafc3e59541f94f6b9406acfd23b Mon Sep 17 00:00:00 2001 From: Fabrice Creuzot Date: Tue, 30 May 2023 20:13:11 +0200 Subject: [PATCH 5/5] Fix getLoadAttributesSelect when there are no default value --- .../Model/Resource/Collection/Abstract.php | 60 +++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php b/app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php index c29ee850e51..b4de5abba6e 100644 --- a/app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php +++ b/app/code/core/Mage/Catalog/Model/Resource/Collection/Abstract.php @@ -95,24 +95,50 @@ protected function _getLoadAttributesSelect($table, $attributeIds = []) $storeId = $this->getStoreId(); if ($storeId) { - $adapter = $this->getConnection(); - $entityIdField = $this->getEntity()->getEntityIdField(); - $joinCondition = [ - 't_s.attribute_id = t_d.attribute_id', - 't_s.entity_id = t_d.entity_id', - $adapter->quoteInto('t_s.store_id = ?', $storeId) - ]; + $adapter = $this->getConnection(); + $entity = $this->getEntity(); + + // see also Mage_Catalog_Model_Resource_Abstract::getAttributeRawValue() $select = $adapter->select() - ->from(['t_d' => $table], [$entityIdField, 'attribute_id']) - ->joinLeft( - ['t_s' => $table], - implode(' AND ', $joinCondition), - [] - ) - ->where('t_d.entity_type_id = ?', $this->getEntity()->getTypeId()) - ->where("t_d.{$entityIdField} IN (?)", array_keys($this->_itemsById)) - ->where('t_d.attribute_id IN (?)', $attributeIds) - ->where('t_d.store_id = ?', 0); + ->from(['e' => $entity->getEntityTable()], []) + ->where('e.entity_id IN (?)', array_keys($this->_itemsById)); + // attr join + $select->joinInner( + ['attr' => $table], + implode(' AND ', [ + 'attr.entity_id = e.entity_id', + $adapter->quoteInto('attr.attribute_id IN (?)', $attributeIds), + 'attr.store_id IN (' . $this->getDefaultStoreId() . ', ' . $storeId . ')', + 'attr.entity_type_id = ' . $entity->getTypeId(), + ]), + [] + ); + // t_d join + $select->joinLeft( + ['t_d' => $table], + implode(' AND ', [ + 't_d.entity_id = e.entity_id', + 't_d.attribute_id = attr.attribute_id', + 't_d.store_id = ' . $this->getDefaultStoreId(), + ]), + [] + ); + // t_s join + $attributeIdExpr = $adapter->getCheckSql( + 't_s.attribute_id IS NULL', + 't_d.attribute_id', + 't_s.attribute_id' + ); + $select->joinLeft( + ['t_s' => $table], + implode(' AND ', [ + 't_s.entity_id = e.entity_id', + 't_s.attribute_id = attr.attribute_id', + 't_s.store_id = ' . $storeId, + ]), + ['e.entity_id', 'attribute_id' => $attributeIdExpr] + ); + $select->group('e.entity_id')->group('attr.attribute_id'); } else { $select = parent::_getLoadAttributesSelect($table) ->where('store_id = ?', $this->getDefaultStoreId());