Passed
Push — master ( 918fe4...07100e )
by Alexey
09:39
created

OptionsParser::warehouse()   B

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 18
nc 3
nop 1
dl 0
loc 26
rs 8.8571
c 1
b 0
f 0
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 'isset':
100
$warehouseIds = self::getWarehouses();
101
                    $selectOptions['order'][] = [
102
                        '(
103
          (SELECT COALESCE(sum(`' . Item\Offer\Warehouse::colPrefix() . 'count`),0) 
104
            FROM ' . \App::$cur->db->table_prefix . Item\Offer\Warehouse::table() . ' iciw 
105
            WHERE iciw.' . Item\Offer\Warehouse::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . '
106
                ' . ($warehouseIds ? ' AND iciw.' . Item\Offer\Warehouse::colPrefix() . Warehouse::index() . ' IN(' . implode(',', $warehouseIds) . ')' : '') . '
107
            )
108
          -
109
          (SELECT COALESCE(sum(' . Warehouse\Block::colPrefix() . 'count) ,0)
110
            FROM ' . \App::$cur->db->table_prefix . Warehouse\Block::table() . ' iewb
111
            inner JOIN ' . \App::$cur->db->table_prefix . Cart::table() . ' icc ON icc.' . Cart::index() . ' = iewb.' . Warehouse\Block::colPrefix() . Cart::index() . ' AND (
112
                (`' . Cart::colPrefix() . 'warehouse_block` = 1 and `' . Cart::colPrefix() . 'cart_status_id` in(2,3,6)) ||
113
                (`' . Cart::colPrefix() . Cart\Status::index() . '` in(0,1) and `' . Cart::colPrefix() . 'date_last_activ` >=subdate(now(),INTERVAL 30 MINUTE))
114
            )
115
            WHERE iewb.' . Warehouse\Block::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . ')
116
          )', $direction
117
                    ];
118
                    break;
119
                case 'name':
120
                case 'sales':
121
                case 'weight':
122
                    $selectOptions['order'][] = [$col, $direction];
123
            }
124
        }
125
    }
126
127
    public static function presetFilters(&$selectOptions) {
128
        if (empty(\App::$cur->Ecommerce->config['view_filter'])) {
129
            return;
130
        }
131
        if (!empty(\App::$cur->Ecommerce->config['view_filter']['options'])) {
132
            foreach (\App::$cur->Ecommerce->config['view_filter']['options'] as $optionId => $optionValue) {
133
                $selectOptions['join'][] = [Item\Param::table(), Item::index() . ' = ' . 'option' . $optionId . '.' . Item\Param::colPrefix() . Item::index() . ' AND ' .
134
                    'option' . $optionId . '.' . Item\Param::colPrefix() . Item\Option::index() . ' = "' . (int) $optionId . '" AND ' .
135
                    'option' . $optionId . '.' . Item\Param::colPrefix() . 'value = "' . (int) $optionValue . '"',
136
                    'inner', 'option' . $optionId];
137
            }
138
        }
139
    }
140
141
    public static function filters(&$options, &$selectOptions) {
142
        if (empty($options['filters'])) {
143
            return;
144
        }
145
        foreach ($options['filters'] as $col => $filter) {
146
            switch ($col) {
147
                case 'price':
148
                    $colName = Item\Offer\Price::colPrefix() . 'price';
149 View Code Duplication
                    if (!empty($filter['min'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
150
                        $selectOptions['where'][] = [$colName, (float) $filter['min'], '>='];
151
                    }
152 View Code Duplication
                    if (!empty($filter['max'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

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.

Loading history...
153
                        $selectOptions['where'][] = [$colName, (float) $filter['max'], '<='];
154
                    }
155
                    break;
156
                case 'options':
157
                case 'offerOptions':
158
                    if ($col == 'offerOptions') {
159
                        $paramPrefix = Item\Offer\Param::colPrefix();
160
                        $itemIndex = Item\Offer::index();
161
                        $optionIndex = Item\Offer\Option::index();
162
                        $table = Item\Offer\Param::table();
163
                    } else {
164
                        $paramPrefix = Item\Param::colPrefix();
165
                        $itemIndex = Item::index();
166
                        $optionIndex = Item\Option::index();
167
                        $table = Item\Param::table();
168
                    }
169
                    foreach ($filter as $optionId => $optionValue) {
170
                        $optionId = (int) $optionId;
171
                        if (is_array($optionValue)) {
172
                            $optionValueArr = [];
173
                            foreach ($optionValue as $val) {
174
                                $optionValueArr[] = \App::$cur->db->connection->pdo->quote($val);
175
                            }
176
                            $qstr = 'IN (' . implode(',', $optionValueArr) . ')';
177
                        } else {
178
                            $qstr = '= ' . \App::$cur->db->connection->pdo->quote($optionValue);
179
                        }
180
                        $selectOptions['join'][] = [$table, $itemIndex . ' = ' . 'option' . $optionId . '.' . $paramPrefix . $itemIndex . ' AND ' .
181
                            'option' . $optionId . '.' . $paramPrefix . $optionIndex . ' = "' . (int) $optionId . '" AND ' .
182
                            'option' . $optionId . '.' . $paramPrefix . 'value ' . $qstr . '',
183
                            'inner', 'option' . $optionId];
184
                    }
185
            }
186
        }
187
    }
188
189
    public static function categories(&$options, &$selectOptions) {
190
        if (empty($options['parent'])) {
191
            return;
192
        }
193
        if (is_array($options['parent']) || strpos($options['parent'], ',') !== false) {
194
            $list = is_array($options['parent']) ? $options['parent'] : explode(',', $options['parent']);
195
            $first = true;
196
            $where = [];
197
            foreach ($list as $categoryId) {
198
                if (!$categoryId) {
199
                    continue;
200
                }
201
                $category = Category::get($categoryId);
202
                $where[] = ['tree_path', $category->tree_path . (int) $categoryId . '/%', 'LIKE', $first ? 'AND' : 'OR'];
203
                $first = false;
204
            }
205
            $selectOptions['where'][] = $where;
206
        } else {
207
            $category = Category::get($options['parent']);
208
            if ($category) {
209
                $selectOptions['where'][] = ['tree_path', $category->tree_path . (int) $options['parent'] . '/%', 'LIKE'];
210
            }
211
        }
212
    }
213
214
    public static function search(&$options, &$selectOptions) {
215
        if (empty($options['search'])) {
216
            return;
217
        }
218
        $searchStr = preg_replace('![^A-zА-я0-9 ]!iSu', ' ', $options['search']);
219
        $searchArr = [];
220
        foreach (explode(' ', $searchStr) as $part) {
221
            $part = trim($part);
222
            if ($part && strlen($part) > 2) {
223
                $searchArr[] = ['search_index', '%' . $part . '%', 'LIKE'];
224
            }
225
        }
226
        if (!empty($searchArr)) {
227
            $selectOptions['where'][] = $searchArr;
228
        }
229
    }
230
231
    public static function warehouse(&$selectOptions) {
232
        if (!empty(\App::$cur->Ecommerce->config['view_empty_warehouse'])) {
233
            return;
234
        }
235
        $warehouseIds = self::getWarehouses();
236
237
        $selectOptions['where'][] = [
238
            '(
239
          (SELECT COALESCE(sum(`' . Item\Offer\Warehouse::colPrefix() . 'count`),0) 
240
            FROM ' . \App::$cur->db->table_prefix . Item\Offer\Warehouse::table() . ' iciw 
241
            WHERE iciw.' . Item\Offer\Warehouse::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . '
242
                ' . ($warehouseIds ? ' AND iciw.' . Item\Offer\Warehouse::colPrefix() . Warehouse::index() . ' IN(' . implode(',', $warehouseIds) . ')' : '') . '
243
            )
244
          -
245
          (SELECT COALESCE(sum(' . Warehouse\Block::colPrefix() . 'count) ,0)
246
            FROM ' . \App::$cur->db->table_prefix . Warehouse\Block::table() . ' iewb
247
            inner JOIN ' . \App::$cur->db->table_prefix . Cart::table() . ' icc ON icc.' . Cart::index() . ' = iewb.' . Warehouse\Block::colPrefix() . Cart::index() . ' AND (
248
                (`' . Cart::colPrefix() . 'warehouse_block` = 1 and `' . Cart::colPrefix() . 'cart_status_id` in(2,3,6)) ||
249
                (`' . Cart::colPrefix() . Cart\Status::index() . '` in(0,1) and `' . Cart::colPrefix() . 'date_last_activ` >=subdate(now(),INTERVAL 30 MINUTE))
250
            )
251
            WHERE iewb.' . Warehouse\Block::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . ')
252
          )',
253
            0,
254
            '>'
255
        ];
256
    }
257
258
    public static function getWarehouses() {
259
        if (!\App::$cur->geography || !\Geography\City::$cur) {
260
            return [];
261
        }
262
        $warehouseIds = [];
263
        $warehouses = \Geography\City\Data::get([['code', 'warehouses'], ['city_id', \Geography\City::$cur->id]]);
264
        if ($warehouses && $warehouses->data) {
265
            foreach (explode(',', $warehouses->data) as $id) {
266
                $warehouseIds[$id] = $id;
267
            }
268
        }
269
        return $warehouseIds;
270
    }
271
}