Passed
Branch master (d9287e)
by refat
05:38
created

Characters::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 11
nc 1
nop 2
dl 0
loc 14
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace System\Validation;
4
5
class Characters
6
{
7
  private $excepts;
8
  private $chars;
9
  private $times;
10
  private $atFirst;
11
  private $atEnd;
12
  private $between;
13
  private $langsRegex;
14
  private $languages;
15
16
  /**
17
   * Constructor
18
   *
19
   */
20
  public function __construct($excepts, $value)
21
  {
22
    $this->excepts = $excepts;
23
    $this->chars = $this->excepts->chars->value ?? $this->excepts->chars->chars ?? null;
24
    $this->times = $this->excepts->chars->times ?? null;
25
    $this->atFirst = $this->excepts->chars->atFirst ?? null;
26
    $this->atEnd = $this->excepts->chars->atEnd ?? null;
27
    $this->between = $this->excepts->chars->between ?? null;
28
    $this->languages = $this->excepts->languages ?? 'english';
29
    $this->langsRegex = $this->excepts->languages ?? $this->languagesArray('english');
30
    $this->value = $value ?? null;
0 ignored issues
show
Bug Best Practice introduced by
The property value does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
31
32
    $this->setChars();
33
    $this->setLanguages();
34
  }
35
36
  private function isExcepts()
37
  {
38
    return is_object($this->excepts) && count((array) $this->excepts);
39
  }
40
41
  private function isCharsString()
42
  {
43
    return is_string($this->chars);
44
  }
45
46
  private function isCharsAnArray()
47
  {
48
    return is_array($this->chars);
49
  }
50
51
  private function canCharsSeparateViaComma()
52
  {
53
    return preg_match('/,/', $this->chars) && preg_match_all('/,/', $this->chars) > 1;
54
  }
55
56
  private function formatCharsViaComma($comma)
57
  {
58
    if ($comma) {
59
      $chars = explode(',', $this->chars);
60
    } else {
61
      $chars = str_split($this->chars);
62
    }
63
    return "\\" . implode('\\', $chars);
64
  }
65
66
  private function formatCharsString()
67
  {
68
    if ($this->canCharsSeparateViaComma()) {
69
      return $this->formatCharsViaComma(true);
70
    } else {
71
      return $this->formatCharsViaComma(false);
72
    }
73
  }
74
75
  private function formatCharsArray()
76
  {
77
    return implode('', (array) $this->chars);
78
  }
79
80
  private function setChars()
81
  {
82
    if ($this->isExcepts()) {
83
      if ($this->isCharsString()) {
84
        $this->chars = $this->formatCharsString();
85
      } else if ($this->isCharsAnArray()) {
86
        $this->chars = $this->formatCharsArray();
87
      }
88
    }
89
  }
90
91
  private function languagesArray($language)
92
  {
93
    $languages = [
94
      'all' => '\\p{L}',
95
      'arabic' =>  '\\x{0621}-\\x{064A}\\x{0660}-\\x{0669} ُ ْ َ ِ ّ~ ً ٍ ٌ',
96
      'english' => 'a-z',
97
      'spanish' => 'a-zñ',
98
      'french' => 'a-zàâçéèêëîïôûùüÿñæœ',
99
      'german' => 'a-zäüöß',
100
    ];
101
    return $languages[$language] ?? $languages['english'];
102
  }
103
104
  private function isLangsAnArray()
105
  {
106
    return is_array($this->languages);
107
  }
108
109
  private function isLangsAnString()
110
  {
111
    return is_string($this->languages);
112
  }
113
114
  private function canlangsSeparateViaComma()
115
  {
116
    return preg_match('/,/', $this->languages) && preg_match_all('/,/', $this->languages);
117
  }
118
119
  private function loopOverLangsViaComma($comma)
120
  {
121
    $loopLangs = $comma ? explode(',', $this->languages) : $this->languages;
122
    $langsRegex = '';
123
    $languages = '';
124
    foreach ($loopLangs as $language) {
125
      $langsRegex .= $this->languagesArray(trim($language));
126
      $languages .= "$language, ";
127
    }
128
    $languages = rtrim($languages, ", ");
129
    return array('languages' => $languages, 'langsRegex' => $langsRegex);
130
  }
131
132
  private function formatLangsString()
133
  {
134
    if ($this->canlangsSeparateViaComma()) {
135
      extract($this->loopOverLangsViaComma(true));
136
    } else {
137
      $langsRegex = $this->languagesArray(trim($this->languages));
138
      $languages = $this->languages;
139
    }
140
    return array('languages' => $languages, 'langsRegex' => $langsRegex);
141
  }
142
143
  private function setLanguages()
144
  {
145
    if ($this->isLangsAnArray()) {
146
      extract($this->loopOverLangsViaComma(false));
147
    } else if ($this->isLangsAnString()) {
148
      extract($this->formatLangsString());
149
    }
150
    $this->languages = $languages;
151
    $this->langsRegex = $langsRegex;
152
    $this->formatLangsRegex();
153
  }
154
155
  private function formatLangsRegex()
156
  {
157
    if ($this->langsRegex !== 'all' && preg_match_all('/a-z/i', $this->langsRegex) > 1) {
158
      $this->langsRegex = preg_replace('/a-z/', '', $this->langsRegex) . 'a-z';
159
    }
160
  }
161
162
  public function variables()
163
  {
164
    $chars = $this->chars;
165
    $langsRegex = $this->langsRegex;
166
    $languages = $this->languages;
167
    $times = $this->times;
168
    $atFirst = $this->atFirst;
169
    $atEnd = $this->atEnd;
170
    $between = $this->between;
171
    $methods = $this->charactersMethods([
172
      "times" => $times,
173
      "atFirst" => $atFirst,
174
      "atEnd" => $atEnd,
175
      "between" => $between,
176
      "chars" => $chars,
177
      "value" => $this->value,
178
    ]);
179
    return [
180
      'chars' => $chars,
181
      'langsRegex' => $langsRegex,
182
      'languages' => $languages,
183
      'times' => $times,
184
      'atFirst' => $atFirst,
185
      'atEnd' => $atEnd,
186
      'between' => $between,
187
      'methods' => $methods,
188
    ];
189
  }
190
191
  private function charactersMethods($args)
192
  {
193
    extract($args);
194
    return [
195
      'charactersTimes' => [
196
        [$times, $chars, $value],
197
        'charachters are too many',
198
      ],
199
      'charactersAtFirst' => [
200
        [$atFirst, $chars, $value],
201
        'charachters cant be at the first',
202
      ],
203
      'charactersAtEnd' => [
204
        [$atEnd, $chars, $value],
205
        'charachters cant be at the end',
206
      ],
207
      'charactersBetween' => [
208
        [$between, $chars, $value],
209
        'charachters cant be between',
210
      ],
211
    ];
212
  }
213
214
  private function charactersFormatCharsRegex($chars)
215
  {
216
    if (strlen($chars) > 1) {
217
      $chars = str_split($chars);
218
      $chars = "\\" . implode('|\\', $chars);
219
    }
220
    return $chars;
221
  }
222
223
  public function charactersAtFirst($atFirst, $chars, $value)
224
  {
225
    if ($atFirst === false) {
226
      $chars = $this->charactersFormatCharsRegex($chars);
227
      $re = "/^($chars" . "|\\s+\\$chars)/";
228
      if (preg_match_all($re, $value)) {
229
        return true;
230
      }
231
      return false;
232
    }
233
  }
234
235
  private function charactersFormatCharsMsg($chars)
236
  {
237
    $chars = explode('\\', $chars);
238
    $chars = implode('', $chars);
239
    $chars = $chars ? "[ $chars ] and" : '';
240
    return $chars;
241
  }
242
243
  public function charactersAtEnd($atEnd, $chars, $value)
244
  {
245
    if ($atEnd === false) {
246
      $chars = $this->charactersFormatCharsRegex($chars);
247
      $re = "/($chars" . "|\\$chars\\s+)$/";
248
      if (preg_match_all($re, $value)) {
249
        return true;
250
      }
251
      return false;
252
    }
253
  }
254
255
  public function charactersBetween($between, $chars, $value)
256
  {
257
    if ($between === false) {
258
      $chars = $this->charactersFormatCharsRegex($chars);
259
      $re = "/.+(${chars})(.+|\\s)/";
260
      if (preg_match_all($re, $value)) {
261
        return true;
262
      }
263
      return false;
264
    }
265
  }
266
267
  public function charactersTimes($times, $chars, $value)
268
  {
269
    if ($times > 0) {
270
      $chars = $this->charactersFormatCharsRegex($chars);
271
      $re = "/($chars)/";
272
      if (preg_match($re, $value) && preg_match_all($re, $value) > $times) {
273
        return true;
274
      }
275
      return false;
276
    }
277
  }
278
279
  public function charactersMsg($chars, $languages, $msg)
280
  {
281
    $chars = $this->charactersFormatCharsMsg($chars);
282
    $languages = $languages ? "[ $languages ]" : '';
283
    return $msg ?: "just $chars $languages letters can be used";
284
  }
285
}
286
287