Explorar el Código

[GENERIC] Zend_Validate_Postcode:

- promoted Zend_Validate_Postcode to core

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@18288 44c647ce-9c0f-0410-b52a-842ac1e357ba
thomas hace 16 años
padre
commit
a8919811d4

+ 113 - 0
documentation/manual/en/module_specs/Zend_Validate-PostCode.xml

@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Reviewed: no -->
+<sect2 id="zend.validate.set.post_code">
+
+    <title>PostCode</title>
+
+    <para>
+        <classname>Zend_Validate_PostCode</classname> allows you to determine if a given value is a
+        valid postal code. Postal codes are specific to cities, and in some locales termed ZIP
+        codes.
+    </para>
+
+    <para>
+        <classname>Zend_Validate_PostCode</classname> knows more than 160 different postal code
+        formates. To select the correct format there are 2 ways. You can either use a fully
+        qualified locale or you can set your own format manually.
+    </para>
+
+    <para>
+        Using a locale is more convenient as Zend Framework already knows the appropriate postal
+        code format for each locale; however, you need to use the fully qualified locale (one
+        containing a region specifier) to do so.  For instance, the locale "de" is a locale but
+        could not be used with <classname>Zend_Validate_PostCode</classname> as it does not include
+        the region; "de_AT", however, would be a valid locale, as it specifies the region code
+        ("AT", for Austria).
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_PostCode('de_AT');
+]]></programlisting>
+
+    <para>
+        When you don't set a locale yourself, then <classname>Zend_Validate_PostCode</classname>
+        will use the application wide set locale, or, when there is none, the locale returned by
+        <classname>Zend_Locale</classname>.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+// application wide locale within your bootstrap
+$locale = new Zend_Locale('de_AT');
+Zend_Registry::set('Zend_Locale', $locale);
+
+$validator = new Zend_Validate_PostCode();
+]]></programlisting>
+
+    <para>
+        You can also change the locale afterwards by calling <methodname>setLocale()</methodname>.
+        And of course you can get the actual used locale by calling
+        <methodname>getLocale()</methodname>.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_PostCode('de_AT');
+$validator->setLocale('en_GB');
+]]></programlisting>
+
+    <para>
+        Postal code formats themself are simply regular expression strings. When the international
+        postal code format, which is used by setting the locale, does not fit your needs, then you
+        can also manually set a format by calling <methodname>setFormat()</methodname>.
+    </para>
+
+    <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_PostCode('de_AT');
+$validator->setFormat('AT-\d{5}');
+]]></programlisting>
+
+    <note>
+        <title>Conventions for self defined formats</title>
+
+        <para>
+            When using self defined formats you should omit the starting (<command>'/^'</command>)
+            and ending tags (<command>'$/'</command>). They are attached automatically.
+        </para>
+
+        <para>
+            You should also be aware that postcode values are always be validated in a strict way.
+            This means that they have to be written standalone without additional characters when
+            they are not covered by the format.
+        </para>
+    </note>
+
+    <sect3 id="zend.validate.set.post_code.constructor">
+        <title>Constructor options</title>
+
+        <para>
+            At it's most basic, you may pass either a <classname>Zend_Locale</classname> object or a
+            string representing a fully qualified locale to the constructor of
+            <classname>Zend_Validate_PostCode</classname>.
+        </para>
+
+    <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_PostCode('de_AT');
+$validator = new Zend_Validate_PostCode($locale);
+]]></programlisting>
+
+        <para>
+            Additionally, you may pass either an array or a <classname>Zend_Config</classname>
+            object to the constructor. When you do so, you must include either the key "locale" or
+            "format"; these will be used to set the appropriate values in the validator object.
+        </para>
+
+    <programlisting language="php"><![CDATA[
+$validator = new Zend_Validate_PostCode(array(
+    'locale' => 'de_AT',
+    'format' => 'AT_\d+'
+));
+]]></programlisting>
+    </sect3>
+</sect2>
+<!--
+vim:se ts=4 sw=4 et:
+-->

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

@@ -23,7 +23,6 @@
                 languages: Chinese, Japanese, Korean. The language is specified by <classname>Zend_Locale</classname>.
             </para>
         </note>
-
     </sect2>
 
     <sect2 id="zend.validate.set.alpha">
@@ -229,6 +228,8 @@ if ($validator->isValid(1)) { // token invalid
         </para>
     </sect2>
 
+    <xi:include href="Zend_Validate-Callback.xml" />
+
     <sect2 id="zend.validate.set.regex">
         <title>Regex</title>
         <para>

+ 201 - 0
library/Zend/Validate/PostCode.php

@@ -0,0 +1,201 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: PostCode.php 17798 2009-08-24 20:07:53Z thomas $
+ */
+
+/**
+ * @see Zend_Validate_Abstract
+ */
+require_once 'Zend/Validate/Abstract.php';
+
+/**
+ * @see Zend_Locale_Format
+ */
+require_once 'Zend/Locale/Format.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ */
+class Zend_Validate_PostCode extends Zend_Validate_Abstract
+{
+    const INVALID  = 'postcodeInvalid';
+    const NO_MATCH = 'postcodeNoMatch';
+
+    /**
+     * @var array
+     */
+    protected $_messageTemplates = array(
+        self::INVALID  => "Invalid type given, value should be a string or a integer",
+        self::NO_MATCH => "'%value%' does not appear to be an postal code"
+    );
+
+    /**
+     * Locale to use
+     *
+     * @var string
+     */
+    protected $_locale;
+
+    /**
+     * Manual postal code format
+     *
+     * @var unknown_type
+     */
+    protected $_format;
+
+    /**
+     * Constructor for the integer validator
+     *
+     * Accepts either a string locale, a Zend_Locale object, or an array or
+     * Zend_Config object containing the keys "locale" and/or "format".
+     *
+     * @param string|Zend_Locale|array|Zend_Config $options
+     */
+    public function __construct($options)
+    {
+        if ($options instanceof Zend_Config) {
+            $options = $options->toArray();
+        }
+
+        if (null === $options) {
+            require_once 'Zend/Registry.php';
+            if (Zend_Registry::isRegistered('Zend_Locale')) {
+                $this->setLocale(Zend_Registry::get('Zend_Locale'));
+            }
+        } elseif (is_array($options)) {
+            // Received
+            if (array_key_exists('locale', $options)) {
+                $this->setLocale($options['locale']);
+            }
+
+            if (array_key_exists('format', $options)) {
+                $this->setFormat($options['format']);
+            }
+        } elseif ($options instanceof Zend_Locale || is_string($options)) {
+            // Received Locale object or string locale
+            $this->setLocale($options);
+        }
+
+        $format = $this->getFormat();
+        if (empty($format)) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("Format has to be a not empty string");
+        }
+    }
+
+    /**
+     * Returns the set locale
+     */
+    public function getLocale()
+    {
+        return $this->_locale;
+    }
+
+    /**
+     * Sets the locale to use
+     *
+     * @param string|Zend_Locale $locale
+     */
+    public function setLocale($locale = null)
+    {
+        require_once 'Zend/Locale.php';
+        $this->_locale = Zend_Locale::findLocale($locale);
+        $locale        = new Zend_Locale($this->_locale);
+        $region        = $locale->getRegion();
+        if (empty($region)) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("Unable to detect a region from the locale '$locale'");
+        }
+
+        $format = Zend_Locale::getTranslation(
+            $locale->getRegion(),
+            'postaltoterritory',
+            $this->_locale
+        );
+
+        if (empty($format)) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("Unable to detect a format from the region '{$locale->getRegion()}'");
+        }
+
+        $this->setFormat($format);
+
+        return $this;
+    }
+
+    /**
+     * Returns the set postal code format
+     *
+     * @return string
+     */
+    public function getFormat()
+    {
+        return $this->_format;
+    }
+
+    /**
+     * Sets a self defined postal format as regex
+     *
+     * @param string $format
+     */
+    public function setFormat($format)
+    {
+        if (empty($format) || !is_string($format)) {
+            require_once 'Zend/Validate/Exception.php';
+            throw new Zend_Validate_Exception("Format has to be a not empty string");
+        }
+
+        if ($format[0] !== '/') {
+            $format = '/^' . $format;
+        }
+
+        if ($format[strlen($format) - 1] !== '/') {
+            $format .= '$/';
+        }
+
+        $this->_format = $format;
+    }
+
+    /**
+     * Defined by Zend_Validate_Interface
+     *
+     * Returns true if and only if $value is a valid postalcode
+     *
+     * @param  string $value
+     * @return boolean
+     */
+    public function isValid($value)
+    {
+        if (!is_string($value) && !is_int($value)) {
+            $this->_error(self::INVALID);
+            return false;
+        }
+
+        $format = $this->getFormat();
+        if (!preg_match($format, $value)) {
+            $this->_error(self::NO_MATCH);
+            return false;
+        }
+
+        return true;
+    }
+}

+ 181 - 0
tests/Zend/Validate/PostCodeTest.php

@@ -0,0 +1,181 @@
+<?php
+/**
+ * Zend Framework
+ *
+ * LICENSE
+ *
+ * This source file is subject to the new BSD license that is bundled
+ * with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://framework.zend.com/license/new-bsd
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@zend.com so we can send you a copy immediately.
+ *
+ * @category   Zend
+ * @package    Zend_Validate
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @version    $Id: PostCodeTest.php 17798 2009-08-24 20:07:53Z thomas $
+ */
+
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Zend_Validate_PostCodeTest::main');
+}
+
+/**
+ * Test helper
+ */
+require_once dirname(__FILE__) . '/../../TestHelper.php';
+
+/**
+ * @see Zend_Validate_PostCode
+ */
+require_once 'Zend/Validate/PostCode.php';
+
+/**
+ * @category   Zend
+ * @package    Zend_Validate
+ * @subpackage UnitTests
+ * @copyright  Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license    http://framework.zend.com/license/new-bsd     New BSD License
+ * @group      Zend_Validate
+ */
+class Zend_Validate_PostCodeTest extends PHPUnit_Framework_TestCase
+{
+    /**
+     * Zend_Validate_PostCode object
+     *
+     * @var Zend_Validate_PostCode
+     */
+    protected $_validator;
+
+    /**
+     * Runs this test suite
+     *
+     * @return void
+     */
+    public static function main()
+    {
+        $suite  = new PHPUnit_Framework_TestSuite('Zend_Validate_PostCodeTest');
+        $result = PHPUnit_TextUI_TestRunner::run($suite);
+    }
+
+    /**
+     * Creates a new Zend_Validate_PostCode object for each test method
+     *
+     * @return void
+     */
+    public function setUp()
+    {
+        $this->_validator = new Zend_Validate_PostCode('de_AT');
+    }
+
+    /**
+     * Ensures that the validator follows expected behavior
+     *
+     * @return void
+     */
+    public function testBasic()
+    {
+        $valuesExpected = array(
+            array('2292', true),
+            array('1000', true),
+            array('0000', true),
+            array('12345', false),
+            array(1234, true),
+            array(9821, true),
+            array('21A4', false),
+            array('ABCD', false),
+            array(true, false),
+            array('AT-2292', false),
+            array(1.56, false)
+        );
+
+        foreach ($valuesExpected as $element) {
+            $this->assertEquals($element[1], $this->_validator->isValid($element[0]),
+                'Test failed with ' . var_export($element, 1));
+        }
+    }
+
+    /**
+     * Ensures that getMessages() returns expected default value
+     *
+     * @return void
+     */
+    public function testGetMessages()
+    {
+        $this->assertEquals(array(), $this->_validator->getMessages());
+    }
+
+    /**
+     * Ensures that a region is available
+     */
+    public function testSettingLocalesWithoutRegion()
+    {
+        try {
+            $this->_validator->setLocale('de');
+            $this->fail();
+        } catch (Zend_Validate_Exception $e) {
+            $this->assertContains('Unable to detect a region', $e->getMessage());
+        }
+    }
+
+    /**
+     * Ensures that the region contains postal codes
+     */
+    public function testSettingLocalesWithoutPostalCodes()
+    {
+        try {
+            $this->_validator->setLocale('gez_ER');
+            $this->fail();
+        } catch (Zend_Validate_Exception $e) {
+            $this->assertContains('Unable to detect a format', $e->getMessage());
+        }
+    }
+
+    /**
+     * Ensures locales can be retrieved
+     */
+    public function testGettingLocale()
+    {
+        $this->assertEquals('de_AT', $this->_validator->getLocale());
+    }
+
+    /**
+     * Ensures format can be set and retrieved
+     */
+    public function testSetGetFormat()
+    {
+        $this->_validator->setFormat('\d{1}');
+        $this->assertEquals('/^\d{1}$/', $this->_validator->getFormat());
+
+        $this->_validator->setFormat('/^\d{1}');
+        $this->assertEquals('/^\d{1}$/', $this->_validator->getFormat());
+
+        $this->_validator->setFormat('/^\d{1}$/');
+        $this->assertEquals('/^\d{1}$/', $this->_validator->getFormat());
+
+        $this->_validator->setFormat('\d{1}$/');
+        $this->assertEquals('/^\d{1}$/', $this->_validator->getFormat());
+
+        try {
+            $this->_validator->setFormat(null);
+            $this->fail();
+        } catch (Zend_Validate_Exception $e) {
+            $this->assertContains('a not empty string', $e->getMessage());
+        }
+
+        try {
+            $this->_validator->setFormat('');
+            $this->fail();
+        } catch (Zend_Validate_Exception $e) {
+            $this->assertContains('a not empty string', $e->getMessage());
+        }
+    }
+}
+
+if (PHPUnit_MAIN_METHOD == 'Zend_Validate_PostCodeTest::main') {
+    Zend_Validate_PostCodeTest::main();
+}