1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Helper for module methods |
5
|
|
|
* |
6
|
|
|
* @author Alexey Krupskiy <[email protected]> |
7
|
|
|
* @link http://inji.ru/ |
8
|
|
|
* @copyright 2016 Alexey Krupskiy |
9
|
|
|
* @license https://github.com/injitools/cms-Inji/blob/master/LICENSE |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
namespace Ecommerce; |
13
|
|
|
|
14
|
|
|
class OptionsParser extends \Object { |
15
|
|
|
|
16
|
|
|
public static function parse($options = []) { |
17
|
|
|
$selectOptions = self::getDefault($options); |
18
|
|
|
|
19
|
|
|
//parse order options |
20
|
|
|
self::order($options, $selectOptions); |
21
|
|
|
|
22
|
|
|
//joined offers |
23
|
|
|
$selectOptions['join'][] = [Item\Offer::table(), Item::index() . ' = ' . Item\Offer::colPrefix() . Item::index(), 'inner']; |
24
|
|
|
|
25
|
|
|
//joined prices, check price configs |
26
|
|
|
$selectOptions['join'][] = [Item\Offer\Price::table(), |
27
|
|
|
Item\Offer::index() . ' = ' . Item\Offer\Price::colPrefix() . Item\Offer::index() . |
28
|
|
|
(empty(\App::$cur->Ecommerce->config['show_zero_price']) ? ' and ' . Item\Offer\Price::colPrefix() . 'price>0' : ''), |
29
|
|
|
empty(\App::$cur->Ecommerce->config['show_without_price']) ? 'inner' : 'left']; |
30
|
|
|
|
31
|
|
|
//join item types |
32
|
|
|
$selectOptions['join'][] = [ |
33
|
|
|
Item\Offer\Price\Type::table(), Item\Offer\Price::colPrefix() . Item\Offer\Price\Type::index() . ' = ' . Item\Offer\Price\Type::index() |
34
|
|
|
]; |
35
|
|
|
|
36
|
|
|
//add filter for item type user roles by current user role |
37
|
|
|
$selectOptions['where'][] = [ |
38
|
|
|
[Item\Offer\Price\Type::index(), null, 'is'], |
39
|
|
|
[ |
40
|
|
|
[Item\Offer\Price\Type::colPrefix() . 'roles', '', '=', 'OR'], |
41
|
|
|
[Item\Offer\Price\Type::colPrefix() . 'roles', '%|' . \Users\User::$cur->role_id . '|%', 'LIKE', 'OR'], |
42
|
|
|
], |
43
|
|
|
]; |
44
|
|
|
|
45
|
|
|
//add custom preset filters from config on where |
46
|
|
|
self::presetFilters($selectOptions); |
47
|
|
|
|
48
|
|
|
//parse filters |
49
|
|
|
self::filters($options, $selectOptions); |
50
|
|
|
|
51
|
|
|
//categories paths |
52
|
|
|
self::categories($options, $selectOptions); |
53
|
|
|
|
54
|
|
|
//search |
55
|
|
|
self::search($options, $selectOptions); |
56
|
|
|
|
57
|
|
|
self::warehouse($selectOptions); |
58
|
|
|
|
59
|
|
|
$selectOptions['group'] = Item::index(); |
60
|
|
|
|
61
|
|
|
return $selectOptions; |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
public static function getDefault(&$options) { |
65
|
|
|
$selectOptions = [ |
66
|
|
|
'where' => !empty($options['where']) ? $options['where'] : [], |
67
|
|
|
'distinct' => false, |
68
|
|
|
'join' => [], |
69
|
|
|
'order' => [], |
70
|
|
|
'start' => isset($options['start']) ? (int) $options['start'] : 0, |
71
|
|
|
'key' => isset($options['key']) ? $options['key'] : null, |
72
|
|
|
'limit' => !empty($options['count']) ? (int) $options['count'] : 0, |
73
|
|
|
]; |
74
|
|
|
|
75
|
|
|
//only not deleted items |
76
|
|
|
$selectOptions['where'][] = ['deleted', 0]; |
77
|
|
|
|
78
|
|
|
//check config of view items without images |
79
|
|
|
if (empty(\App::$cur->Ecommerce->config['view_empty_image'])) { |
80
|
|
|
$selectOptions['where'][] = ['image_file_id', 0, '!=']; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
return $selectOptions; |
84
|
|
|
} |
85
|
|
|
|
86
|
|
|
public static function order(&$options, &$selectOptions) { |
87
|
|
|
if (empty($options['sort']) || !is_array($options['sort'])) { |
88
|
|
|
return; |
89
|
|
|
} |
90
|
|
|
foreach ($options['sort'] as $col => $direction) { |
91
|
|
|
$direction = strtolower($direction) == 'desc' ? 'desc' : 'asc'; |
92
|
|
|
switch ($col) { |
93
|
|
|
case 'price': |
94
|
|
|
$selectOptions['order'][] = [Item\Offer\Price::colPrefix() . 'price', $direction]; |
95
|
|
|
break; |
96
|
|
|
case 'new': |
97
|
|
|
$selectOptions['order'][] = ['date_create', $direction]; |
98
|
|
|
break; |
99
|
|
|
case 'name': |
100
|
|
|
case 'sales': |
101
|
|
|
case 'weight': |
102
|
|
|
$selectOptions['order'][] = [$col, $direction]; |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
public static function presetFilters(&$selectOptions) { |
108
|
|
|
if (empty(\App::$cur->Ecommerce->config['view_filter'])) { |
109
|
|
|
return; |
110
|
|
|
} |
111
|
|
|
if (!empty(\App::$cur->Ecommerce->config['view_filter']['options'])) { |
112
|
|
|
foreach (\App::$cur->Ecommerce->config['view_filter']['options'] as $optionId => $optionValue) { |
113
|
|
|
$selectOptions['join'][] = [Item\Param::table(), Item::index() . ' = ' . 'option' . $optionId . '.' . Item\Param::colPrefix() . Item::index() . ' AND ' . |
114
|
|
|
'option' . $optionId . '.' . Item\Param::colPrefix() . Item\Option::index() . ' = "' . (int) $optionId . '" AND ' . |
115
|
|
|
'option' . $optionId . '.' . Item\Param::colPrefix() . 'value = "' . (int) $optionValue . '"', |
116
|
|
|
'inner', 'option' . $optionId]; |
117
|
|
|
} |
118
|
|
|
} |
119
|
|
|
} |
120
|
|
|
|
121
|
|
|
public static function filters(&$options, &$selectOptions) { |
122
|
|
|
if (empty($options['filters'])) { |
123
|
|
|
return; |
124
|
|
|
} |
125
|
|
|
foreach ($options['filters'] as $col => $filter) { |
126
|
|
|
switch ($col) { |
127
|
|
|
case 'price': |
128
|
|
|
$colName = Item\Offer\Price::colPrefix() . 'price'; |
129
|
|
View Code Duplication |
if (!empty($filter['min'])) { |
|
|
|
|
130
|
|
|
$selectOptions['where'][] = [$colName, (float) $filter['min'], '>=']; |
131
|
|
|
} |
132
|
|
View Code Duplication |
if (!empty($filter['max'])) { |
|
|
|
|
133
|
|
|
$selectOptions['where'][] = [$colName, (float) $filter['max'], '<=']; |
134
|
|
|
} |
135
|
|
|
break; |
136
|
|
|
case 'options': |
137
|
|
|
case 'offerOptions': |
138
|
|
|
if ($col == 'offerOptions') { |
139
|
|
|
$paramPrefix = Item\Offer\Param::colPrefix(); |
140
|
|
|
$itemIndex = Item\Offer::index(); |
141
|
|
|
$optionIndex = Item\Offer\Option::index(); |
142
|
|
|
$table = Item\Offer\Param::table(); |
143
|
|
|
} else { |
144
|
|
|
$paramPrefix = Item\Param::colPrefix(); |
145
|
|
|
$itemIndex = Item::index(); |
146
|
|
|
$optionIndex = Item\Option::index(); |
147
|
|
|
$table = Item\Param::table(); |
148
|
|
|
} |
149
|
|
|
foreach ($filter as $optionId => $optionValue) { |
150
|
|
|
$optionId = (int) $optionId; |
151
|
|
|
if (is_array($optionValue)) { |
152
|
|
|
$optionValueArr = []; |
153
|
|
|
foreach ($optionValue as $val) { |
154
|
|
|
$optionValueArr[] = \App::$cur->db->connection->pdo->quote($val); |
155
|
|
|
} |
156
|
|
|
$qstr = 'IN (' . implode(',', $optionValueArr) . ')'; |
157
|
|
|
} else { |
158
|
|
|
$qstr = '= ' . \App::$cur->db->connection->pdo->quote($optionValue); |
159
|
|
|
} |
160
|
|
|
$selectOptions['join'][] = [$table, $itemIndex . ' = ' . 'option' . $optionId . '.' . $paramPrefix . $itemIndex . ' AND ' . |
161
|
|
|
'option' . $optionId . '.' . $paramPrefix . $optionIndex . ' = "' . (int) $optionId . '" AND ' . |
162
|
|
|
'option' . $optionId . '.' . $paramPrefix . 'value ' . $qstr . '', |
163
|
|
|
'inner', 'option' . $optionId]; |
164
|
|
|
} |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
public static function categories(&$options, &$selectOptions) { |
170
|
|
|
if (empty($options['parent'])) { |
171
|
|
|
return; |
172
|
|
|
} |
173
|
|
|
if (strpos($options['parent'], ',') !== false) { |
174
|
|
|
$first = true; |
175
|
|
|
$where = []; |
176
|
|
|
foreach (explode(',', $options['parent']) as $categoryId) { |
177
|
|
|
if (!$categoryId) { |
178
|
|
|
continue; |
179
|
|
|
} |
180
|
|
|
$category = Category::get($categoryId); |
181
|
|
|
$where[] = ['tree_path', $category->tree_path . (int) $categoryId . '/%', 'LIKE', $first ? 'AND' : 'OR']; |
182
|
|
|
$first = false; |
183
|
|
|
} |
184
|
|
|
$selectOptions['where'][] = $where; |
185
|
|
|
} else { |
186
|
|
|
$category = Category::get($options['parent']); |
187
|
|
|
if ($category) { |
188
|
|
|
$selectOptions['where'][] = ['tree_path', $category->tree_path . (int) $options['parent'] . '/%', 'LIKE']; |
189
|
|
|
} |
190
|
|
|
} |
191
|
|
|
} |
192
|
|
|
|
193
|
|
|
public static function search(&$options, &$selectOptions) { |
194
|
|
|
if (empty($options['search'])) { |
195
|
|
|
return; |
196
|
|
|
} |
197
|
|
|
$searchStr = preg_replace('![^A-zА-я0-9 ]!iSu', ' ', $options['search']); |
198
|
|
|
$searchArr = []; |
199
|
|
|
foreach (explode(' ', $searchStr) as $part) { |
200
|
|
|
$part = trim($part); |
201
|
|
|
if ($part && strlen($part) > 2) { |
202
|
|
|
$searchArr[] = ['search_index', '%' . $part . '%', 'LIKE']; |
203
|
|
|
} |
204
|
|
|
} |
205
|
|
|
if (!empty($searchArr)) { |
206
|
|
|
$selectOptions['where'][] = $searchArr; |
207
|
|
|
} |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
public static function warehouse(&$selectOptions) { |
211
|
|
|
if (!empty(\App::$cur->Ecommerce->config['view_empty_warehouse'])) { |
212
|
|
|
return; |
213
|
|
|
} |
214
|
|
|
$warehouseIds = self::getWarehouses(); |
215
|
|
|
|
216
|
|
|
$selectOptions['where'][] = [ |
217
|
|
|
'( |
218
|
|
|
(SELECT COALESCE(sum(`' . Item\Offer\Warehouse::colPrefix() . 'count`),0) |
219
|
|
|
FROM ' . \App::$cur->db->table_prefix . Item\Offer\Warehouse::table() . ' iciw |
220
|
|
|
WHERE iciw.' . Item\Offer\Warehouse::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . ' |
221
|
|
|
' . ($warehouseIds ? ' AND iciw.' . Item\Offer\Warehouse::colPrefix() . Warehouse::index() . ' IN(' . implode(',', $warehouseIds) . ')' : '') . ' |
222
|
|
|
) |
223
|
|
|
- |
224
|
|
|
(SELECT COALESCE(sum(' . Warehouse\Block::colPrefix() . 'count) ,0) |
225
|
|
|
FROM ' . \App::$cur->db->table_prefix . Warehouse\Block::table() . ' iewb |
226
|
|
|
inner JOIN ' . \App::$cur->db->table_prefix . Cart::table() . ' icc ON icc.' . Cart::index() . ' = iewb.' . Warehouse\Block::colPrefix() . Cart::index() . ' AND ( |
227
|
|
|
(`' . Cart::colPrefix() . 'warehouse_block` = 1 and `' . Cart::colPrefix() . 'cart_status_id` in(2,3,6)) || |
228
|
|
|
(`' . Cart::colPrefix() . Cart\Status::index() . '` in(0,1) and `' . Cart::colPrefix() . 'date_last_activ` >=subdate(now(),INTERVAL 30 MINUTE)) |
229
|
|
|
) |
230
|
|
|
WHERE iewb.' . Warehouse\Block::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . ') |
231
|
|
|
)', |
232
|
|
|
0, |
233
|
|
|
'>' |
234
|
|
|
]; |
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
public static function getWarehouses() { |
238
|
|
|
if (!\App::$cur->geography || !\Geography\City::$cur) { |
239
|
|
|
return []; |
240
|
|
|
} |
241
|
|
|
$warehouseIds = []; |
242
|
|
|
$warehouses = \Geography\City\Data::get([['code', 'warehouses'], ['city_id', \Geography\City::$cur->id]]); |
243
|
|
|
if ($warehouses && $warehouses->data) { |
244
|
|
|
foreach (explode(',', $warehouses->data) as $id) { |
245
|
|
|
$warehouseIds[$id] = $id; |
246
|
|
|
} |
247
|
|
|
} |
248
|
|
|
return $warehouseIds; |
249
|
|
|
} |
250
|
|
|
} |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.