Use Zend_Form_Element_File in CRUD

image

When designing applications in Zend Framework using Zend_Form component simplifies working with the entity once created the form with the configured validators, filters, and so forth, as used when creating and when editing data in the database.
Very often entities contain elements of type File – whether it be a picture preview, file name for downloading or photo in the gallery. That's only if You want to change the essence of the form which has a File element, it becomes clear that standard decorator Zend_Form_Element_File is not suitable for the shape change of the essence – because it can't display the presence of the loaded file, does not allow to delete this file, etc.

In other words, when you open the entity for the changes, all the other form elements are populated with values from database – in this case Zend_Form_Element_File do not have.
In this article I want to share my implementation work with Zend_Form_Element_File through the creation of CRUD (create-read-update-delete) on ZendFramework 1.11

Under jabracada you expect a detailed description of how to create a decorator how to attach it to the form and instructions for working with the controller.



Zend_Form_Element_File – General information, features


When you add a new entity in the database Zend_Form_Element_File is the following (standard) way:
image

If you change the entity Zend_Form_Element_File by default looks similar. Our task is to bring this element to this:
image
Accordingly, displays the current loaded file name, the element to indicate the new file (the old one will be replaced by them), and a checkbox to remove an uploaded file and reset the column with a photo for the edited entity.

Create your own decorator for Zend_Form_Element_File

To do this, in the folder application/forms/Decorators create a file File.php with the following class

    <?php

    class Application_Form_Decorators_File extends Zend_Form_Decorator_Abstract

    {

    public function buildLabel()

    {

    $element = $this->getElement();

    $label = $element->getLabel();

    if ($translator = $element->getTranslator()) {

    $label = $translator->translate($label);

    }

    if ($element->isRequired()) {

    $label .= '*';

    }

    $label .= ':';

    return $element->getView()

    ->formLabel($element->getName(), $label);

    }

    public function buildInput()

    $element = $this->getElement();

    $helper = $element->helper;

    return $element->getView()->$helper(

    $element->getName(),

    $element->getValue(),

    $element->getAttribs(),

    $element->options

    );

    }

    public function buildErrors()

    {

    $element = $this->getElement();

    $messages = $element->getMessages();

    if (empty($messages)) {

    return ";

    }

    return '<div class="errors">' .

    $element->getView()->formErrors($messages) . '</div>';

    }

    public function buildDescription()

    {

    $element = $this->getElement();

    $desc = $element->getDescription();

    if (empty($desc)) {

    return ";

    }

    return '<div class="description">' . $desc . '</div>';

    }

    public function render($content)

    {

    $element = $this->getElement();

    if (!$element instanceof Zend_Form_Element) {

    return $content;

    }

    if (null === $element->getView()) {

    return $content;

    $separator = $this->getSeparator();

    $placement = $this->getPlacement();

    $label = $this->buildLabel();

    $input = $this->buildInput();

    $errors = $this->buildErrors();

    $desc = $this->buildDescription();

    $renderedContent = $element->getView()->partial(

    'decorators/file.phtml',

    array('element'=>$element));

    $output = '<tr><td>'

    . $label .'</td><td>' . $renderedContent

    . $input

    . $errors

    . $desc

    . '</td></tr>';

    switch ($placement) {

    case (self::PREPEND):

    return $output . $separator . $content;

    case (self::APPEND):

    default:

    return $content . $separator . $output;

    }

    }

    }



Thus we can assemble the element appearance "in parts", adding the desired information to output. With the help of the user

    $renderedContent = $element->getView()->partial(

    'decorators/file.phtml',

    array('element'=>$element));



Along the way, share information about current element (Zend_Form_Element_File) as $element (needed for
will render the file application/views/scripts/decorators/file.phtml with the following content:

    the
  1. You have uploaded a photo '<?php echo $this->element->getDescription(); ?>'.<br>
  2. the
  3. You can change the photo, putting a new file. If the change of pictures is not required, leave this field blank. <br>
  4. <input name="<?php echo $this->element->getName(); ?>_checkbox" type="checkbox" value="on" /><br />



the Use of decorators in the form


As a custom designer is only needed when you change the entity, adding an entity subject to a standard decorator:

    if ($this->_options['type'] == 'edit' && !is_null($this->_options['photo_file'])) {

    $photo->setDescription($this->_options['photo_file']);

    $photo->setDecorators(array(

    array('ViewScript', array('viewScript' => 'decorators/file.phtml')),

    'File',

    'Errors',

    array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')),

    array('Label', array('tag' => 'td')),

    array(array('row' => 'HtmlTag'), array('tag' => 'tr'))

    ));

    } else {

    $photo->setDecorators(array(

    'File',

    'Errors',

    array(array('data' => 'HtmlTag'), array('tag' => 'td', 'class' => 'element')),

    array('Label', array('tag' => 'td')),

    array(array('row' => 'HtmlTag'), array('tag' => 'tr'))

    ));



Using a decorator in the controller:


For each uploaded picture created previews with the filter, respectively, when deletion of the images should delete and a preview.

    // if checked for deletion, delete the file and pidem in the database is null

    if (!is_null($this->getRequest()->getParam('photo_checkbox')) && $this->getRequest()->getParam('photo_checkbox') == 'on') {

    if (file_exists(PUBLIC_PATH . '/userfiles/images/full/' . $item->photo))

    unlink(PUBLIC_PATH . '/userfiles/images/full/' . $item->photo);

    if (file_exists(PUBLIC_PATH . '/userfiles/images/thumb/' . $item->photo))

    unlink(PUBLIC_PATH . '/userfiles/images/thumb/' . $item->photo);

    $item->photo = null;

    }

    // if you specify a new file and uploaded it, then deleted the old file and write to new database.

    // if the File element is not filled in, $form- > photo- > getFileName() == array(null) ;

    if (!is_null($form->photo->getFileName()) && count($form->photo->getFileName()) != 0) {

    if (file_exists(PUBLIC_PATH . '/userfiles/images/full/' . $item->photo)) {

    unlink(PUBLIC_PATH . '/userfiles/images/full/' . $item->photo);

    }

    if (file_exists(PUBLIC_PATH . '/userfiles/images/thumb/' . $item->photo)) {

    unlink(PUBLIC_PATH . '/userfiles/images/thumb/' . $item->photo);

    }

    $item->photo = $form->getValue('photo');



Source code:


    the
  1. Application_Form_Decorators_File
  2. the
  3. Application_Form_Photogallery
  4. the
  5. PhotogalleryController


If the topic is relevant, then some more material about writing of filters for processing images uploaded via Zend_Form_Element_File (gdlib and imagic).

Thank you for your attention, accept comments and suggestions. Not so long ago started to learn Zend Framework, solutions such tasks are not found — I had to fix by myself. If something is not done quite correctly and (or) not in the style of ZF, please unsubscribe in the comments, will correct.

The current implementation works successfully.
Article based on information from habrahabr.ru

Comments

Popular posts from this blog

Powershell and Cyrillic in the console (updated)

Active/Passive PostgreSQL Cluster, using Pacemaker, Corosync

Automatic deployment ElasticBeanstalk using Bitbucket Pipelines