66
77namespace Magento \Catalog \Model \Attribute ;
88
9+ use Magento \Catalog \Model \AbstractModel ;
10+ use Magento \Framework \DataObject ;
911use Magento \Framework \EntityManager \MetadataPool ;
1012use Magento \Eav \Api \AttributeRepositoryInterface as AttributeRepository ;
1113use Magento \Framework \Api \SearchCriteriaBuilder ;
1517use Magento \Framework \App \ResourceConnection ;
1618
1719/**
18- * Class ScopeOverriddenValue
1920 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2021 */
2122class ScopeOverriddenValue
@@ -76,7 +77,7 @@ public function __construct(
7677 * Whether attribute value is overridden in specific store
7778 *
7879 * @param string $entityType
79- * @param \Magento\Catalog\Model\ AbstractModel $entity
80+ * @param AbstractModel $entity
8081 * @param string $attributeCode
8182 * @param int|string $storeId
8283 * @return bool
@@ -86,39 +87,41 @@ public function containsValue($entityType, $entity, $attributeCode, $storeId)
8687 if ((int )$ storeId === Store::DEFAULT_STORE_ID ) {
8788 return false ;
8889 }
89- if (!isset ($ this ->attributesValues [$ storeId ])) {
90+ $ values = $ this ->getAttributesValues ($ entityType , $ entity );
91+
92+ if (!isset ($ values [$ storeId ])) {
9093 $ this ->initAttributeValues ($ entityType , $ entity , (int )$ storeId );
94+ $ values = $ this ->getAttributesValues ($ entityType , $ entity );
9195 }
9296
93- return isset ($ this ->attributesValues [$ storeId ])
94- && array_key_exists ($ attributeCode , $ this ->attributesValues [$ storeId ]);
97+ return isset ($ values [$ storeId ]) && array_key_exists ($ attributeCode , $ values [$ storeId ]);
9598 }
9699
97100 /**
98101 * Get attribute default values
99102 *
100103 * @param string $entityType
101- * @param \Magento\Catalog\Model\ AbstractModel $entity
104+ * @param AbstractModel $entity
102105 * @return array
103106 *
104107 * @deprecated 101.0.0
105108 */
106109 public function getDefaultValues ($ entityType , $ entity )
107110 {
108- if ($ this ->attributesValues === null ) {
111+ $ values = $ this ->getAttributesValues ($ entityType , $ entity );
112+ if (!isset ($ values [Store::DEFAULT_STORE_ID ])) {
109113 $ this ->initAttributeValues ($ entityType , $ entity , (int )$ entity ->getStoreId ());
114+ $ values = $ this ->getAttributesValues ($ entityType , $ entity );
110115 }
111116
112- return isset ($ this ->attributesValues [Store::DEFAULT_STORE_ID ])
113- ? $ this ->attributesValues [Store::DEFAULT_STORE_ID ]
114- : [];
117+ return $ values [Store::DEFAULT_STORE_ID ] ?? [];
115118 }
116119
117120 /**
118121 * Init attribute values.
119122 *
120123 * @param string $entityType
121- * @param \Magento\Catalog\Model\ AbstractModel $entity
124+ * @param AbstractModel $entity
122125 * @param int $storeId
123126 * @throws \Magento\Framework\Exception\LocalizedException
124127 * @return void
@@ -129,6 +132,7 @@ private function initAttributeValues($entityType, $entity, $storeId)
129132 /** @var \Magento\Eav\Model\Entity\Attribute\AbstractAttribute $attribute */
130133 $ attributeTables = [];
131134 if ($ metadata ->getEavEntityType ()) {
135+ $ entityId = $ entity ->getData ($ metadata ->getLinkField ());
132136 foreach ($ this ->getAttributes ($ entityType ) as $ attribute ) {
133137 if (!$ attribute ->isStatic ()) {
134138 $ attributeTables [$ attribute ->getBackend ()->getTable ()][] = $ attribute ->getAttributeId ();
@@ -147,7 +151,7 @@ private function initAttributeValues($entityType, $entity, $storeId)
147151 'a.attribute_id = t.attribute_id ' ,
148152 ['attribute_code ' => 'a.attribute_code ' ]
149153 )
150- ->where ($ metadata ->getLinkField () . ' = ? ' , $ entity -> getData ( $ metadata -> getLinkField ()) )
154+ ->where ($ metadata ->getLinkField () . ' = ? ' , $ entityId )
151155 ->where ('t.attribute_id IN (?) ' , $ attributeCodes )
152156 ->where ('t.store_id IN (?) ' , $ storeIds );
153157 $ selects [] = $ select ;
@@ -158,9 +162,12 @@ private function initAttributeValues($entityType, $entity, $storeId)
158162 \Magento \Framework \DB \Select::SQL_UNION_ALL
159163 );
160164 $ attributes = $ metadata ->getEntityConnection ()->fetchAll ((string )$ unionSelect );
165+ $ values = array_fill_keys ($ storeIds , []);
161166 foreach ($ attributes as $ attribute ) {
162- $ this -> attributesValues [$ attribute ['store_id ' ]][$ attribute ['attribute_code ' ]] = $ attribute ['value ' ];
167+ $ values [$ attribute ['store_id ' ]][$ attribute ['attribute_code ' ]] = $ attribute ['value ' ];
163168 }
169+ $ values += $ this ->getAttributesValues ($ entityType , $ entity );
170+ $ this ->setAttributesValues ($ entityType , $ entity , $ values );
164171 }
165172 }
166173
@@ -187,4 +194,52 @@ private function getAttributes($entityType)
187194 );
188195 return $ searchResult ->getItems ();
189196 }
197+
198+ /**
199+ * Clear entity attributes values cache
200+ *
201+ * @param string $entityType
202+ * @param DataObject $entity
203+ * @return void
204+ * @throws \Exception
205+ */
206+ public function clearAttributesValues (string $ entityType , DataObject $ entity ): void
207+ {
208+ if (isset ($ this ->attributesValues [$ entityType ])) {
209+ $ metadata = $ this ->metadataPool ->getMetadata ($ entityType );
210+ $ entityId = $ entity ->getData ($ metadata ->getLinkField ());
211+ unset($ this ->attributesValues [$ entityType ][$ entityId ]);
212+ }
213+ }
214+
215+ /**
216+ * Get entity attributes values from cache
217+ *
218+ * @param string $entityType
219+ * @param DataObject $entity
220+ * @return array
221+ * @throws \Exception
222+ */
223+ private function getAttributesValues (string $ entityType , DataObject $ entity ): array
224+ {
225+ $ metadata = $ this ->metadataPool ->getMetadata ($ entityType );
226+ $ entityId = $ entity ->getData ($ metadata ->getLinkField ());
227+ return $ this ->attributesValues [$ entityType ][$ entityId ] ?? [];
228+ }
229+
230+ /**
231+ * Set entity attributes values into cache
232+ *
233+ * @param string $entityType
234+ * @param DataObject $entity
235+ * @param array $values
236+ * @return void
237+ * @throws \Exception
238+ */
239+ private function setAttributesValues (string $ entityType , DataObject $ entity , array $ values ): void
240+ {
241+ $ metadata = $ this ->metadataPool ->getMetadata ($ entityType );
242+ $ entityId = $ entity ->getData ($ metadata ->getLinkField ());
243+ $ this ->attributesValues [$ entityType ][$ entityId ] = $ values ;
244+ }
190245}
0 commit comments