Chain::datetime()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
/**
3
 * Particle.
4
 *
5
 * @link      http://github.com/particle-php for the canonical source repository
6
 * @copyright Copyright (c) 2005-2016 Particle (http://particle-php.com)
7
 * @license   https://github.com/particle-php/validator/blob/master/LICENSE New BSD License
8
 */
9
namespace Particle\Validator;
10
11
use Particle\Validator\Output\Structure;
12
use Particle\Validator\Output\Subject;
13
use Particle\Validator\Value\Container;
14
15
/**
16
 * Represents a collection of Rules which may break the chain of validation (but usually don't).
17
 *
18
 * @package Particle\Validator
19
 */
20
class Chain
21
{
22
    /**
23
     * The key we want to validate.
24
     *
25
     * @var string
26
     */
27
    protected $key;
28
29
    /**
30
     * The name that we can use in error messages.
31
     *
32
     * @var string
33
     */
34
    protected $name;
35
36
    /**
37
     * The array of all rules for this chain.
38
     *
39
     * @var Rule[]
40
     */
41
    protected $rules = [];
42
43
    /**
44
     * The message stack to append messages to.
45
     *
46
     * @var MessageStack
47
     */
48
    protected $messageStack;
49
50
    /**
51
     * Construct the chain.
52
     *
53
     * @param string $key
54
     * @param string $name
55
     * @param bool $required
56
     * @param bool $allowEmpty
57
     */
58 264
    public function __construct($key, $name, $required, $allowEmpty)
59
    {
60 264
        $this->key = $key;
61 264
        $this->name = $name;
62
63 264
        $this->addRule(new Rule\Required($required));
64 264
        $this->addRule(new Rule\NotEmpty($allowEmpty));
65 264
    }
66
67
    /**
68
     * Overwrite the default __clone behaviour to make sure the rules are cloned too.
69
     */
70 3
    public function __clone()
71
    {
72 3
        $rules = [];
73 3
        foreach ($this->rules as $rule) {
74 3
            $rules[] = clone $rule;
75 3
        }
76 3
        $this->rules = $rules;
77 3
    }
78
79
    /**
80
     * Set a callable or boolean value which may be used to alter the allow empty requirement on validation time.
81
     *
82
     * This may be incredibly helpful when doing conditional validation.
83
     *
84
     * @param callable|bool $allowEmpty
85
     * @return $this
86
     */
87 11
    public function allowEmpty($allowEmpty)
88
    {
89 11
        $this->getNotEmptyRule()->setAllowEmpty($allowEmpty);
90 11
        return $this;
91
    }
92
93
    /**
94
     * Validate the value to consist only out of alphanumeric characters.
95
     *
96
     * @param bool $allowWhitespace
97
     * @return $this
98
     */
99 9
    public function alnum($allowWhitespace = Rule\Alnum::DISALLOW_SPACES)
100
    {
101 9
        return $this->addRule(new Rule\Alnum($allowWhitespace));
102
    }
103
104
    /**
105
     * Validate that the value only consists our of alphabetic characters.
106
     *
107
     * @param bool $allowWhitespace
108
     * @return $this
109
     */
110 7
    public function alpha($allowWhitespace = Rule\Alpha::DISALLOW_SPACES)
111
    {
112 7
        return $this->addRule(new Rule\Alpha($allowWhitespace));
113
    }
114
115
    /**
116
     * Validate that the value is between $min and $max (inclusive).
117
     *
118
     * @param int $min
119
     * @param int $max
120
     * @return $this
121
     */
122 8
    public function between($min, $max)
123
    {
124 8
        return $this->addRule(new Rule\Between($min, $max));
125
    }
126
127
    /**
128
     * Validate that the value is a boolean.
129
     *
130
     * @return $this
131
     */
132 9
    public function bool()
133 1
    {
134 9
        return $this->addRule(new Rule\Boolean());
135
    }
136
137
    /**
138
     * Validate by executing a callback function, and returning its result.
139
     *
140
     * @param callable $callable
141
     * @return $this
142
     */
143 5
    public function callback(callable $callable)
144
    {
145 5
        return $this->addRule(new Rule\Callback($callable));
146
    }
147
148
    /**
149
     * Validates that the value is a valid credit card number.
150
     * @return $this
151
     */
152 15
    public function creditCard()
153
    {
154 15
        return $this->addRule(new Rule\CreditCard());
155
    }
156
157
    /**
158
     * Validates that the value is a date. If format is passed, it *must* be in that format.
159
     *
160
     * @param string|null $format
161
     * @return $this
162
     */
163 10
    public function datetime($format = null)
164
    {
165 10
        return $this->addRule(new Rule\Datetime($format));
166
    }
167
168
    /**
169
     * Validates that all characters of the value are decimal digits.
170
     *
171
     * @return $this
172
     */
173 4
    public function digits()
174
    {
175 4
        return $this->addRule(new Rule\Digits());
176
    }
177
178
    /**
179
     * Validates a value to be a nested array, which can then be validated using a new Validator instance.
180
     *
181
     * @param callable $callback
182
     * @return $this
183
     */
184 6
    public function each(callable $callback)
185
    {
186 6
        return $this->addRule(new Rule\Each($callback));
187
    }
188
189
    /**
190
     * Validates that the value is a valid email address (format only).
191
     * @return $this
192
     */
193 7
    public function email()
194
    {
195 7
        return $this->addRule(new Rule\Email());
196
    }
197
198
    /**
199
     * Validates that the value is equal to $value.
200
     *
201
     * @param string $value
202
     * @return $this
203
     */
204 2
    public function equals($value)
205
    {
206 2
        return $this->addRule(new Rule\Equal($value));
207
    }
208
209
    /**
210
     * Validates that the value represents a float.
211
     *
212
     * @return $this
213
     */
214 9
    public function float()
215
    {
216 9
        return $this->addRule(new Rule\IsFloat());
217
    }
218
219
    /**
220
     * Validates that the value is greater than $value.
221
     *
222
     * @param int $value
223
     * @return $this
224
     */
225 3
    public function greaterThan($value)
226
    {
227 3
        return $this->addRule(new Rule\GreaterThan($value));
228
    }
229
230
    /**
231
     * Validates that the value is in the array with optional "loose" checking.
232
     *
233
     * @param string $hashAlgorithm
234
     * @param bool $allowUppercase
235
     * @return $this
236
     * @see \Particle\Validator\Rule\Hash
237
     */
238 12
    public function hash($hashAlgorithm, $allowUppercase = Rule\Hash::DISALLOW_UPPERCASE)
239
    {
240 12
        return $this->addRule(new Rule\Hash($hashAlgorithm, $allowUppercase));
241
    }
242
243
    /**
244
     * Validates that the value is in the array with optional "loose" checking.
245
     *
246
     * @param array $array
247
     * @param bool $strict
248
     * @return $this
249
     */
250 6
    public function inArray(array $array, $strict = Rule\InArray::STRICT)
251
    {
252 6
        return $this->addRule(new Rule\InArray($array, $strict));
253
    }
254
255
    /**
256
     * Validates the value represents a valid integer
257
     *
258
     * @param bool $strict
259
     * @return $this
260
     * @see \Particle\Validator\Rule\Integer
261
     */
262 18
    public function integer($strict = false)
263
    {
264 18
        return $this->addRule(new Rule\Integer($strict));
265
    }
266
267
    /**
268
     * Validates the value is an array
269
     *
270
     * @return $this
271
     * @see \Particle\Validator\Rule\IsArray
272
     */
273 7
    public function isArray()
274
    {
275 7
        return $this->addRule(new Rule\IsArray());
276
    }
277
278
    /**
279
     * Validates that the value represents a valid JSON string
280
     *
281
     * @return $this
282
     * @see \Particle\Validator\Rule\Json
283
     */
284 11
    public function json()
285
    {
286 11
        return $this->addRule(new Rule\Json());
287
    }
288
289
    /**
290
     * Validate the value to be of precisely length $length.
291
     *
292
     * @param int $length
293
     * @return $this
294
     */
295 13
    public function length($length)
296
    {
297 13
        return $this->addRule(new Rule\Length($length));
298
    }
299
300
    /**
301
     * Validates that the length of the value is between $min and $max.
302
     *
303
     * If $max is null, it has no upper limit. The default is inclusive.
304
     *
305
     * @param int $min
306
     * @param int|null $max
307
     * @return $this
308
     */
309 9
    public function lengthBetween($min, $max)
310
    {
311 9
        return $this->addRule(new Rule\LengthBetween($min, $max));
312
    }
313
314
    /**
315
     * Validates that the value is less than $value.
316
     *
317
     * @param int $value
318
     * @return $this
319
     */
320 3
    public function lessThan($value)
321
    {
322 3
        return $this->addRule(new Rule\LessThan($value));
323
    }
324
325
    /**
326
     * Mount a rule object onto this chain.
327
     *
328
     * @param Rule $rule
329
     * @return $this
330
     */
331 12
    public function mount(Rule $rule)
332
    {
333 12
        return $this->addRule($rule);
334
    }
335
336
    /**
337
     * Validates that the value is either a integer or a float.
338
     *
339
     * @return $this
340
     */
341 11
    public function numeric()
342
    {
343 11
        return $this->addRule(new Rule\Numeric());
344
    }
345
346
    /**
347
     * Validates that the value is a valid phone number for $countryCode.
348
     *
349
     * @param string $countryCode
350
     * @see \Particle\Validator\Rule\Phone
351
     * @return $this
352
     */
353 13
    public function phone($countryCode)
354
    {
355 13
        return $this->addRule(new Rule\Phone($countryCode));
356
    }
357
358
    /**
359
     * Validates that the value matches the regular expression $regex.
360
     *
361
     * @param string $regex
362
     * @return $this
363
     */
364 2
    public function regex($regex)
365
    {
366 2
        return $this->addRule(new Rule\Regex($regex));
367
    }
368
369
    /**
370
     * Set a callable or boolean value which may be used to alter the required requirement on validation time.
371
     *
372
     * This may be incredibly helpful when doing conditional validation.
373
     *
374
     * @param callable|bool $required
375
     * @return $this
376
     */
377 5
    public function required($required)
378
    {
379 5
        $this->getRequiredRule()->setRequired($required);
380 5
        return $this;
381
    }
382
383
    /**
384
     * Validates that the value represents a string.
385
     *
386
     * @return $this
387
     */
388 5
    public function string()
389
    {
390 5
        return $this->addRule(new Rule\IsString());
391
    }
392
393
    /**
394
     * Validates that the value is a valid URL. The schemes array is to selectively whitelist URL schemes.
395
     *
396
     * @param array $schemes
397
     * @return $this
398
     */
399 7
    public function url(array $schemes = [])
400
    {
401 7
        return $this->addRule(new Rule\Url($schemes));
402
    }
403
404
    /**
405
     * Validates that the value is a valid UUID
406
     *
407
     * @param int $version
408
     * @return $this
409
     */
410 42
    public function uuid($version = Rule\Uuid::UUID_VALID)
411
    {
412 42
        return $this->addRule(new Rule\Uuid($version));
413
    }
414
415
    /**
416
     * Attach a representation of this Chain to the Output\Structure $structure.
417
     *
418
     * @internal
419
     * @param Structure $structure
420
     * @param MessageStack $messageStack
421
     * @return Structure
422
     */
423 2
    public function output(Structure $structure, MessageStack $messageStack)
424
    {
425 2
        $subject = new Subject($this->key, $this->name);
426
427 2
        foreach ($this->rules as $rule) {
428 2
            $rule->output($subject, $messageStack);
429 2
        }
430
431 2
        $structure->addSubject($subject);
432
433 2
        return $structure;
434
    }
435
436
    /**
437
     * Validates the values in the $values array and appends messages to $messageStack. Returns the result as a bool.
438
     *
439
     * @param MessageStack $messageStack
440
     * @param Container $input
441
     * @param Container $output
442
     * @return bool
443
     */
444 259
    public function validate(MessageStack $messageStack, Container $input, Container $output)
445
    {
446 259
        $valid = true;
447 259
        foreach ($this->rules as $rule) {
448 259
            $rule->setMessageStack($messageStack);
449 259
            $rule->setParameters($this->key, $this->name);
450
451 259
            $valid = $rule->isValid($this->key, $input) && $valid;
452
453 259
            if (!$valid && $rule->shouldBreakChainOnError() || $rule->shouldBreakChain()) {
454 50
                break;
455
            }
456 259
        }
457
458 259
        if ($valid && $input->has($this->key)) {
459 140
            $output->set($this->key, $input->get($this->key));
460 140
        }
461 259
        return $valid;
462
    }
463
464
    /**
465
     * Shortcut method for storing a rule on this chain, and returning the chain.
466
     *
467
     * @param Rule $rule
468
     * @return $this
469
     */
470 264
    protected function addRule(Rule $rule)
471
    {
472 264
        $this->rules[] = $rule;
473
474 264
        return $this;
475
    }
476
477
    /**
478
     * Returns the first rule, which is always the required rule.
479
     *
480
     * @return Rule\Required
481
     */
482 5
    protected function getRequiredRule()
483
    {
484 5
        return $this->rules[0];
485
    }
486
487
    /**
488
     * Returns the second rule, which is always the allow empty rule.
489
     *
490
     * @return Rule\NotEmpty
491
     */
492 11
    protected function getNotEmptyRule()
493
    {
494 11
        return $this->rules[1];
495
    }
496
}
497