Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 23-11-2013 16:05:46

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

initialiser un controller dans un module différent

bonjour,
je me suis lancé à la découverte du ZF2 à partir du tuto de Rob Allen. Et j'ai commencé à le modifier à ma sauce.
voici la structure avec 2 modules
un module Poste avec
PosteController
PosteForm
Poste
PosteTable

un module Operation
OperationController
OperationForm
Operation
OperationTable

chaque module accède à sa table mysql Poste et Operation. Je peux modifier les tables comme je veux. Tout fonctionne bien.

maintenant le sujet qui me pose souci :
Dans le formulaire OperationForm je souhaite afficher une liste déroulante contenant les champs de la table Poste.
Pour cela, j'ai choisi de faire appel au module Poste par le biais de PosteController. Voici le code du select dans OperationForm :

Code:

 [lang=php]       $Postecontrol = new PosteController();
             $PostesListe = $Postecontrol->getPosteTable()->fetchAll();
      
        $this->add(array(
                'name' => 'Poste',
                'type' => 'Select',
                'options' => array(
                        'label' => 'Poste',
                        'value_options' => ($PostesListe),
                ),
        ));

ce code génére une fatal error " Call to a member function get() on a non-object in .../Poste/Controller/PosteController.php "
en debug, j'ai découvert que l'objet $Postecontrol est bien créé mais non initialisé. la fonction getPosteTable() dans PosteController.php est en cause. 

Code:

 [lang=php] //PosteController.php
   public function getPosteTable()
    {
        if (!$this->posteTable) {
            $sm = $this->getServiceLocator(); //$sm vaut null
            $this->posteTable = $sm->get('Poste\Model\PosteTable');
        }
        return $this->posteTable;
    }

La fonction getServiceLocator() ne renvoie rien. J'en déduis qu'il faut fournir au servicelocator les informations nécessaires pour se connecter à la table Poste ou initialiser Postecontrol.
là, j'avoue que je ne sais pas trop comment faire pour manipuler les objets d'un module dans un autre.

J'espère avoir été assez clair.
Merci d'avance pour votre aide.
Arnica

Hors ligne

 

#2 25-11-2013 15:51:59

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

Re: initialiser un controller dans un module différent

Salut, tu t'y prend pas du tout comme il faut c'est pour ça smile.

Je ne connais pas trop Zend\Db car j'utilise doctrine mais le principe reste sensiblement le même.

En fait la fonction getServiceLocator() renvoi le service locator qui est injecté automatiquement lors de la création d'un contrôleur dans le processus MVC. Le problème c'est que toi tu fais un new PosteController() donc tu ne passes pas par le processus MVC et l'injection n'est pas faite.

Le plus simple étant soit d'implémenter l'interface ServiceLocatorAwareInterface dans ton formulaire de façon à ce que le service locator soit automatiquement injecté dans ton formulaire. Attention encore une fois si tu fais un new MonForm() pas d'injection tu dois créer une entrée dans la clé invokable de ta config vers le formulaire. Si tu veux vraiment faire ça encore plus proprement tu peux le déclarer dans le formElementManager ça fonctionne de la même manière la seule différence c'est qu'il fait un test sur le type d'objet que tu renvoies et il ne peux renvoyer que des formulaires. Une fois que tu as le service locator tu as tout ce dont tu as besoin (même peut être trop d'ailleurs ^^).

Le mieux est de créer une fabrique pour créer ton formulaire, un service pour les accès à la base de données. De cette façon dans la fabrique tu passes le service dont tu as besoin à ton formulaire et celui-ci aura accès à tout ce que tu as besoin pour ce formulaire. Ceci évite d'utiliser le service locator pour autre chose que l'appel de ton fetchAll(). Là tu as le service, normalement ton service ne permet pas de récupérer le service locator (il le connait mais c'est tout) donc pas de tentation !

Hors ligne

 

#3 25-11-2013 20:57:52

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

salut, merci pour ta réponse.
Je me doutais bien que quelque chose clochait dans ma manière d'aborder le problème.
Je me penche de ce pas sur la fabrique de formulaire. ça me parait plus propre.

encore merci !

Hors ligne

 

#4 27-11-2013 13:52:05

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

Salut,
j'ai creusé un peu la question suite à tes remarques, Orkin.

Orkin a écrit:

Le plus simple étant soit d'implémenter l'interface ServiceLocatorAwareInterface dans ton formulaire de façon à ce que le service locator soit automatiquement injecté dans ton formulaire. Attention encore une fois si tu fais un new MonForm() pas d'injection tu dois créer une entrée dans la clé invokable de ta config vers le formulaire. Si tu veux vraiment faire ça encore plus proprement tu peux le déclarer dans le formElementManager ça fonctionne de la même manière la seule différence c'est qu'il fait un test sur le type d'objet que tu renvoies et il ne peux renvoyer que des formulaires. Une fois que tu as le service locator tu as tout ce dont tu as besoin (même peut être trop d'ailleurs ^^).

cette partie là, j'ai compris le principe. je n'ai pas approfondi le formElementManager mais c'est anecdotique pour le moment.

Orkin a écrit:

Le mieux est de créer une fabrique pour créer ton formulaire, un service pour les accès à la base de données. De cette façon dans la fabrique tu passes le service dont tu as besoin à ton formulaire et celui-ci aura accès à tout ce que tu as besoin pour ce formulaire. Ceci évite d'utiliser le service locator pour autre chose que l'appel de ton fetchAll(). Là tu as le service, normalement ton service ne permet pas de récupérer le service locator (il le connait mais c'est tout) donc pas de tentation !

par contre l'histoire de la fabrique de formulaire m'amène à plusieurs réflexions :
la fabrique de formulaire en elle-même ne me pose pas de problème, la doc de ZF est claire.
1) Je ne suis pas sûr de comprendre dans quel fichier je dois créer ma fabrique : est-ce dans le fichier OperationForm.php à la place de la classe OperationForm ? ou bien dans le fichier module.php ?

2) comment et dans quel fichier puis-je appeler cette fabrique de formulaire ?
3) l'utilisation de la fabrique a-t-elle des conséquences sur la vue ? si oui de quelle manière?

merci d'avance et bon courage
Arnica

Hors ligne

 

#5 27-11-2013 14:40:37

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

Re: initialiser un controller dans un module différent

Salut, je pense que tu n'as pas compris le principe d'une fabrique en fait smile.

La fabrique te permet de contrôler de quelle façon un objet va être instancié et ses dépendances ! Donc ça n'a pas de rapport avec ton OperationForm.php puisque la fabrique va te permettre de créer cet objet.

Tu peux mettre une fabrique dans ton fichier module.config.php via une fonction anonyme mais ce n'est pas le mieux car pose problème pour mettre ta configuration en cache. Tu peux aussi le faire dans ton fichier Module.php de la même manière mais si tu as beaucoup de fabrique ça va devenir imbuvable de lire ton code. Le mieux est donc de créer une classe implémentant l'interface FactoryInterface. A partir de ce moment là tu va pouvoir créer ton objet comme tu le veux. Ensuite il te suffit de créer une entrée dans ton service locator comme tu le fais normalement pour un contrôleur la seule différence est que tu le mettras dans factories au lieu de invokables.

Ensuite tu appelles cette fabrique à la place d'instancier ton formulaire donc là où tu fais ton new MonFormulaire() tu veras $this->getServiceLocator()->get('formElementManager')->get('MonForm') (formElementManager n'est à mettre que si tu l'as déclaré dans le formElementManager. La fabrique te retourne une instance de ton formulaire donc aucune incidence sur le reste de ton application puisque tu manipules toujours un objet de type formulaire. La différence est que c'est la fabrique qui fera le new MonForm() et lui passera ses références.

Hors ligne

 

#6 01-12-2013 08:34:47

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

Salut,
merci, Orkin, pour tes remarques. J'ai approfondi le sujet, (ce qui explique la latence de mes réponses...)
j'ai créé une classe implémentant l'interface factoryinterface. Ce qui donne ça :

Code:

[lang=php]
<?php
namespace Operation\Form;

use Zend\Form\Form;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class OperationFormFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sm)
    {
        // appel du formulaire
        $myOperationForm = new Operation\Form\OperationForm();
        //je récupère l'accès à la table Poste et je récupère l'ensemble de la table
        $PosteListe = $sm->get('PosteTable'); //PosteTable : fabrique définie dans module.PHP
        $poste = $PosteListe->fetchAll();

        // renseigne le formulaire
        $myOperationForm->setParam($poste); 

        // on retourne l'objet
        return $myOperationForm;
    }
}

j'ai renseigné module.php de cette façon :

Code:

[lang=php]
...
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
 ...
                'PosteTable' =>  function($sm) {
                    $tableGateway = $sm->get('PosteTableGateway');
                    $table = new PosteTable($tableGateway);
                    return $table;
                },
                'PosteTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Poste());
                    return new TableGateway('Postes', $dbAdapter, null, $resultSetPrototype); //"Postes" correspond au nom de la table dans la BDD
                },
                
                'OperationForm' => 'Operation\Form\OperationFormFactory',
                
            ),
        );
    }

Dans le controller, j'ai modifié l'appel au formulaire de cette façon :

Code:

[lang=php]
...
    public function addAction()
    {
       //$form = new OperationForm(); //à remplacer par l'appel à la fabrique
        $form = $this->getServiceLocator()->get('OperationForm');
...

et maintenant j'ai une erreur du type ServiceNotCreatedException
"While attempting to create operationform(alias: OperationForm) an invalid factory was registered for this instance type."
dans la stack trace, ça plante à l'appel de
#0 /opt/lampp/htdocs/compte_courant_test/vendor/zendframework/zendframework/library/Zend/ServiceManager/ServiceManager.php(494): Zend\ServiceManager\ServiceManager->createFromFactory('operationform', 'OperationForm')

visiblement, j'ai mal défini ou paramétré ma fabrique mais je ne vois pas où.
de plus, je n'arrive pas à débugger ce truc

quelques pistes à explorer ?
merci
Arnica

Dernière modification par arnica33 (01-12-2013 15:13:04)

Hors ligne

 

#7 01-12-2013 10:55:46

tdutrion
Administrateur
Lieu: Dijon, Paris, Edinburgh
Date d'inscription: 23-12-2009
Messages: 614
Site web

Re: initialiser un controller dans un module différent

Bonjour,

As-tu essaye de renvoyer une instance de ton objet dans le factory ?

Code:

[lang=php]
public function getServiceConfig()
    {
        return array(
            'factories' => array(
 ...
                'PosteTable' =>  function($sm) {
                    $tableGateway = $sm->get('PosteTableGateway');
                    $table = new PosteTable($tableGateway);
                    return $table;
                },
                'PosteTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Poste());
                    return new TableGateway('Postes', $dbAdapter, null, $resultSetPrototype); //"Postes" correspond au nom de la table dans la BDD
                },
                
                'OperationForm' =>function($sm) {
                    return new \Operation\Form\OperationFormFactory();
                },       
            ),
        );
    }

Hors ligne

 

#8 01-12-2013 11:13:50

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

Re: initialiser un controller dans un module différent

Salut c'est bizarre ça devrait fonctionner, retourner l'instance directement pose le même problème qu'avant puisque ça utilise une fonction anonyme et ça fou la merde pour les caches.

Là je ne vois pas ce que tu as loupé. Ah si peut être une idée, pourrais-tu mettre le code de ton formulaire ?

Hors ligne

 

#9 01-12-2013 15:11:32

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

@Théocrite
[edit]Je viens d'essayer, ça me renvoie la même erreur.
je corrige ce que je viens d'écrire, je n'ai pas la même erreur maintenant j'ai
"Fatal error: Call to undefined method Operation\Form\OperationFormFactory::get() in /opt/lampp/htdocs/compte_courant_test/module/Operation/src/Operation/Controller/OperationController.php on line 36"
ce qui correspond à la ligne suivante du controleur

Code:

[lang=php]
//operationcontroller.php
    public function addAction()
    {
       //$form = new OperationForm(); //à remplacer par l'appel à la fabrique
        $form = $this->getServiceLocator()->get('OperationForm');

        $form->get('submit')->setValue('Add'); //ligne 36
...

Je comprends que l'application cherche une methode get dans la fabrique au lieu de la chercher dans l'instance du formulaire que la fabrique aurait dû créer ??
ou alors c'est une mauvaise utilisation du $form...

@Orkin
voici le code de mon formulaire

Code:

[lang=php]
<?php
//base pour les formulaires d'ajout et de supppression
namespace Operation\Form;

use Zend\Form\Form;

class OperationForm extends Form // implements ServiceLocatorAwareInterface
{
    protected $PosteSelect;
    
    public function __construct($name = null)
    {
//3 éléments NumOp caché (renseigné automatiquement), Operation et le bouton submit
        // we want to ignore the name passed
        parent::__construct('operation');
        $this->setAttribute('method', 'post');
        $this->add(array(
            'name' => 'NumOp',
            'type' => 'Hidden',
        ));
        $this->add(array(
            'name' => 'Operation',
            'type' => 'Select',
            'options' => array(
                'label' => 'Opération',
                    'value_options' => array('0'=>'crédit','1'=>'débit'),
            ),
        ));
        $this->add(array(
                'name' => 'Date',
                'type' => 'Date',
                'options' => array(
                        'label' => 'Date',
                ),
        ));
              
        $this->add(array(
                'name' => 'Poste',
                'type' => 'Select',
                'options' => array(
                        'label' => 'Poste',
                        'value_options' => ($PosteSelect),
                ),
        ));
        
        $this->add(array(
                'name' => 'Libelle',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Libelle',
                ),
        ));
        $this->add(array(
                'name' => 'Cheque',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Cheque',
                ),
        ));
        $this->add(array(
                'name' => 'Realise',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Realise',
                ),
        ));
        $this->add(array(
                'name' => 'Montant',
                /*'type' => 'Float',*/
                'options' => array(
                        'label' => 'Montant',
                ),
        ));
        $this->add(array(
            'name' => 'submit',
            'type' => 'Submit',
            'attributes' => array(
                'value' => 'Go',
                'id' => 'submitbutton',
            ),
        ));
    }
   
public function setParam($value)
    {
        $this->$PosteSelect=$value;
    }
}

m'est avis qu'il s'agit d'une histoire de chemin de fichier mal défini ou quelque chose dans le genre...
merci à tous les deux
Arnica

Dernière modification par arnica33 (01-12-2013 16:00:22)

Hors ligne

 

#10 01-12-2013 22:51:22

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

Re: initialiser un controller dans un module différent

Non, le problème est le suivant : tu initialises le formulaire dans le constructeur et ensuite tu lui passes le posteSelect via setParam donc ça plante puisqu'il ne connait pas posteSelect.

Donc soit tu le met en paramètre tu constructeur soit tu créé le formulaire dans une méthode init() que tu appelles après le setParam.

Ensuite dans ton setParam : $this->$PosteSelect c'est pas correct c'est $this->PosteSelect

Hors ligne

 

#11 03-12-2013 21:51:39

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

bonsoir,
j'ai pris en compte les remarques d'Orkin.
j'ai testé les 2 propositions le passage en paramètre du constructeur et la fonction init. Dans les 2 cas, j'ai la même erreur que précédemment.
voici le code de mon formulaire avec la fonction init()

Code:

[lang=php]
<?php
//base pour les formulaires d'ajout et de supppression
namespace Operation\Form;

use Zend\Form\Form;

class OperationForm extends Form
{
protected $PosteSelect;
    
public function __construct($name = null)
    {
        //$this->PosteSelect = $PosteSelect;
//3 éléments NumOp caché (renseigné automatiquement), Operation et le bouton submit
        // we want to ignore the name passed
        parent::__construct('operation');
    
    }
    
public function setParam($value)
    {
        $this->PosteSelect = $value;
    }
    
public function init()
    {
        $this->setAttribute('method', 'post');
        $this->add(array(
            'name' => 'NumOp',
            'type' => 'Hidden',
        ));
        $this->add(array(
            'name' => 'Operation',
            'type' => 'Select',
            'options' => array(
                'label' => 'Opération',
                    'value_options' => array('0'=>'crédit','1'=>'débit'),
            ),
        ));
        $this->add(array(
                'name' => 'Date',
                'type' => 'Date',
                'options' => array(
                        'label' => 'Date',
                ),
        ));
              
        $this->add(array(
                'name' => 'Poste',
                'type' => 'Select',
                'options' => array(
                        'label' => 'Poste',
                        'value_options' => array($this->PosteSelect),
                        //'value_options' => array('0'=>'crédit','1'=>'débit'),
                ),
        ));
        
        $this->add(array(
                'name' => 'Libelle',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Libelle',
                ),
        ));
        $this->add(array(
                'name' => 'Cheque',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Cheque',
                ),
        ));
        $this->add(array(
                'name' => 'Realise',
                'type' => 'Text',
                'options' => array(
                        'label' => 'Realise',
                ),
        ));
        $this->add(array(
                'name' => 'Montant',
                /*'type' => 'Float',*/
                'options' => array(
                        'label' => 'Montant',
                ),
        ));
        $this->add(array(
            'name' => 'submit',
            'type' => 'Submit',
            'attributes' => array(
                'value' => 'Go',
                'id' => 'submitbutton',
            ),
        ));
    }
}

à l'origine de ce post, je voulais "simplement" renseigné le select suivant avec les données d'une table.

Code:

 [lang=php]
      $this->add(array(
                'name' => 'Poste',
                'type' => 'Select',
                'options' => array(
                        'label' => 'Poste',
                        'value_options' => array($this->PosteSelect),
                        //'value_options' => array('0'=>'crédit','1'=>'débit'),
                ),
        ));

du coup, je ne sais même plus ce qui est correct, quel que soit le code du select, j'ai toujours la même erreur. Mais je pense que c'est secondaire pour l'instant, le problème vient d'ailleurs visiblement puisque lorsque je code "en dur" les valeurs possibles du select, l'erreur revient.

sinon le code de la classe OperationFormFactory ça peut toujours servir si jamais une bonne âme a une idée à proposer.

Code:

[lang=php]
<?php
namespace Operation\Form;

use Zend\Form\Form;
use Zend\ServiceManager\FactoryInterface;
use Zend\ServiceManager\ServiceLocatorInterface;

class OperationFormFactory implements FactoryInterface
{
    public function createService(ServiceLocatorInterface $sm)
    {
        // on crée notre objet
        $myOperationForm = new Operation\Form\OperationForm();
        // on récupère une autre dépendance que l'on injecte
        //je récupère l'accès à la table poste et je récupère l'ensemble de la table
        $PosteListe = $sm->get('PosteTable');
        $poste = $PosteListe->fetchAll();

        // on le passe à notre classe
        $myOperationForm->setParam($poste);
        //initialise l'instance
        $myOperationForm->init();
                
        // on retourne l'objet
        return $myOperationForm();
    }
}

ce que je trouve bizarre en debuggant pas à pas c'est que je ne passe jamais par la classe OperationFormFactory. Quand le pointeur du debuggeur arrive sur la ligne "class OperationFormFactory implements FactoryInterface", je passe directement à l'erreur.

bonne soirée et merci d'avance pour votre aide
Arnica

Hors ligne

 

#12 04-12-2013 18:37:54

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

Re: initialiser un controller dans un module différent

Salut Arnica,
je ne sais pas si c'est la solution qui va résoudre ton problème mais essaye de mettre ce code dans ta fabrique :

Code:

[lang=php]
$PosteListe = $sm->getServiceLocator()->get('PosteTable');

Cordialement Shishi

Hors ligne

 

#13 04-12-2013 22:00:53

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

merci Shishi pour ta suggestion, mais j'ai toujours la même erreur.

sinon j'ai fait un "echo get_class" dans mon controller après avoir appelé mon formulaire via la fabrique

Code:

[lang=php]
$form = $this->getServiceLocator()->get('MyOperationForm');
echo get_class($form);

cela me renvoie "Operation\Form\OperationFormFactory"
je pensais que $form serait de la classe OperationForm ??

bonne soirée
Arnica

Hors ligne

 

#14 05-12-2013 19:21:29

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

Re: initialiser un controller dans un module différent

Là c'est pas un problème de ZF2 mais un problème PHP ...

Quand tu retournes une variable tu mets souvent des parenthèses après ? :p

Code:

[lang=php]
// on retourne l'objet
        return $myOperationForm(); // Sans parenthèses ;)

De plus retire le constructeur de ton formulaire il ne sert plus wink

Peut-tu mettre le code de ta config où tu déclares le formulaire dans le service locator (le tableau complet stp).

Hors ligne

 

#15 06-12-2013 21:21:07

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

ah nom de ... je commence à voir mon code en double...
merci Orkin

voila le code du module.php où je déclare la fabrique mais pas le formulaire. J'espère que je te comprends bien. Je n'ai rien mis dans le fichier module.config.php

Code:

[lang=php]
<?php
namespace Operation;

use Operation\Model\Operation;
use Operation\Model\OperationTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;

class Module
{
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    // Add this method: permet d'utiliser toujours la même instance de OperationTable et de ne pas saturer la mémoire = sorte de buffer
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'Operation\Model\OperationTable' =>  function($sm) {
                    $tableGateway = $sm->get('OperationTableGateway');
                    $table = new OperationTable($tableGateway);
                    return $table;
                },
                'OperationTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Operation());
                    return new TableGateway('Operations', $dbAdapter, null, $resultSetPrototype); //"Operations" correspond au nom de la table dans la BDD
                },
                'PosteTable' =>  function($sm) {
                    $tableGateway = $sm->get('PosteTableGateway');
                    $table = new PosteTable($tableGateway);
                    return $table;
                },
                'PosteTableGateway' => function ($sm) {
                    $dbAdapter = $sm->get('Zend\Db\Adapter\Adapter');
                    $resultSetPrototype = new ResultSet();
                    $resultSetPrototype->setArrayObjectPrototype(new Poste());
                    return new TableGateway('Postes', $dbAdapter, null, $resultSetPrototype); //"Postes" correspond au nom de la table dans la BDD
                },
                
                //'OperationForm' => 'Operation\Form\OperationFormFactory',
               // 'OperationForm' => 'OperationFormFactory',
                
                'MyOperationForm' =>function($sm) {
                    return new \Operation\Form\OperationFormFactory();
                },
                
                
            ),
        );
    }
}
?>

Hors ligne

 

#16 07-12-2013 09:11:18

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

Re: initialiser un controller dans un module différent

Bonjour arnica,

je remarque que la fabrique et le formulaire ont le même namespace donc dans ta fabrique essaye ce code :

Code:

[lang=php]
$myOperationForm = new OperationForm();

Hors ligne

 

#17 07-12-2013 11:22:02

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

Merci Shishi
effectivement même namespace.
J'ai toujours la même erreur : (pour rappel)
Fatal error: Call to undefined method Operation\Form\OperationFormFactory::get() in /opt/lampp/htdocs/compte_courant_test/module/Operation/src/Operation/Controller/OperationController.php on line 37

Hors ligne

 

#18 07-12-2013 13:37:11

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

Re: initialiser un controller dans un module différent

Et mais c'est normal que ça ne fonctionne pas ...

arnica33 a écrit:

Code:

[lang=php]
<?php
namespace Operation;

use Operation\Model\Operation;
use Operation\Model\OperationTable;
use Zend\Db\ResultSet\ResultSet;
use Zend\Db\TableGateway\TableGateway;

class Module
{
    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\ClassMapAutoloader' => array(
                __DIR__ . '/autoload_classmap.php',
            ),
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    public function getConfig()
    {
        return include __DIR__ . '/config/module.config.php';
    }

    // Add this method: permet d'utiliser toujours la même instance de OperationTable et de ne pas saturer la mémoire = sorte de buffer
    public function getServiceConfig()
    {
        return array(
            'factories' => array(               
                'MyOperationForm' =>function($sm) {
                    return new \Operation\Form\OperationFormFactory();
                },
                
                
            ),
        );
    }
}
?>

As-tu relu ton code smile ? Ce que tu fais là c'est que tu déclares une fabrique avec comme nom "MyOperationForm" qui te retourne une instance de l'objet OperationFormFactory via une fabrique sous forme de fonction anonyme. Donc c'est normal que ça te retourne une instance de ta fabrique au lieu d'un formulaire.
Lorsque tu déclares une fabrique soit tu fais une fonction anonyme (ce que tu fais là), soit tu créés une classe qui implémente l'interface FactoryInterface. Mais en aucun cas les deux en même temps. Tu créés une fabrique via une fonction anonyme qui te retourne une instance te ta fabrique. Tu tournes en rond ...

Remplaces ton code

Code:

[lang=php]
'MyOperationForm' =>function($sm) {
    return new \Operation\Form\OperationFormFactory();
},

Par

Code:

[lang=php]
'MyOperationForm' => 'Operation\Form\OperationFormFactory',

Et ça fonctionnera si t'as pas faire de bêtises ailleurs wink.

@Shishi : c'est plus propre mais ça ne vient pas de là le problème wink.

Hors ligne

 

#19 07-12-2013 16:56:50

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

bon sang ! c'est ça! ça y est, je passe par la fabrique. En plus, j'avais commencé par ce codage. De bricolages en bricolages, je me suis perdu.
j'avais beau relire mon code, je ne comprends pas encore tout.
merci Orkin, tout n'est pas gagné, j'ai d'autres erreurs mais j'ai quand même avancé un peu.
Quel soulagement !

bonne soirée
Arnica

Hors ligne

 

#20 08-12-2013 08:07:47

arnica33
Membre
Date d'inscription: 23-11-2013
Messages: 25

Re: initialiser un controller dans un module différent

Un dernier message pour remercier Orkin, shishi et Théocrite.
J'ai résolu mon problème, sujet clos.

bonne journée
Arnica

Hors ligne

 

#21 08-12-2013 11:50:35

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

Re: initialiser un controller dans un module différent

Si tu as des choses que tu ne comprends pas hésites pas à demander wink. Ca n'a pas d'intérêt pour toi de faire des choses que tu ne comprends pas même si ça fonctionne car tu progresses pas :p.

Content que ton problème soit réglé quand même wink

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