Sfoglia il codice sorgente

[ZF-8261] Zend_Validate_Ip:

- added options to select the valid protocol
- added new manual section

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@18986 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas 16 anni fa
parent
commit
204c8ae6d1

+ 87 - 0
documentation/manual/en/module_specs/Zend_Validate-Ip.xml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect2 id="zend.validate.set.ip">
+
+    <title>Ip</title>
+
+    <para>
+        <classname>Zend_Validate_Ip</classname> allows you to validate if a given value is an IP
+        address. It supports the IPv4 and also the IPv6 standard.
+    </para>
+
+    <sect3 id="zend.validate.set.ip.basic">
+        <title>Basic usage</title>
+
+        <para>
+            A basic example of usage is below:
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_Ip();
+if ($validator->isValid($ip)) {
+    // ip appears to be valid
+} else {
+    // ip is invalid; print the reasons
+}
+]]></programlisting>
+
+        <note>
+            <title>Invalid IP addresses</title>
+
+            <para>
+                Keep in mind that <classname>Zend_Validate_Ip</classname> only validates IP
+                addresses. Addresses like 'mydomain.com' or '192.168.50.1/index.html' are no valid
+                IP addresses. They are eighter hostnames or valid <acronym>URL</acronym>s but not IP
+                addresses.
+            </para>
+        </note>
+
+        <note>
+            <title>IPv6 validation</title>
+
+            <para>
+                <classname>Zend_Validate_Ip</classname> validates IPv6 addresses with regex. The
+                reason is that the filters and methods from PHP itself don't follow the RFC. Many
+                other available classes also don't follow it.
+            </para>
+        </note>
+    </sect3>
+
+    <sect3 id="zend.validate.set.ip.singletype">
+        <title>Validate IPv4 or IPV6 alone</title>
+
+        <para>
+            Sometimes it's usefull to validate only one of the supported formats. For example when
+            your network only supports IPv4. In this case it would be useless to allow IPv6 within
+            this validator.
+        </para>
+
+        <para>
+            To limit <classname>Zend_Validate_Ip</classname> to one protocol you can set the options
+            <property>allowipv4</property> or <property>allowipv6</property> to
+            <constant>FALSE</constant>. You can do this eighter by giving the option to the
+            constructor or by using <methodname>setOptions()</methodname> afterwards.
+        </para>
+
+        <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_Ip(array('allowipv6' => false);
+if ($validator->isValid($ip)) {
+    // ip appears to be valid ipv4 address
+} else {
+    // ip is no ipv4 address
+}
+]]></programlisting>
+
+        <note>
+            <title>Default behaviour</title>
+
+            <para>
+                The default behaviour which <classname>Zend_Validate_Ip</classname> follows is to
+                allow both standards.
+            </para>
+        </note>
+    </sect3>
+</sect2>
+<!--
+vim:se ts=4 sw=4 et:
+-->

+ 1 - 6
documentation/manual/en/module_specs/Zend_Validate-Set.xml

@@ -188,12 +188,7 @@ if ($validator->isValid($iban)) {
         </para>
     </sect2>
 
-    <sect2 id="zend.validate.set.ip">
-        <title>Ip</title>
-        <para>
-            Returns <constant>TRUE</constant> if and only if <varname>$value</varname> is a valid IP address.
-        </para>
-    </sect2>
+    <xi:include href="Zend_Validate-Ip.xml" />
 
     <sect2 id="zend.validate.set.less_than">
         <title>LessThan</title>

+ 77 - 4
library/Zend/Validate/Ip.php

@@ -44,6 +44,78 @@ class Zend_Validate_Ip extends Zend_Validate_Abstract
     );
 
     /**
+     * internal options
+     *
+     * @var array
+     */
+    protected $_options = array(
+        'allowipv6' => true,
+        'allowipv4' => true
+    );
+
+    /**
+     * Sets validator options
+     *
+     * @param integer          $allow       OPTIONAL Set what types of hostname to allow (default ALLOW_DNS)
+     * @param boolean          $validateIdn OPTIONAL Set whether IDN domains are validated (default true)
+     * @param boolean          $validateTld OPTIONAL Set whether the TLD element of a hostname is validated (default true)
+     * @param Zend_Validate_Ip $ipValidator OPTIONAL
+     * @return void
+     * @see http://www.iana.org/cctld/specifications-policies-cctlds-01apr02.htm  Technical Specifications for ccTLDs
+     */
+    public function __construct($options = array())
+    {
+        if ($options instanceof Zend_Config) {
+            $options = $options->toArray();
+        } else if (!is_array($options)) {
+            $options = func_get_args();
+            $temp['allowipv6'] = array_shift($options);
+            if (!empty($options)) {
+                $temp['allowipv4'] = array_shift($options);
+            }
+
+            $options = $temp;
+        }
+
+        $options += $this->_options;
+        $this->setOptions($options);
+    }
+
+    /**
+     * Returns all set options
+     *
+     * @return array
+     */
+    public function getOptions()
+    {
+        return $this->_options;
+    }
+
+    /**
+     * Sets the options for this validator
+     *
+     * @param array $options
+     * @return Zend_Validate_Ip
+     */
+    public function setOptions($options)
+    {
+        if (array_key_exists('allowipv6', $options)) {
+            $this->_options['allowipv6'] = (boolean) $options['allowipv6'];
+        }
+
+        if (array_key_exists('allowipv4', $options)) {
+            $this->_options['allowipv4'] = (boolean) $options['allowipv4'];
+        }
+
+        if (!$this->_options['allowipv4'] && !$this->_options['allowipv6']) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception('Nothing to validate. Check your options');
+        }
+
+        return $this;
+    }
+
+    /**
      * Defined by Zend_Validate_Interface
      *
      * Returns true if and only if $value is a valid IP address
@@ -59,10 +131,11 @@ class Zend_Validate_Ip extends Zend_Validate_Abstract
         }
 
         $this->_setValue($value);
-
-        if (!$this->_validateIPv4($value) && !$this->_validateIPv6($value)) {
-                $this->_error(self::NOT_IP_ADDRESS);
-                return false;
+        if (($this->_options['allowipv4'] && !$this->_options['allowipv6'] && !$this->_validateIPv4($value)) ||
+            (!$this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv6($value)) ||
+            ($this->_options['allowipv4'] && $this->_options['allowipv6'] && !$this->_validateIPv4($value) && !$this->_validateIPv6($value))) {
+            $this->_error(self::NOT_IP_ADDRESS);
+            return false;
         }
 
         return true;

+ 24 - 0
tests/Zend/Validate/IpTest.php

@@ -87,6 +87,30 @@ class Zend_Validate_IpTest extends PHPUnit_Framework_TestCase
         $this->assertEquals(array(), $this->_validator->getMessages());
     }
 
+    public function testOnlyIpv4()
+    {
+        $this->_validator->setOptions(array('allowipv6' => false));
+        $this->assertTrue($this->_validator->isValid('1.2.3.4'));
+        $this->assertFalse($this->_validator->isValid('a:b:c:d:e::1.2.3.4'));
+    }
+
+    public function testOnlyIpv6()
+    {
+        $this->_validator->setOptions(array('allowipv4' => false));
+        $this->assertFalse($this->_validator->isValid('1.2.3.4'));
+        $this->assertTrue($this->_validator->isValid('a:b:c:d:e::1.2.3.4'));
+    }
+
+    public function testNoValidation()
+    {
+        try {
+            $this->_validator->setOptions(array('allowipv4' => false, 'allowipv6' => false));
+            $this->fail();
+        } catch (Zend_Validate_Exception $e) {
+            $this->assertContains('Nothing to validate', $e->getMessage());
+        }
+    }
+
     public function testInvalidIpForZF4809()
     {
         $this->assertFalse($this->_validator->isValid('1.2.333'));