File indexing completed on 2025-01-19 05:21:39
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Validate 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Validate_Abstract 0024 */ 0025 // require_once 'Zend/Validate/Abstract.php'; 0026 0027 /** 0028 * @category Zend 0029 * @package Zend_Validate 0030 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0031 * @license http://framework.zend.com/license/new-bsd New BSD License 0032 */ 0033 class Zend_Validate_Ip extends Zend_Validate_Abstract 0034 { 0035 const INVALID = 'ipInvalid'; 0036 const NOT_IP_ADDRESS = 'notIpAddress'; 0037 0038 /** 0039 * @var array 0040 */ 0041 protected $_messageTemplates = array( 0042 self::INVALID => "Invalid type given. String expected", 0043 self::NOT_IP_ADDRESS => "'%value%' does not appear to be a valid IP address", 0044 ); 0045 0046 /** 0047 * internal options 0048 * 0049 * @var array 0050 */ 0051 protected $_options = array( 0052 'allowipv6' => true, 0053 'allowipv4' => true 0054 ); 0055 0056 /** 0057 * Sets validator options 0058 * 0059 * @param array $options OPTIONAL Options to set, see the manual for all available options 0060 */ 0061 public function __construct($options = array()) 0062 { 0063 if ($options instanceof Zend_Config) { 0064 $options = $options->toArray(); 0065 } else if (!is_array($options)) { 0066 $options = func_get_args(); 0067 $temp['allowipv6'] = array_shift($options); 0068 if (!empty($options)) { 0069 $temp['allowipv4'] = array_shift($options); 0070 } 0071 0072 $options = $temp; 0073 } 0074 0075 $options += $this->_options; 0076 $this->setOptions($options); 0077 } 0078 0079 /** 0080 * Returns all set options 0081 * 0082 * @return array 0083 */ 0084 public function getOptions() 0085 { 0086 return $this->_options; 0087 } 0088 0089 /** 0090 * Sets the options for this validator 0091 * 0092 * @param array $options 0093 * @throws Zend_Validate_Exception 0094 * @return Zend_Validate_Ip 0095 */ 0096 public function setOptions($options) 0097 { 0098 if (array_key_exists('allowipv6', $options)) { 0099 $this->_options['allowipv6'] = (boolean) $options['allowipv6']; 0100 } 0101 0102 if (array_key_exists('allowipv4', $options)) { 0103 $this->_options['allowipv4'] = (boolean) $options['allowipv4']; 0104 } 0105 0106 if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) { 0107 // require_once 'Zend/Validate/Exception.php'; 0108 throw new Zend_Validate_Exception('Nothing to validate. Check your options'); 0109 } 0110 0111 return $this; 0112 } 0113 0114 /** 0115 * Defined by Zend_Validate_Interface 0116 * 0117 * Returns true if and only if $value is a valid IP address 0118 * 0119 * @param mixed $value 0120 * @return boolean 0121 */ 0122 public function isValid($value) 0123 { 0124 if (!is_string($value)) { 0125 $this->_error(self::INVALID); 0126 return false; 0127 } 0128 0129 $this->_setValue($value); 0130 if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) || 0131 (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) || 0132 ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) { 0133 $this->_error(self::NOT_IP_ADDRESS); 0134 return false; 0135 } 0136 0137 return true; 0138 } 0139 0140 /** 0141 * Validates an IPv4 address 0142 * 0143 * @param string $value 0144 * @return bool 0145 */ 0146 protected function _validateIPv4($value) { 0147 $ip2long = ip2long($value); 0148 if($ip2long === false) { 0149 return false; 0150 } 0151 0152 return $value == long2ip($ip2long); 0153 } 0154 0155 /** 0156 * Validates an IPv6 address 0157 * 0158 * @param string $value Value to check against 0159 * @return boolean True when $value is a valid ipv6 address 0160 * False otherwise 0161 */ 0162 protected function _validateIPv6($value) { 0163 if (strlen($value) < 3) { 0164 return $value == '::'; 0165 } 0166 0167 if (strpos($value, '.')) { 0168 $lastcolon = strrpos($value, ':'); 0169 if (!($lastcolon && $this->_validateIPv4(substr($value, $lastcolon + 1)))) { 0170 return false; 0171 } 0172 0173 $value = substr($value, 0, $lastcolon) . ':0:0'; 0174 } 0175 0176 if (strpos($value, '::') === false) { 0177 return preg_match('/\A(?:[a-f0-9]{1,4}:){7}[a-f0-9]{1,4}\z/i', $value); 0178 } 0179 0180 $colonCount = substr_count($value, ':'); 0181 if ($colonCount < 8) { 0182 return preg_match('/\A(?::|(?:[a-f0-9]{1,4}:)+):(?:(?:[a-f0-9]{1,4}:)*[a-f0-9]{1,4})?\z/i', $value); 0183 } 0184 0185 // special case with ending or starting double colon 0186 if ($colonCount == 8) { 0187 return preg_match('/\A(?:::)?(?:[a-f0-9]{1,4}:){6}[a-f0-9]{1,4}(?:::)?\z/i', $value); 0188 } 0189 0190 return false; 0191 } 0192 }