1<?php 2 3/* 4 * This file is part of Respect/Validation. 5 * 6 * (c) Alexandre Gomes Gaigalas <alexandre@gaigalas.net> 7 * 8 * For the full copyright and license information, please view the "LICENSE.md" 9 * file that was distributed with this source code. 10 */ 11 12namespace Respect\Validation\Rules; 13 14use Respect\Validation\Exceptions\ComponentException; 15 16class Length extends AbstractRule 17{ 18 public $minValue; 19 public $maxValue; 20 public $inclusive; 21 22 public function __construct($min = null, $max = null, $inclusive = true) 23 { 24 $this->minValue = $min; 25 $this->maxValue = $max; 26 $this->inclusive = $inclusive; 27 $paramValidator = new OneOf(new Numeric(), new NullType()); 28 if (!$paramValidator->validate($min)) { 29 throw new ComponentException( 30 sprintf('%s is not a valid numeric length', $min) 31 ); 32 } 33 34 if (!$paramValidator->validate($max)) { 35 throw new ComponentException( 36 sprintf('%s is not a valid numeric length', $max) 37 ); 38 } 39 40 if (!is_null($min) && !is_null($max) && $min > $max) { 41 throw new ComponentException( 42 sprintf('%s cannot be less than %s for validation', $min, $max) 43 ); 44 } 45 } 46 47 public function validate($input) 48 { 49 $length = $this->extractLength($input); 50 51 return $this->validateMin($length) && $this->validateMax($length); 52 } 53 54 protected function extractLength($input) 55 { 56 if (is_string($input)) { 57 return mb_strlen($input, mb_detect_encoding($input)); 58 } 59 60 if (is_array($input) || $input instanceof \Countable) { 61 return count($input); 62 } 63 64 if (is_object($input)) { 65 return count(get_object_vars($input)); 66 } 67 68 if (is_int($input)) { 69 return strlen((string)$input); 70 } 71 72 return false; 73 } 74 75 protected function validateMin($length) 76 { 77 if (is_null($this->minValue)) { 78 return true; 79 } 80 81 if ($this->inclusive) { 82 return $length >= $this->minValue; 83 } 84 85 return $length > $this->minValue; 86 } 87 88 protected function validateMax($length) 89 { 90 if (is_null($this->maxValue)) { 91 return true; 92 } 93 94 if ($this->inclusive) { 95 return $length <= $this->maxValue; 96 } 97 98 return $length < $this->maxValue; 99 } 100} 101