Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 18-08-2014 15:29:33

shishi
Membre
Date d'inscription: 17-03-2013
Messages: 67

Error lors d'un upload de fichier.

Bonjour a toutes et a tous,

je rencontre un problème avec un formulaire d'upload ayant 2 champ input file dans 2 fieldsets différents.

Voici le contexte j'ai un entité note d'infection avec comme attributs (ninf_id, ninf_bar_id et ninf_url), et chaque note a un barème qui lui correspond clé étrangère ninf_bar_id.
donc j'ai également un entité barème avec comme attributs (bar_id, bar_url)

voici les code pour créer mon formulaire :

Le fieldset pour le barème :

Code:

[lang=php]<?php 

namespace RouilleRecolte\Form\Fieldset;

use Zend\Form\Element;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\Form\Fieldset;
use RouilleRecolte\Entity\Bareme;

class BaremeFieldset extends Fieldset {
    
    public function prepareFieldset($name = 'bareme'){
        
        parent::__construct($name);

        $this
            ->setHydrator(new ClassMethodsHydrator(false))
            ->setObject(new Bareme())
        ;
        
        $bar_id = new Element\Hidden('bar_id');
        
        $bar_url = new Element\File('bar_url');
        $bar_url->setLabel('<span style=\'color:blue;\'>* </span>Url du fichier contenant le barème de la notation d\'infection : ');
        $bar_url->setAttributes(
            array(
                'id'            => 'bar_url', 
                'placeholder'    => 'Choisissez un fichier.', 
                //'required'        => true,  
            )
        );
                
        $this->add($bar_id)
             ->add($bar_url);
        
    }
}

Le fieldset pour la note dans lequel j'inclus le fieldset du bareme :

Code:

[lang=php]<?php 

namespace RouilleRecolte\Form\Fieldset;

use Zend\Form\Element;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
use Zend\Form\Fieldset;
use RouilleRecolte\Entity\Ninf;

class NinfFieldset extends Fieldset {
    
    public function prepareFieldset(){
        
        parent::__construct('ninf');

         $this
             ->setHydrator(new ClassMethodsHydrator(false))
             ->setObject(new Ninf())
         ;
        
        $ninf_id = new Element\Hidden('ninf_id');
        
        $ninf_url = new Element\File('ninf_url');
        $ninf_url->setLabel('<span style=\'color:blue;\'>* </span>Url du fichier de notation d\'infection : ');
        $ninf_url->setAttributes(
            array(
                'id'            => 'ninf_url', 
                'placeholder'    => 'Choisissez un fichier.', 
                //'required'        => true,  
            )
        );
        
        $bareme = new BaremeFieldset();
        $bareme->prepareFieldset('ninf_bar_id');
                
        $this->add($ninf_id)
             ->add($ninf_url)
             ->add($bareme);
        
    }
}

et enfin le code de mon formulaire incluant le fieldset de la note :

Code:

[lang=php]<?php 

namespace RouilleRecolte\Form;

use Zend\Form\Form;
use Zend\Form\Element;
use Zend\Stdlib\Hydrator\ClassMethods as ClassMethodsHydrator;
use RouilleRecolte\Form\Fieldset\NinfFieldset;

class PostNinfForm extends Form {

    public function prepareElements(){
                
        $this->setAttribute('method', 'post')
             ->setHydrator(new ClassMethodsHydrator(false));
        
        $this->setAttribute('enctype','multipart/form-data');
        
        //On ajoute un élément csrf au formulaire
        $csrf = new Element\Csrf('ninf_csrf');
        $csrf->setOptions(
            array (
                'csrf_options'    => array (
                    'timeout'    => 600
                )
            )
        );
        //On créer le fieldset de la notation d'infection
        $ninf = new NinfFieldset();
        $ninf->prepareFieldset();
        $ninf->setUseAsBaseFieldset(true);
        
        /*$bareme = new BaremeFieldset();
        $bareme->prepareFieldset();*/
        
        $submit = new Element\Submit('submit');
        $submit->setAttributes(
            array(
                'value'    => 'Ajouter',
                'class'    => 'btn btn-success',
                'id'    => 'submit',
            )
        );
        
        //Ajout des éléments au formulaire
        $this->add($csrf)
             ->add($ninf)
             //->add($bareme)
             ->add($submit);
        
        
    }
    
}

1ere question ai je la bonne méthode et les bonne pratique concernant la construction de mon formulaire ou dois-je inclure le fieldset du bareme lors de la création du formulaire et non lors de la création du fieldset de la note?

ensuite dans mon controlleur j'ai :

Code:

[lang=php]public function ajouterAction()
    {
        $viewModel = new ViewModel();
        
        $this->ninfPostForm->prepareElements();
        
        $request = $this->getRequest();
        if ($request->isPost()) {
            $data = array_merge_recursive(
                $this->getRequest()->getPost()->toArray(),
                $this->getRequest()->getFiles()->toArray()
            );
            
            $ninfPostFormFilter = $this->getServiceLocator()->get('rouille-recolte-ninf-post-filter');
            $ninfPostFormFilter->prepareFilters();
            $this->ninfPostForm->setInputFilter($ninfPostFormFilter);
            
            $this->ninfPostForm->setData($data);
            
            if ($this->ninfPostForm->isValid()) {
                $size = new Size(array('max' => '5MB'));
                $adapterHTTP = new Http();
                $adapterHTTP->addValidator($size);
                if (!$adapterHTTP->isValid()){
                    $dataError = $adapterHTTP->getMessages();
                        $error = array();
                        foreach($dataError as $key=>$row)
                        {
                        $error[] = $row;
                        } //set formElementErrors
                        var_dump($dataError);
                        $this->ninfPostForm->setMessages(array('ninf' => array('ninf_url'=>$error )));
                }else{
                    if (!$adapterHTTP->isValid()){
                        $error = array();
                        foreach($dataError as $key=>$row)
                        {
                            $error[] = $row;
                        } //set formElementErrors
                        var_dump($dataError);
                        $this->ninfPostForm->setMessages(array('ninf' => array('ninf_bar_id'=> array('bar_url' => $error ))));
                    }
                    $adapterHTTP->setDestination('./data/lieux/notations/' . $this->session->offSetGet('db'));
                    if ($adapterHTTP->receive()) {
                        if ($adapterHTTP->isUploaded()){
                            var_dump('ok');
                            
                        }
                    }else {
                        var_dump($adapterHTTP->getMessages());
                    }
                }
            }else{
                var_dump($this->ninfPostForm->getMessages());
            }
        }
$viewModel->setVariables(
            array(
                'form'    => $this->ninfPostForm, 
            )
        );
        
        return $viewModel;

Voila pour le code le souci c'est que lorsque je soumet le formulaire l'adapter me renvoi une erreur :

'fileUploadErrorUnknown' => string 'Unknown error while uploading file 'array (
  'bar_url' => 'Penguins.jpg',
)'

Si vous avez une idée de la cause de cette erreur je suis preneur ou dois-je obligatoirement sortir le fieldset du bareme de celui de la note.

Autre question j'ai tenter de faire l'upload avec le plugin prgfile et à chaque fois ca me renvoi une erreur file was not found.

Merci d'avance de m'avoir lu et pour vos réponse
cordialement

Hors ligne

 

#2 18-08-2014 19:45:52

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Error lors d'un upload de fichier.

Salut, pour la construction des fieldset c'est assez simple tu fais un fieldset par table et après tu ajoutes un fieldset directement au formulaire ou à un fieldset en fonction de ton modèle de données. Si tu as une relation entre fieldset1 et fieldset2 c'est mieux de le mettre directement dans le fieldset par contre s'il n'y a pas de lien c'est dans le formulaire.

Le plugin prgfile il sert pour éviter les problèmes lorsque l'on fait un retour arrière smile. Donc pour ton problème je dirais déjà essaye avec un seul fichier voir ce que ça fait. Si ça fonctionne c'est que ça viendrait de l'upload de 2 fichiers en même temps et là je ne saurais pas t'aider. Par contre ce que tu peux faire c'est faire de l'upload en ajax (tu peux d'ailleurs si tu fais ça le convertir en base64 et l'enregistrer ensuite côté serveur), cette méthode t'impose d'avoir une table de gestion de fichiers et ensuite tu fais des liens vers ta table de fichiers dans les tables que tu utilises (je sais pas si j'ai été très clair ^^).

Hors ligne

 

#3 18-08-2014 19:55:05

shishi
Membre
Date d'inscription: 17-03-2013
Messages: 67

Re: Error lors d'un upload de fichier.

Salut Orkin,

merci pour ta réponse pour la construction des fieldset c'est bien ce que j'avais compris en lisant plusieur post sur ce forum et comme il y a une relation entre les 2 table et que mon entité Notation est constituée de la sorte :

ninf_id => int
ninf_bar_id => entité bareme (avec donc bar_id et bar_url)
ninf_url => string

donc c'est pour cela que j'ai inclu le fieldset bareme dans le fieldset notation
Lorsque je n'affiche pas le champ input file du bareme (bar_url) l'upload fonctionne très bien donc le problème viendrait d'un upload de 2 fichiers, en fait lorsque je fait un print_r de la variable $_FILE cela donne :

Code:

array (size=1)
  'ninf' => 
    array (size=5)
      'name' => 
        array (size=2)
          'ninf_url' => string 'Koala.jpg' (length=9)
          'ninf_bar_id' => 
            array (size=1)
              ...
      'type' => 
        array (size=2)
          'ninf_url' => string 'application/octet-stream' (length=24)
          'ninf_bar_id' => null
      'tmp_name' => 
        array (size=2)
          'ninf_url' => string 'C:\xampp\tmp\php75A9.tmp' (length=24)
          'ninf_bar_id' => 
            array (size=1)
              ...
      'error' => 
        array (size=2)
          'ninf_url' => int 0
          'ninf_bar_id' => 
            array (size=1)
              ...
      'size' => 
        array (size=2)
          'ninf_url' => string '780831' (length=6)
          'ninf_bar_id' => null

Je pense que le problème vient du fait que le 2ème fichier a uploader est dans un array (ninf_bar_id)
J'ai lu quelque post ou les personnes rencontré les même problèmes masi je n'ai pas trouver ou pas compris la solution.

Hors ligne

 

#4 18-08-2014 20:34:23

Orkin
Administrateur
Lieu: Paris
Date d'inscription: 09-12-2011
Messages: 1261

Re: Error lors d'un upload de fichier.

Sans avoir les liens c'est pas facile de t'expliquer la solution proposée smile.

Hors ligne

 

#5 19-08-2014 09:46:00

shishi
Membre
Date d'inscription: 17-03-2013
Messages: 67

Re: Error lors d'un upload de fichier.

Bonjour,

en effet voici les quelques liens discutant du même problème :

Lien N°1

J'ai essayer de recréer un tableau pour que les clés 'bar_url' soient comme celle de 'ninf_url' et non dans des Array mais sans succès.

Lien N°2

Lien N°3

voila les liens que j'ai retrouvés, si j'en retrouve d'autres j'éditerais mon post.

j'ai même essayer de m'inspirer de la fonction prepareFiles de la class Zend\File\Transfer\Adapter\Http mais en vain..

En tout cas merci d'essayer de m'aider car je commence a désespérer car après j'ai un autre formulaire ou j'utiliserais le fieldset de la notation en collection..

Hors ligne

 

#6 19-08-2014 17:50:30

shishi
Membre
Date d'inscription: 17-03-2013
Messages: 67

Re: Error lors d'un upload de fichier.

J'ai trouvé une solution pour réussir a uploader les 2 fichiers mais elle ne me convient pas de trop car il faut modifier une classe du framework à savoir :
la class Zend\File\Transfer\Adapter\Http

remplacer (ligne 418):

Code:

foreach ($content as $param => $file) {
                    foreach ($file as $number => $target) {
                        $this->files[$form . '_' . $number . '_'][$param]      = $target;
                        $this->files[$form]['multifiles'][$number] = $form . '_' . $number . '_';
                    }
                }

par :

Code:

foreach ($content as $param => $file) {
                    foreach ($file as $number => $target) {
                        // temporary fix
                        if( is_array( $target ) )
                        {
                            $target = array_pop( $target );
                        }
                        // end temporary fix
                        $this->files[$form . '_' . $number . '_'][$param]      = $target;
                        $this->files[$form]['multifiles'][$number] = $form . '_' . $number . '_';
                    }
                }

j'ai trouvé cette solution à ce lien :

Solution

Est ce u'il y a une solution pour ne pas devoir modifier la classe du framework?

et je rencontre un n'autre problème lorsque le fichier dépasse la taille ou n'a pas la bonne extension je n'arrive pas a afficher l'erreur sous l'input voici le code utilisé :

Code:

foreach ($adapterHTTP->getMessages() as $row) {
                            $error[$name] = $row;
                        }
                        
                        $this->ninfPostForm->setMessages(array('ninf'    =>    array('ninf_url'    =>    $error)));

merci d'avance
cordialement

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages