|
1 <?php |
|
2 /** |
|
3 * Zend Framework |
|
4 * |
|
5 * LICENSE |
|
6 * |
|
7 * This source file is subject to the new BSD license that is bundled |
|
8 * with this package in the file LICENSE.txt. |
|
9 * It is also available through the world-wide-web at this URL: |
|
10 * http://framework.zend.com/license/new-bsd |
|
11 * If you did not receive a copy of the license and are unable to |
|
12 * obtain it through the world-wide-web, please send an email |
|
13 * to license@zend.com so we can send you a copy immediately. |
|
14 * |
|
15 * @category Zend |
|
16 * @package Zend_Validate |
|
17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
18 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
19 * @version $Id: Ip.php 22668 2010-07-25 14:50:46Z thomas $ |
|
20 */ |
|
21 |
|
22 /** |
|
23 * @see Zend_Validate_Abstract |
|
24 */ |
|
25 require_once 'Zend/Validate/Abstract.php'; |
|
26 |
|
27 /** |
|
28 * @category Zend |
|
29 * @package Zend_Validate |
|
30 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
|
31 * @license http://framework.zend.com/license/new-bsd New BSD License |
|
32 */ |
|
33 class Zend_Validate_Ip extends Zend_Validate_Abstract |
|
34 { |
|
35 const INVALID = 'ipInvalid'; |
|
36 const NOT_IP_ADDRESS = 'notIpAddress'; |
|
37 |
|
38 /** |
|
39 * @var array |
|
40 */ |
|
41 protected $_messageTemplates = array( |
|
42 self::INVALID => "Invalid type given. String expected", |
|
43 self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address", |
|
44 ); |
|
45 |
|
46 /** |
|
47 * internal options |
|
48 * |
|
49 * @var array |
|
50 */ |
|
51 protected $_options = array( |
|
52 'allowipv6' => true, |
|
53 'allowipv4' => true |
|
54 ); |
|
55 |
|
56 /** |
|
57 * Sets validator options |
|
58 * |
|
59 * @param array $options OPTIONAL Options to set, see the manual for all available options |
|
60 * @return void |
|
61 */ |
|
62 public function __construct($options = array()) |
|
63 { |
|
64 if ($options instanceof Zend_Config) { |
|
65 $options = $options->toArray(); |
|
66 } else if (!is_array($options)) { |
|
67 $options = func_get_args(); |
|
68 $temp['allowipv6'] = array_shift($options); |
|
69 if (!empty($options)) { |
|
70 $temp['allowipv4'] = array_shift($options); |
|
71 } |
|
72 |
|
73 $options = $temp; |
|
74 } |
|
75 |
|
76 $options += $this->_options; |
|
77 $this->setOptions($options); |
|
78 } |
|
79 |
|
80 /** |
|
81 * Returns all set options |
|
82 * |
|
83 * @return array |
|
84 */ |
|
85 public function getOptions() |
|
86 { |
|
87 return $this->_options; |
|
88 } |
|
89 |
|
90 /** |
|
91 * Sets the options for this validator |
|
92 * |
|
93 * @param array $options |
|
94 * @return Zend_Validate_Ip |
|
95 */ |
|
96 public function setOptions($options) |
|
97 { |
|
98 if (array_key_exists('allowipv6', $options)) { |
|
99 $this->_options['allowipv6'] = (boolean) $options['allowipv6']; |
|
100 } |
|
101 |
|
102 if (array_key_exists('allowipv4', $options)) { |
|
103 $this->_options['allowipv4'] = (boolean) $options['allowipv4']; |
|
104 } |
|
105 |
|
106 if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) { |
|
107 require_once 'Zend/Validate/Exception.php'; |
|
108 throw new Zend_Validate_Exception('Nothing to validate. Check your options'); |
|
109 } |
|
110 |
|
111 return $this; |
|
112 } |
|
113 |
|
114 /** |
|
115 * Defined by Zend_Validate_Interface |
|
116 * |
|
117 * Returns true if and only if $value is a valid IP address |
|
118 * |
|
119 * @param mixed $value |
|
120 * @return boolean |
|
121 */ |
|
122 public function isValid($value) |
|
123 { |
|
124 if (!is_string($value)) { |
|
125 $this->_error(self::INVALID); |
|
126 return false; |
|
127 } |
|
128 |
|
129 $this->_setValue($value); |
|
130 if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) || |
|
131 (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) || |
|
132 ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) { |
|
133 $this->_error(self::NOT_IP_ADDRESS); |
|
134 return false; |
|
135 } |
|
136 |
|
137 return true; |
|
138 } |
|
139 |
|
140 /** |
|
141 * Validates an IPv4 address |
|
142 * |
|
143 * @param string $value |
|
144 */ |
|
145 protected function _validateIPv4($value) { |
|
146 $ip2long = ip2long($value); |
|
147 if($ip2long === false) { |
|
148 return false; |
|
149 } |
|
150 |
|
151 return $value == long2ip($ip2long); |
|
152 } |
|
153 |
|
154 /** |
|
155 * Validates an IPv6 address |
|
156 * |
|
157 * @param string $value Value to check against |
|
158 * @return boolean True when $value is a valid ipv6 address |
|
159 * False otherwise |
|
160 */ |
|
161 protected function _validateIPv6($value) { |
|
162 if (strlen($value) < 3) { |
|
163 return $value == '::'; |
|
164 } |
|
165 |
|
166 if (strpos($value, '.')) { |
|
167 $lastcolon = strrpos($value, ':'); |
|
168 if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) { |
|
169 return false; |
|
170 } |
|
171 |
|
172 $value = substr($value, 0, $lastcolon) . ':0:0'; |
|
173 } |
|
174 |
|
175 if (strpos($value, '::') === false) { |
|
176 return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); |
|
177 } |
|
178 |
|
179 $colonCount = substr_count($value, ':'); |
|
180 if ($colonCount < 8) { |
|
181 return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); |
|
182 } |
|
183 |
|
184 // special case with ending or starting double colon |
|
185 if ($colonCount == 8) { |
|
186 return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); |
|
187 } |
|
188 |
|
189 return false; |
|
190 } |
|
191 } |