Zend Framework: Upload file by using Zend Form Element

filezend-formzend-framework

At this moment I am working on a Form in Zend Framework.
It has to become a Form where a company can fill in candidate details.

I am pretty new with Zend, so that's why I am posting my question.

This is what the form looks like (some fields removed to make the code shorter)

<?php

class Application_Form_Validate_ContactMethodSelected extends Zend_Validate_Abstract {
const INVALID = 'invalid';

protected $_messageTemplates = array(
    self::INVALID => 'Ten minste 1 vorm van contact invullen, telefoon, mobiel of e-mail'
);

public function isValid($value, $context = array())
{
// You need to use your element names, consider making these dynamic
$checkFields = array('telefoon','mobiel','mail');
// Check if all are empty
foreach ( $checkFields as $field ) {
if (isset($context[$field]) && !empty($context[$field])) {

    if (!empty($value)) {
        // This is the element with content... validate as true
        return true;
    }
    // we are going to return false and no error
    // to break validation chain on other empty values
    // This is a quick hack, don't have time to invest in this
    return false;
    }
}

// All were empty, set your own error message
$this->_error(self::INVALID);
return false;
}

}


class Application_Form_Nieuwkandidaat extends Zend_Form {

public function init() {
    $this->setMethod('post');

    $DB = Zend_Db_Table::getDefaultAdapter();

    $id = $this->createElement('hidden', 'id');
    $voornaam = $this->createElement('text', 'voornaam');
    $voornaam->setLabel('Voornaam:')
            ->setAttrib('size', 50)->addValidator('StringLength', false, array(2, 30))
            ->setRequired(true);
    $telefoon = $this->createElement('text', 'telefoon');
    $telefoon->setLabel('Telefoon:')
            ->setAttrib('size', 50)->setAllowEmpty(false)
            ->addValidator(new Application_Form_Validate_ContactMethodSelected(), true)
            ->addValidator('StringLength', false, array(10, 10));
    $mobiel = $this->createElement('text', 'mobiel');
    $mobiel->setLabel('Mobiel:')
            ->setAttrib('size', 50)->setAllowEmpty(false)
            ->addValidator(new Application_Form_Validate_ContactMethodSelected(), true)
            ->addValidator('StringLength', false, array(10, 10));
    $mail = $this->createElement('text', 'mail');
    $mail->setLabel('E-mail:')
            ->setAttrib('size', 50)->setAllowEmpty(false)
            ->addValidator(new Application_Form_Validate_ContactMethodSelected(), true)
            ->addValidator('StringLength', false, array(6, 40))->addValidator('EmailAddress', true);
    $register = $this->createElement('submit', 'register');
    $register->setLabel("Verstuur")
            ->setIgnore(true);
    $reset = $this->createElement('reset', 'reset');
    $reset->setLabel("Reset")
            ->setIgnore(true);
    $this->addElements(array(
        $voornaam,
        $mobiel,
        $telefoon,
        $mail,
        $id,
    ));

    $this->addDisplayGroup(array(
        'voornaam',
        'mobiel',
        'telefoon',
        'mail',
        'telefoon'
            ), 'contacts', array('legend' => 'Contact Informatie'));

    $contacts = $this->getDisplayGroup('contacts');
    $contacts->setDecorators(array(
        'FormElements',
        'Fieldset',
        array('HtmlTag', array('tag' => 'div', 'style' => 'width:50%;;float:left;'))
    ));

    $this->setDecorators(array(
        'FormElements',
        array('HtmlTag', array('tag' => 'div', 'style' => 'width:98%')),
        'Form'
    ));

    $this->addElement($register);
}

}

How can I add a form element where I can select a file and upload it, so it will be stored (let's say for example in /application/tmp)

If I have to place the code from my controller, please let me know as well

Thanks in advance!

Best Answer

First of all, rather than extending Zend_Validate_Abstract, you should be extending Zend_Form with an init() method where you can create your form elements:

<?php

class Application_Form_ContactMethodSelected extends Zend_Form
{
    public function init()
    {
    }
}

Now that you have an actual form to work with, you can add things like your File upload element:

<?php

class Application_Form_ContactMethodSelected extends Zend_Form
{
    public function init()
    {
        $this->setAttrib('enctype', 'multipart/form-data');

        $file = new Zend_Form_Element_File('file');
        $file->setLabel('File')
            ->setDestination(APPLICATION_PATH . '/tmp')
            ->setRequired(true);

        $submit = new Zend_Form_Element_Submit('submit');
        $submit->setLabel('Upload');

        $this->addElements(array($file, $submit));
    }
}

Now that you have a form with some elements, you can use it in your controller:

<?php

class IndexController extends Zend_Controller_Action 
{
    public function indexAction() 
    {
        $form = new Application_Form_ContactMethodSelected();

        if ($this->_request->isPost()) {
            $formData = $this->_request->getPost();
            if ($form->isValid($formData)) {

                // success - do something with the uploaded file
                $uploadedData = $form->getValues();
                $fullFilePath = $form->file->getFileName();

                Zend_Debug::dump($uploadedData, '$uploadedData');
                Zend_Debug::dump($fullFilePath, '$fullFilePath');

                echo "done";
                exit;

            } else {
                $form->populate($formData);
            }
        }

        $this->view->form = $form;
    }
}

And in your view script, you can display your form:

<h1>My upload form</h1>
<?php echo $this->form; ?>