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:
Complex classes like Assert often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Assert, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
169 | class Assert |
||
|
|||
170 | { |
||
171 | 94 | public static function string($value, $message = '') |
|
180 | |||
181 | 16 | public static function stringNotEmpty($value, $message = '') |
|
186 | |||
187 | 17 | public static function integer($value, $message = '') |
|
188 | { |
||
189 | 17 | if (!is_int($value)) { |
|
190 | 13 | static::reportInvalidArgument(sprintf( |
|
191 | 13 | $message ?: 'Expected an integer. Got: %s', |
|
192 | 13 | static::typeToString($value) |
|
193 | )); |
||
194 | } |
||
195 | 4 | } |
|
196 | |||
197 | 16 | public static function integerish($value, $message = '') |
|
198 | { |
||
199 | 16 | if (!is_numeric($value) || $value != (int) $value) { |
|
200 | 4 | static::reportInvalidArgument(sprintf( |
|
201 | 4 | $message ?: 'Expected an integerish value. Got: %s', |
|
202 | 4 | static::typeToString($value) |
|
203 | )); |
||
204 | } |
||
205 | 12 | } |
|
206 | |||
207 | 16 | public static function float($value, $message = '') |
|
208 | { |
||
209 | 16 | if (!is_float($value)) { |
|
210 | 8 | static::reportInvalidArgument(sprintf( |
|
211 | 8 | $message ?: 'Expected a float. Got: %s', |
|
212 | 8 | static::typeToString($value) |
|
213 | )); |
||
214 | } |
||
215 | 8 | } |
|
216 | |||
217 | 20 | public static function numeric($value, $message = '') |
|
218 | { |
||
219 | 20 | if (!is_numeric($value)) { |
|
220 | 4 | static::reportInvalidArgument(sprintf( |
|
221 | 4 | $message ?: 'Expected a numeric. Got: %s', |
|
222 | 4 | static::typeToString($value) |
|
223 | )); |
||
224 | } |
||
225 | 16 | } |
|
226 | |||
227 | 24 | public static function natural($value, $message = '') |
|
228 | { |
||
229 | 24 | if (!is_int($value) || $value < 0) { |
|
230 | 16 | static::reportInvalidArgument(sprintf( |
|
231 | 16 | $message ?: 'Expected a non-negative integer. Got %s', |
|
232 | 16 | static::valueToString($value) |
|
233 | )); |
||
234 | } |
||
235 | 8 | } |
|
236 | |||
237 | 16 | public static function boolean($value, $message = '') |
|
238 | { |
||
239 | 16 | if (!is_bool($value)) { |
|
240 | 8 | static::reportInvalidArgument(sprintf( |
|
241 | 8 | $message ?: 'Expected a boolean. Got: %s', |
|
242 | 8 | static::typeToString($value) |
|
243 | )); |
||
244 | } |
||
245 | 8 | } |
|
246 | |||
247 | 23 | public static function scalar($value, $message = '') |
|
248 | { |
||
249 | 23 | if (!is_scalar($value)) { |
|
250 | 11 | static::reportInvalidArgument(sprintf( |
|
251 | 11 | $message ?: 'Expected a scalar. Got: %s', |
|
252 | 11 | static::typeToString($value) |
|
253 | )); |
||
254 | } |
||
255 | 12 | } |
|
256 | |||
257 | 23 | public static function object($value, $message = '') |
|
258 | { |
||
259 | 23 | if (!is_object($value)) { |
|
260 | 15 | static::reportInvalidArgument(sprintf( |
|
261 | 15 | $message ?: 'Expected an object. Got: %s', |
|
262 | 15 | static::typeToString($value) |
|
263 | )); |
||
264 | } |
||
265 | 8 | } |
|
266 | |||
267 | 16 | public static function resource($value, $type = null, $message = '') |
|
284 | |||
285 | 20 | public static function isCallable($value, $message = '') |
|
286 | { |
||
287 | 20 | if (!is_callable($value)) { |
|
288 | 8 | static::reportInvalidArgument(sprintf( |
|
289 | 8 | $message ?: 'Expected a callable. Got: %s', |
|
290 | 8 | static::typeToString($value) |
|
291 | )); |
||
292 | } |
||
293 | 12 | } |
|
294 | |||
295 | 20 | public static function isArray($value, $message = '') |
|
296 | { |
||
297 | 20 | if (!is_array($value)) { |
|
298 | 12 | static::reportInvalidArgument(sprintf( |
|
299 | 12 | $message ?: 'Expected an array. Got: %s', |
|
300 | 12 | static::typeToString($value) |
|
301 | )); |
||
302 | } |
||
303 | 8 | } |
|
304 | |||
305 | 20 | public static function isTraversable($value, $message = '') |
|
322 | |||
323 | 20 | View Code Duplication | public static function isArrayAccessible($value, $message = '') |
332 | |||
333 | 24 | View Code Duplication | public static function isCountable($value, $message = '') |
342 | |||
343 | 616 | View Code Duplication | public static function isIterable($value, $message = '') |
352 | |||
353 | 16 | public static function isInstanceOf($value, $class, $message = '') |
|
354 | { |
||
355 | 16 | if (!($value instanceof $class)) { |
|
356 | 12 | static::reportInvalidArgument(sprintf( |
|
357 | 12 | $message ?: 'Expected an instance of %2$s. Got: %s', |
|
358 | 12 | static::typeToString($value), |
|
359 | 12 | $class |
|
360 | )); |
||
361 | } |
||
362 | 4 | } |
|
363 | |||
364 | 16 | public static function notInstanceOf($value, $class, $message = '') |
|
365 | { |
||
366 | 16 | if ($value instanceof $class) { |
|
367 | 4 | static::reportInvalidArgument(sprintf( |
|
368 | 4 | $message ?: 'Expected an instance other than %2$s. Got: %s', |
|
369 | 4 | static::typeToString($value), |
|
370 | 4 | $class |
|
371 | )); |
||
372 | } |
||
373 | 12 | } |
|
374 | |||
375 | 20 | public static function isInstanceOfAny($value, array $classes, $message = '') |
|
389 | |||
390 | 23 | public static function isEmpty($value, $message = '') |
|
399 | |||
400 | 23 | public static function notEmpty($value, $message = '') |
|
409 | |||
410 | 11 | public static function null($value, $message = '') |
|
411 | { |
||
412 | 11 | if (null !== $value) { |
|
413 | 8 | static::reportInvalidArgument(sprintf( |
|
414 | 8 | $message ?: 'Expected null. Got: %s', |
|
415 | 8 | static::valueToString($value) |
|
416 | )); |
||
417 | } |
||
418 | 3 | } |
|
419 | |||
420 | 11 | public static function notNull($value, $message = '') |
|
428 | |||
429 | 15 | public static function true($value, $message = '') |
|
430 | { |
||
431 | 15 | if (true !== $value) { |
|
432 | 11 | static::reportInvalidArgument(sprintf( |
|
433 | 11 | $message ?: 'Expected a value to be true. Got: %s', |
|
434 | 11 | static::valueToString($value) |
|
435 | )); |
||
436 | } |
||
437 | 4 | } |
|
438 | |||
439 | 19 | public static function false($value, $message = '') |
|
440 | { |
||
441 | 19 | if (false !== $value) { |
|
442 | 15 | static::reportInvalidArgument(sprintf( |
|
443 | 15 | $message ?: 'Expected a value to be false. Got: %s', |
|
444 | 15 | static::valueToString($value) |
|
445 | )); |
||
446 | } |
||
447 | 4 | } |
|
448 | |||
449 | 33 | public static function eq($value, $value2, $message = '') |
|
450 | { |
||
451 | 33 | if ($value2 != $value) { |
|
452 | 17 | static::reportInvalidArgument(sprintf( |
|
453 | 17 | $message ?: 'Expected a value equal to %2$s. Got: %s', |
|
454 | 17 | static::valueToString($value), |
|
455 | 17 | static::valueToString($value2) |
|
456 | )); |
||
457 | } |
||
458 | 16 | } |
|
459 | |||
460 | 28 | public static function notEq($value, $value2, $message = '') |
|
469 | |||
470 | 16 | public static function same($value, $value2, $message = '') |
|
471 | { |
||
472 | 16 | if ($value2 !== $value) { |
|
473 | 12 | static::reportInvalidArgument(sprintf( |
|
474 | 12 | $message ?: 'Expected a value identical to %2$s. Got: %s', |
|
475 | 12 | static::valueToString($value), |
|
476 | 12 | static::valueToString($value2) |
|
477 | )); |
||
478 | } |
||
479 | 4 | } |
|
480 | |||
481 | 16 | public static function notSame($value, $value2, $message = '') |
|
490 | |||
491 | 8 | public static function greaterThan($value, $limit, $message = '') |
|
492 | { |
||
493 | 8 | if ($value <= $limit) { |
|
494 | 4 | static::reportInvalidArgument(sprintf( |
|
495 | 4 | $message ?: 'Expected a value greater than %2$s. Got: %s', |
|
496 | 4 | static::valueToString($value), |
|
497 | 4 | static::valueToString($limit) |
|
498 | )); |
||
499 | } |
||
500 | 4 | } |
|
501 | |||
502 | 12 | public static function greaterThanEq($value, $limit, $message = '') |
|
503 | { |
||
504 | 12 | if ($value < $limit) { |
|
505 | 4 | static::reportInvalidArgument(sprintf( |
|
506 | 4 | $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', |
|
507 | 4 | static::valueToString($value), |
|
508 | 4 | static::valueToString($limit) |
|
509 | )); |
||
510 | } |
||
511 | 8 | } |
|
512 | |||
513 | 8 | public static function lessThan($value, $limit, $message = '') |
|
514 | { |
||
515 | 8 | if ($value >= $limit) { |
|
516 | 4 | static::reportInvalidArgument(sprintf( |
|
517 | 4 | $message ?: 'Expected a value less than %2$s. Got: %s', |
|
518 | 4 | static::valueToString($value), |
|
519 | 4 | static::valueToString($limit) |
|
520 | )); |
||
521 | } |
||
522 | 4 | } |
|
523 | |||
524 | 12 | public static function lessThanEq($value, $limit, $message = '') |
|
525 | { |
||
526 | 12 | if ($value > $limit) { |
|
527 | 4 | static::reportInvalidArgument(sprintf( |
|
528 | 4 | $message ?: 'Expected a value less than or equal to %2$s. Got: %s', |
|
529 | 4 | static::valueToString($value), |
|
530 | 4 | static::valueToString($limit) |
|
531 | )); |
||
532 | } |
||
533 | 8 | } |
|
534 | |||
535 | 16 | View Code Duplication | public static function range($value, $min, $max, $message = '') |
546 | |||
547 | 8 | public static function oneOf($value, array $values, $message = '') |
|
557 | |||
558 | 20 | View Code Duplication | public static function contains($value, $subString, $message = '') |
568 | |||
569 | 20 | View Code Duplication | public static function notContains($value, $subString, $message = '') |
579 | |||
580 | 40 | public static function notWhitespaceOnly($value, $message = '') |
|
581 | { |
||
582 | 40 | if (preg_match('/^\s*$/', $value)) { |
|
583 | 24 | static::reportInvalidArgument(sprintf( |
|
584 | 24 | $message ?: 'Expected a non-whitespace string. Got: %s', |
|
585 | 24 | static::valueToString($value) |
|
586 | )); |
||
587 | } |
||
588 | 16 | } |
|
589 | |||
590 | 12 | View Code Duplication | public static function startsWith($value, $prefix, $message = '') |
600 | |||
601 | 12 | public static function startsWithLetter($value, $message = '') |
|
619 | |||
620 | 12 | View Code Duplication | public static function endsWith($value, $suffix, $message = '') |
630 | |||
631 | 12 | public static function regex($value, $pattern, $message = '') |
|
632 | { |
||
633 | 12 | if (!preg_match($pattern, $value)) { |
|
634 | 8 | static::reportInvalidArgument(sprintf( |
|
635 | 8 | $message ?: 'The value %s does not match the expected pattern.', |
|
636 | 8 | static::valueToString($value) |
|
637 | )); |
||
638 | } |
||
639 | 4 | } |
|
640 | |||
641 | 12 | public static function notRegex($value, $pattern, $message = '') |
|
652 | |||
653 | 12 | View Code Duplication | public static function alpha($value, $message = '') |
667 | |||
668 | 12 | View Code Duplication | public static function digits($value, $message = '') |
682 | |||
683 | 12 | View Code Duplication | public static function alnum($value, $message = '') |
697 | |||
698 | 16 | View Code Duplication | public static function lower($value, $message = '') |
712 | |||
713 | 16 | View Code Duplication | public static function upper($value, $message = '') |
727 | |||
728 | 24 | public static function length($value, $length, $message = '') |
|
738 | |||
739 | 24 | public static function minLength($value, $min, $message = '') |
|
740 | { |
||
741 | 24 | if (static::strlen($value) < $min) { |
|
742 | 8 | static::reportInvalidArgument(sprintf( |
|
743 | 8 | $message ?: 'Expected a value to contain at least %2$s characters. Got: %s', |
|
744 | 8 | static::valueToString($value), |
|
745 | 8 | $min |
|
746 | )); |
||
747 | } |
||
748 | 16 | } |
|
749 | |||
750 | 24 | public static function maxLength($value, $max, $message = '') |
|
751 | { |
||
752 | 24 | if (static::strlen($value) > $max) { |
|
753 | 8 | static::reportInvalidArgument(sprintf( |
|
754 | 8 | $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', |
|
755 | 8 | static::valueToString($value), |
|
756 | 8 | $max |
|
757 | )); |
||
758 | } |
||
759 | 16 | } |
|
760 | |||
761 | 40 | View Code Duplication | public static function lengthBetween($value, $min, $max, $message = '') |
774 | |||
775 | 36 | public static function fileExists($value, $message = '') |
|
786 | |||
787 | 12 | View Code Duplication | public static function file($value, $message = '') |
798 | |||
799 | 12 | View Code Duplication | public static function directory($value, $message = '') |
810 | |||
811 | public static function readable($value, $message = '') |
||
812 | { |
||
813 | if (!is_readable($value)) { |
||
814 | static::reportInvalidArgument(sprintf( |
||
815 | $message ?: 'The path %s is not readable.', |
||
816 | static::valueToString($value) |
||
817 | )); |
||
818 | } |
||
819 | } |
||
820 | |||
821 | public static function writable($value, $message = '') |
||
822 | { |
||
823 | if (!is_writable($value)) { |
||
824 | static::reportInvalidArgument(sprintf( |
||
825 | $message ?: 'The path %s is not writable.', |
||
826 | static::valueToString($value) |
||
827 | )); |
||
828 | } |
||
829 | } |
||
830 | |||
831 | 8 | public static function classExists($value, $message = '') |
|
832 | { |
||
833 | 8 | if (!class_exists($value)) { |
|
834 | 4 | static::reportInvalidArgument(sprintf( |
|
835 | 4 | $message ?: 'Expected an existing class name. Got: %s', |
|
836 | 4 | static::valueToString($value) |
|
837 | )); |
||
838 | } |
||
839 | 4 | } |
|
840 | |||
841 | 8 | public static function subclassOf($value, $class, $message = '') |
|
851 | |||
852 | 8 | View Code Duplication | public static function implementsInterface($value, $interface, $message = '') |
862 | |||
863 | 12 | View Code Duplication | public static function propertyExists($classOrObject, $property, $message = '') |
872 | |||
873 | 12 | View Code Duplication | public static function propertyNotExists($classOrObject, $property, $message = '') |
882 | |||
883 | 27 | View Code Duplication | public static function methodExists($classOrObject, $method, $message = '') |
892 | |||
893 | 27 | View Code Duplication | public static function methodNotExists($classOrObject, $method, $message = '') |
902 | |||
903 | 12 | View Code Duplication | public static function keyExists($array, $key, $message = '') |
904 | { |
||
905 | 12 | if (!(isset($array[$key]) || array_key_exists($key, $array))) { |
|
906 | 4 | static::reportInvalidArgument(sprintf( |
|
907 | 4 | $message ?: 'Expected the key %s to exist.', |
|
908 | 4 | static::valueToString($key) |
|
909 | )); |
||
910 | } |
||
911 | 8 | } |
|
912 | |||
913 | 12 | View Code Duplication | public static function keyNotExists($array, $key, $message = '') |
914 | { |
||
915 | 12 | if (isset($array[$key]) || array_key_exists($key, $array)) { |
|
916 | 8 | static::reportInvalidArgument(sprintf( |
|
917 | 8 | $message ?: 'Expected the key %s to not exist.', |
|
918 | 8 | static::valueToString($key) |
|
919 | )); |
||
920 | } |
||
921 | 4 | } |
|
922 | |||
923 | 8 | public static function count($array, $number, $message = '') |
|
931 | |||
932 | 12 | View Code Duplication | public static function minCount($array, $min, $message = '') |
942 | |||
943 | 12 | View Code Duplication | public static function maxCount($array, $max, $message = '') |
953 | |||
954 | 12 | public static function countBetween($array, $min, $max, $message = '') |
|
967 | |||
968 | 48 | public static function uuid($value, $message = '') |
|
985 | |||
986 | 24 | public static function throws(Closure $expression, $class = 'Exception', $message = '') |
|
1012 | |||
1013 | 980 | public static function __callStatic($name, $arguments) |
|
1041 | |||
1042 | 441 | protected static function valueToString($value) |
|
1043 | { |
||
1044 | 441 | if (null === $value) { |
|
1045 | 11 | return 'null'; |
|
1046 | } |
||
1047 | |||
1048 | 432 | if (true === $value) { |
|
1049 | 15 | return 'true'; |
|
1050 | } |
||
1051 | |||
1052 | 422 | if (false === $value) { |
|
1053 | 13 | return 'false'; |
|
1054 | } |
||
1055 | |||
1056 | 409 | if (is_array($value)) { |
|
1057 | 1 | return 'array'; |
|
1058 | } |
||
1059 | |||
1060 | 408 | if (is_object($value)) { |
|
1061 | 2 | if (method_exists($value, '__toString')) { |
|
1062 | 1 | return get_class($value).': '.self::valueToString($value->__toString()); |
|
1063 | } |
||
1064 | |||
1065 | 1 | return get_class($value); |
|
1066 | } |
||
1067 | |||
1068 | 407 | if (is_resource($value)) { |
|
1069 | 1 | return 'resource'; |
|
1070 | } |
||
1071 | |||
1078 | |||
1079 | 169 | protected static function typeToString($value) |
|
1083 | |||
1084 | 124 | protected static function strlen($value) |
|
1096 | |||
1097 | 625 | protected static function reportInvalidArgument($message) |
|
1101 | |||
1102 | private function __construct() |
||
1105 | } |
||
1106 |