Проблема проверки и / или фильтрации Zend Framework - PullRequest
1 голос
/ 30 марта 2012

У меня проблема с фильтрацией и проверкой формы ниже. Если два мобильных номера введены в национальном формате (07777654321), проверка формы завершается неудачно, но если они введены в международном формате (447777654321), она проверяется. Насколько я понимаю, фильтры будут применяться первыми, поэтому при применении идентичных параметров mobile и mobile_confirm должны обрабатываться с одинаковым набором фильтров.

Так что, если я введу 07777654321 в оба поля, оно будет отфильтровано до 447777654321 в обоих полях, которые затем должны быть проверены. Куда я иду не так.

Я использую ZF 1.11.3.

<?php

class Test_Form_Check extends Zend_Form
{

    public function init()
    {

        $mobile= new Zend_Form_Element_Text( 'mobile' );
        $mobile->addFilter(new Test_Filter_MobileFilter('44'))
                ->addValidator(new Test_Validate_Mobile())
                ->setRequired( true );

        $mobile1= new Zend_Form_Element_Text( 'mobile_confirm' );
        $mobile1->addFilter(new Test_Filter_MobileFilter('44'))
                ->addValidator(new Test_Validate_Mobile())
                ->addValidator('Identical', false, array('token' => 'mobile', 'messages' => 'Mobile numbers do not match.'))
                ->setRequired( true );

        $Add = new Zend_Form_Element_Submit('Add');
        $Add->setLabel('Submit');

        $this->addElement($mobile)
                ->addElement($mobile1)
                ->addElement( $Add );

    }
}


class Test_Validate_Mobile extends Zend_Validate_Abstract
{
    const NOT_DIGITS   = 'notDigits';
    const STRING_EMPTY = 'digitsStringEmpty';
    const INVALID      = 'digitsInvalid';
    const INVALIDPHONE = 'phonenumberinvalid';

    protected static $_filter = null;

    protected $_messageTemplates = array(
        self::NOT_DIGITS   => "'%value%' must contain only digits",
        self::STRING_EMPTY => "'%value%' is an empty string",
        self::INVALID      => "Invalid type given. String, integer or float expected",
        self::INVALIDPHONE => "Invalid number, try with country code",
    );


    public function isValid($value)
    {
        if (!is_string($value) && !is_int($value) && !is_float($value)) {
            $this->_error(self::INVALID);
            return false;
        }

        if (!preg_match('/^(447)[0-9]{9}$/', $value)) {
            $this->_error(self::INVALIDPHONE);
            return false;
        }

        $this->_setValue((string) $value);

        if ('' === $this->_value) {
            $this->_error(self::STRING_EMPTY);
            return false;
        }

        if (null === self::$_filter) {
            require_once 'Zend/Filter/Digits.php';
            self::$_filter = new Zend_Filter_Digits();
        }

        if ($this->_value !== self::$_filter->filter($this->_value)) {
            $this->_error(self::NOT_DIGITS);
            return false;
        }

        return true;
    }
}


class Test_Filter_MobileFilter implements Zend_Filter_Interface
{
    /**
    * Default country code
    *
    * @var string
    */
    protected $_def_country = '44';

    public function __construct($options = null)
    {
        if ($options !== null) {
            if (is_string($options) && is_numeric($options)) {
                $this->_def_country = $options;
            }
            else {
                require_once 'Zend/Filter/Exception.php';
                throw new Zend_Filter_Exception('Options not valid country code');
            }
        }
    }

    public function filter($value)
    {
        if (!empty($value)) {
            $replace = array(' ','+','-','(',')');

            $value = str_replace($replace, '', $value);
            $value = preg_replace('/\A0/', $this->_def_country, $value);

        }
        return $value;
    }

}

Я буду очень благодарен за любую помощь с этим. Он ведет меня за поворот.

1 Ответ

3 голосов
/ 30 марта 2012

Я думаю, проблема в валидаторе Zend_Validate_Identical, он использует необработанное необработанное значение из $ _POST. Просто быстрое решение:

class My_Validate_Identical extends Zend_Validate_Identical
{
    /**
     *
     * @var Zend_Form_Element 
     */
    protected $_element = null;

    public function __construct($token = null)
    {
        if (is_array($token) && array_key_exists('element', $token)) {
            $this->_element = $token['element'];
        }
        parent::__construct($token);
    }
    public function isValid($value, $context = null)
    {
        $context[$this->getToken()] = $this->_element->getValue();
        return parent::isValid($value, $context);
    }    
}

Прикрепление валидатора:

$mobile1->addValidator(new My_Validate_Identical(array(
                'token' => 'mobile', 
                'messages' => 'Mobile numbers do not match.',
                'element' => $mobile
                )))

Надеюсь, это поможет:)

...