2010-09-11 15 views
3

J'ai un formulaire zend qui permet à l'utilisateur de remplir les attributs d'un objet. Par exemple, un artiste de musique. Le formulaire contient des informations de base sur l'artiste, telles que le nom, le numéro de téléphone, l'adresse, etc., mais il contient également un champ de téléchargement de fichier. Si l'utilisateur télécharge un fichier, il est stocké avec cette instance de l'objet dans la base de données (essentiellement une ligne), si l'utilisateur veut jamais modifier cette instance particulière, le formulaire est repeuplé avec les informations sur les objets. Cependant, le formulaire ne repeuple pas les informations de téléchargement de fichier car il ne va pas le ré-uploader.Fichier Zend Form, Comment indiquer à l'utilisateur qu'un fichier a déjà été téléchargé?

Comment puis-je signaler à l'utilisateur qu'un fichier a déjà été téléchargé, indiquer quel fichier il contient, et éventuellement même le lier? quelque chose de similaire à remplir les éléments de formulaire est préféré. J'aimerais idéalement être en mesure d'offrir à l'utilisateur la possibilité de télécharger sur le fichier précédemment téléchargé, de sorte que l'élément de téléchargement de fichier devrait rester. Une idée? Merci beaucoup pour la lecture.

Cheers, Joe Chin

Répondre

6

Le moyen le plus rapide que j'ai trouvé pour obtenir cette implémentation était de combiner the answer from Chelmertz avec this thread. Au lieu de définir un décorateur pour montrer le fichier précédemment téléchargé, je place le lien dans la description de l'élément et ensuite je le jette dans un script de vue.

La solution finale ressemble à ceci:

Zend Form fichier:

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) 
      ))); 
    } 

    ... 
}} 

Voir script pour gérer les détails du fichier et de l'élément de forme:

<!-- 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> 

Enfin dans le contrôleur je:

//$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); 

    ... 

} 

Cela devrait vous donner quelque chose qui ressemble à:

alt text

2

How can I signal to the user that a file was already uploaded, indicate which file it was, and possibly even link to it?

Je n'imprimer le fichier téléchargé précédemment.

Pour ce faire, vous pouvez utiliser un décorateur de formulaire. Ceci est une esquisse qui doit être modifiée et refactorisée en gardant à l'esprit la sécurité, mais imprime une image-tag. (Si vous préférez afficher une liste de fichiers, il y a un soupçon à la fin.)

// has to override a File-decorator in my case 
class ArtistDecorator extends Zend_Form_Decorator_File { 
    private $_artistId; 
    public function __construct($options = array()) { 
     if(isset($options['artistId'])) { 
      $this->_artistId = $options['artistId']; 
      unset($options['artistId']); 
     } 
     return parent::__construct($options); 
    } 

    public function render($content) { 
     return '<img src="/images/'.$this->_artistId.'.jpg" />'.$content; 
    } 
} 

class Application_Form_Login extends Zend_Form{ 
    private $_artistId; 

    public function __construct($options = array()) { 
     if(isset($options['artistId'])) { 
      $this->_artistId = $options['artistId']; 
      unset($options['artistId']); 
     } 
     return parent::__construct($options); 
    } 

    public function init() { 
     $this 
      ->setAction('/') 
      ->setMethod('post'); 
     $el = new Zend_Form_Element_File('image'); 
     if($this->_artistId) { 
      $el->setDecorators(array(new ArtistDecorator(array('artistId' => 3)))); 
     }  
     $this->addElement($el); 
    } 
} 

Vous devez pas remplir le fichier-élément puisqu'il vous ne voulez pas à télécharger le même fichier encore et encore et encore.

Si le fichier (s) un mp3 ou alors: suivre la même routine, mais utiliser une sortie comme:

<ul> 
    <li><a href="/music/song_1.mp3">Song 1</a></li> 
    <li><a href="/music/song_2.mp3">Song 2</a></li> 
</ul> 

Injecter les « chansons » au constructeur du formulaire.

+0

Salut, nu avec moi comme je l'ai utilisé Zend pendant environ un mois.Dans mon contrôleur j'ai la ligne $ form-> options = array ('trackName' => 'trackFileName'); Je reçois cette erreur: "Message: Aucun élément valide spécifié pour le groupe d'affichage" Je crois que c'est parce que $ options n'est pas un élément de formulaire défini. Comment puis-je pousser ce tableau à la forme pour le décorateur? Merci – JoeChin

+0

Salut, s'il vous plaît ne tenez pas compte de mon dernier commentaire, avec un peu plus de googling j'ai trouvé que je pouvais passer le tableau en utilisant: $ form = new Zend_Form (array()); – JoeChin

+0

Oui, vous devriez essayer de déplacer la logique du formulaire hors de vos contrôleurs afin que le formulaire puisse facilement être réutilisé dans plusieurs actions (même si ce n'est pas souhaitable, c'est une très bonne pratique de séparation). Faites nous savoir comment cela marche. – chelmertz