5
5
*/
6
6
namespace Magento \Eav \Model \ResourceModel ;
7
7
8
+ use Magento \Eav \Model \Config ;
8
9
use Magento \Framework \DataObject ;
10
+ use Magento \Framework \DB \Select ;
11
+ use Magento \Framework \DB \Sql \UnionExpression ;
9
12
use Magento \Framework \EntityManager \MetadataPool ;
10
13
use Magento \Framework \EntityManager \Operation \AttributeInterface ;
11
14
use Magento \Framework \Model \Entity \ScopeInterface ;
12
15
use Magento \Framework \Model \Entity \ScopeResolver ;
13
16
use Psr \Log \LoggerInterface ;
14
17
18
+ /**
19
+ * EAV read handler
20
+ */
15
21
class ReadHandler implements AttributeInterface
16
22
{
17
23
/**
@@ -30,23 +36,21 @@ class ReadHandler implements AttributeInterface
30
36
private $ logger ;
31
37
32
38
/**
33
- * @var \Magento\Eav\Model\ Config
39
+ * @var Config
34
40
*/
35
41
private $ config ;
36
42
37
43
/**
38
- * ReadHandler constructor.
39
- *
40
44
* @param MetadataPool $metadataPool
41
45
* @param ScopeResolver $scopeResolver
42
46
* @param LoggerInterface $logger
43
- * @param \Magento\Eav\Model\ Config $config
47
+ * @param Config $config
44
48
*/
45
49
public function __construct (
46
50
MetadataPool $ metadataPool ,
47
51
ScopeResolver $ scopeResolver ,
48
52
LoggerInterface $ logger ,
49
- \ Magento \ Eav \ Model \ Config $ config
53
+ Config $ config
50
54
) {
51
55
$ this ->metadataPool = $ metadataPool ;
52
56
$ this ->scopeResolver = $ scopeResolver ;
@@ -86,6 +90,8 @@ private function getEntityAttributes(string $entityType, DataObject $entity): ar
86
90
}
87
91
88
92
/**
93
+ * Get context variables
94
+ *
89
95
* @param ScopeInterface $scope
90
96
* @return array
91
97
*/
@@ -99,6 +105,8 @@ protected function getContextVariables(ScopeInterface $scope)
99
105
}
100
106
101
107
/**
108
+ * Execute read handler
109
+ *
102
110
* @param string $entityType
103
111
* @param array $entityData
104
112
* @param array $arguments
@@ -129,38 +137,73 @@ public function execute($entityType, $entityData, $arguments = [])
129
137
}
130
138
}
131
139
if (count ($ attributeTables )) {
132
- $ attributeTables = array_keys ( $ attributeTables ) ;
133
- foreach ($ attributeTables as $ attributeTable ) {
140
+ $ identifiers = null ;
141
+ foreach ($ attributeTables as $ attributeTable => $ attributeIds ) {
134
142
$ select = $ connection ->select ()
135
143
->from (
136
144
['t ' => $ attributeTable ],
137
145
['value ' => 't.value ' , 'attribute_id ' => 't.attribute_id ' ]
138
146
)
139
- ->where ($ metadata ->getLinkField () . ' = ? ' , $ entityData [$ metadata ->getLinkField ()]);
147
+ ->where ($ metadata ->getLinkField () . ' = ? ' , $ entityData [$ metadata ->getLinkField ()])
148
+ ->where ('attribute_id IN (?) ' , $ attributeIds );
149
+ $ attributeIdentifiers = [];
140
150
foreach ($ context as $ scope ) {
141
151
//TODO: if (in table exists context field)
142
152
$ select ->where (
143
- $ metadata -> getEntityConnection () ->quoteIdentifier ($ scope ->getIdentifier ()) . ' IN (?) ' ,
153
+ $ connection ->quoteIdentifier ($ scope ->getIdentifier ()) . ' IN (?) ' ,
144
154
$ this ->getContextVariables ($ scope )
145
- )->order ('t. ' . $ scope ->getIdentifier () . ' DESC ' );
155
+ );
156
+ $ attributeIdentifiers [] = $ scope ->getIdentifier ();
146
157
}
158
+ $ attributeIdentifiers = array_unique ($ attributeIdentifiers );
159
+ $ identifiers = array_intersect ($ identifiers ?? $ attributeIdentifiers , $ attributeIdentifiers );
147
160
$ selects [] = $ select ;
148
161
}
149
- $ unionSelect = new \Magento \Framework \DB \Sql \UnionExpression (
150
- $ selects ,
151
- \Magento \Framework \DB \Select::SQL_UNION_ALL
152
- );
153
- foreach ($ connection ->fetchAll ($ unionSelect ) as $ attributeValue ) {
162
+ $ this ->applyIdentifierForSelects ($ selects , $ identifiers );
163
+ $ unionSelect = new UnionExpression ($ selects , Select::SQL_UNION_ALL , '( %s ) ' );
164
+ $ orderedUnionSelect = $ connection ->select ();
165
+ $ orderedUnionSelect ->from (['u ' => $ unionSelect ]);
166
+ $ this ->applyIdentifierForUnion ($ orderedUnionSelect , $ identifiers );
167
+ $ attributes = $ connection ->fetchAll ($ orderedUnionSelect );
168
+ foreach ($ attributes as $ attributeValue ) {
154
169
if (isset ($ attributesMap [$ attributeValue ['attribute_id ' ]])) {
155
170
$ entityData [$ attributesMap [$ attributeValue ['attribute_id ' ]]] = $ attributeValue ['value ' ];
156
171
} else {
157
172
$ this ->logger ->warning (
158
- "Attempt to load value of nonexistent EAV attribute ' {$ attributeValue ['attribute_id ' ]}'
173
+ "Attempt to load value of nonexistent EAV attribute ' {$ attributeValue ['attribute_id ' ]}'
159
174
for entity type ' $ entityType'. "
160
175
);
161
176
}
162
177
}
163
178
}
164
179
return $ entityData ;
165
180
}
181
+
182
+ /**
183
+ * Apply identifiers column on select array
184
+ *
185
+ * @param Select[] $selects
186
+ * @param array $identifiers
187
+ */
188
+ private function applyIdentifierForSelects (array $ selects , array $ identifiers )
189
+ {
190
+ foreach ($ selects as $ select ) {
191
+ foreach ($ identifiers as $ identifier ) {
192
+ $ select ->columns ($ identifier , 't ' );
193
+ }
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Apply identifiers order on union select
199
+ *
200
+ * @param Select $unionSelect
201
+ * @param array $identifiers
202
+ */
203
+ private function applyIdentifierForUnion (Select $ unionSelect , array $ identifiers )
204
+ {
205
+ foreach ($ identifiers as $ identifier ) {
206
+ $ unionSelect ->order ($ identifier );
207
+ }
208
+ }
166
209
}
0 commit comments