ZF-12264: Lost value from first file element in form with several file elements.

Description

I have a form which allows to manage an information in DB. This form contains few text inputs, textareas and three file elements. When I submit the form, information is saved to DB (from file elements are saved names of files). In a class for this form I've set a 'required' only for first file element. And when I submit form, to DB get only second and third names of files. But in any another cases (first and second, first and third, only first) name of the first file gets to DB. And if I remove 'required' condition for first file element and submit form - everething is ok and all three names get to DB.

If you need little more information - ask. Thx in advance.

UPD: sorry for Form class view. I dont know why it looks like piece of text.

Class for my form:


class Form_AdminHotels extends Zend_Form
{
    public function init() {    
        $this->setMethod('POST');
        $this->setAttrib('enctype', 'multipart/form-data');     
        $this->setDecorators(array( 
            'FormElements', 
            array('HtmlTag', array('tag' => 'table')), 
            'Form' 
        )); 
        
        $this->setElementDecorators(array( 
            'ViewHelper', 
            'Errors', 
            array('decorator' => array('td' => 'HtmlTag'), 'options' => array('tag' => 'td')), 
            array('Label', array('tag' => 'td')), 
            array('decorator' => array('tr' => 'HtmlTag'), 'options' => array('tag' => 'tr')), 
        )); 
    
        $this->addElement('text', 'id', array(
            'label' => '#',
            'attribs' => array(
                'maxlength' => 100,
                'size' => 30,
                'readonly' => 'readonly'
            ),
            
            
        ));
        
        $this->addElement('text', 'name', array(
            'label' => 'Имя*',
            'attribs' => array(
                'maxlength' => 100,
                'size' => 30
            ),
            'validators' => array(
                array('StringLength', false, array(3,100, 'messages' => 'Введите корректное имя')),
                array('NotEmpty', true, array('messages' => 'Имя не может быть пустым')),
            ),          
            'required' => TRUE
        ));
        
                            
        $this->addElement('textarea', 'description', array(
            'label' => 'Описание',
            'attribs' => array(
                'maxlength' => 1000,
                'rows' => 10,
                'cols' => 35,
                'id' => 'replaced1'
            ),           
            'required' => TRUE
        ));
        
        
        $this->addElement('file', 'img1', array(
            'label' => 'Картинка 1',
            'attribs' => array(
                'maxlength' => 100,
                'size' => 30
            ),    
            
           //'required' => TRUE    <-- remove this comment
        ));
        $this->getElement('img1')->setDecorators(
            array(
                'File',
                'Errors',
                array(array('data' => 'HtmlTag'), array('tag' => 'td')),
                array('Label', array('tag' => 'th')),
                array(array('row' => 'HtmlTag'), array('tag' => 'tr'))
            )
        );
        
        $this->addElement('file', 'img2', array(
            'label' => 'Картинка 2',
            'attribs' => array(
                'maxlength' => 100,
                'size' => 30
            ),
                
            
        ));
        $this->getElement('img2')->setDecorators(
            array(
                'File',
                'Errors',
                array(array('data' => 'HtmlTag'), array('tag' => 'td')),
                array('Label', array('tag' => 'th')),
                array(array('row' => 'HtmlTag'), array('tag' => 'tr'))
            )
        );
        $this->addElement('file', 'img3', array(
            'label' => 'Картинка 3',
            'attribs' => array(
                'maxlength' => 100,
                'size' => 30
            ),
            
        ));
        $this->getElement('img3')->setDecorators(
            array(
                'File',
                'Errors',
                array(array('data' => 'HtmlTag'), array('tag' => 'td')),
                array('Label', array('tag' => 'th')),
                array(array('row' => 'HtmlTag'), array('tag' => 'tr'))
            )
        );
        
        $this->addElement('textarea', 'inside', array(
            'label' => 'Подробное описание',
            'attribs' => array(
                'maxlength' => 100000,
                'rows' => 10,
                'cols' => 35,
                'id' => 'replaced2'
            ),           
            'required' => TRUE
        ));
        
        $this->addElement('textarea', 'inHotel', array(
            'label' => 'Подробное описание',
            'attribs' => array(
                'maxlength' => 100000,
                'rows' => 10,
                'cols' => 35,
                'id' => 'replaced3'
            ),           
            'required' => TRUE
        ));
        
        $this->addElement('textarea', 'outside', array(
            'label' => 'Подробное описание',
            'attribs' => array(
                'maxlength' => 100000,
                'rows' => 10,
                'cols' => 35,
                'id' => 'replaced4'
            ),           
            'required' => TRUE
        ));
        
        
    }

}   

Action from controller:


public function hotelseditAction() {
        $this->view->ckeditor = 1;
        $this->view->datepicker = 1;        
        $hotelsMapper = new Application_Model_HotelsMapper();
        $id = $this->getRequest()->getParam('hotelId');
        $form = new Form_AdminHotels;
        $this->view->form = $form;
        if($id != 0) {
            $hotel = $hotelsMapper->getHotelById($id);
            //die(print_r($hotel->toArray()));
            $form->populate($hotel->toArray());         
        } 
        if ($this->getRequest()->isPost()) {
            $values = $this->getRequest()->getParams(); 
            if($form->isValid($values)){    
                $adapter = new Zend_File_Transfer_Adapter_Http();       
                $adapter->setDestination(APPLICATION_PATH.'/uploads');
                $adapter->receive();
                if (!$adapter->receive()) {
                    $messages = $adapter->getMessages();
                    echo implode("\n", $messages);
                    //die(print_r());
                }
                //die(print_r($form->getValues()));
                $hotel = new Application_Model_Hotels($form->getValues());          
                $hotelsMapper->save($hotel);
                
                $this->_helper->getHelper('redirector')->goToUrlAndExit($this->view->url(array(),'admin_hotels'));
            } else {
                $form->populate($values);
            }   
        }
    }

Application_Model_HotelsMapper class


class Application_Model_HotelsMapper
{
    protected $_dbTable;
    protected $_dbTableClass = 'Application_Model_DbTable_Hotels';
    protected $_select;

    public function __construct() {
        $this->_select = $this->getDbTable()->select();
    }
    
    public function setDbTable($dbTable)
    {       
        if (is_string($dbTable)) {          
            $dbTable = new $dbTable();
        }
        if (!$dbTable instanceof Zend_Db_Table_Abstract) {
            throw new Exception('Invalid table data gateway provided');
        }
        $this->_dbTable = $dbTable;
        return $this;
    }

    public function getDbTable()
    {       
        if (null === $this->_dbTable) {
            $this->setDbTable($this->_dbTableClass);
        }       
        return $this->_dbTable;
    }

    public function setJoins() {
        
    }
    
    public function save(Application_Model_Hotels $tour)
    {
        $data = array(            
            'description' => $tour->getDescription(),            
            'name' => $tour->getName(),
            'img1' => $tour->getImg1(),
            'img2' => $tour->getImg2(),
            'img3' => $tour->getImg3(),
            'inside' => $tour->getInside(),
            'inHotel' => $tour->getInHotel(),           
            'outside' => $tour->getOutside(),           
        );      
        if (null === ($id = $tour->getId())) {
            unset($data['id']);
            $this->getDbTable()->insert($data);
        } else {
            $this->getDbTable()->update($data, array('id = ?' => $id));
        }
    }
                
    public function getHotelById($hotelId) {
        $select = $this->_select->where('id = ?', $hotelId);
        return $this->getDbTable()->fetchRow($select);
    }
    
    public function deleteHotel($idList) {
        $this->getDbTable()->delete('id in ('.$idList.')');
    } 
    
    public function getAll() {      
        $select = $this->_select;       
        return $this->getDbTable()->fetchAll($select);
    }
    
    
}

Application_Model_Hotels Class


class Application_Model_Hotels
{
    protected $_name;
    protected $_id;
    protected $_description;    
    protected $_img1;
    protected $_img2;
    protected $_img3;
    protected $_inside;
    protected $_inHotel;
    protected $_outside;
    
    public function __construct(array $options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }

    public function __set($name, $value)
    {
        $method = 'set' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid comment property');
        }
        $this->$method($value);
    }

    public function __get($name)
    {
        $method = 'get' . $name;
        if (('mapper' == $name) || !method_exists($this, $method)) {
            throw new Exception('Invalid comment property');
        }
        return $this->$method();
    }

    public function setOptions(array $options)
    {       
        $methods = get_class_methods($this);        
        foreach ($options as $key => $value) {              
            $method = 'set' . ucfirst($key);                
            if (in_array($method, $methods)) {
                        
                $this->$method($value);
            }           
        }
        return $this;
    }

    public function setDescription($description)
    {
        $this->_description = $description;
        return $this;
    }

    public function getDescription()
    {
        return $this->_description;
    }   

    public function setName($name)
    {       
        $this->_name =  $name;      
        return $this;
    }

    public function getName()
    {
        return $this->_name;
    }
    
    public function setId($id)
    {
        $this->_id = (int) $id;
        return $this;
    }

    public function getId()
    {
        return $this->_id;
    }
    
        
    public function setImg1($img1)
    {
        $this->_img1 = $img1;
        return $this;
    }

    public function getImg1()
    {
        return $this->_img1;
    }
    
    public function setImg2($img2)
    {
        $this->_img2 = $img2;
        return $this;
    }

    public function getImg2()
    {
        return $this->_img2;
    }
    
    public function setImg3($img3)
    {
        $this->_img3 = $img3;
        return $this;
    }

    public function getImg3()
    {
        return $this->_img3;
    }
    
    public function setInside($inside)
    {
        $this->_inside = $inside;
        return $this;
    }

    public function getInside()
    {
        return $this->_inside;
    }
    
    public function setInHotel($inHotel)
    {
        $this->_inHotel = $inHotel;
        return $this;
    }

    public function getInHotel()
    {
        return $this->_inHotel;
    }
    
    public function setOutside($outside)
    {
        $this->_outside = $outside;
        return $this;
    }

    public function getOutside()
    {
        return $this->_outside;
    }
    
}

Table into DB:


CREATE TABLE IF NOT EXISTS `hotels` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `description` text COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
  `img1` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `img2` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `img3` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `inside` text COLLATE utf8_unicode_ci NOT NULL,
  `inHotel` text COLLATE utf8_unicode_ci NOT NULL,
  `outside` text COLLATE utf8_unicode_ci NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=2 ;

Comments

UPD: if you upload all files and before it set them as 'required' in form class - all names of files will not put into DB

Code tags added.