Search code examples
zend-frameworkzend-formzend-file

Zend Form File, How to indicate to the user that a file was previously uploaded?


I have a zend form that lets the user fill out attributes of an object. For example, a music artist. The form has basic information about the artist, things like name, phone number, address, and what not, but it also has a file upload field. If the user uploads a file, its stored with this instance of the object in the database (essentially a row), if the user ever wants to edit this particular instance, the form is repopulated with the objects information. However the form does not repopulate the file upload information because its not going to reupload it.

How can I signal to the user that a file was already uploaded, indicate which file it was, and possibly even link to it? something similar to populating the form elements is preferred. I'd ideally like to be able to offer the user the ability to upload over the previously uploaded file, so the file upload element should stay. Any idea? Thanks a lot for reading.

Cheers, Joe Chin


Solution

  • The fastest way I found to get this implemented was to combine the answer from Chelmertz with this thread.

    Instead of defining a decorator to show the previously uploaded file, I am placing the link in the description for the element and then I am dumping it into a view script.

    The final solution looks like this:

    Zend Form File:

    class Application_Form_LabDetails extends Zend_Form{
    private $_uploadPath;
    private $_artistID;
    private $_singleFile;
    
    public function __construct($options = array()) {
    
        if(isset($options['uploadPath'])) {
            $this->_uploadPath = $options['uploadPath'];
            unset($options['uploadPath']);
        }
    
        if(isset($options['artistID'])) {
            $this->_artistID = sprintf("%06s",(string)$options['artistID']);
            unset($options['artistID']);
        }
    
        if(isset($options['singleFile'])) {
            $this->_singleID = $options['singleFile'];
            unset($options['singleFile']);
        }
    
        return parent::__construct($options);
    }
    
    public function init()
    {
        $this->setName('artistDetails');
    
        ...
    
        $singleID = $this->createElement('file', '$singleFile');
        $singleID->setLabel('Current Single')
            ->setDestination('data/uploads')
            ->addValidator('count',true, 1)
            ->addValidator('Size', true, 5242880)
            ->addValidator('Extension', true, 'mp3');
    
        if($this->_cocFile){
            $singleID->setDescription(
                '<a href="/'.$this->_uploadPath.'/'.$this->_artistID
                .$this->_singleFile.'" taget="_blank">'
                .$this->_singleFile.'</a>')
            ->setDecorators(
                array('File',
                array('ViewScript',
                array('viewScript' => 'artist/file.phtml', 'placement' => false)
                )));
        }
    
        ...
    }}
    

    View script to handle file details and form element:

    <!-- decorator through view script,  placed in 'views/scripts/controller/file.phtml' -->
    <!-- outputs form label markup -->
    <dt id="<?php echo $this->element->getName(); ?>-label">
        <label for="<?php echo $this->element->getName(); ?>" 
            class="<?php if ($this->element->isRequired()): ?>required<?php endif; ?>">
            <?php echo $this->element->getLabel(); ?></label><br />
        <span>Uploaded: <?php echo $this->element->getDescription(); ?></span>
    </dt>
    
    <!-- outputs form element markup -->
    <dd id="<?php echo $this->element->getName(); ?>-element">
        <?php echo $this->content; ?>
        <?php if ($this->element->hasErrors()): ?>
            <ul class="error">
                <?php echo $this->formErrors($this->element->getMessages()); ?>
            </ul>
        <?php endif; ?>
    </dd>
    

    Lastly in the controller I have:

    //$id is taken from the URI
    if ($id > 0) {
    
        $artistDetails = new Application_Model_DbTable_ArtistDetails();
        $artistData = $artistDetails->getArtistDetails($id);
        $options = array(
            'uploadPath' => $config->uploads->labs->path,
            'artistID' => $artistData['a_id'],
            'singleFile' => $artistData['a_singleFile'],
            );
    
        $form = new Application_Form_LabDetails($options);
    
        ...
    
    }
    

    This should give you something that looks like:

    alt text