Symfony, sfPropelPager et passage de variables

Dans le cadre d’un projet, j’ai dû réaliser une pagination des résultats d’une recherche qui possédait de nombreux critères. Or le fait est que je n’avais jamais réalisé un Pager avec Symfony, car je me suis toujours basé sur le listing généré par l’Admin Generator…

Ce fut donc une expérience intéressante que de réaliser la pagination en utilisant le sfPropelPager de Symfony comme base. Donc pour replacer le contexte, on effectue un sélection sur une table individu avec une longue liste de Criteria et on fait :

$this->pager = new sfPropelPager('Individu', 20);
$this->pager->setCriteria($c);

$this->pager->setPage($this->getRequestParameter('page',$this->getUser()->getAttribute('page',1,'sf_admin/annuaire')));

$this->pager->init();
$this->recherche=$recherche;

// save page
if ($this->getRequestParameter('page')) {    $this->getUser()->setAttribute('page', $this->getRequestParameter('page'),'sf_admin/annuaire');}

On suppose que l’on a nommé les variables “recherche[…]” dans le formulaire de recherche, ainsi Symfony va mettre les résultats dans une matrice associative “recherche” que l’on va récupérer en paramètre. Je laisse le soin au lecteur de consulter la documentation de symfony concernant l’utilisation du pager pour gérer la navigation et autre.

Une fois la recherche effectuée et le Pager initialisé se pose un problème, Comment conserver les paramètres de la recherche page après page ????

Sans plus aller chercher en avant dans la totalité des solutions possibles, car j’en ai tenté plusieurs dont le passage en GET des paramètres dans l’url à chaque page… Voilà le moyen qu’utilise Symfony et qui permet de contourner tout le principe de passage de variable d’une action à un template (du Controler à une Vue) :

Il est en fait possible d’utiliser des Namespace, qui a contrario de C++ ne permettent pas de définir des classes, mais servent plus d’entrepôts pour stocker des variables. Il est ainsi possible dans notre cas de stocker la recherche et de la repasser de page en page, ainsi en début de méthode de recherche on écrit les lignes suivantes :

if($this->getRequestParameter('recherche')){$recherche = $this->getRequestParameter('recherche');

$this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/annuaire');

$this->getUser()->getAttributeHolder()->removeNamespace('sf_admin/annuaire/recherche');

$this->getUser()->getAttributeHolder()->add($recherche, 'sf_admin/annuaire/recherche');}

$recherche = $this->getUser()->getAttributeHolder()->getAll('sf_admin/annuaire/recherche');

Cette simple commande en début de code permet d’une part de récupérer les paramètres de la recherche via getRequestParameter lors du chargement de la première page et de les sauvegarder dans le namespace, et sinon si aucun paramètre n’est passé, de reprendre dans le namespace les paramètres.

Ainsi on court-circuite le passage de variables à une template qui ne va pas les modifier sauf en cas de nouvelle recherche.