Thomas,
i always think that the implementation of the
Zend_File_Transfer_Adapter_Abstract::addValidator() incorrect. Just compare
the implementation of the Zend_Form_Element::_loadValidator() with it.

following are the two implementations,notice to the red highlight code.

following is the implementation of Zend_Form_Element::_loadValidator()

/**
     * Lazy-load a validator
     *
     * @param  array $validator Validator definition
     * @return Zend_Validate_Interface
     */
    protected function _loadValidator(array $validator)
    {
        $origName = $validator['validator'];
        $name     =
$this->getPluginLoader(self::VALIDATE)->load($validator['validator']);

        if (array_key_exists($name, $this->_validators)) {
            require_once 'Zend/Form/Exception.php';
            throw new Zend_Form_Exception(sprintf('Validator instance
already exists for validator "%s"', $origName));
        }

        if (empty($validator['options'])) {
            $instance = new $name;
        } else {
            $messages = false;
            if (isset($validator['options']['messages'])) {
                $messages = $validator['options']['messages'];
                unset($validator['options']['messages']);
            }

            $r = new ReflectionClass($name);
            if ($r->hasMethod('__construct')) {
                $instance = $r->newInstanceArgs((array)
$validator['options']);
            } else {
                $instance = $r->newInstance();
            }

            if ($messages) {
                if (is_array($messages)) {
                    $instance->setMessages($messages);
                } elseif (is_string($messages)) {
                    $instance->setMessage($messages);
                }
            }
        }

        $instance->zfBreakChainOnFailure =
$validator['breakChainOnFailure'];

        if ($origName != $name) {
            $validatorNames     = array_keys($this->_validators);
            $order              = array_flip($validatorNames);
            $order[$name]       = $order[$origName];
            $validatorsExchange = array();
            unset($order[$origName]);
            asort($order);
            foreach ($order as $key => $index) {
                if ($key == $name) {
                    $validatorsExchange[$key] = $instance;
                    continue;
                }
                $validatorsExchange[$key] = $this->_validators[$key];
            }
            $this->_validators = $validatorsExchange;
        } else {
            $this->_validators[$name] = $instance;
        }

        return $instance;
    }

and following is the implementation of
Zend_File_Transfer_Adapter_Abstract:: addValidator()

/**
     * Adds a new validator for this class
     *
     * @param  string|array $validator           Type of validator to add
     * @param  boolean      $breakChainOnFailure If the validation chain
should stop an failure
     * @param  string|array $options             Options to set for the
validator
     * @param  string|array $files               Files to limit this
validator to
     * @return Zend_File_Transfer_Adapter
     */
    public function addValidator($validator, $breakChainOnFailure = false,
$options = null, $files = null)
    {
        if ($validator instanceof Zend_Validate_Interface) {
            $name = get_class($validator);
        } elseif (is_string($validator)) {
            $name      =
$this->getPluginLoader(self::VALIDATE)->load($validator);
            $validator = new $name($options);
            if (is_array($options) && isset($options['messages'])) {
                if (is_array($options['messages'])) {
                    $validator->setMessages($options['messages']);
                } elseif (is_string($options['messages'])) {
                    $validator->setMessage($options['messages']);
                }

                unset($options['messages']);
            }
        } else {
            require_once 'Zend/File/Transfer/Exception.php';
            throw new Zend_File_Transfer_Exception('Invalid validator
provided to addValidator; must be string or Zend_Validate_Interface');
        }

        $this->_validators[$name] = $validator;
        $this->_break[$name]      = $breakChainOnFailure;
        $files                    = $this->_getFiles($files, true, true);
        foreach ($files as $file) {
            $this->_files[$file]['validators'][] = $name;
            $this->_files[$file]['validated']    = false;
        }

        return $this;
    }

in the Zend_Form_Element::_loadValidator(), it instance a validator after
unset the messages from the options,because the messages options should not
be apart the parameters of the validator constructor.It should be the custom
error messages for the validator.

Best regards
Jacky

2009/3/31 Thomas Weidner <thomas.weid...@gmx.at>

> So you propose that Zend_Form_Element_File and Zend_File_Transfer should
> not behave the same like all other Zend_Form_Element's ?
>
> This would be unlogically and lead to a difference between the elements. I
> see no reason why we should not allow to overwrite messages from a validator
> for the file element, but for all others.
>
> Greetings
> Thomas Weidner, I18N Team Leader, Zend Framework
> http://www.thomasweidner.com
>
> ----- Original Message ----- From: "Jacky Chen" <jacky...@gmail.com>
> To: "Thomas Weidner" <thomas.weid...@gmx.at>
> Sent: Tuesday, March 31, 2009 4:24 AM
> Subject: Re: [fw-general] Bug with zend_file addValidator method
>
>
> Thomas,
> may be you don't understand me, sorry for my poor english.
>
> for example,i add the file IsImage validator to the file element as
> following:
>
> $file = new Zend_Form_Element_File('file');
> $file->addValidator('isImage',true,array('messages'=>array(Z
> end_Validate_File_IsImage::NOT_DETECTED=>'the file is not an image')));
>
> then,in the addValidator() method of file transfer adapter would pass the
> $options that contains the
> array('messages'=>array(Zend_Validate_File_IsImage::NOT_DETECTED=>'the file
> is not an image')) to the IsImage validator constructor.Actually, the
> 'messages' option should not pass to the IsImage validator constructor.
>
> compare the _loadValidator() method in the Zend_Form_Element and the
> addValidator() method in the Zend_File_Transfer_Adapter_Abstract as
> following highlight code:
>
> Zend_Form_Element::_loadValidator():
> -----------------------------------------
> protected function _loadValidator(array $validator)
>   {
>       $origName = $validator['validator'];
>       $name     =
> $this->getPluginLoader(self::VALIDATE)->load($validator['validator']);
>
>       if (array_key_exists($name, $this->_validators)) {
>           require_once 'Zend/Form/Exception.php';
>           throw new Zend_Form_Exception(sprintf('Validator instance
> already exists for validator "%s"', $origName));
>       }
>
>       if (empty($validator['options'])) {
>           $instance = new $name;
>       } else {
>           $messages = false;
>           if (isset($validator['options']['messages'])) {
>               $messages = $validator['options']['messages'];
>               unset($validator['options']['messages']);
>           }
>
>           $r = new ReflectionClass($name);
>           if ($r->hasMethod('__construct')) {
>               $instance = $r->newInstanceArgs((array)
> $validator['options']);
>           } else {
>               $instance = $r->newInstance();
>           }
>
>           if ($messages) {
>               if (is_array($messages)) {
>                   $instance->setMessages($messages);
>               } elseif (is_string($messages)) {
>                   $instance->setMessage($messages);
>               }
>           }
>       }
>
>       $instance->zfBreakChainOnFailure =
> $validator['breakChainOnFailure'];
>
>       if ($origName != $name) {
>           $validatorNames     = array_keys($this->_validators);
>           $order              = array_flip($validatorNames);
>           $order[$name]       = $order[$origName];
>           $validatorsExchange = array();
>           unset($order[$origName]);
>           asort($order);
>           foreach ($order as $key => $index) {
>               if ($key == $name) {
>                   $validatorsExchange[$key] = $instance;
>                   continue;
>               }
>               $validatorsExchange[$key] = $this->_validators[$key];
>           }
>           $this->_validators = $validatorsExchange;
>       } else {
>           $this->_validators[$name] = $instance;
>       }
>
>       return $instance;
>   }
>
> Zend_File_Transfer_Adapter_Abstract::addValidator()
>
> -------------------------------------------------------------------------------
> public function addValidator($validator, $breakChainOnFailure = false,
> $options = null, $files = null)
>   {
>       if ($validator instanceof Zend_Validate_Interface) {
>           $name = get_class($validator);
>       } elseif (is_string($validator)) {
>           $name      =
> $this->getPluginLoader(self::VALIDATE)->load($validator);
>           $validator = new $name($options);
>           if (is_array($options) && isset($options['messages'])) {
>               if (is_array($options['messages'])) {
>                   $validator->setMessages($options['messages']);
>               } elseif (is_string($options['messages'])) {
>                   $validator->setMessage($options['messages']);
>               }
>
>               unset($options['messages']);
>           }
>       } else {
>           require_once 'Zend/File/Transfer/Exception.php';
>           throw new Zend_File_Transfer_Exception('Invalid validator
> provided to addValidator; must be string or Zend_Validate_Interface');
>       }
>
>       $this->_validators[$name] = $validator;
>       $this->_break[$name]      = $breakChainOnFailure;
>       $files                    = $this->_getFiles($files, true, true);
>       foreach ($files as $file) {
>           $this->_files[$file]['validators'][] = $name;
>           $this->_files[$file]['validated']    = false;
>       }
>
>       return $this;
>   }
>
>
> sorry for my poor english again,i can't describe my mind clearly.
>
> Best Regards,
> Jacky
>
> 2009/3/31 Thomas Weidner <thomas.weid...@gmx.at>
>
>  Zend_File_Transfer behaves exactly the same as Zend_Form.
>> Both components do not allow to overwrite existing options on a validator
>> instance.
>>
>> The reason is that when you give a instance of Zend_Validate_Interface
>> (where you have to extend your validators from) you must already have set
>> any wished options as the setOptions() method is not defined within this
>> interface.
>>
>> So the options array is only valid for all Zend validators but not for
>> self
>> created validators.
>>
>> Greetings
>> Thomas Weidner, I18N Team Leader, Zend Framework
>> http://www.thomasweidner.com
>>
>> ----- Original Message ----- From: "Jacky Chen" <jacky...@gmail.com>
>> To: "Thomas Weidner" <thomas.weid...@gmx.at>
>> Sent: Monday, March 30, 2009 7:28 PM
>> Subject: Re: [fw-general] Bug with zend_file addValidator method
>>
>>
>>
>> sorry,it is Zend_File_Transfer_Adapter_Abstract, within the method
>> addValidator() of the class,the validator was instance before the
>> $options['messages'] been unset.
>> the code as following:
>>
>> public function addValidator($validator, $breakChainOnFailure = false,
>> $options = null, $files = null)
>> {
>>      if ($validator instanceof Zend_Validate_Interface) {
>>          $name = get_class($validator);
>>      } elseif (is_string($validator)) {
>>          $name      =
>> $this->getPluginLoader(self::VALIDATE)->load($validator);
>>          $validator = new $name($options);
>>          if (is_array($options) && isset($options['messages'])) {
>>              if (is_array($options['messages'])) {
>>                  $validator->setMessages($options['messages']);
>>              } elseif (is_string($options['messages'])) {
>>                  $validator->setMessage($options['messages']);
>>              }
>>              unset($options['messages']);
>>          }
>>      } else {
>>       ......
>>
>> in the above highlight code,shoud change to :
>>
>>   $messages = false;
>>   if (is_array($options) && isset($options['messages'])) {
>>       $messages = $options['messages'];
>>       unset($options['messages']);
>>   }
>>   $validator = new $name($options);
>>   if ($messages) {
>>        if (is_array($messages)) {
>>             $validator->setMessages($messages);
>>        } elseif (is_string($messages)) {
>>             $validator->setMessage($messages);
>>        }
>>   }
>>
>> Best Regards,
>> Jacky
>>
>> 2009/3/30 Thomas Weidner <thomas.weid...@gmx.at>
>>
>>  Sorry, but your description is not very descriptive.
>>
>>> Maybe you can give a example of what's your problem ?
>>>
>>> PS: There is no Zend_File_Adapter class or component.
>>>
>>> Greetings
>>> Thomas Weidner, I18N Team Leader, Zend Framework
>>> http://www.thomasweidner.com
>>>
>>> ----- Original Message ----- From: "Jacky Chen" <jacky...@gmail.com>
>>> To: <fw-general@lists.zend.com>
>>> Sent: Monday, March 30, 2009 12:05 PM
>>> Subject: [fw-general] Bug with zend_file addValidator method
>>>
>>>
>>>
>>> Hi there,
>>> there is a bug for the method addValidator in Zend_File Adapter,it should
>>> construct the validator instance after unset the options with messages.
>>>
>>> Best Regards,
>>> Jacky
>>>
>>>
>>>
>>>
>>
>

Reply via email to