J'ai découvert au fil de mes flux RSS un petit script qui permet d'obtenir l'auto-complétion du mode CLI de Symfony. Je tente, de cet article, de vous expliquer en quoi il est pratique, et comment l'installer sur votre serveur.
Tag - symfony
lundi, mars 1 2010
Auto-complétion des commandes Symfony
Par Mikael Randy le lundi, mars 1 2010, 16:41 - Symfony
dimanche, février 21 2010
Symfony 2 reloaded
Par Mikael Randy le dimanche, février 21 2010, 22:48 - Symfony
Ce mercredi 17 février 2010, en clôture du Symfony Live 2010, Fabien Potencier a présenté Symfony 2 qui porte le nom de code de "Symfony reloaded". En voici un retour en quelques points clés.
vendredi, janvier 29 2010
Créer une classe parent pour tout le modèle avec Doctrine
Par Mikael Randy le vendredi, janvier 29 2010, 14:12 - Symfony
Pour qui a déjà utilisé Doctrine de manière un tant soit peu avancé, une problématique a dû se poser à un moment où à un autre : Comment faire pour définir un comportement pour tout mon modèle ?
Dernièrement, j'ai voulu mettre en place un système loguant toutes les suppressions, pour des besoins de tracabilité. La solution la plus simple me semblait être de pouvoir surcharger la méthode de suppression générique au niveau de mon projet.
Or, lorsque l'on regarde d'un peu plus près l'arborescence de classe généré par Doctrine, on peut se rendre compte qu'il manque d'une classe générique à tout le modèle, au niveau du projet et qui permettrait de faire ce que je cherchais à faire.
Le fonctionnement de base de Doctrine
Doctrine gère 2 types de classes, qui ont chacune une arborescence bien spécifique : les classes de tables et les classes d'entités.
Les classes de tables permettent de gérer les collections, c'est à dire les groupes d'enregistrements
Les classes d'entités permettent la gestion des unités, c'est à dire chaque enregistrement indépendamment.
Si votre projet nécessite la présence, par exemple, de 2 tables : "User" et "Right", Doctrine va générer l'arborescence de classe suivante :

Comme on peut le remarquer, toutes les classes qui se trouvent dans le projet sont gérées indépendamment, et la 1ère classe générique se trouve au niveau du coeur de symfony. Dans le sfDoctrinePlugin, pour être précis.
Ajouter un niveau de classe avec Doctrine
Afin de pouvoir disposer d'un niveau de classe supplémentaire, au niveau du projet, il est possible de configurer Doctrine pour que les classes "Base" et "BaseTable" héritent d'autres tables que celles par défaut (respectivement sfDoctrineRecord et Doctrine_Table).
Pour agir sur la configuration de Doctrine, il vous faut éditer le fichier "config/ProjectConfiguration.class.php" comme suit :
class ProjectConfiguration extends sfProjectConfiguration { public function setup() { // ... // custom builder options for doctrine sfConfig::set('doctrine_model_builder_options', array( 'baseTableClassName' => 'MyDoctrineTable', 'baseClassName' => 'MyDoctrineRecord')); } }
Ainsi, avec ces configurations, on demande à Doctrine de faire en sorte que toutes les classes "Base" héritent de la classe "MyDoctrineRecord" et que les classes "BaseTable" héritent de la classe "MyDoctrineTable", comme illustré dans l'exemple suivant :

Ces classes là doivent bien entendu elles même se remettre dans l'arborescence de classe.
Les squelettes de base de ces classes doivent donc être les suivants :
class MyDoctrineTable extends Doctrine_Table { // ... } class MyDoctrineRecord extends sfDoctrineRecord { // ... }
A partir de là, il suffit de régénérer le modèle pour que la nouvelle arborescence soit disponible :
symfony doctrine:build-model
Et, de cette manière, il est donc possible d'agir sur toutes les opérations réalisées par le modèle depuis ces classes.
mardi, décembre 22 2009
Enregistrer une collection d'objet, avec contrôle de fonctionnement
Par Mikael Randy le mardi, décembre 22 2009, 14:37 - Symfony
Ce jour, un de mes développeurs a fait une découverte sympathique sur Doctrine.
Le besoin de base était le suivant : On manipule une liste d'objet (création, affectation de contenu) dans l'optique de les sauvegarder.
La syntaxe que nous tout un chacun est tenté de faire est la suivante :
try { for($i = 0; $i < 10; $i++) { $item = new Item(); $item->setValue($i); $item->save(); } } catch (sfException $e) { echo "An error occurs while data saving" }
Or, le soucis, avec cette méthode, c'est que si une erreur intervient au cours de la sauvegarde, par exemple, pour l'item n°5, eh bien en base, nous aurons les items correctement enregistrée (entre 0 et 4), mais il manquera la fin (de 5 à 9).
La solution est simple, me direz vous, il suffit d'ouvrir une transaction avant, et de la fermer après. Eh bien oui, vous avez raison, mais j'ai trouvé encore plus élégant : les collections Doctrine (Doctrine_Collection). Si vous êtes un habitué de Doctrine, vous avez déjà croisé cette classe puisque Doctrine remplace les tableaux par des instances de celle-ci.
Toujours est-il que l'équivalent du code précédent, mais en prenant en compte la transaction, et en utilisant les Doctrine_Collection est le code suivant :
$items = new Doctrine_Collection('Item', 'id'); try { for($i = 0; $i < 10; $i++) { $item = new Item(); $item->setValue('value ok'); if($i == 5) $item->setValue('error value'); // Add item into Doctrine_Collection $items->add($item); } // Save collection content, in a SQL transaction $item->save(); } catch (sfException $e) { echo "An error occurs while data saving" }
Je trouve ça tellement plus pratique et élégant que je suis tombé sous le charme de cette méthode.