Test Failed
Push — master ( 88a34f...1ce20a )
by Julien
04:37
created

Validate::addSoftDeleteValidation()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 26
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 3
eloc 13
c 2
b 1
f 0
nc 3
nop 3
dl 0
loc 26
ccs 0
cts 17
cp 0
crap 12
rs 9.8333
1
<?php
2
3
/**
4
 * This file is part of the Zemit Framework.
5
 *
6
 * (c) Zemit Team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE.txt
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Zemit\Mvc\Model;
13
14
use Zemit\Db\Column;
0 ignored issues
show
Bug introduced by
The type Zemit\Db\Column was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Zemit\Validation;
16
use Phalcon\Validation\Validator\Between;
17
use Phalcon\Validation\Validator\Date;
18
use Phalcon\Validation\Validator\InclusionIn;
19
use Phalcon\Validation\Validator\Numericality;
20
use Phalcon\Validation\Validator\PresenceOf;
21
use Phalcon\Validation\Validator\StringLength\Max;
22
use Phalcon\Validation\Validator\StringLength\Min;
23
use Phalcon\Validation\Validator\Uniqueness;
24
25
trait Validate
26
{
27
    /**
28
     * Add default basic validations
29
     * - Position
30
     * - Soft delete
31
     * - Create
32
     * - Update
33
     * - Delete
34
     * - Restore
35
     * - Uuid
36
     * - Uid
37
     * - Guid
38
     *
39
     * @param Validation|null $validator
40
     * @return Validation
41
     */
42
    public function genericValidation(?Validation $validator = null)
43
    {
44
        $validator ??= new Validation();
45
        
46
        $this->addPositionValidation($validator);
47
        $this->addSoftDeleteValidation($validator);
48
        $this->addCreatedValidation($validator);
49
        $this->addUpdatedValidation($validator);
50
        $this->addDeletedValidation($validator);
51
        $this->addRestoredValidation($validator);
52
        $this->addUuidValidation($validator, 'uid');
53
        $this->addUuidValidation($validator, 'uuid');
54
        $this->addUuidValidation($validator, 'guid');
55
        
56
        return $validator;
57
    }
58
    
59
    /**
60
     * Add basic validations for an unsigned field
61
     * - Must be numeric
62
     * - Must be an unsigned integer
63
     */
64
    public function addUnsignedIntValidation(Validation $validator, string $field = 'id', bool $allowEmpty = true): Validation
65
    {
66
        if (!$allowEmpty) {
67
            $validator->add($field, new PresenceOf([
68
                'message' => $this->_('required'),
0 ignored issues
show
Bug introduced by
It seems like _() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
                'message' => $this->/** @scrutinizer ignore-call */ _('required'),
Loading history...
69
            ]));
70
        }
71
        
72
        // Must be numeric
73
        $validator->add($field, new Numericality([
74
            'message' => $this->_('not-numeric'),
75
            'allowEmpty' => $allowEmpty,
76
        ]));
77
        
78
        // Must be an unsigned integer
79
        $validator->add($field, new Between([
80
            'minimum' => Column::MIN_UNSIGNED_INT,
81
            'maximum' => Column::MAX_UNSIGNED_INT,
82
            'message' => $this->_('not-an-unsigned-integer'),
83
            'allowEmpty' => $allowEmpty,
84
        ]));
85
        
86
        return $validator;
87
    }
88
    
89
    /**
90
     * Add basic validations for an unsigned field
91
     * - Must be numeric
92
     * - Must be an unsigned integer
93
     */
94
    public function addUnsignedBigIntValidation(Validation $validator, string $field = 'id', bool $allowEmpty = true): Validation
95
    {
96
        if (!$allowEmpty) {
97
            $validator->add($field, new PresenceOf([
98
                'message' => $this->_('required'),
99
                'allowEmpty' => false,
100
            ]));
101
        }
102
        
103
        // Must be numeric
104
        $validator->add($field, new Numericality([
105
            'message' => $this->_('not-numeric'),
106
            'allowEmpty' => true,
107
        ]));
108
        
109
        // Must be an unsigned integer
110
        $validator->add($field, new Between([
111
            'minimum' => Column::MIN_UNSIGNED_BIGINT,
112
            'maximum' => Column::MAX_UNSIGNED_BIGINT,
113
            'message' => $this->_('not-an-unsigned-big-integer'),
114
            'allowEmpty' => true,
115
        ]));
116
        
117
        return $validator;
118
    }
119
    
120
    public function addNumberValidation(Validation $validator, string $field, int $min, int $max, bool $allowEmpty = true): Validation
121
    {
122
        if (!$allowEmpty) {
123
            $validator->add($field, new PresenceOf([
124
                'message' => $this->_('required'),
125
                'allowEmpty' => false,
126
            ]));
127
        }
128
        
129
        // Must be numeric
130
        $validator->add($field, new Numericality([
131
            'message' => $this->_('not-numeric'),
132
            'allowEmpty' => true,
133
        ]));
134
        
135
        // Must be an unsigned integer
136
        $validator->add($field, new Between([
137
            'minimum' => $min,
138
            'maximum' => $max,
139
            'message' => $this->_('not-between'),
140
            'allowEmpty' => true,
141
        ]));
0 ignored issues
show
Bug Best Practice introduced by
In this branch, the function will implicitly return null which is incompatible with the type-hinted return Zemit\Validation. Consider adding a return statement or allowing null as return value.

For hinted functions/methods where all return statements with the correct type are only reachable via conditions, ?null? gets implicitly returned which may be incompatible with the hinted type. Let?s take a look at an example:

interface ReturnsInt {
    public function returnsIntHinted(): int;
}

class MyClass implements ReturnsInt {
    public function returnsIntHinted(): int
    {
        if (foo()) {
            return 123;
        }
        // here: null is implicitly returned
    }
}
Loading history...
142
    }
143
    
144
    public function addStringLengthValidation(Validation $validator, string $field, int $minChar = 0, int $maxChar = 255, bool $allowEmpty = true): Validation
145
    {
146
        if (!$allowEmpty) {
147
            $validator->add($field, new PresenceOf([
148
                'message' => $this->_('required'),
149
                'allowEmpty' => false,
150
            ]));
151
        }
152
        
153
        $validator->add($field, new Min([
154
            'min' => $minChar,
155
            'message' => $this->_('min-length'),
156
            'allowEmpty' => true,
157
        ]));
158
        
159
        $validator->add($field, new Max([
160
            'max' => $maxChar,
161
            'message' => $this->_('max-length'),
162
            'allowEmpty' => true,
163
        ]));
164
        
165
        return $validator;
166
    }
167
    
168
    public function addInclusionInValidation(Validation $validator, string $field, array $domainList = [], bool $allowEmpty = true): Validation
169
    {
170
        if (!$allowEmpty) {
171
            $validator->add($field, new PresenceOf([
172
                'message' => $this->_('required'),
173
                'allowEmpty' => false,
174
            ]));
175
        }
176
        
177
        $validator->add($field, new InclusionIn([
178
            'message' => $this->_('not-valid'),
179
            'domain' => $domainList,
180
            'allowEmpty' => true,
181
        ]));
182
        
183
        return $validator;
184
    }
185
    
186
    /**
187
     * Add boolean validation
188
     * - Must be 0, 1, true or false
189
     */
190
    public function addBooleanValidation(Validation $validator, string $field, bool $allowEmpty = true): Validation
191
    {
192
        if (!$allowEmpty) {
193
            $validator->add($field, new PresenceOf([
194
                'message' => $this->_('required'),
195
                'allowEmpty' => false,
196
            ]));
197
        }
198
        
199
        $validator->add($field, new InclusionIn([
200
            'message' => $this->_('not-boolean'),
201
            'domain' => [1, 0, true, false],
202
            'allowEmpty' => true,
203
        ]));
204
        
205
        return $validator;
206
    }
207
    
208
    /**
209
     * Add domain inclusion validation
210
     * - Must be valid value from the domain list
211
     */
212
    public function addInclusionValidation(Validation $validator, string $field, array $domain = [], bool $allowEmpty = true, bool $strict = true): Validation
213
    {
214
        if (!$allowEmpty) {
215
            $validator->add($field, new PresenceOf([
216
                'message' => $this->_('required'),
217
                'allowEmpty' => false,
218
            ]));
219
        }
220
        
221
        $validator->add($field, new InclusionIn([
222
            'message' => $this->_('not-valid'),
223
            'domain' => $domain,
224
            'strict' => $strict,
225
            'allowEmpty' => true,
226
        ]));
227
        
228
        return $validator;
229
    }
230
    
231
    /**
232
     * Add presence validation
233
     * - Must be present
234
     */
235
    public function addPresenceValidation(Validation $validator, string $field, bool $allowEmpty = true): Validation
236
    {
237
        $validator->add($field, new PresenceOf([
238
            'message' => $this->_('required'),
239
            'allowEmpty' => $allowEmpty,
240
        ]));
241
        
242
        return $validator;
243
    }
244
    
245
    /**
246
     * Add uniqueness validation
247
     * - Must be present (if allowEmpty is false)
248
     * - Must be unique
249
     */
250
    public function addUniquenessValidation(Validation $validator, string $field, bool $allowEmpty = true): Validation
251
    {
252
        if (!$allowEmpty) {
253
            $validator->add($field, new PresenceOf([
254
                'message' => $this->_('required'),
255
                'allowEmpty' => false,
256
            ]));
257
        }
258
        
259
        $validator->add($field, new Uniqueness([
260
            'message' => $this->_('not-unique'),
261
            'allowEmpty' => false,
262
        ]));
263
        
264
        return $validator;
265
    }
266
    
267
    /**
268
     * Add basic validation for the id field
269
     * - Must be an unsigned number
270
     * - Must be unique
271
     */
272
    public function addIdValidation(Validation $validator, string $field = 'id'): Validation
273
    {
274
        if (property_exists($this, $field)) {
275
            
276
            $this->addUnsignedIntValidation($validator, $field);
277
        }
278
        
279
        return $validator;
280
    }
281
    
282
    /**
283
     * Add basic validations for the position field
284
     * - Must be numeric
285
     * - Must be an unsigned integer
286
     */
287
    public function addPositionValidation(Validation $validator, string $field = 'position', bool $allowEmpty = true): Validation
288
    {
289
        if (property_exists($this, $field)) {
290
            
291
            if (!$allowEmpty) {
292
                $validator->add($field, new PresenceOf([
293
                    'message' => $this->_('required'),
294
                    'allowEmpty' => false,
295
                ]));
296
            }
297
            
298
            // Must be numeric
299
            $validator->add($field, new Numericality([
300
                'message' => $this->_('not-numeric'),
301
                'allowEmpty' => true,
302
            ]));
303
            
304
            // Must be an unsigned integer
305
            $validator->add($field, new Between([
306
                'minimum' => Column::MIN_UNSIGNED_INT,
307
                'maximum' => Column::MAX_UNSIGNED_INT,
308
                'message' => $this->_('not-an-unsigned-integer'),
309
                'allowEmpty' => true,
310
            ]));
311
        }
312
        
313
        return $validator;
314
    }
315
    
316
    /**
317
     * Add basic validations for the position field
318
     * - Must be YES or NO
319
     * - Must be numeric
320
     */
321
    public function addSoftDeleteValidation(Validation $validator, string $field = 'deleted', bool $allowEmpty = true): Validation
322
    {
323
        if (property_exists($this, $field)) {
324
            
325
            if (!$allowEmpty) {
326
                $validator->add($field, new PresenceOf([
327
                    'message' => $this->_('required'),
328
                    'allowEmpty' => false,
329
                ]));
330
            }
331
            
332
            // Must be YES or NO
333
            $validator->add($field, new InclusionIn([
334
                'message' => $this->_('not-valid'),
335
                'domain' => [Column::YES, Column::NO],
336
                'strict' => true,
337
            ]));
338
            
339
            // Must be numeric
340
            $validator->add($field, new Numericality([
341
                'message' => $this->_('not-numeric'),
342
                'allowEmpty' => true,
343
            ]));
344
        }
345
        
346
        return $validator;
347
    }
348
    
349
    /**
350
     * Add basic validations for the $field
351
     * - Must be unique
352
     * - Field is required
353
     */
354
    public function addUuidValidation(Validation $validator, string $field = 'uuid', bool $allowEmpty = false): Validation
355
    {
356
        if (property_exists($this, $field) && $this->getModelsMetaData()->hasAttribute($this, $field)) {
0 ignored issues
show
Bug introduced by
It seems like getModelsMetaData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

356
        if (property_exists($this, $field) && $this->/** @scrutinizer ignore-call */ getModelsMetaData()->hasAttribute($this, $field)) {
Loading history...
357
            
358
            // If field is required
359
            if (!$allowEmpty) {
360
                $validator->add($field, new PresenceOf([
361
                    'message' => $this->_('required'),
362
                    'allowEmpty' => false,
363
                ]));
364
            }
365
            
366
            // Must be unique
367
            $validator->add($field, new Uniqueness([
368
                'message' => $this->_('not-unique'),
369
                'allowEmpty' => true,
370
            ]));
371
        }
372
        
373
        return $validator;
374
    }
375
    
376
    /**
377
     * Add basic validations for the $userIdField and $dateField field
378
     * - $userIdField: Must be numeric
379
     * - $userIdField: Must be an unsigned integer
380
     * - $dateField: Must be a valid date
381
     */
382
    public function addCrudValidation(Validation $validator, string $userIdField, string $dateField, bool $allowEmpty = true): Validation
383
    {
384
        if (property_exists($this, $userIdField)) {
385
            
386
            if (!$allowEmpty) {
387
                $validator->add($userIdField, new PresenceOf([
388
                    'message' => $this->_('required'),
389
                    'allowEmpty' => false,
390
                ]));
391
            }
392
            
393
            // Must be numeric
394
            $validator->add($userIdField, new Numericality([
395
                'message' => $this->_('not-numeric'),
396
                'allowEmpty' => true,
397
            ]));
398
            
399
            // Must be an unsigned integer
400
            $validator->add($userIdField, new Between([
401
                'minimum' => Column::MIN_UNSIGNED_INT,
402
                'maximum' => Column::MAX_UNSIGNED_INT,
403
                'message' => $this->_('not-an-unsigned-integer'),
404
                'allowEmpty' => true,
405
            ]));
406
        }
407
        
408
        if (property_exists($this, $dateField)) {
409
            
410
            // if the $userIdField is filled
411
            if (!empty($this->readAttribute($userIdField))) {
0 ignored issues
show
Bug introduced by
It seems like readAttribute() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

411
            if (!empty($this->/** @scrutinizer ignore-call */ readAttribute($userIdField))) {
Loading history...
412
                
413
                $validator->add($dateField, new PresenceOf([
414
                    'message' => $this->_('required'),
415
                    'allowEmpty' => false,
416
                ]));
417
                
418
                // Must be a valid date format
419
                $validator->add($dateField, new Date([
420
                    'format' => Column::DATETIME_FORMAT,
421
                    'message' => $this->_('invalid-date-format'),
422
                    'allowEmpty' => true,
423
                ]));
424
            }
425
        }
426
        
427
        return $validator;
428
    }
429
    
430
    /**
431
     * Add crud validation to the user id and date field
432
     */
433
    public function addCreatedValidation(Validation $validator, string $createdByField = 'createdBy', string $createdAtField = 'createdAt', bool $allowEmpty = true): Validation
434
    {
435
        return $this->addCrudValidation($validator, $createdByField, $createdAtField, $allowEmpty);
436
    }
437
    
438
    /**
439
     * Add crud validation to the user id and date field
440
     */
441
    public function addUpdatedValidation(Validation $validator, string $updatedByField = 'updatedBy', string $updatedAtField = 'updatedAt', bool $allowEmpty = true): Validation
442
    {
443
        return $this->addCrudValidation($validator, $updatedByField, $updatedAtField, $allowEmpty);
444
    }
445
    
446
    /**
447
     * Add crud validation to the user id and date field
448
     */
449
    public function addDeletedValidation(Validation $validator, string $deletedField = 'deletedBy', string $dateField = 'deletedAt', bool $allowEmpty = true): Validation
450
    {
451
        return $this->addCrudValidation($validator, $deletedField, $dateField, $allowEmpty);
452
    }
453
    
454
    /**
455
     * Add crud validation to the user id and date field
456
     */
457
    public function addRestoredValidation(Validation $validator, string $restoredByField = 'restoredBy', string $restoredAtField = 'restoredAt', bool $allowEmpty = true): Validation
458
    {
459
        return $this->addCrudValidation($validator, $restoredByField, $restoredAtField, $allowEmpty);
460
    }
461
}
462