1<?php 2/** 3 * Zend Framework (http://framework.zend.com/) 4 * 5 * @link http://github.com/zendframework/zf2 for the canonical source repository 6 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 7 * @license http://framework.zend.com/license/new-bsd New BSD License 8 */ 9 10namespace Zend\Validator; 11 12use Zend\Stdlib\StringUtils; 13use Zend\Stdlib\StringWrapper\StringWrapperInterface as StringWrapper; 14 15class StringLength extends AbstractValidator 16{ 17 const INVALID = 'stringLengthInvalid'; 18 const TOO_SHORT = 'stringLengthTooShort'; 19 const TOO_LONG = 'stringLengthTooLong'; 20 21 /** 22 * @var array 23 */ 24 protected $messageTemplates = array( 25 self::INVALID => "Invalid type given. String expected", 26 self::TOO_SHORT => "The input is less than %min% characters long", 27 self::TOO_LONG => "The input is more than %max% characters long", 28 ); 29 30 /** 31 * @var array 32 */ 33 protected $messageVariables = array( 34 'min' => array('options' => 'min'), 35 'max' => array('options' => 'max'), 36 ); 37 38 protected $options = array( 39 'min' => 0, // Minimum length 40 'max' => null, // Maximum length, null if there is no length limitation 41 'encoding' => 'UTF-8', // Encoding to use 42 ); 43 44 protected $stringWrapper; 45 46 /** 47 * Sets validator options 48 * 49 * @param int|array|\Traversable $options 50 */ 51 public function __construct($options = array()) 52 { 53 if (!is_array($options)) { 54 $options = func_get_args(); 55 $temp['min'] = array_shift($options); 56 if (!empty($options)) { 57 $temp['max'] = array_shift($options); 58 } 59 60 if (!empty($options)) { 61 $temp['encoding'] = array_shift($options); 62 } 63 64 $options = $temp; 65 } 66 67 parent::__construct($options); 68 } 69 70 /** 71 * Returns the min option 72 * 73 * @return int 74 */ 75 public function getMin() 76 { 77 return $this->options['min']; 78 } 79 80 /** 81 * Sets the min option 82 * 83 * @param int $min 84 * @throws Exception\InvalidArgumentException 85 * @return StringLength Provides a fluent interface 86 */ 87 public function setMin($min) 88 { 89 if (null !== $this->getMax() && $min > $this->getMax()) { 90 throw new Exception\InvalidArgumentException( 91 "The minimum must be less than or equal to the maximum length, but {$min} > {$this->getMax()}" 92 ); 93 } 94 95 $this->options['min'] = max(0, (int) $min); 96 return $this; 97 } 98 99 /** 100 * Returns the max option 101 * 102 * @return int|null 103 */ 104 public function getMax() 105 { 106 return $this->options['max']; 107 } 108 109 /** 110 * Sets the max option 111 * 112 * @param int|null $max 113 * @throws Exception\InvalidArgumentException 114 * @return StringLength Provides a fluent interface 115 */ 116 public function setMax($max) 117 { 118 if (null === $max) { 119 $this->options['max'] = null; 120 } elseif ($max < $this->getMin()) { 121 throw new Exception\InvalidArgumentException( 122 "The maximum must be greater than or equal to the minimum length, but {$max} < {$this->getMin()}" 123 ); 124 } else { 125 $this->options['max'] = (int) $max; 126 } 127 128 return $this; 129 } 130 131 /** 132 * Get the string wrapper to detect the string length 133 * 134 * @return StringWrapper 135 */ 136 public function getStringWrapper() 137 { 138 if (!$this->stringWrapper) { 139 $this->stringWrapper = StringUtils::getWrapper($this->getEncoding()); 140 } 141 return $this->stringWrapper; 142 } 143 144 /** 145 * Set the string wrapper to detect the string length 146 * 147 * @param StringWrapper $stringWrapper 148 * @return StringLength 149 */ 150 public function setStringWrapper(StringWrapper $stringWrapper) 151 { 152 $stringWrapper->setEncoding($this->getEncoding()); 153 $this->stringWrapper = $stringWrapper; 154 } 155 156 /** 157 * Returns the actual encoding 158 * 159 * @return string 160 */ 161 public function getEncoding() 162 { 163 return $this->options['encoding']; 164 } 165 166 /** 167 * Sets a new encoding to use 168 * 169 * @param string $encoding 170 * @return StringLength 171 * @throws Exception\InvalidArgumentException 172 */ 173 public function setEncoding($encoding) 174 { 175 $this->stringWrapper = StringUtils::getWrapper($encoding); 176 $this->options['encoding'] = $encoding; 177 return $this; 178 } 179 180 /** 181 * Returns true if and only if the string length of $value is at least the min option and 182 * no greater than the max option (when the max option is not null). 183 * 184 * @param string $value 185 * @return bool 186 */ 187 public function isValid($value) 188 { 189 if (!is_string($value)) { 190 $this->error(self::INVALID); 191 return false; 192 } 193 194 $this->setValue($value); 195 196 $length = $this->getStringWrapper()->strlen($value); 197 if ($length < $this->getMin()) { 198 $this->error(self::TOO_SHORT); 199 } 200 201 if (null !== $this->getMax() && $this->getMax() < $length) { 202 $this->error(self::TOO_LONG); 203 } 204 205 if (count($this->getMessages())) { 206 return false; 207 } 208 209 return true; 210 } 211} 212