Passed
Push — master ( 6aea51...c8f806 )
by Alexey
05:04
created

OptionsParser::order()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 20
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 16
nc 14
nop 2
dl 0
loc 20
rs 7.2765
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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'])) {
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...
130
                        $selectOptions['where'][] = [$colName, (float) $filter['min'], '>='];
131
                    }
132 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...
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
}