Qui l'eu CRUD ? Ou comment créer un thème pour les CRUD Doctrine de Symfony.

09.08.2010  • Samuel Breton

Symfony propose des outils très puissants pour faciliter le développement d’applications et surtout la génération des modules grâce à l’Admin Generator et le CRUD. Chacunes de ces solutions à ses avantages et ses inconvénients.

L’admin generator permet en une commande d’avoir un module complet et fonctionnel avec de nombreuses fonctionnalités, le tout relativement configurable. En contre partie, l’ajout de fonctionnalités spécifiques et la mise en forme peuvent rapidement s’avérer fastidieuses. Être obligé d’aller fouiller dans le cache pour aller faire des copier/coller afin de pouvoir surcharger une action, c’est comme qui dirait, bien mais pas top…

D’autre part le CRUD permet lui aussi de générer en une seule commade un module, mais ce module est plus que limité et on se retrouve systématiquement à ré-implémenter les mêmes fonctionnalités de base comme le pager, les filters, etc. Par contre travailler avec un CRUD permet de garder la main sur le code, ce qui n’est pas négligeable.

C’est pourquoi je vous propose de voir comment fabriquer un thème pour le CRUD de manière à l’enrichir de quelques fonctionnalités indispensables pour ne pas avoir à les ré-écrire systematiquement et ainsi ganger du temps. Je vais en profiter pour développer ce thème au sein d’un plugin de manière à pouvoir s’en resservir facilement.

Pour se faire je vais partir d’un projet vierge type sandbox auquel je rajoute le plugin sfTaskExtraPlugin qui facilite grandement la génération de plugins.
Pour me simplifier la vie, je vais reprendre le schema.yml et les fixtures (affiliates.yml, category.yml et jobs.yml) de Jobeet pour avoir un modèle sur lequel m’appuyer pour les exemples.

(Attention le fichier de fixture category.yml comporte les traductions, alors que le schema n’a pas le behavior I18n. Il faut au choix modifier le schema.yml pour rajouter le behavior ou modifier les categories pour supprimer les traductions)

Un petit ./symfony doctrine:build –all –and-load et nous voilà parti.

Let’s rock!

Pour fabriquer un module de type CRUD symfony se sert de template de code pour générer les actions et les vues. Ces fichiers sont bien cachés au fin fond du symfony ! On les trouve dans

/lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/data/generator/sfDoctrineModule/default

On va donc utiliser le thème par défaut que l’on va enrichir.

Tout d’abord, on va générer l’arborescence du plugin grâce à la commande generate:plugin de sfTaskExtraPlugin.

./symfony generate:plugin myCrudThemePlugin

Puis on prépare l’arborescence qui va accueillir les fichiers du template à l’intérieur du plugin.

mkdir -p plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme

Et on y copie tous les fichiers du thème par défaut.

cp -r lib/vendor/symfony/lib/plugins/sfDoctrinePlugin/data/generator/sfDoctrineModule/default/* plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme

Si vous avez fait un checkout de symfony, les fichiers que vous avez copiés contiennent les informations de svn. Il faut nettoyer tout ça. Je vous propose une petite ligne de commande qui permet de faire ca.

find plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme -name .svn -exec rm -rf {} \;

Les fichiers sont prêts. A ce stade, on pourrait déjà générer un thème en utilisant notre thème. Il sufirait d’activer le plugin dans

/config/ProjectConfiguration.class.php

enablePlugins(array(
      ...
      'myCrudThemePlugin',
    ));
  }
}

Et de lancer la commande :

./symfony doctrine:generate-module --theme="myCrudTheme" frontend job JobeetJob

Mais ne le faites pas ! :p Ca n’aurait pas un grand intérêt étant donné que l’on a rien changé par rapport au thème par défaut.

Nous allons commencer par rajouter un pager sur la page de listing. Il faut modifier l’action dans

/plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme/parts/indexAction.php


  public function executeIndex(sfWebRequest $request)
  {
    $query = Doctrine_Core::getTable('getModelClass() ?>')->createQuery('getModelClass(), 0, 1)) ?>');

    $this->pager = new sfDoctrinePager('getModelClass() ?>', sfConfig::get('app_myCrudThemePlugin_pagination', 20));
    $this->pager->setQuery($query);
    $this->pager->setPage($this->getRequestParameter('page', 1));
    $this->pager->init();
  }

Pour l’affichage du pager, je vous propose de créer un partial que l’on va inclure dans un module du plugin. Etant donné que le fonctionnement est générique, on a pas besoin qu’il soit recopié systèmatiquement dans les modules générés.

On va générer un module appelé shared qui va accueillir le partial du pager et éventuellement d’autres éléments que l’on voudra mutualiser.
La encore sfTaskExtraPlugin nous aide bien car il intégre une commande qui fais ca.

./symfony generate:plugin-module myCrudThemePlugin shared

Il nous reste à aller créer notre partial dans

/plugins/myCrudThemePlugin/modules/shared/templates/_pager.php

haveToPaginate()): ?>
  
  

Un pager générique qui fonctionne pour les sfDoctrineRoute et les sfRequestRoute. Il prends deux paramètres, route (obligatoire) et object (facultatif).

On modifie la vue indexSuccess.php pour la faire fonctionner avec le pager et ajouter le partial du pager.

Dans

/plugins/myCrudThemePlugin/data/generator/sfDoctrineModule/myCrudTheme/template/templates/indexSuccess.php

getPluralName()) ?> List

getColumns() as $column): ?> [?php foreach ($pager->getResults() as $getSingularName() ?>): ?] getColumns() as $column): ?> isPrimaryKey()): ?> params['route_prefix']) && $this->params['route_prefix']): ?> [?php endforeach; ?]
getPhpName())) ?>
[?php echo $getSingularName() ?>->getgetPhpName()) ?>() ?] [?php echo $getSingularName() ?>->getgetPhpName()) ?>() ?] [?php echo $getSingularName() ?>->getgetPhpName()) ?>() ?]
[?php include_partial('shared/pager', array('pager' => $pager, 'route' => 'params['route_prefix']) && $this->params['route_prefix']) ? $this->getUrlForAction('index') : $this->getModuleName().'/index' ?>')) ?] params['route_prefix']) && $this->params['route_prefix']): ?> New New

On peut d’ores et déjà générer le crud pour tester,

./symfony doctrine:generate-module --theme="myCrudTheme" frontend job JobeetJob

Et vous voilà libéré de la tâche rébarbative des pagers ! :p

Ca faisait un petit moment que je voulais traiter ce sujet sur le blog, et je comptais continuer en intégrant les formFilter. Malheureusement, je manque de temps pour aller plus loin.
Mais vous avez désormais en votre possession les éléments pour pouvoir faire votre propre thème et l’enrichir à votre guise.

J’espére que ca vous aura été utile et si j’en ai le temps je ferais un prochain post pour voir cette intégration des formFilter 😉

Directeur conseil chez Spiriit
J'accompagne nos clients sur la mise en place de la stratégie, de l'architecture et dans la structuration du projet. J'interviens en amont des projets pour la planification et en aval sur la partie KPI / Performance.
Voir l’étude de cas
Lire l’article
Lire l’actualité
En savoir plus
En savoir plus
Voir le témoignage
Fermer