Au cours de son développement Sylius, l'équipe s’est rendu compte qu’elle dupliquait énormément de code pour gérer ses CRUDs. Ne voulant pas réinventer Symfony ou utiliser un admin generator, elle décida de créer un bundle simple et flexible: SyliusResourceBundle. Je présenterai comment gérer ses CRUDs avec ce bundle en écrivant le minimum de code et, surtout, sans en dupliquer! Il a été pensé afin de pouvoir supporter plusieurs types de drivers (DoctrineORM, PHPCR). De plus, il permet de construire rapidement une API grâce au FOSTRestBundle. Je mettrai en avant l’ensemble des composants utilisés par ce bundle comme Doctrine. Il facilite la configuration le ResolveDoctrineTargetEntitiesPass ainsi que la création de MappingDriver. Il utilise aussi l’EventDispatcher: des évènements sont soulevés lorsque une action est exécutée sur une ressource. Il apporte aussi de nouveaux FormType ou FormExtension comme la CollectionExtension qui permet de gérer ses forms collection (js inclus).
2. QUI SUIS-JE ?
Arnaud Langlade (@_aRn0D)
Développeur Symfony chez Clever Age
www.clever-age.com / @CleverAge
3. SYLIUS
Framework E-commerce créé par Paweł Jędrzejewski
Ensemble de bundles Symfony et composants PHP e-commerce
Sylius Starndard Edition
Quelques chiffres : ~200 contributeurs / ~1700 stars
7. POURQUOI LA CRÉATION DE CE BUNDLE?
Le back office de Sylius est composé d'énormement de CRUDs
Eviter la duplication de code parce que c'est mal!
Développer plus vite en automatisant des tâches
8. UNE SOLUTION? RESOURCECONTROLLER?
Création du ResourceController :
C'est un contrôleur générique
Plus de code, il est intialisé via une configuration
Il étend the FOSRestController
Utilisation du EventDispatcher (répartiteur d'évènement) :
Il permet de personnaliser les actions
Solution plus flexible
9. QUELS SONT ORM/ODM SUPPORTÉS ?
Doctrine ORM : Sylius l'utilise par défaut
Doctrine Phpcr-ODM : Sylius intègre le CMF pour gérer des contenus
Doctrine Mongodb-ODM
Bientôt sûrement plus !
10. ATTENTION!
Ce n'est pas un admin generator!
Il faut créer vos formulaires, vos templates et le routing (pour le moment!)
11. CRÉER SON CRUD EN QUELQUES MINUTES !
Par exemple, créons un CRUD pour gérer des clients (customer).
19. ET PAF ! ÇA FAIT DES CHOCAPICS !
Notre CRUD est prêt à l'emploi !! On crée notre API ?
20. EXPOSER SES CLIENTS VIA API REST
Configurer le FOSRestBundle
# app/config.yml
fos_rest:
format_listener:
rules:
{ path: '^/', priorities: ['html', 'json'], fallback_format: html}
Le ResourceController retourne le données dans le format souhaité
GET /customer/57 HTTP/1.1
Host: myshop.com
Accept: application/json
22. C'EST TOUT ?
Lionframe (Rapid RESTful API Development)
Génération automatique des formulaires et du routing
23. PLUS DE FLEXIBILITÉ ?
Le comportement des méthodes du ResourceController est configurable
24. CONFIGURER LES METHODES DU RESOURCECONTROLLER
Ajouter une entrée _sylius dans le tableau defaults des routes
# app/routing.yml
myapp_customer_create:
defaults:
_sylius:
template: WebBundle:Backend/Customer:custom_create.html.twig
31. SYLIUS FONCTIONNE AVEC DES BUNDLES
Ils doivent être facilement étendables
Ils peuvent supporter plusieurs "drivers" (ORM/ODM)
Ils ne doivent être couplés les uns aux autres
33. MAIS QUE SE PASSE T'IL?
$ php app/console container:debug | grep customer
myapp.controller.customer container SyliusBundleResourceBundleControllerResourceController
myapp.manager.customer n/a alias for doctrine.orm.default_entity_manager
myapp.repository.customer container SyliusBundleResourceBundleDoctrineORMEntityRepository
myapp.form.type.customer container myappCustomerBundleFormTypeCustomerType
$ php app/console container:debug parameters | grep customer
myapp.model.customer.class myappCustomerBundleModelCustomer
myapp.model.customer.class myappCustomerBundleModelCustomer
myapp.controller.customer.class SyliusBundleResourceBundleControllerResourceController
myapp.repository.customer.class SyliusBundleResourceBundleDoctrineORMEntityRepository
myapp.form.type.customer.class myappCustomerBundleFormTypeCustomerType
myapp.validation_group.customer ["myapp"]
myapp_customer.driver doctrine/orm
34. ETENDRE FACILEMENT VOTRE BUNDLE
Utiliser l'injecteur de dépendences (Dependency Injector)
Déclarer votre classe en tant mapped-superclass (évènement loadClassMetadata)
35. GÉRER PLUSIEURS DRIVERS
Créer votre "Doctrine Mapping Driver"
Fournir plusieurs implementations Doctrine pour un modèle
Vos documents et entités sont dans le même namespace
36. LIMITER LE COUPLAGE DE VOS BUNDLES
Utiliser le Resolve Target Entity Listener
Définir des relations entre différentes entités sans les écrire en dur
Il ré-écrit les paramètres targetEntity dans le mapping de votre modèle
<! Resources/config/doctrine/order.xml >
<onetomany field="orders" targetentity="SyliusComponentOrderModelOrderInterface">
<! ... >
</onetomany>
38. GO TO THE FUTURE!
Refactoring de la SyliusResourceExtension
Rendre le système plus flexible
Uniformiser la configuration
De nouveaux FormType ?
Un datagrid ?
39. VENEZ CONTRIBUER!
Merci à tous les contributeurs!
N'hésister pas à nous soumettre vos PRs...
... surtout si vous aimez écrire de la doc :D !