Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 19 | class Validator |
||
| 20 | { |
||
| 21 | |||
| 22 | /** |
||
| 23 | * The Plexity object (contains the validation configuration) |
||
| 24 | * @var \Ballen\Plexity\Plexity |
||
| 25 | */ |
||
| 26 | private $configuration; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Numeric values list |
||
| 30 | * @var array |
||
| 31 | */ |
||
| 32 | protected $numbers = [ |
||
| 33 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 |
||
| 34 | ]; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Special Character list |
||
| 38 | * @see https://www.owasp.org/index.php/Password_special_characters |
||
| 39 | * @var array |
||
| 40 | */ |
||
| 41 | protected $specialCharacters = [ |
||
| 42 | ' ', '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '.', |
||
| 43 | '/', ':', ';', '<', '=', '>', '?', '@', '[', ']', '\\', '^', '_', '`', |
||
| 44 | '{', '|', '}', '~', |
||
| 45 | ]; |
||
| 46 | |||
| 47 | /** |
||
| 48 | * Validates all the configured rules and responds as requested. |
||
| 49 | * @return boolean |
||
| 50 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 51 | */ |
||
| 52 | 22 | public function validate(Plexity $configuration) |
|
| 64 | |||
| 65 | /** |
||
| 66 | * Checks the minimum length requirement. |
||
| 67 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 68 | */ |
||
| 69 | 22 | View Code Duplication | public function checkMinimumLength() |
| 77 | |||
| 78 | /** |
||
| 79 | * Checks the minimum maximum length requirement. |
||
| 80 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 81 | */ |
||
| 82 | 20 | View Code Duplication | public function checkMaximumLength() |
| 90 | |||
| 91 | /** |
||
| 92 | * Checks the lowercase character(s) requirement. |
||
| 93 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 94 | */ |
||
| 95 | 18 | public function checkLowerCase() |
|
| 103 | |||
| 104 | /** |
||
| 105 | * Checks the upper case character(s) requirement. |
||
| 106 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 107 | */ |
||
| 108 | 17 | public function checkUpperCase() |
|
| 116 | |||
| 117 | /** |
||
| 118 | * Checks the numeric character(s) requirement. |
||
| 119 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 120 | */ |
||
| 121 | 16 | View Code Duplication | public function checkNumericCharacters() |
| 129 | |||
| 130 | /** |
||
| 131 | * Checks the special character(s) requirement. |
||
| 132 | * @throws \Ballen\Plexity\Exceptions\ValidationException |
||
| 133 | */ |
||
| 134 | 14 | View Code Duplication | public function checkSpecialCharacters() |
| 135 | { |
||
| 136 | 14 | if ($this->configuration->rules()->get(Plexity::RULE_SPECIAL) > 0) { |
|
| 137 | 4 | if (!$this->validateSpecialCharacters()) { |
|
| 138 | 2 | throw new \Ballen\Plexity\Exceptions\ValidationException('The string failed to meet the special character requirements.'); |
|
| 139 | } |
||
| 140 | 2 | } |
|
| 141 | 12 | } |
|
| 142 | |||
| 143 | 12 | View Code Duplication | public function checkNotIn() |
| 151 | |||
| 152 | /** |
||
| 153 | * Validates the upper case requirements. |
||
| 154 | * @return boolean |
||
| 155 | */ |
||
| 156 | 2 | private function validateUpperCase() |
|
| 160 | |||
| 161 | /** |
||
| 162 | * Validates the lower case requirements. |
||
| 163 | * @return boolean |
||
| 164 | */ |
||
| 165 | 2 | private function validateLowerCase() |
|
| 169 | |||
| 170 | /** |
||
| 171 | * Validates the special character requirements. |
||
| 172 | * @return boolean |
||
| 173 | */ |
||
| 174 | 4 | private function validateSpecialCharacters() |
|
| 175 | { |
||
| 176 | 4 | if ($this->countOccurences($this->specialCharacters, $this->configuration->checkString()) >= $this->configuration->rules()->get(Plexity::RULE_SPECIAL)) { |
|
| 177 | 2 | return true; |
|
| 178 | } |
||
| 179 | 2 | return false; |
|
| 180 | } |
||
| 181 | |||
| 182 | /** |
||
| 183 | * Validates the numeric case requirements. |
||
| 184 | * @return boolean |
||
| 185 | */ |
||
| 186 | 4 | private function validateNumericCharacters() |
|
| 187 | { |
||
| 188 | 4 | if ($this->countOccurences($this->numbers, $this->configuration->checkString()) >= $this->configuration->rules()->get(Plexity::RULE_NUMERIC)) { |
|
| 189 | 2 | return true; |
|
| 190 | } |
||
| 191 | 2 | return false; |
|
| 192 | } |
||
| 193 | |||
| 194 | /** |
||
| 195 | * Validates the minimum string length requirements. |
||
| 196 | * @return boolean |
||
| 197 | */ |
||
| 198 | 6 | View Code Duplication | private function validateLengthMin() |
| 205 | |||
| 206 | /** |
||
| 207 | * Validates the maximum string length requirements. |
||
| 208 | * @return boolean |
||
| 209 | */ |
||
| 210 | 5 | View Code Duplication | private function validateLengthMax() |
| 217 | |||
| 218 | /** |
||
| 219 | * Validates the not_in requirements. |
||
| 220 | * @return boolean |
||
| 221 | */ |
||
| 222 | 2 | View Code Duplication | private function validateNotIn() |
| 229 | |||
| 230 | /** |
||
| 231 | * Count the number of occurences of a character or string in a string. |
||
| 232 | * @param array $needles The character/string to count occurences of. |
||
| 233 | * @param string $haystack The string to check against. |
||
| 234 | * @return int The number of occurences. |
||
| 235 | */ |
||
| 236 | 8 | private function countOccurences(array $needles, $haystack) |
|
| 244 | } |
||
| 245 |