6
6
7
7
namespace Magento \Rule \Model \Condition \Sql ;
8
8
9
+ use Magento \Framework \App \ObjectManager ;
9
10
use Magento \Framework \DB \Select ;
11
+ use Magento \Framework \Exception \NoSuchEntityException ;
10
12
use Magento \Rule \Model \Condition \AbstractCondition ;
11
13
use Magento \Rule \Model \Condition \Combine ;
14
+ use Magento \Eav \Api \AttributeRepositoryInterface ;
15
+ use Magento \Catalog \Model \Product ;
16
+ use Magento \Eav \Model \Entity \Collection \AbstractCollection ;
12
17
13
18
/**
14
19
* Class SQL Builder
@@ -41,12 +46,22 @@ class Builder
41
46
*/
42
47
protected $ _expressionFactory ;
43
48
49
+ /**
50
+ * @var AttributeRepositoryInterface
51
+ */
52
+ private $ attributeRepository ;
53
+
44
54
/**
45
55
* @param ExpressionFactory $expressionFactory
56
+ * @param AttributeRepositoryInterface|null $attributeRepository
46
57
*/
47
- public function __construct (ExpressionFactory $ expressionFactory )
48
- {
58
+ public function __construct (
59
+ ExpressionFactory $ expressionFactory ,
60
+ AttributeRepositoryInterface $ attributeRepository = null
61
+ ) {
49
62
$ this ->_expressionFactory = $ expressionFactory ;
63
+ $ this ->attributeRepository = $ attributeRepository ?:
64
+ ObjectManager::getInstance ()->get (AttributeRepositoryInterface::class);
50
65
}
51
66
52
67
/**
@@ -88,12 +103,12 @@ protected function _getChildCombineTablesToJoin(Combine $combine, $tables = [])
88
103
/**
89
104
* Join tables from conditions combination to collection
90
105
*
91
- * @param \Magento\Eav\Model\Entity\Collection\ AbstractCollection $collection
106
+ * @param AbstractCollection $collection
92
107
* @param Combine $combine
93
108
* @return $this
94
109
*/
95
110
protected function _joinTablesToCollection (
96
- \ Magento \ Eav \ Model \ Entity \ Collection \ AbstractCollection $ collection ,
111
+ AbstractCollection $ collection ,
97
112
Combine $ combine
98
113
) {
99
114
foreach ($ this ->_getCombineTablesToJoin ($ combine ) as $ alias => $ joinTable ) {
@@ -112,10 +127,11 @@ protected function _joinTablesToCollection(
112
127
*
113
128
* @param AbstractCondition $condition
114
129
* @param string $value
130
+ * @param bool $isDefaultStoreUsed
115
131
* @return string
116
132
* @throws \Magento\Framework\Exception\LocalizedException
117
133
*/
118
- protected function _getMappedSqlCondition (AbstractCondition $ condition , $ value = '' )
134
+ protected function _getMappedSqlCondition (AbstractCondition $ condition , $ value = '' , $ isDefaultStoreUsed = true )
119
135
{
120
136
$ argument = $ condition ->getMappedSqlField ();
121
137
@@ -130,9 +146,16 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, $value =
130
146
throw new \Magento \Framework \Exception \LocalizedException (__ ('Unknown condition operator ' ));
131
147
}
132
148
149
+ $ defaultValue = 0 ;
150
+ // Check if attribute has a table with default value and add it to the query
151
+ if ($ this ->canAttributeHaveDefaultValue ($ condition ->getAttribute (), $ isDefaultStoreUsed )) {
152
+ $ defaultField = 'at_ ' . $ condition ->getAttribute () . '_default.value ' ;
153
+ $ defaultValue = $ this ->_connection ->quoteIdentifier ($ defaultField );
154
+ }
155
+
133
156
$ sql = str_replace (
134
157
':field ' ,
135
- $ this ->_connection ->getIfNullSql ($ this ->_connection ->quoteIdentifier ($ argument ), 0 ),
158
+ $ this ->_connection ->getIfNullSql ($ this ->_connection ->quoteIdentifier ($ argument ), $ defaultValue ),
136
159
$ this ->_conditionOperatorMap [$ conditionOperator ]
137
160
);
138
161
@@ -144,10 +167,11 @@ protected function _getMappedSqlCondition(AbstractCondition $condition, $value =
144
167
/**
145
168
* @param Combine $combine
146
169
* @param string $value
170
+ * @param bool $isDefaultStoreUsed
147
171
* @return string
148
172
* @SuppressWarnings(PHPMD.NPathComplexity)
149
173
*/
150
- protected function _getMappedSqlCombination (Combine $ combine , $ value = '' )
174
+ protected function _getMappedSqlCombination (Combine $ combine , $ value = '' , $ isDefaultStoreUsed = true )
151
175
{
152
176
$ out = (!empty ($ value ) ? $ value : '' );
153
177
$ value = ($ combine ->getValue () ? '' : ' NOT ' );
@@ -158,9 +182,9 @@ protected function _getMappedSqlCombination(Combine $combine, $value = '')
158
182
$ con = ($ getAggregator == 'any ' ? Select::SQL_OR : Select::SQL_AND );
159
183
$ con = (isset ($ conditions [$ key +1 ]) ? $ con : '' );
160
184
if ($ condition instanceof Combine) {
161
- $ out .= $ this ->_getMappedSqlCombination ($ condition , $ value );
185
+ $ out .= $ this ->_getMappedSqlCombination ($ condition , $ value, $ isDefaultStoreUsed );
162
186
} else {
163
- $ out .= $ this ->_getMappedSqlCondition ($ condition , $ value );
187
+ $ out .= $ this ->_getMappedSqlCondition ($ condition , $ value, $ isDefaultStoreUsed );
164
188
}
165
189
$ out .= $ out ? (' ' . $ con ) : '' ;
166
190
}
@@ -170,21 +194,55 @@ protected function _getMappedSqlCombination(Combine $combine, $value = '')
170
194
/**
171
195
* Attach conditions filter to collection
172
196
*
173
- * @param \Magento\Eav\Model\Entity\Collection\ AbstractCollection $collection
197
+ * @param AbstractCollection $collection
174
198
* @param Combine $combine
175
- *
176
199
* @return void
177
200
*/
178
201
public function attachConditionToCollection (
179
- \ Magento \ Eav \ Model \ Entity \ Collection \ AbstractCollection $ collection ,
202
+ AbstractCollection $ collection ,
180
203
Combine $ combine
181
204
) {
182
205
$ this ->_connection = $ collection ->getResource ()->getConnection ();
183
206
$ this ->_joinTablesToCollection ($ collection , $ combine );
184
- $ whereExpression = (string )$ this ->_getMappedSqlCombination ($ combine );
207
+ $ isDefaultStoreUsed = $ this ->checkIsDefaultStoreUsed ($ collection );
208
+ $ whereExpression = (string )$ this ->_getMappedSqlCombination ($ combine , '' , $ isDefaultStoreUsed );
185
209
if (!empty ($ whereExpression )) {
186
210
// Select ::where method adds braces even on empty expression
187
211
$ collection ->getSelect ()->where ($ whereExpression );
188
212
}
189
213
}
214
+
215
+ /**
216
+ * Check is default store used
217
+ *
218
+ * @param AbstractCollection $collection
219
+ * @return bool
220
+ */
221
+ private function checkIsDefaultStoreUsed (AbstractCollection $ collection ): bool
222
+ {
223
+ return (int )$ collection ->getStoreId () === (int )$ collection ->getDefaultStoreId ();
224
+ }
225
+
226
+ /**
227
+ * Check if attribute can have default value
228
+ *
229
+ * @param string $attributeCode
230
+ * @param bool $isDefaultStoreUsed
231
+ * @return bool
232
+ */
233
+ private function canAttributeHaveDefaultValue (string $ attributeCode , bool $ isDefaultStoreUsed ): bool
234
+ {
235
+ if ($ isDefaultStoreUsed ) {
236
+ return false ;
237
+ }
238
+
239
+ try {
240
+ $ attribute = $ this ->attributeRepository ->get (Product::ENTITY , $ attributeCode );
241
+ } catch (NoSuchEntityException $ e ) {
242
+ // It's not exceptional case as we want to check if we have such attribute or not
243
+ return false ;
244
+ }
245
+
246
+ return !$ attribute ->isScopeGlobal ();
247
+ }
190
248
}
0 commit comments