【问题标题】:Zend Form Validate Range DateZend 表单验证范围日期
【发布时间】:2011-06-17 15:04:48
【问题描述】:

谁帮我为 Zend 框架创建了一个自定义验证器,它检查日期是否在一个范围内?

例子:

dateGT = 2011-09-05
dateLT = 2011-07-05

如果表单域设置为: dateFieldForm = 2011-08-15 我希望验证器返回 true!

如果表单域设置为: dateFieldForm = 2011-10-15 我希望验证器返回 false!

【问题讨论】:

    标签: php zend-framework date zend-form zend-validate


    【解决方案1】:

    抱歉,前面有大代码:

    <?php
    
    /** @see Zend_Validate_Abstract */
    require_once 'Zend/Validate/Abstract.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 My_Validate_DateCompare extends Zend_Validate_Abstract
    {
        /**
         * Error codes
         * @const string
         */
        const NOT_SAME      = 'notSame';
        const MISSING_TOKEN = 'missingToken';
        const NOT_LATER     = 'notLater';
        const NOT_EARLIER   = 'notEarlier';
        const NOT_BETWEEN   = 'notBetween';
    
        /**
         * Error messages
         * @var array
         */
        protected $_messageTemplates = array(
            self::NOT_SAME       => "The date '%value%' does not match the required",
            self::NOT_BETWEEN    => "The date is not in the valid range",
            self::NOT_LATER      => "The date '%value%' is not later than the required",
            self::NOT_EARLIER    => "The date '%value%' is not earlier than required",
            self::MISSING_TOKEN  => 'No date was provided to match against',
        );
    
        /**
         * @var array
         */
        protected $_messageVariables = array(
            'token' => '_tokenString'
        );
    
        /**
         * Original token against which to validate
         * @var string
         */
        protected $_tokenString;
        protected $_token;
        protected $_compare;
    
        /**
         * Sets validator options
         *
         * @param  mixed $token
         * @param  mixed $compare
         * @return void
         */
        public function __construct($token = null, $compare = null)
        {
            if (null !== $token) {
                $this->setToken($token);
                $this->setCompare($compare);
            }
        }
    
        /**
         * Set token against which to compare
         *
         * @param  mixed $token
         * @return Zend_Validate_Identical
         */
        public function setToken($token)
        {
            $this->_tokenString = (string) $token;
            $this->_token       = $token;
            return $this;
        }
    
        /**
         * Retrieve token
         *
         * @return string
         */
        public function getToken()
        {
            return $this->_token;
        }
    
        /**
         * Set compare against which to compare
         *
         * @param  mixed $compare
         * @return Zend_Validate_Identical
         */
        public function setCompare($compare)
        {
            $this->_compareString = (string) $compare;
            $this->_compare       = $compare;
            return $this;
        }
    
        /**
         * Retrieve compare
         *
         * @return string
         */
        public function getCompare()
        {
            return $this->_compare;
        }
    
        /**
         * Defined by Zend_Validate_Interface
         *
         * Returns true if and only if a token has been set and the provided value
         * matches that token.
         *
         * @param  mixed $value
         * @return boolean
         */
        public function isValid($value)
        {
            $this->_setValue((string) $value);
            $token = $this->getToken();
    
            if ($token === null) {
                $this->_error(self::MISSING_TOKEN);
                return false;
            }
    
            $date1 = new Zend_Date($value);
            $date2 = new Zend_Date($token);
    
            // Not Later
            if ($this->getCompare() === true){
                if ($date1->compare($date2) < 0 || $date1->equals($date2)) {
                    $this->_error(self::NOT_LATER);
                    return false;
                }
            // Not Earlier
            } elseif ($this->getCompare() === false) {
                if ($date1->compare($date2) > 0 || $date1->equals($date2)) {
                    $this->_error(self::NOT_EARLIER);
                    return false;
                }
            // Exact Match
            } elseif ($this->getCompare() === null) {
                if (!$date1->equals($date2)) {
                    $this->_error(self::NOT_SAME);
                    return false;
                }
            // In Range
            } else {
                $date3 = new Zend_Date($this->getCompare());
    
                if ($date1->compare($date2) < 0 || $date1->compare($date3) > 0) {
                    $this->_error(self::NOT_BETWEEN);
                    return false;
                }
            }
    
            // Date is valid
            return true;
        }
    }
    

    用法:

    $element->addValidator(new My_Validate_DateCompare('startdate')); //exact match
    $element->addValidator(new My_Validate_DateCompare('startdate', null)); //exact match
    $element->addValidator(new My_Validate_DateCompare('startdate', 'enddate')); //between dates
    $element->addValidator(new My_Validate_DateCompare('startdate', true)); //not later
    $element->addValidator(new My_Validate_DateCompare('startdate', false)); //not earlier
    

    使用全局设置的日期格式(存储在 Zend_Registry('Locale') 中)。

    还建议根据情况自定义错误消息。

    最新更新:修复了错误的默认可选参数,该参数应为 NULL 而不是 True。 更改了消息以减少混乱。 一些格式和空格。

    【讨论】:

    • 对不起,如果我想使用魔法方法,我应该调用验证器吗? $this-&gt;bookingdate-&gt;addValidator('DateCompare', false, array($this-&gt;begindate, $this-&gt;enddate));我试过了还是不行!
    • 您必须将路径注册到您的库 $form-&gt;addElementPrefixPath('My_Foo_Validate', 'My/Foo/Validate', 'validate'); ,您也可以更改类的前缀以匹配您的库
    • 我最终以这种方式解决了它:在我的控制器中,使用 setter 和 getter 将表单 $form = new Form_SetBookingDateChecking(array('begindate' =&gt; $checking-&gt;begindate, 'enddate' =&gt; $checking-&gt;enddate)); 设置为表单,然后使用验证器:$this-&gt;bookingdate-&gt;addValidator('DateCompare', false, array($this-&gt;getBegindate(), $this-&gt;getEnddate()));。我想澄清一下,在你的函数中有一个错误,这一行:if ($date1-&gt;compare($date2)&gt;0 || $date1-&gt;compare($date3)&lt;0){ 应该是if ($date1-&gt;compare($date2) &lt; 0 || $date1-&gt;compare($date3) &gt; 0) {。再次感谢!
    • 大声笑这是可能的,我会在这里修复它,我很久以前就做了这个,但最终没有使用它。
    • 我为你的班级写了一个测试phpunit。我希望它可以帮助你。我在下一个答案中发布!
    【解决方案2】:

    我为 venimus 的课程编写了一个测试 phpunit。我希望它可以帮助某人。

    class Validate_DateCompareTest extends PHPUnit_Framework_TestCase {
    
    public function dataForTest()
    {
        return array(
            array('2011-06-05', '2011-06-01', '2011-06-10', true), //between dates
            array('2011-06-10', '2011-06-01', '2011-06-10', true), //between dates
            array('2011-06-01', '2011-06-01', '2011-06-10', true), //between dates
            array('2011-06-15', '2011-06-01', '2011-06-10', false), //between dates
            array('2011-05-30', '2011-06-01', '2011-06-10', false), //between dates
            array('2011-06-01', '2011-06-01', null, true), //exact match
            array('2011-06-15', '2011-06-01', null, false), //exact match
            array('2011-05-30', '2011-06-01', null, false), //exact match
            array('2011-06-02', '2011-06-01', true, true), //not later
            array('2011-06-01', '2011-06-01', true, false), //not later
            array('2011-05-30', '2011-06-01', true, false), //not later
            array('2011-05-30', '2011-06-01', false, true), //not earlier
            array('2011-06-01', '2011-06-01', false, false), //not earlier
            array('2011-06-10', '2011-06-01', false, false), //not earlier
        );
    }
    
    /**
     * @dataProvider dataForTest
     * @param $value
     * @param $token
     * @param $compare
     * @param $expected
     * @return void
     */
    public function testDateCompare($value, $token, $compare, $expected)
    {
        /** @var $validate My_Validate_DateCompare */
        $validate = new My_Validate_DateCompare($token, $compare);
        $this->assertEquals(
            $expected,
            $validate->isValid($value),
            "value: $value -- token: $token -- compare: $compare"
        );
    }
    

    }

    这门课对我真的很有帮助,再次感谢!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-06
      • 2014-02-13
      • 1970-01-01
      • 2019-06-09
      • 2016-03-15
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多