Issues

ZF-12358: Zend form with an optional file / isValid function returns false if the file isn't uploaded

Description

I have the following form:

 
class Soulbag_Admin_Form_Issue_Article extends Zend_Form {
    public function init() {
        $element = new Zend_Form_Element_Text('title');
        $element
            ->setLabel('Titre')
            ->setRequired(true)
            ->addValidator(new Zend_Validate_NotEmpty());
        $this->addElement($element);

        $element = new Zend_Form_Element_Text('subtitle');
        $element->setLabel('Sous-titre');
        $this->addElement($element);
        
        $element = new Zend_Form_Element_Textarea('description');
        $element->setLabel('Description');
        $this->addElement($element);
        
        $element = new Zend_Form_Element_Radio('is_headline');
        $element
            ->setLabel('A la une')
            ->addMultiOptions(array('1' => 'Oui', '0' => 'Non'))
            ->setValue('0');
        $this->addElement($element);
        
        $element = new Zend_Form_Element_File('articleimage');
        $element
            ->setLabel('Image pour carousel')
            ->setDescription('JPEG 632x251 px')
            ->setRequired(false)
            ->setValueDisabled(true)
            ->addValidator('Count', true, array('min' => 0, 'max' => 1))
            ->setDestination(IMAGE_TMP_PATH);
        $this->addElement($element);
        
        $element = new Zend_Form_Element_Hidden('id');
        $element->addValidator(new Zend_Validate_Int())->setDecorators(array('ViewHelper'));
        $this->addElement($element);
        
        $element = new Zend_Form_Element_Hidden('issue_id');
        $element->addValidator(new Zend_Validate_Int())->setDecorators(array('ViewHelper'));
        $this->addElement($element);
        
        $this
            ->setAttrib('id', 'issue_article_form')
            ->setAttrib('enctype', 'multipart/form-data');
    }
}

So I want the file to be optional (required is set to false, and min count to 0).

Once submitted, I'm testing the form validity this way :

 
if ($this->getRequest()->isPost()) {
   if (!$this->view->form->isValid($this->getRequest()->getPost())) {
       ....

It works good when I upload a file, but when I don't, isValid returns false, despite I guess it shouldn't, as I set the file to be optional.

Concerning HTTP traces I have :

 
-----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="title" OTIS TAYLORss
-----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="subtitle" Le guérisseur
-----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="description" 

En préparation de la sortie de son nouvel album “Contraband” (Telarc), Otis Taylor nous a conviés à son Trance Blues Festival en novembre dernier. Un événement appelé, s’il se pérennise, à devenir majeur. C’est aussi l’occasion d’en apprendre plus sur l’homme. Retour sur l’œuvre, le parcours et l’intention artistique d’un personnage sans beaucoup d’équivalent.
Par Éric D.

-----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="is_headline" 0 -----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="MAX_FILE_SIZE" 2097152 -----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="articleimage" -----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="id" 597 -----------------------------4597977918582022601949785681 Content-Disposition: form-data; name="issue_id" -----------------------------4597977918582022601949785681--

After a little debug session on Zend framework, I think the problem comes from Zend_File_Transfer_Adapter_Abstract.setOptions, which is called by Zend_Form_Element_File.isValid.

In my case, as I ask the file to be optional, this code is called :

 
if (!$this->isRequired()) {
            $adapter->setOptions(array('ignoreNoFile' => true), $this->getName());

(Zend_Form_Element_File line 428)

In the Zend_File_Transfer_Adapter_Abstract.setOptions function, the first line is :

 
$file = $this->_getFiles($files, false, true);

In my case, this returns null, so the ignoreNoFile is never placed in the _files array. This returns null because the _files array is like that :

 
Array
(
    [articleimage] => Array
        (
            [destination] => /home/smennesson/workspace/soulbag_trunk/front/public/images/tmp
        )

)

There isn't a 'name' key set because the file isn't uploaded, but _getFiles expects a 'name' key to return something:

 if (!isset($content['name'])) {

line 1468

Maybe I'm misunderstanding something, please help.

Comments

No comments to display