Bonjour
Je cherche désespérément à avoir une url classique type /param/value plutot que ?param=value avec un formulaire et une methode get.
si quelqu'un pouvait me mettre sur la bonne voie, faut-il créer une route manuellement ?
merci !
Bonjour
Je cherche désespérément à avoir une url classique type /param/value plutot que ?param=value avec un formulaire et une methode get.
si quelqu'un pouvait me mettre sur la bonne voie, faut-il créer une route manuellement ?
merci !
Bonjour,
Je ne pense pas que ce soit possible (du moins pas simplement ni systématiquement).
Voir un sujet similaire : http://www.developpez.net/forums/d69...rl-formulaire/
Par contre si j'accède manuellement avec l'url /param/value ça fonctionne bien.
La solution serait alors d'envoyer en POST, et de rediriger vers la "bonne" url, dommage![]()
Voir ici pour un exemple : GET forms with the MVC .
Il s'agit d'ajouter un plugin au controller frontal qui va détecter la présence de paramètres de type GET (?xxx=yyy&zzz=aaa), qui va réécrire l'url au format Zend par défaut (/xxx/yyy/zzz/aaa), et qui va actionner une redirection vers cette nouvelle url.
Je l'ai implémenté pour l'application que je suis en train de développer, ça fonctionne plutôt bien![]()
Super ça fonctionne très bien
Je me suis pris la tête la dessus pendant une journée car je pensait qu'il y avait forcément un réglage pour ce genre de truc presque classique, pas facile l'apprentissage de ZF et en particulier la POO
Edit : Thanks !
Petit problème quand même
Le formulaire est comme envoyé des le chargement de la page et m'affiche un " Value is required and can't be empty" pour les champs ayant un setRequired(true), le code "responsable" :
Ce code est placé dans mon action index, j'ose pas vous le montrer
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 // if we get here then the search query is in the URL as parameters if ($formSearchInLinks->isValid($this->_getAllParams())) { }![]()
???
Pour ma part, le plugin intervient au niveau du controlleur frontal, donc avant le controlleur d'action.
Je n'ai pas rencontré de soucis particulier à ce niveau.
Dans mon bootstrap
Le plugin
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 $frontController->registerPlugin(new My_Controller_Plugin_CleanQuery());
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92 <?php /** * Plugin that cleans up querystrings in GET submissions * NB : ce plugin ne fonctionne pas lorsque les valeurs des paramètres contiennent des '/' */ class My_Controller_Plugin_CleanQuery extends Zend_Controller_Plugin_Abstract { /** * @var boolean */ protected $permanent; /** * Takes a flag in the constructor to determine whether the redirects * are permanent or just temporary (default); * * @param boolean $permanent */ public function __construct($permanent=true) { $this->permanent=$permanent; } /** * Cleans the GET and if it's changed does a redirect */ public function routeStartup(Zend_Controller_Request_Abstract $request) { // On supprime les paramètres qui n'ont pas de valeur if($this->getRequest()->isGet()) { $params = $this->getRequest()->getParams(); if($params) { $new_params = $this->_filterArray($params); if(count($params, COUNT_RECURSIVE) > count($new_params, COUNT_RECURSIVE)) { // $uri = $this->getRequest()->getRequestUri(); $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?') + 1) . http_build_query($new_params); $this->getResponse()->setRedirect($path, $this->permanent?301:302); $this->getResponse()->sendResponse(); exit; } } } // Si on a des paramètres qui sont passés par _GET, on réécrit l'url pour passer des paramètres ZF-Style if (isset($_GET) && is_array($_GET) && !empty($_GET)) { $path = ''; //array_walk($_GET, array(__CLASS__, 'encodeParam')); foreach ($_GET as $key => $value) { if (is_array ($value) ) { foreach ($value as $_value) { $path .= '/' . $key . '/' . $_value; } continue; } if ($key != 'submit') $path .= '/' . $key . '/' . $value; } $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?')) . $path; $this->getResponse()->setRedirect($path, $this->_permanent ? 301 : 302); $this->getResponse()->sendResponse(); exit; } } /** * Cleans out false values from an array * * @param array $array */ private function _filterArray($array) { foreach($array as $key=>$value) { if(is_array($value)) { $value = $this->_filterArray($value); $array[$key]=$value; } if($value==='') { unset($array[$key]); } } return $array; } public static function encodeParam(&$value, &$key) { $value = urlencode($value); $key = urlencode($key); } }
Moi aussi (bootstrap.php) :
Mais j'avais mis le code de ma rechercher dans la même action que mon index, j'ai mis la recherche dans une action searchAction avec un target du form vers celle ci et du coup je n'ai plus ce pb.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $frontController->registerPlugin(new Plugin_CleanQuery()); // Dispatch the request using the front controller. $frontController->dispatch();
Juste pour info, ce serait sympa de répondre et de savoir où je vais (où ne vais pas) que vaut ce code en général, est-ce que les bonnes pratiques sont respectées ? oui/non pk ?
ps : et pourquoi les fichiers générés via zend studio n'ont pas la balise de fermeture de php
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101 <?php /** * IndexController - The default controller class * * @author * @version */ require_once 'Zend/Controller/Action.php'; class IndexController extends Zend_Controller_Action { public $formSearchInLinks; public $selectFlux; public $pageFlux; public function init(){ $this->view->querySearchInLinks = null; // form search in links $this->formSearchInLinks = new formSearchLink(); $this->formSearchInLinks->setAction('/index/search'); $this->formSearchInLinks->setMethod('GET'); // les flux (links) $flux = new Flux(); $this->selectFlux = $flux->select(); } public function setPagination($currentPage){ // nav de pages en pages $this->pageFlux = Zend_Paginator::factory($this->selectFlux); $this->pageFlux->setPageRange(10); $this->pageFlux->setCurrentPageNumber($currentPage); $this->pageFlux->setItemCountPerPage(40); } public function send2View(){ // on envoi les données au template $this->view->formSearchInLinks = $this->formSearchInLinks; $this->view->links = $this->pageFlux; } public function indexAction() { $this->view->title = 'Liens et Ressources pour PHP'; $this->view->headTitle('PHPLinks.fr'); // flux de quelle langue ? if($this->_getParam('lang')!=NULL){ $this->selectFlux->where('lang like ?',$this->_getParam('lang')); } // pagination $this->setPagination($this->_getParam('page', 1)); // on balance les données à la vue $this->send2View(); } public function searchAction(){ // clean url from form methode=get if (isset($_GET) && is_array($_GET) && !empty($_GET)) { $path = ''; array_walk($_GET, array('IndexController', 'encodeParam')); foreach ($_GET as $key => $value) { if ($key != 'Ok') $path .= '/' . $key . '/' . $value; } $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?')) . $path; $this->getResponse()->setRedirect($path, $this->_permanent ? 301 : 302); $this->getResponse()->sendResponse(); return; } // if we get here then the search query is in the URL as parameters if ($this->formSearchInLinks->isValid($this->_getAllParams())) { // filtre la requete sql $this->selectFlux->where('titre like ?','%'.$this->formSearchInLinks->getValue('q').'%'); // affiche la recherche dans la case du form $this->formSearchInLinks->__get('q')->setValue($this->formSearchInLinks->getValue('q')); $this->view->title = 'Recherche de "'.$this->formSearchInLinks->getValue('q').'"'; $this->view->headTitle('Recherche parmis les liens php'); } // pagination $this->setPagination($this->_getParam('page', 1)); // on balance les données à la vue $this->send2View(); //hop on rend avec la vue de l'index $this->render('index'); } /* * fonction diverses */ public static function encodeParam(&$value, &$key) { $value = urlencode($value); $key = urlencode($key); } } ?>??
Par contre, je ne met aucun code spécifique dans mes controlleurs d'action, contrairement à toi (cf le début de la méthode searchAction).
Sinon pour les bonnes pratiques, je ne peux pas trop te dire, je débute avec ZF.
Pour le tag de fermeture, c'est 'imposé' par les bonnes pratiques de Zend Framework (quand on parle du loup ...). Car si tu mets un espace blanc après le tag de fermeture, tu ne peux plus balancer des headers dans le code qui sera éxécuté après cette page. C'est écrit dans la documentation du framework ICI
Bien vu pour la doc sur la fermeture du tag php, c'est vrai que ça limite la casse mais je pensais pas qu'on pouvait le faire.
qu'entends-tu par code spécifique ? si tu parles de ce bout de code où l'a tu mis ? dans une fonction ?
Edit : on pourrait le mettre dans un init() du controller ou je dit une connerie ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 // clean url from form methode=get if (isset($_GET) && is_array($_GET) && !empty($_GET)) { $path = ''; array_walk($_GET, array('IndexController', 'encodeParam')); foreach ($_GET as $key => $value) { if ($key != 'Ok') $path .= '/' . $key . '/' . $value; } $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?')) . $path; $this->getResponse()->setRedirect($path, $this->_permanent ? 301 : 302); $this->getResponse()->sendResponse(); return; }
Autre question svp
J'ai voulu faire une fonction pour ajouter d'autres paramètres à supprimer en plus de 'submit' comme par exemple si le bouton submit a comme attribut name="Ok"...
J'ai donc appelé dans mon action :Mais ça marche pas, parce que le plugin est instancié avant mon action (pas mal ça) ! How-to ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part Plugin_CleanQuery::addBadParam('Ok');
Regarde la méthode routeStartup de mon plugin, en 2è partie, tu trouveras ce bout de code
Si tu veux pouvoir ajouter des éléments supplémentaires à supprimer, il faut effectivement que tu le fasses dans la page précédente... Soit via un attribut stocké en session... Soit tu normalises ton code en mettant toujours le(s) même(s) nom(s) à ton(tes) boutons ?
Salut
voici lu plugin modifié, je vais voir ce que je peux faire avec les sessions :
Par contre un $submit = new Zend_Form_Element_Submit('Ok!'); me donne par defaut un attribut NAME="Ok" et meme en fixant avec setName() cela ne fonctionne pas, en gros il est impossible d'avoir un input type=submit avec un name différent de la value
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 <?php /** * Plugin that cleans up querystrings in GET submissions * NB : ce plugin ne fonctionne pas lorsque les valeurs des paramètres contiennent des '/' */ class Plugin_CleanQuery extends Zend_Controller_Plugin_Abstract { /** * @var boolean */ protected $permanent; protected $badVarToClear=array('submit','Ok'); /** * Takes a flag in the constructor to determine whether the redirects * are permanent or just temporary (default); * * @param boolean $permanent */ public function __construct($permanent=true) { $this->permanent=$permanent; } /** * Cleans the GET and if it's changed does a redirect */ public function routeStartup(Zend_Controller_Request_Abstract $request) { // On supprime les paramètres qui n'ont pas de valeur if($this->getRequest()->isGet()) { $params = $this->getRequest()->getParams(); if($params) { $new_params = $this->_filterArray($params); if(count($params, COUNT_RECURSIVE) > count($new_params, COUNT_RECURSIVE)) { // $uri = $this->getRequest()->getRequestUri(); $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?') + 1) . http_build_query($new_params); $this->getResponse()->setRedirect($path, $this->permanent?301:302); $this->getResponse()->sendResponse(); exit; } } } // Si on a des paramètres qui sont passés par _GET, on réécrit l'url pour passer des paramètres ZF-Style if (isset($_GET) && is_array($_GET) && !empty($_GET)) { $path = ''; //array_walk($_GET, array(__CLASS__, 'encodeParam')); foreach ($_GET as $key => $value) { if (is_array ($value) ) { foreach ($value as $_value) { $path .= '/' . $key . '/' . $_value; } continue; } if (!in_array($key,$this->badVarToClear)){ $path .= '/' . $key . '/' . $value; } } $uri = $_SERVER['REQUEST_URI']; $path = substr($uri, 0, strpos($uri, '?')) . $path; $this->getResponse()->setRedirect($path, $this->_permanent ? 301 : 302); $this->getResponse()->sendResponse(); exit; } } /* * @param string $param * @param array $param */ public function addBadParam($param){ if (!is_array($param)){ $param = array($param); } foreach ($param as $p){ $this->badVarToClear[]=$p; } } /** * Cleans out false values from an array * * @param array $array */ private function _filterArray($array) { foreach($array as $key=>$value) { if(is_array($value)) { $value = $this->_filterArray($value); $array[$key]=$value; } if($value==='') { unset($array[$key]); } } return $array; } public static function encodeParam(&$value, &$key) { $value = urlencode($value); $key = urlencode($key); } }![]()
Ce n'est pas plutôt la valeur que tu dois initialiser avec $element->setValue($value) ?
Ma modif est inutile alors, addBadParam() et _filterArray() font la même chose si je comprend bien?
Si mais ça ne fonctionne pas, le code suivant :
retourne ça :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $submit = new Zend_Form_Element_Submit('Ok!'); $submit->setAttrib('id','submitBtn_formSearchInLinks'); $submit->setName('ddd'); $submit->setValue('Ok!');
Edit : j'ai trouvé en fait il faut utiliser setLabel() (voir ici)
Code : Sélectionner tout - Visualiser dans une fenêtre à part <input type="submit" value="ddd" id="submitBtn_formSearchInLinks" name="ddd"/>
Du coup je suis perdu, il te reste une question en suspens ou pas ?
Pour la méthode _filterArray, elle permet de supprimer les paramètres qui n'ont pas de valeur associée
Salut
ok pour _filterArray donc ma fonction sert à quelque chose seulement pas facile à implémenté du coup j'ai mis en dur mon paramètre 'Ok' dan la fonction en attendant de faire mieux (et si c'est possible).
Sinon j'essaye de regarder le code de Magento mais y'a un paquet de fichiers![]()
Pourrais-tu poser clairement à nouveau ton problème, parce que je comprends plus vraiment où est le problème exactementMerci
Attention Magento n'utilise pas l'application MVC du Zend Framework.Sinon j'essaye de regarder le code de Magento mais y'a un paquet de fichiers![]()
Bon courage.
C'est juste qu'au départ j'essayait d'attribuer une valeur a un bouton sans utiliser seLabel() mais setValue() ça c'est reglé
Par contre j'aurai bien voulu mettre en place (via les sessions ?) ma fonction addBadParam() qui permet de supprimer de l'url d'un formulaire GET des paramètres donnés. C'est surtout pour apprendre tout ça. Voila la question acutelle
Sinon pour Magento, sais-tu pourquoi ils n'ont pas opté pour le MVC du ZF ?
Et tu veux réaliser cette opération avant l'exécution du contrôleur ou après ?
Concernant Magento, je n'en sais pas plus que ça, probablement que ça n'entrait pas dans leur besoin ou que ça compliquait l'abstraction (car il faut se rappeler que c'est une application qui doit pouvoir être utilisée sur différents environnements et différentes configurations).
Partager