Completed
Push — master ( f17270...776132 )
by Alexey
07:15
created

OptionsParser::categories()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 21
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 16
nc 6
nop 2
dl 0
loc 21
rs 8.7624
c 0
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($options, $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($options, $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(&$options, &$selectOptions) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
            $selectOptions['where'][] = ['tree_path', $category->tree_path . (int) $options['parent'] . '/%', 'LIKE'];
188
        }
189
    }
190
191
    public static function search(&$options, &$selectOptions) {
192
        if (empty($options['search'])) {
193
            return;
194
        }
195
        $searchStr = preg_replace('![^A-zА-я0-9 ]!iSu', ' ', $options['search']);
196
        $searchArr = [];
197
        foreach (explode(' ', $searchStr) as $part) {
198
            $part = trim($part);
199
            if ($part && strlen($part) > 2) {
200
                $searchArr[] = ['search_index', '%' . $part . '%', 'LIKE'];
201
            }
202
        }
203
        if (!empty($searchArr)) {
204
            $selectOptions['where'][] = $searchArr;
205
        }
206
    }
207
208
    public static function warehouse(&$options, &$selectOptions) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
209
        if (!empty(\App::$cur->Ecommerce->config['view_empty_warehouse'])) {
210
            return;
211
        }
212
        $warehouseIds = self::getWarehouses();
213
214
        $selectOptions['where'][] = [
215
            '(
216
          (SELECT COALESCE(sum(`' . Item\Offer\Warehouse::colPrefix() . 'count`),0) 
217
            FROM ' . \App::$cur->db->table_prefix . Item\Offer\Warehouse::table() . ' iciw 
218
            WHERE iciw.' . Item\Offer\Warehouse::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . '
219
                ' . ($warehouseIds ? ' AND iciw.' . Item\Offer\Warehouse::colPrefix() . Warehouse::index() . ' IN(' . implode(',', $warehouseIds) . ')' : '') . '
220
            )
221
          -
222
          (SELECT COALESCE(sum(' . Warehouse\Block::colPrefix() . 'count) ,0)
223
            FROM ' . \App::$cur->db->table_prefix . Warehouse\Block::table() . ' iewb
224
            inner JOIN ' . \App::$cur->db->table_prefix . Cart::table() . ' icc ON icc.' . Cart::index() . ' = iewb.' . Warehouse\Block::colPrefix() . Cart::index() . ' AND (
225
                (`' . Cart::colPrefix() . 'warehouse_block` = 1 and `' . Cart::colPrefix() . 'cart_status_id` in(2,3,6)) ||
226
                (`' . Cart::colPrefix() . Cart\Status::index() . '` in(0,1) and `' . Cart::colPrefix() . 'date_last_activ` >=subdate(now(),INTERVAL 30 MINUTE))
227
            )
228
            WHERE iewb.' . Warehouse\Block::colPrefix() . Item\Offer::index() . ' = ' . Item\Offer::index() . ')
229
          )',
230
            0,
231
            '>'
232
        ];
233
    }
234
235
    public static function getWarehouses() {
236
        if (!\App::$cur->geography || !\Geography\City::$cur) {
237
            return [];
238
        }
239
        $warehouseIds = [];
240
        $warehouses = \Geography\City\Data::get([['code', 'warehouses'], ['city_id', \Geography\City::$cur->id]]);
241
        if ($warehouses && $warehouses->data) {
242
            foreach (explode(',', $warehouses->data) as $id) {
243
                $warehouseIds[$id] = $id;
244
            }
245
        }
246
        return $warehouseIds;
247
    }
248
249
}
250