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 ( 533da6...33cff4 )
by Robert
08:57
created

Validator::setAttributeNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 1
crap 1
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\Component;
12
use yii\base\NotSupportedException;
13
14
/**
15
 * Validator is the base class for all validators.
16
 *
17
 * Child classes should override the [[validateValue()]] and/or [[validateAttribute()]] methods to provide the actual
18
 * logic of performing data validation. Child classes may also override [[clientValidateAttribute()]]
19
 * to provide client-side validation support.
20
 *
21
 * Validator declares a set of [[builtInValidators|built-in validators]] which can
22
 * be referenced using short names. They are listed as follows:
23
 *
24
 * - `boolean`: [[BooleanValidator]]
25
 * - `captcha`: [[\yii\captcha\CaptchaValidator]]
26
 * - `compare`: [[CompareValidator]]
27
 * - `date`: [[DateValidator]]
28
 * - `datetime`: [[DateValidator]]
29
 * - `time`: [[DateValidator]]
30
 * - `default`: [[DefaultValueValidator]]
31
 * - `double`: [[NumberValidator]]
32
 * - `each`: [[EachValidator]]
33
 * - `email`: [[EmailValidator]]
34
 * - `exist`: [[ExistValidator]]
35
 * - `file`: [[FileValidator]]
36
 * - `filter`: [[FilterValidator]]
37
 * - `image`: [[ImageValidator]]
38
 * - `in`: [[RangeValidator]]
39
 * - `integer`: [[NumberValidator]]
40
 * - `match`: [[RegularExpressionValidator]]
41
 * - `required`: [[RequiredValidator]]
42
 * - `safe`: [[SafeValidator]]
43
 * - `string`: [[StringValidator]]
44
 * - `trim`: [[FilterValidator]]
45
 * - `unique`: [[UniqueValidator]]
46
 * - `url`: [[UrlValidator]]
47
 * - `ip`: [[IpValidator]]
48
 *
49
 * For more details and usage information on Validator, see the [guide article on validators](guide:input-validation).
50
 * 
51
 * @property array $attributeNames cleaned attribute names without the `!` character at the beginning. This property is read-only.
52
 *
53
 * @author Qiang Xue <[email protected]>
54
 * @since 2.0
55
 */
56
class Validator extends Component
57
{
58
    /**
59
     * @var array list of built-in validators (name => class or configuration)
60
     */
61
    public static $builtInValidators = [
62
        'boolean' => 'yii\validators\BooleanValidator',
63
        'captcha' => 'yii\captcha\CaptchaValidator',
64
        'compare' => 'yii\validators\CompareValidator',
65
        'date' => 'yii\validators\DateValidator',
66
        'datetime' => [
67
            'class' => 'yii\validators\DateValidator',
68
            'type' => DateValidator::TYPE_DATETIME,
69
        ],
70
        'time' => [
71
            'class' => 'yii\validators\DateValidator',
72
            'type' => DateValidator::TYPE_TIME,
73
        ],
74
        'default' => 'yii\validators\DefaultValueValidator',
75
        'double' => 'yii\validators\NumberValidator',
76
        'each' => 'yii\validators\EachValidator',
77
        'email' => 'yii\validators\EmailValidator',
78
        'exist' => 'yii\validators\ExistValidator',
79
        'file' => 'yii\validators\FileValidator',
80
        'filter' => 'yii\validators\FilterValidator',
81
        'image' => 'yii\validators\ImageValidator',
82
        'in' => 'yii\validators\RangeValidator',
83
        'integer' => [
84
            'class' => 'yii\validators\NumberValidator',
85
            'integerOnly' => true,
86
        ],
87
        'match' => 'yii\validators\RegularExpressionValidator',
88
        'number' => 'yii\validators\NumberValidator',
89
        'required' => 'yii\validators\RequiredValidator',
90
        'safe' => 'yii\validators\SafeValidator',
91
        'string' => 'yii\validators\StringValidator',
92
        'trim' => [
93
            'class' => 'yii\validators\FilterValidator',
94
            'filter' => 'trim',
95
            'skipOnArray' => true,
96
        ],
97
        'unique' => 'yii\validators\UniqueValidator',
98
        'url' => 'yii\validators\UrlValidator',
99
        'ip' => 'yii\validators\IpValidator',
100
    ];
101
    /**
102
     * @var array|string attributes to be validated by this validator. For multiple attributes,
103
     * please specify them as an array; for single attribute, you may use either a string or an array.
104
     */
105
    public $attributes = [];
106
    /**
107
     * @var string the user-defined error message. It may contain the following placeholders which
108
     * will be replaced accordingly by the validator:
109
     *
110
     * - `{attribute}`: the label of the attribute being validated
111
     * - `{value}`: the value of the attribute being validated
112
     *
113
     * Note that some validators may introduce other properties for error messages used when specific
114
     * validation conditions are not met. Please refer to individual class API documentation for details
115
     * about these properties. By convention, this property represents the primary error message
116
     * used when the most important validation condition is not met.
117
     */
118
    public $message;
119
    /**
120
     * @var array|string scenarios that the validator can be applied to. For multiple scenarios,
121
     * please specify them as an array; for single scenario, you may use either a string or an array.
122
     */
123
    public $on = [];
124
    /**
125
     * @var array|string scenarios that the validator should not be applied to. For multiple scenarios,
126
     * please specify them as an array; for single scenario, you may use either a string or an array.
127
     */
128
    public $except = [];
129
    /**
130
     * @var bool whether this validation rule should be skipped if the attribute being validated
131
     * already has some validation error according to some previous rules. Defaults to true.
132
     */
133
    public $skipOnError = true;
134
    /**
135
     * @var bool whether this validation rule should be skipped if the attribute value
136
     * is null or an empty string.
137
     */
138
    public $skipOnEmpty = true;
139
    /**
140
     * @var bool whether to enable client-side validation for this validator.
141
     * The actual client-side validation is done via the JavaScript code returned
142
     * by [[clientValidateAttribute()]]. If that method returns null, even if this property
143
     * is true, no client-side validation will be done by this validator.
144
     */
145
    public $enableClientValidation = true;
146
    /**
147
     * @var callable a PHP callable that replaces the default implementation of [[isEmpty()]].
148
     * If not set, [[isEmpty()]] will be used to check if a value is empty. The signature
149
     * of the callable should be `function ($value)` which returns a boolean indicating
150
     * whether the value is empty.
151
     */
152
    public $isEmpty;
153
    /**
154
     * @var callable a PHP callable whose return value determines whether this validator should be applied.
155
     * The signature of the callable should be `function ($model, $attribute)`, where `$model` and `$attribute`
156
     * refer to the model and the attribute currently being validated. The callable should return a boolean value.
157
     *
158
     * This property is mainly provided to support conditional validation on the server-side.
159
     * If this property is not set, this validator will be always applied on the server-side.
160
     *
161
     * The following example will enable the validator only when the country currently selected is USA:
162
     *
163
     * ```php
164
     * function ($model) {
165
     *     return $model->country == Country::USA;
166
     * }
167
     * ```
168
     *
169
     * @see whenClient
170
     */
171
    public $when;
172
    /**
173
     * @var string a JavaScript function name whose return value determines whether this validator should be applied
174
     * on the client-side. The signature of the function should be `function (attribute, value)`, where
175
     * `attribute` is an object describing the attribute being validated (see [[clientValidateAttribute()]])
176
     * and `value` the current value of the attribute.
177
     *
178
     * This property is mainly provided to support conditional validation on the client-side.
179
     * If this property is not set, this validator will be always applied on the client-side.
180
     *
181
     * The following example will enable the validator only when the country currently selected is USA:
182
     *
183
     * ```javascript
184
     * function (attribute, value) {
185
     *     return $('#country').val() === 'USA';
186
     * }
187
     * ```
188
     *
189
     * @see when
190
     */
191
    public $whenClient;
192
193
194
    /**
195
     * Creates a validator object.
196
     * @param string|\Closure $type the validator type. This can be either:
197
     *  * a built-in validator name listed in [[builtInValidators]];
198
     *  * a method name of the model class;
199
     *  * an anonymous function;
200
     *  * a validator class name.
201
     * @param \yii\base\Model $model the data model to be validated.
202
     * @param array|string $attributes list of attributes to be validated. This can be either an array of
203
     * the attribute names or a string of comma-separated attribute names.
204
     * @param array $params initial values to be applied to the validator properties.
205
     * @return Validator the validator
206
     */
207 42
    public static function createValidator($type, $model, $attributes, $params = [])
208
    {
209 42
        $params['attributes'] = $attributes;
210
211 42
        if ($type instanceof \Closure || $model->hasMethod($type)) {
212
            // method-based validator
213 3
            $params['class'] = __NAMESPACE__ . '\InlineValidator';
214 3
            $params['method'] = $type;
215
        } else {
216 40
            if (isset(static::$builtInValidators[$type])) {
217 36
                $type = static::$builtInValidators[$type];
218
            }
219 40
            if (is_array($type)) {
220 11
                $params = array_merge($type, $params);
221
            } else {
222 34
                $params['class'] = $type;
223
            }
224
        }
225
226 42
        return Yii::createObject($params);
227
    }
228
229
    /**
230
     * @inheritdoc
231
     */
232 388
    public function init()
233
    {
234 388
        parent::init();
235 388
        $this->attributes = (array) $this->attributes;
236 388
        $this->on = (array) $this->on;
237 388
        $this->except = (array) $this->except;
238 388
    }
239
240
    /**
241
     * Validates the specified object.
242
     * @param \yii\base\Model $model the data model being validated
243
     * @param array|null $attributes the list of attributes to be validated.
244
     * Note that if an attribute is not associated with the validator - it will be
245
     * ignored. If this parameter is null, every attribute listed in [[attributes]] will be validated.
246
     */
247 18
    public function validateAttributes($model, $attributes = null)
248
    {
249 18
        if (is_array($attributes)) {
250 16
            $newAttributes = [];
251 16
            foreach ($attributes as $attribute) {
252 16
                if (in_array($attribute, $this->getAttributeNames(), true)) {
253 15
                    $newAttributes[] = $attribute;
254
                }
255
            }
256 16
            $attributes = $newAttributes;
257
        } else {
258 4
            $attributes = $this->getAttributeNames();
259
        }
260
261 18
        foreach ($attributes as $attribute) {
262 17
            $skip = $this->skipOnError && $model->hasErrors($attribute)
263 17
                || $this->skipOnEmpty && $this->isEmpty($model->$attribute);
264 17
            if (!$skip) {
265 12
                if ($this->when === null || call_user_func($this->when, $model, $attribute)) {
266 12
                    $this->validateAttribute($model, $attribute);
267
                }
268
            }
269
        }
270 18
    }
271
272
    /**
273
     * Validates a single attribute.
274
     * Child classes must implement this method to provide the actual validation logic.
275
     * @param \yii\base\Model $model the data model to be validated
276
     * @param string $attribute the name of the attribute to be validated.
277
     */
278 12
    public function validateAttribute($model, $attribute)
279
    {
280 12
        $result = $this->validateValue($model->$attribute);
281 12
        if (!empty($result)) {
282 7
            $this->addError($model, $attribute, $result[0], $result[1]);
283
        }
284 12
    }
285
286
    /**
287
     * Validates a given value.
288
     * You may use this method to validate a value out of the context of a data model.
289
     * @param mixed $value the data value to be validated.
290
     * @param string $error the error message to be returned, if the validation fails.
291
     * @return bool whether the data is valid.
292
     */
293 96
    public function validate($value, &$error = null)
294
    {
295 96
        $result = $this->validateValue($value);
296 91
        if (empty($result)) {
297 59
            return true;
298
        }
299
300 79
        list($message, $params) = $result;
301 79
        $params['attribute'] = Yii::t('yii', 'the input value');
302 79
        if (is_array($value)) {
303 12
            $params['value'] = 'array()';
304 74
        } elseif (is_object($value)) {
305 5
            $params['value'] = 'object';
306
        } else {
307 69
            $params['value'] = $value;
308
        }
309 79
        $error = $this->formatMessage($message, $params);
310
311 79
        return false;
312
    }
313
314
    /**
315
     * Validates a value.
316
     * A validator class can implement this method to support data validation out of the context of a data model.
317
     * @param mixed $value the data value to be validated.
318
     * @return array|null the error message and the parameters to be inserted into the error message.
319
     * Null should be returned if the data is valid.
320
     * @throws NotSupportedException if the validator does not supporting data validation without a model
321
     */
322 1
    protected function validateValue($value)
323
    {
324 1
        throw new NotSupportedException(get_class($this) . ' does not support validateValue().');
325
    }
326
327
    /**
328
     * Returns the JavaScript needed for performing client-side validation.
329
     *
330
     * Calls [[getClientOptions()]] to generate options array for client-side validation.
331
     *
332
     * You may override this method to return the JavaScript validation code if
333
     * the validator can support client-side validation.
334
     *
335
     * The following JavaScript variables are predefined and can be used in the validation code:
336
     *
337
     * - `attribute`: an object describing the the attribute being validated.
338
     * - `value`: the value being validated.
339
     * - `messages`: an array used to hold the validation error messages for the attribute.
340
     * - `deferred`: an array used to hold deferred objects for asynchronous validation
341
     * - `$form`: a jQuery object containing the form element
342
     *
343
     * The `attribute` object contains the following properties:
344
     * - `id`: a unique ID identifying the attribute (e.g. "loginform-username") in the form
345
     * - `name`: attribute name or expression (e.g. "[0]content" for tabular input)
346
     * - `container`: the jQuery selector of the container of the input field
347
     * - `input`: the jQuery selector of the input field under the context of the form
348
     * - `error`: the jQuery selector of the error tag under the context of the container
349
     * - `status`: status of the input field, 0: empty, not entered before, 1: validated, 2: pending validation, 3: validating
350
     *
351
     * @param \yii\base\Model $model the data model being validated
352
     * @param string $attribute the name of the attribute to be validated.
353
     * @param \yii\web\View $view the view object that is going to be used to render views or view files
354
     * containing a model form with this validator applied.
355
     * @return string|null the client-side validation script. Null if the validator does not support
356
     * client-side validation.
357
     * @see getClientOptions()
358
     * @see \yii\widgets\ActiveForm::enableClientValidation
359
     */
360 1
    public function clientValidateAttribute($model, $attribute, $view)
361
    {
362 1
        return null;
363
    }
364
365
    /**
366
     * Returns the client-side validation options.
367
     * This method is usually called from [[clientValidateAttribute()]]. You may override this method to modify options
368
     * that will be passed to the client-side validation.
369
     * @param \yii\base\Model $model the model being validated
370
     * @param string $attribute the attribute name being validated
371
     * @return array the client-side validation options
372
     * @since 2.0.11
373
     */
374
    public function getClientOptions($model, $attribute)
375
    {
376
        return [];
377
    }
378
379
    /**
380
     * Returns a value indicating whether the validator is active for the given scenario and attribute.
381
     *
382
     * A validator is active if
383
     *
384
     * - the validator's `on` property is empty, or
385
     * - the validator's `on` property contains the specified scenario
386
     *
387
     * @param string $scenario scenario name
388
     * @return bool whether the validator applies to the specified scenario.
389
     */
390 26
    public function isActive($scenario)
391
    {
392 26
        return !in_array($scenario, $this->except, true) && (empty($this->on) || in_array($scenario, $this->on, true));
393
    }
394
395
    /**
396
     * Adds an error about the specified attribute to the model object.
397
     * This is a helper method that performs message selection and internationalization.
398
     * @param \yii\base\Model $model the data model being validated
399
     * @param string $attribute the attribute being validated
400
     * @param string $message the error message
401
     * @param array $params values for the placeholders in the error message
402
     */
403 92
    public function addError($model, $attribute, $message, $params = [])
404
    {
405 92
        $params['attribute'] = $model->getAttributeLabel($attribute);
406 92
        if (!isset($params['value'])) {
407 92
            $value = $model->$attribute;
408 92
            if (is_array($value)) {
409 28
                $params['value'] = 'array()';
410 90
            } elseif (is_object($value) && !method_exists($value, '__toString')) {
411 1
                $params['value'] = '(object)';
412
            } else {
413 90
                $params['value'] = $value;
414
            }
415
        }
416 92
        $model->addError($attribute, $this->formatMessage($message, $params));
417 92
    }
418
419
    /**
420
     * Checks if the given value is empty.
421
     * A value is considered empty if it is null, an empty array, or an empty string.
422
     * Note that this method is different from PHP empty(). It will return false when the value is 0.
423
     * @param mixed $value the value to be checked
424
     * @return bool whether the value is empty
425
     */
426 28
    public function isEmpty($value)
427
    {
428 28
        if ($this->isEmpty !== null) {
429
            return call_user_func($this->isEmpty, $value);
430
        } else {
431 28
            return $value === null || $value === [] || $value === '';
432
        }
433
    }
434
435
    /**
436
     * Formats a mesage using the I18N, or simple strtr if `\Yii::$app` is not available.
437
     * @param string $message
438
     * @param array $params
439
     * @since 2.0.12
440
     * @return string
441
     */
442 171
    protected function formatMessage($message, $params)
443
    {
444 171
        if (Yii::$app !== null) {
445 50
            return \Yii::$app->getI18n()->format($message, $params, Yii::$app->language);
446
        }
447
448 121
        $placeholders = [];
449 121
        foreach ((array) $params as $name => $value) {
450 121
            $placeholders['{' . $name . '}'] = $value;
451
        }
452
453 121
        return ($placeholders === []) ? $message : strtr($message, $placeholders);
454
    }
455
456
    /**
457
     * Returns cleaned attribute names without the `!` character at the beginning
458
     * @return array attribute names.
459
     * @since 2.0.12
460
     */
461
    public function getAttributeNames()
462
    {
463 30
        return array_map(function($attribute) {
464 29
            return ltrim($attribute, '!');
465 30
        }, $this->attributes);
466
    }
467
}
468