GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Push — filters-dev ( 64ed0d...adb503 )
by Ivan
08:47
created

PropertiesHelper   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 205
Duplicated Lines 4.88 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 6
Bugs 0 Features 0
Metric Value
wmc 27
c 6
b 0
f 0
lcom 1
cbo 3
dl 10
loc 205
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
F appendPropertiesFilters() 10 156 25
B createSubQuery() 0 28 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace app\properties;
4
5
6
use app\models\ObjectStaticValues;
7
use app\models\Property;
8
use app\modules\shop\models\ConfigConfigurationModel;
9
use Yii;
10
use yii\db\ActiveQuery;
11
use yii\db\Expression;
12
use yii\db\Query;
13
14
class PropertiesHelper
15
{
16
17
    /**
18
     * Добавляет к запросу фильтры по свойствам
19
     * @param $object \app\models\Object
20
     * @param $query ActiveQuery
21
     * @param $values_by_property_id array
22
     * @param array $dynamic_values_by_property_id array
23
     * @param string $multiFilterMode
24
     * @throws \Exception
25
     */
26
    public static function appendPropertiesFilters(
27
        $object,
28
        &$query,
29
        $values_by_property_id,
30
        $dynamic_values_by_property_id = [],
31
        $multiFilterMode = ConfigConfigurationModel::MULTI_FILTER_MODE_INTERSECTION
32
    )
33
    {
34
35
        // сначала сгруппируем свойства по типу хранения
36
        $by_storage = [
37
            'eav' => [],
38
            'table_inheritance' => [],
39
            'static_values' => [],
40
        ];
41
        $dynamic_by_storage = [
42
            'eav' => [],
43
            'table_inheritance' => [],
44
        ];
45
        foreach ($values_by_property_id as $property_id => $values) {
46
            // values может быть просто строкой(одно значение), а может уже прийти массивом
47
            $values = (array)$values;
48
            $property = Property::findById($property_id);
49
            if ($property === null) {
50
                continue;
51
            }
52
            if ($property->is_eav) {
53
                $by_storage['eav'][] = [
54
                    'property' => $property,
55
                    'values' => $values,
56
                ];
57
            } elseif ($property->is_column_type_stored) {
58
                $by_storage['table_inheritance'][] = [
59
                    'property' => $property,
60
                    'values' => $values,
61
                ];
62
            } elseif ($property->has_static_values) {
63
                $by_storage['static_values'] = array_merge($by_storage['static_values'], $values);
64
            } else {
65
                throw new \Exception("Wrong property type for " . $property->id);
66
            }
67
        }
68
        foreach ($dynamic_values_by_property_id as $property_id => $values) {
69
            $property = Property::findById($property_id);
70
            if ($property) {
71
                if ($property->is_eav) {
72
                    $dynamic_by_storage['eav'][] = [
73
                        'property' => $property,
74
                        'values' => $values,
75
                    ];
76
                } elseif ($property->is_column_type_stored) {
77
                    $dynamic_by_storage['table_inheritance'][] = [
78
                        'property' => $property,
79
                        'values' => $values,
80
                    ];
81
                } else {
82
                    throw new \Exception("Wrong property type for " . $property->id);
83
                }
84
            }
85
        }
86
87
        $ti_clauses = [];
88
        $join_table_name = "PropertiesJoinTable1";
89
90
        foreach ($by_storage['table_inheritance'] as $item) {
91
            $property = $item['property'];
92
            $or_clauses = [];
93
            foreach ($item['values'] as $val) {
94
                $or_clauses[] = "$join_table_name." .
95
                    Yii::$app->db->quoteColumnName($property->key) . " = " .
96
                    Yii::$app->db->quoteValue($val);
97
            }
98
99
            $ti_clauses[] = implode(" OR ", $or_clauses);
100
101
        }
102
        foreach ($dynamic_by_storage['table_inheritance'] as $item) {
103
            $property = $item['property'];
104
            $clauses = [];
105 View Code Duplication
            if (isset($item['values']['min']) && strlen($item['values']['min'])) {
106
                $clauses[] = "$join_table_name." .
107
                    Yii::$app->db->quoteColumnName($property->key) . " >= " .
108
                    Yii::$app->db->quoteValue((double)($item['values']['min']));
109
            }
110 View Code Duplication
            if (isset($item['values']['max']) && strlen($item['values']['max'])) {
111
                $clauses[] = "$join_table_name." .
112
                    Yii::$app->db->quoteColumnName($property->key) . " <= " .
113
                    Yii::$app->db->quoteValue((double)($item['values']['max']));
114
            }
115
            if (!empty($clauses)) {
116
                $ti_clauses[] = '(' . implode(" AND ", $clauses) . ')';
117
            }
118
        }
119
        if (count($ti_clauses) > 0) {
120
            $ti_clauses = implode(" AND ", $ti_clauses);
121
122
            $query = $query->innerJoin(
123
                $object->column_properties_table_name . " $join_table_name",
124
                "$join_table_name.object_model_id = " .
125
                Yii::$app->db->quoteTableName($object->object_table_name) . ".id " .
126
                " AND " . $ti_clauses
127
            );
128
        }
129
130
131
        if (count($by_storage['static_values'])) {
132
133
            switch ($multiFilterMode) {
134
                case ConfigConfigurationModel::MULTI_FILTER_MODE_UNION:
135
                    $subQuery = new Query();
136
                    $lastQuery = $subQuery;
137
                    $counter = 0;
138
                    foreach ($by_storage['static_values'] as $staticValues) {
139
                        $tmp = self::createSubQuery($object, $staticValues, ++$counter, $multiFilterMode);
140
                        $lastQuery->innerJoin(
141
                            ['osvm' . $counter => $tmp]
142
                            , 'osvm' . $counter . '.object_model_id = ' . 'osv' . ($counter - 1) . '.object_model_id'
143
                        );
144
                        $lastQuery = $tmp;
145
                    }
146
147
                    $query->innerJoin(
148
                        $subQuery->join[0][1]
149
                        , 'osvm1.object_model_id = ' . Yii::$app->db->quoteTableName($object->object_table_name) . '.id'
150
                    );
151
152
                    break;
153
                default:
154
                    $query->innerJoin(
155
                        ['osvm' => self::createSubQuery($object, $by_storage['static_values'])]
156
                        , 'osvm.object_model_id = ' . Yii::$app->db->quoteTableName($object->object_table_name) . '.id'
157
                    );
158
            }
159
        }
160
161
        if (count($by_storage['eav'])) {
162
            foreach ($by_storage['eav'] as $item) {
163
                $joinTableName = 'EAVJoinTable' . $item['property']->id;
164
                if (count($item['values']) > 0) {
165
                    $query = $query->innerJoin(
166
                        $object->eav_table_name . " " . $joinTableName,
167
                        "$joinTableName.object_model_id = " .
168
                        Yii::$app->db->quoteTableName($object->object_table_name) . ".id "
169
                    )->andWhere(
170
                        new Expression(
171
                            '`' . $joinTableName . '`.`value` in (' .
172
                            implode(', ', array_map('intval', $item['values'])) .
173
                            ') AND `' . $joinTableName . '`.`key` = "' . $item['property']->key . '"'
174
                        )
175
                    );
176
                }
177
            }
178
        }
179
180
181
    }
182
183
    /**
184
     * @param \app\models\Object $object
185
     * @param array $psvs
186
     * @param int $counter
187
     * @param string $multiFilterMode
188
     * @return Query
189
     */
190
    public static function createSubQuery(
191
        \app\models\Object $object,
192
        $psvs = [],
193
        $counter = 1,
194
        $multiFilterMode = ConfigConfigurationModel::MULTI_FILTER_MODE_INTERSECTION
195
    )
196
    {
197
        $tableInner = 'osv' . $counter;
198
        switch ($multiFilterMode) {
199
            case ConfigConfigurationModel::MULTI_FILTER_MODE_UNION:
200
                $having = "count($tableInner.object_model_id) BETWEEN 1 AND " . count($psvs);
201
                break;
202
            default:
203
                $having = "count($tableInner.object_model_id) = " . count($psvs);
204
        }
205
        $subQuery = (new Query)
206
            ->select("$tableInner.object_model_id")
207
            ->distinct()
208
            ->from(ObjectStaticValues::tableName() . " $tableInner")
209
            ->where([
210
                "$tableInner.object_id" => $object->id,
211
                "$tableInner.property_static_value_id" => $psvs
212
            ])
213
            ->groupBy("$tableInner.object_model_id")
214
            ->having($having);
215
216
        return $subQuery;
217
    }
218
}
219