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.
Completed
Push — master ( 6d277d...c73de3 )
by Robert
11:50
created

ExistValidator::validateAttribute()   D

Complexity

Conditions 10
Paths 68

Size

Total Lines 30
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 10

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 23
cts 23
cp 1
rs 4.8196
c 0
b 0
f 0
cc 10
eloc 19
nc 68
nop 2
crap 10

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
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\validators;
9
10
use Yii;
11
use yii\base\InvalidConfigException;
12
13
/**
14
 * ExistValidator validates that the attribute value exists in a table.
15
 *
16
 * ExistValidator checks if the value being validated can be found in the table column specified by
17
 * the ActiveRecord class [[targetClass]] and the attribute [[targetAttribute]].
18
 *
19
 * This validator is often used to verify that a foreign key contains a value
20
 * that can be found in the foreign table.
21
 *
22
 * The following are examples of validation rules using this validator:
23
 *
24
 * ```php
25
 * // a1 needs to exist
26
 * ['a1', 'exist']
27
 * // a1 needs to exist, but its value will use a2 to check for the existence
28
 * ['a1', 'exist', 'targetAttribute' => 'a2']
29
 * // a1 and a2 need to exist together, and they both will receive error message
30
 * [['a1', 'a2'], 'exist', 'targetAttribute' => ['a1', 'a2']]
31
 * // a1 and a2 need to exist together, only a1 will receive error message
32
 * ['a1', 'exist', 'targetAttribute' => ['a1', 'a2']]
33
 * // a1 needs to exist by checking the existence of both a2 and a3 (using a1 value)
34
 * ['a1', 'exist', 'targetAttribute' => ['a2', 'a1' => 'a3']]
35
 * ```
36
 *
37
 * @author Qiang Xue <[email protected]>
38
 * @since 2.0
39
 */
40
class ExistValidator extends Validator
41
{
42
    /**
43
     * @var string the name of the ActiveRecord class that should be used to validate the existence
44
     * of the current attribute value. It not set, it will use the ActiveRecord class of the attribute being validated.
45
     * @see targetAttribute
46
     */
47
    public $targetClass;
48
    /**
49
     * @var string|array the name of the ActiveRecord attribute that should be used to
50
     * validate the existence of the current attribute value. If not set, it will use the name
51
     * of the attribute currently being validated. You may use an array to validate the existence
52
     * of multiple columns at the same time. The array key is the name of the attribute with the value to validate,
53
     * the array value is the name of the database field to search.
54
     */
55
    public $targetAttribute;
56
    /**
57
     * @var string|array|\Closure additional filter to be applied to the DB query used to check the existence of the attribute value.
58
     * This can be a string or an array representing the additional query condition (refer to [[\yii\db\Query::where()]]
59
     * on the format of query condition), or an anonymous function with the signature `function ($query)`, where `$query`
60
     * is the [[\yii\db\Query|Query]] object that you can modify in the function.
61
     */
62
    public $filter;
63
    /**
64
     * @var bool whether to allow array type attribute.
65
     */
66
    public $allowArray = false;
67
68
    /**
69
     * @var string and|or define how target attributes are related
70
     * @since 2.0.11
71
     */
72
    public $targetAttributeJunction = 'and';
73
74
    /**
75
     * @inheritdoc
76
     */
77 12
    public function init()
78
    {
79 12
        parent::init();
80 12
        if ($this->message === null) {
81 12
            $this->message = Yii::t('yii', '{attribute} is invalid.');
82 12
        }
83 12
    }
84
85
    /**
86
     * @inheritdoc
87
     */
88 6
    public function validateAttribute($model, $attribute)
89
    {
90 6
        $targetAttribute = $this->targetAttribute === null ? $attribute : $this->targetAttribute;
91 6
        $params = $this->prepareConditions($targetAttribute, $model, $attribute);
92 6
        $conditions[] = $this->targetAttributeJunction == 'or' ? 'or' : 'and';
0 ignored issues
show
Coding Style Comprehensibility introduced by
$conditions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $conditions = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
93
94 6
        if (!$this->allowArray) {
95 6
            foreach ($params as $key => $value) {
96 6
                if (is_array($value)) {
97 3
                    $this->addError($model, $attribute, Yii::t('yii', '{attribute} is invalid.'));
98
99 3
                    return;
100
                }
101 6
                $conditions[] = [$key => $value];
102 6
            }
103 6
        } else {
104 3
            $conditions[] = $params;
105
        }
106
107 6
        $targetClass = $this->targetClass === null ? get_class($model) : $this->targetClass;
108 6
        $query = $this->createQuery($targetClass, $conditions);
109
110 6
        if (is_array($model->$attribute)) {
111 3
            if ($query->count("DISTINCT [[$targetAttribute]]") != count($model->$attribute)) {
112 3
                $this->addError($model, $attribute, $this->message);
113 3
            }
114 6
        } elseif (!$query->exists()) {
115 6
            $this->addError($model, $attribute, $this->message);
116 6
        }
117 6
    }
118
119
    /**
120
     * Processes attributes' relations described in $targetAttribute parameter into conditions, compatible with
121
     * [[\yii\db\Query::where()|Query::where()]] key-value format.
122
     *
123
     * @param $targetAttribute array|string $attribute the name of the ActiveRecord attribute that should be used to
124
     * validate the existence of the current attribute value. If not set, it will use the name
125
     * of the attribute currently being validated. You may use an array to validate the existence
126
     * of multiple columns at the same time. The array key is the name of the attribute with the value to validate,
127
     * the array value is the name of the database field to search.
128
     * @param \yii\base\Model $model the data model to be validated
129
     * @param string $attribute the name of the attribute to be validated in the $model
130
     * @return array conditions, compatible with [[\yii\db\Query::where()|Query::where()]] key-value format.
131
     * @throws InvalidConfigException
132
     */
133 6
    private function prepareConditions($targetAttribute, $model, $attribute)
134
    {
135 6
        if (is_array($targetAttribute)) {
136 3
            if ($this->allowArray) {
137
                throw new InvalidConfigException('The "targetAttribute" property must be configured as a string.');
138
            }
139 3
            $params = [];
140 3
            foreach ($targetAttribute as $k => $v) {
141 3
                $params[$v] = is_int($k) ? $model->$attribute : $model->$k;
142 3
            }
143 3
        } else {
144 3
            $params = [$targetAttribute => $model->$attribute];
145
        }
146 6
        return $params;
147
    }
148
149
    /**
150
     * @inheritdoc
151
     */
152 6
    protected function validateValue($value)
153
    {
154 6
        if ($this->targetClass === null) {
155 3
            throw new InvalidConfigException('The "targetClass" property must be set.');
156
        }
157 6
        if (!is_string($this->targetAttribute)) {
158 3
            throw new InvalidConfigException('The "targetAttribute" property must be configured as a string.');
159
        }
160
161 3
        $query = $this->createQuery($this->targetClass, [$this->targetAttribute => $value]);
162
163 3
        if (is_array($value)) {
164 3
            if (!$this->allowArray) {
165 3
                return [$this->message, []];
166
            }
167
            return $query->count("DISTINCT [[$this->targetAttribute]]") == count($value) ? null : [$this->message, []];
168
        } else {
169 3
            return $query->exists() ? null : [$this->message, []];
170
        }
171
    }
172
173
    /**
174
     * Creates a query instance with the given condition.
175
     * @param string $targetClass the target AR class
176
     * @param mixed $condition query condition
177
     * @return \yii\db\ActiveQueryInterface the query instance
178
     */
179 9
    protected function createQuery($targetClass, $condition)
180
    {
181
        /* @var $targetClass \yii\db\ActiveRecordInterface */
182 9
        $query = $targetClass::find()->andWhere($condition);
183 9
        if ($this->filter instanceof \Closure) {
184
            call_user_func($this->filter, $query);
185 9
        } elseif ($this->filter !== null) {
186
            $query->andWhere($this->filter);
187
        }
188
189 9
        return $query;
190
    }
191
}
192