Passed
Branch master (d58e91)
by refat
04:17
created

Validation::checkForErrorsInCharactersMethods()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 2
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace System;
4
5
use System\Date;
6
use System\Characters;
7
8
class Validation
9
{
10
  /**
11
   * Application Object
12
   *
13
   * @var \System\Application
14
   */
15
  private $app;
16
17
  /**
18
   * Input name
19
   *
20
   * @var string
21
   */
22
  private $input;
23
24
  /**
25
   * Input value
26
   *
27
   * @var string
28
   */
29
  private $value;
30
31
  /**
32
   * Errors container
33
   *
34
   * @var array
35
   */
36
  private $errors = [];
37
38
  /**
39
   * Constructor
40
   *
41
   * @param \System\Application $app
42
   */
43
  public function __construct(Application $app)
44
  {
45
    $this->app = $app;
46
  }
47
48
  public function input($input, $request = 'post')
49
  {
50
    $this->input = $input;
51
52
    $this->value = $this->app->request->$request($this->input);
53
54
    return $this;
55
  }
56
57
  /**
58
   * Get the value for the input name
59
   *
60
   * @return mixed
61
   */
62
  private function value()
63
  {
64
    return mb_strtolower($this->value);
65
  }
66
67
  /**
68
   * Determine if the input is not empty
69
   *
70
   * @param bool $call
71
   * @param string $msg
72
   * @return $this
73
   */
74
  public function require($call = true, $msg = null)
75
  {
76
    if ($call === false) return $this;
77
78
    $value = $this->value();
79
80
    if ($value === '' || $value === null) {
81
      $msg = $msg ?: 'this field is required';
82
83
      $this->addError($this->input, $msg);
84
    }
85
    return $this;
86
  }
87
88
  /**
89
   * Call the function by given $type
90
   *
91
   * @param string $type
92
   * @return function
0 ignored issues
show
Bug introduced by
The type System\function 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...
93
   */
94
  public function type($type)
95
  {
96
    return $this->$type();
97
  }
98
99
  /**
100
   * Determine if the input is valid email
101
   *
102
   * @param bool $call
103
   * @param string $msg
104
   * @return $this
105
   */
106
  public function email($call = true, $msg = null)
107
  {
108
    if ($call === false) return $this;
109
110
    $value = $this->value();
111
112
    if (!$value && $value != '0') return $this;
113
114
    if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
115
      $msg = $msg ?: 'e-mail is not valid';
116
117
      $this->addError($this->input, $msg);
118
    }
119
    return $this;
120
  }
121
122
  /**
123
   * Determine if the input is an image
124
   *
125
   * @param bool $call
126
   * @param string $customErrorMessage
127
   * @return $this
128
   */
129
  public function image($call = true, $msg = null)
130
  {
131
    if ($call === false) return $this;
132
133
    $file = $this->app->request->file($this->input);
134
135
    if (!$file->exists()) return $this;
136
137
    if (!$file->isImage()) {
138
      $msg = $msg ?: 'image is not valid';
139
140
      $this->addError($this->input, $msg);
141
    }
142
    return $this;
143
  }
144
145
  /**
146
   * Determine if the input has number
147
   *
148
   * @param bool $call
149
   * @param string $msg
150
   * @return $this
151
   */
152
  public function number($call = true, $msg = null)
153
  {
154
    if ($call === false) return $this;
155
156
    $value = $this->value();
157
158
    if (!$value && $value != '0') return $this;
159
160
    if (!is_numeric($value)) {
161
      $msg = $msg ?: 'this field must be a number';
162
163
      $this->addError($this->input, $msg);
164
    }
165
    return $this;
166
  }
167
168
  /**
169
   * Determine if the input has float value
170
   *
171
   * @param bool $call
172
   * @param string $msg
173
   * @return $this
174
   */
175
  public function float($call = true, $msg = null)
176
  {
177
    if ($call === false) return $this;
178
179
    $value = $this->value();
180
181
    if (!$value && $value != '0') return $this;
182
183
    if (!is_float($value)) {
0 ignored issues
show
introduced by
The condition is_float($value) is always false.
Loading history...
184
      $msg = $msg ?: "this field must be a float number";
185
186
      $this->addError($this->input, $msg);
187
    }
188
    return $this;
189
  }
190
191
  /**
192
   * Determine if the input is a date
193
   * Determine if the input between the range if the $options['start']
194
   * or the $options ['end'] is exists
195
   *
196
   * @param string $options
197
   * @param string $msg
198
   * @return $this
199
   */
200
  public function date($options = [], $msg = null)
201
  {
202
    if ($options === false) return $this;
0 ignored issues
show
introduced by
The condition $options === false is always false.
Loading history...
203
204
    $value = $this->value();
205
206
    if (!$value && $value != '0') return $this;
207
208
    $options = json_encode($options);
209
    $options = json_decode($options);
210
211
    extract($this->dateMethods($options));
212
213
    $date = new Date($value, $options);
214
215
    if (!$date->$method()) {
216
      $this->addError($this->input, $msg);
217
    }
218
    return $this;
219
  }
220
221
  private function dateMethods($options)
222
  {
223
    $method = null;
224
    $msg = null;
225
    if ($options->start && $options->end) {
226
      $method = 'isDateBetween';
227
      $msg = 'this field must be between ' . $options->start . ' and ' . $options->end;
228
    } elseif ($options->start) {
229
      $method = 'minimum';
230
      $msg = 'the date can\'t be under ' . $options->start;
231
    } elseif ($options->end) {
232
      $method = 'maximum';
233
      $msg = 'the date can\'t be above ' . $options->end;
234
    }
235
    return array('method' => $method, 'msg'=> $msg);
236
  }
237
238
  /**
239
   * Determine if the input has simple text
240
   *
241
   * @param bool $call
242
   * @param string $msg
243
   * @return $this
244
   */
245
  public function text($call = true, $msg = null)
246
  {
247
    if ($call === false) return $this;
248
249
    $value = $this->value();
250
251
    if (!$value && $value != '0') return $this;
252
253
    if (!is_string($value)) {
0 ignored issues
show
introduced by
The condition is_string($value) is always true.
Loading history...
254
      $msg = $msg ?: 'the field must be a text';
255
256
      $this->addError($this->input, $msg);
257
    }
258
    return $this;
259
  }
260
261
  /**
262
   * Determine if the input has pure string
263
   *
264
   * @param bool $call
265
   * @param string $msg
266
   * @return $this
267
   */
268
  public function noNumbers($call = true, $msg = null)
269
  {
270
    if ($call === false) return $this;
271
272
    $value = $this->value();
273
274
    if (!$value && $value != '0') return $this;
275
276
    if (preg_match('~[0-9]~', $value)) {
277
      $msg = $msg ?: 'numbers are not allow';
278
279
      $this->addError($this->input, $msg);
280
    }
281
282
    return $this;
283
  }
284
285
  /**
286
   * Determine if the input has pure string
287
   *
288
   * @param array $excepts
289
   * @param string $msg
290
   * @return $this
291
   */
292
  public function characters($excepts, $msg = null)
293
  {
294
    if ($excepts === false) return $this;
0 ignored issues
show
introduced by
The condition $excepts === false is always false.
Loading history...
295
296
    $value = $this->value();
297
298
    if (!$value && $value != '0') return $this;
299
300
    $characters = new Characters($excepts);
301
    $chars = $characters->getChars();
302
    $langsRegex = $characters->getLangsRegex();
303
    $languages = $characters->getLanguages();
304
    $times = $characters->getTimes();
305
    $atFirst = $characters->getAtFirst();
306
    $atEnd = $characters->getAtEnd();
307
    $between = $characters->getBetween();
308
    $methods = $this->charactersMethods([
309
      "times" => $times,
310
      "atFirst" => $atFirst,
311
      "atEnd" => $atEnd,
312
      "between" => $between,
313
      "chars" => $chars,
314
      "value" => $value,
315
    ]);
316
317
    if ($this->checkForErrorsInCharactersMethods($methods, $msg)) {
318
      return $this;
319
    }
320
321
    $re = "/^[0-9\\s$chars$langsRegex]*$/u";
322
    if (!preg_match($re, $value)) {
323
      $chars = $this->charactersFormatCharsMsg($chars);
324
      $languages = $languages ? "[ $languages ]" : '';
325
      $msg = $msg ?: "just $chars $languages letters can be used";
326
      $this->addError($this->input, $msg);
327
    }
328
    return $this;
329
  }
330
331
  private function charactersFormatCharsRegex($chars)
332
  {
333
    if (strlen($chars) > 1) {
334
      $chars = str_split($chars);
335
      $chars = "\\" . implode('|\\', $chars);
336
    }
337
    return $chars;
338
  }
339
340
  private function charactersFormatCharsMsg($chars)
341
  {
342
    $chars = explode('\\', $chars);
343
    $chars = implode('', $chars);
344
    $chars = $chars ? "[ $chars ] and" : '';
345
    return $chars;
346
  }
347
348
  private function charactersMethods($args)
349
  {
350
    extract($args);
351
    return [
352
      'charactersTimes' => [
353
        [$times, $chars, $value],
354
        'charachters are too many',
355
      ],
356
      'charactersAtFirst' => [
357
        [$atFirst, $chars, $value],
358
        'charachters cant be at the first',
359
      ],
360
      'charactersAtEnd' => [
361
        [$atEnd, $chars, $value],
362
        'charachters cant be at the end',
363
      ],
364
      'charactersBetween' => [
365
        [$between, $chars, $value],
366
        'charachters cant be between',
367
      ],
368
    ];
369
  }
370
371
  private function charactersTimes($times, $chars, $value)
372
  {
373
    if ($times > 0) {
374
      $chars = $this->charactersFormatCharsRegex($chars);
375
      $re = "/($chars)/";
376
      if (preg_match($re, $value) && preg_match_all($re, $value) > $times) {
377
        return true;
378
      }
379
      return false;
380
    }
381
  }
382
383
  private function charactersAtFirst($atFirst, $chars, $value)
384
  {
385
    if ($atFirst === false) {
386
      $chars = $this->charactersFormatCharsRegex($chars);
387
      $re = "/^($chars" . "|\\s+\\$chars)/";
388
      if (preg_match_all($re, $value)) {
389
        return true;
390
      }
391
      return false;
392
    }
393
  }
394
395
  private function charactersAtEnd($atEnd, $chars, $value)
396
  {
397
    if ($atEnd === false) {
398
      $chars = $this->charactersFormatCharsRegex($chars);
399
      $re = "/($chars" . "|\\$chars\\s+)$/";
400
      if (preg_match_all($re, $value)) {
401
        return true;
402
      }
403
      return false;
404
    }
405
  }
406
407
  private function charactersBetween($between, $chars, $value)
408
  {
409
    if ($between === false) {
410
      $chars = $this->charactersFormatCharsRegex($chars);
411
      $re = "/.+(${chars})(.+|\\s)/";
412
      if (preg_match_all($re, $value)) {
413
        return true;
414
      }
415
      return false;
416
    }
417
  }
418
419
  private function checkForErrorsInCharactersMethods($methods, $msg)
420
  {
421
    foreach ($methods as $method => $options) {
422
      if (call_user_func_array(array($this, $method), $options[0])) {
423
        $msg = $msg ?: $options[1];
424
        $this->addError($this->input, $msg);
425
        return true;
426
      }
427
    }
428
    return false;
429
  }
430
431
  /**
432
   * Determine if the input has spaces between the letters or the words
433
   *
434
   * @param bool $call
435
   * @param string $msg
436
   * @return $this
437
   */
438
  public function noSpaces($call = true, $msg = null)
439
  {
440
    if ($call === false) return $this;
441
442
    $value = $this->value();
443
444
    if (!$value && $value != '0') return $this;
445
446
    if (preg_match('/\s/', $value)) {
447
      $msg = $msg ?: 'spaces are not allow';
448
449
      $this->addError($this->input, $msg);
450
    }
451
    return $this;
452
  }
453
454
  /**
455
   * Determine if the given input has the value that are passed
456
   *
457
   * @param array $characters
458
   * @param string $msg
459
   * @return $this
460
   */
461
  public function containJust($characters = [], $msg = null)
462
  {
463
    if ($characters === false) return $this;
0 ignored issues
show
introduced by
The condition $characters === false is always false.
Loading history...
464
465
    $value = $this->value();
466
467
    if (!$value && $value != '0') return $this;
468
469
    if (!is_array($characters) && $characters !== '') {
0 ignored issues
show
introduced by
The condition is_array($characters) is always true.
Loading history...
470
      $characters = [$characters];
471
    }
472
473
    $path = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $path is dead and can be removed.
Loading history...
474
    $indexes = null;
0 ignored issues
show
Unused Code introduced by
The assignment to $indexes is dead and can be removed.
Loading history...
475
476
    $files = [];
477
    $final = [];
478
479
    foreach ($characters as $key => $character) {
480
      if (strpos($character, 'path:') === 0) {
481
        unset($characters[$key]);
482
483
        $path = substr($character, 5);
484
485
        $getFrom = 'value';
486
487
        if (strpos($path, '::')) {
488
          list($path, $getFrom) = explode('::', $path);
489
        }
490
491
        if (strpos($path, ':[')) {
492
          list($path, $indexes) = explode(':[', $path);
493
494
          $indexes = rtrim($indexes, ']');
495
496
          if (strpos($indexes, '][')) {
497
            $indexesInFiles = [];
498
499
            $indexes = explode('][', $indexes);
500
501
            foreach ($indexes as $index) {
502
              if (!empty($indexesInFiles)) {
503
                $indexesInFiles = $indexesInFiles[$index];
504
505
              } else {
506
                $indexesInFiles = $this->app->file->call($path . '.php')[$index];
507
              }
508
            }
509
            $files += $indexesInFiles;
510
          } else {
511
            $files += $this->app->file->call($path . '.php')[$indexes];
512
          }
513
        } else {
514
          $files += $this->app->file->call($path . '.php');
515
        }
516
        if ($getFrom === 'keys') {
517
          $final += array_keys($files);
518
        } else {
519
          $final += array_values($files);
520
        }
521
      } else {
522
        array_push($final, $character);
523
      }
524
    }
525
526
    if (!in_array($value, $final)) {
527
      $msg = $msg ?: 'wrong value';
528
529
      $this->addError($this->input, $msg);
530
    }
531
    return $this;
532
  }
533
534
  /**
535
   * Determine if the input value should equal length
536
   *
537
   * @param int $length
538
   * @param string $msg
539
   * @return $this
540
   */
541
  public function length($length = null, $msg = null)
542
  {
543
    if ($length === false) return $this;
0 ignored issues
show
introduced by
The condition $length === false is always false.
Loading history...
544
545
    $value = $this->value();
546
547
    if (!$value && $value != '0') return $this;
548
549
    if (strlen($value) !== $length) {
550
      $msg = $msg ?: `this field can be just ${length} charachter`;
551
552
      $this->addError($this->input, $msg);
553
    }
554
    return $this;
555
  }
556
557
  /**
558
   * Determine if the input value should be at most the given length
559
   *
560
   * @param int $length
561
   * @param string $msg
562
   * @return $this
563
   */
564
  public function maxLen($length = null, $msg = null)
565
  {
566
    if ($length === false) return $this;
0 ignored issues
show
introduced by
The condition $length === false is always false.
Loading history...
567
568
    $value = $this->value();
569
570
    if (!$value && $value != '0') return $this;
571
572
    if (strlen($value) > $length) {
573
      $msg = $msg ?: "this field can be maximum $length charachter";
574
575
      $this->addError($this->input, $msg);
576
    }
577
    return $this;
578
  }
579
580
  /**
581
   * Determine if the input value should be at least the given length
582
   *
583
   * @param int $length
584
   * @param string $msg
585
   * @return $this
586
   */
587
  public function minLen($length = null, $msg = null)
588
  {
589
    if ($length === false) return $this;
0 ignored issues
show
introduced by
The condition $length === false is always false.
Loading history...
590
591
    $value = $this->value();
592
593
    if (!$value && $value != '0') return $this;
594
595
    if (strlen($value) < $length) {
596
      $msg = $msg ?: "this field can be minimum $length charachter";
597
598
      $this->addError($this->input, $msg);
599
    }
600
    return $this;
601
  }
602
603
  /**
604
   * Determine if the $input matches the given input
605
   *
606
   * @param string $input
607
   * @param string $msg
608
   * @return $this
609
   */
610
  public function match($input, $msg = null)
611
  {
612
    if ($input === false) return $this;
0 ignored issues
show
introduced by
The condition $input === false is always false.
Loading history...
613
614
    $value = $this->value();
615
616
    $valueConfirm = $this->app->request->post($input);
617
618
    if ($value && $valueConfirm) {
619
      if ($value !== $valueConfirm) {
620
        $msg = $msg ?: 'passwords doesn\'t match';
621
622
        $this->addError('match', $msg);
623
      }
624
    }
625
    return $this;
626
  }
627
628
  /**
629
   * Determine if the input is unique in database
630
   *
631
   * @param array $data
632
   * @param string $msg
633
   * @return $this
634
   */
635
  public function unique($data = [], $msg = null)
636
  {
637
    if ($data === false) return $this;
0 ignored issues
show
introduced by
The condition $data === false is always false.
Loading history...
638
639
    $value = $this->value();
640
641
    if (!$data) return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
642
643
    if (is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always true.
Loading history...
644
      list($table, $column) = $data;
645
    } else {
646
      $table = $data;
647
      $column = $this->input;
648
    }
649
650
    $result = $this->app->db->select($column)->from($table)->where($column . ' = ? ', $value)->fetch();
651
652
    if ($result) {
653
      $msg = $msg ?: sprintf('%s is already exist', ucfirst($this->input));
654
655
      $this->addError($this->input, $msg);
656
    }
657
    return $this;
658
  }
659
660
  /**
661
   * Determine if all inputs are valid
662
   *
663
   * @return bool
664
   */
665
  public function passes()
666
  {
667
    return empty($this->errors);
668
  }
669
670
  /**
671
   * Determine if there are any invalid inputs
672
   *
673
   * @return bool
674
   */
675
  public function fails()
676
  {
677
    return !empty($this->errors);
678
  }
679
680
  /**
681
   * Determine if the given input has previous errors
682
   *
683
   * @param string $input
684
   */
685
  private function hasError($input)
686
  {
687
    return array_key_exists($input, $this->errors);
688
  }
689
690
  /**
691
   * Add input error
692
   *
693
   * @param string $inputName
694
   * @param string $msg
695
   * @return void
696
   */
697
  public function addError($input, $msg)
698
  {
699
    if (!$this->hasError($input)) $this->errors[$input] = $msg;
700
  }
701
702
  /**
703
   * Get all errors
704
   *
705
   * @return array
706
   */
707
  public function getErrors()
708
  {
709
    return $this->errors;
710
  }
711
}
712