Meet Elcodi, the flexible e-commerce components built on Symfony2
-
Upload
aldo-chiecchia -
Category
Software
-
view
824 -
download
1
Transcript of Meet Elcodi, the flexible e-commerce components built on Symfony2
![Page 1: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/1.jpg)
Programming made fun
ELCODI
![Page 2: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/2.jpg)
github.com/mmoreram
github.com/alch
github.com/elcodi-bot
@zimage
@elcodi_dev
@mmoreramMarc Morera
Aldo Chiecchia
Elcodi Bot
![Page 3: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/3.jpg)
it began as an internal project@befactory
![Page 4: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/4.jpg)
LET’s TALK ABOUT…
Hello World!
Simple doctrine mapping
The Cart system
Annotations
![Page 5: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/5.jpg)
did you just say Annotations?
![Page 6: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/6.jpg)
DON’T PANIC
![Page 7: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/7.jpg)
1.HELLO WORLDWhat is my purpose in life?
![Page 8: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/8.jpg)
SYMFONY2 ECOMMERCE APPS
S.O.L.I.D. Reusable
Testable Community
![Page 9: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/9.jpg)
philosophy
Elcodi was born to be a Symfony project
Symfony components Symfony Framework
![Page 10: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/10.jpg)
we love all of symfony…so we are putting our efforts in both
![Page 11: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/11.jpg)
coupled to the framework?OMFG!
Why not get the best of both worlds?
Symfony components for advanced devs
Symfony framework for the pragmatic devs
Everybody’s happy
![Page 12: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/12.jpg)
Core stuff, only symfony components
![Page 13: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/13.jpg)
Web app, frontend
![Page 14: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/14.jpg)
Web app, backoffice
![Page 15: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/15.jpg)
The playground!
![Page 16: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/16.jpg)
![Page 17: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/17.jpg)
with symfony-standard
"require": { "elcodi/elcodi": "~0.4", "elcodi/bamboo-fixtures": “~0.1”, “doctrine/doctrine-fixtures-bundle": “v2.2.0"}
composer.json
![Page 18: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/18.jpg)
new Doctrine\Bundle\DoctrineCacheBundle\DoctrineCacheBundle(),new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle(),new Knp\Bundle\GaufretteBundle\KnpGaufretteBundle(),new Elcodi\Bundle\CoreBundle\ElcodiCoreBundle(),new Elcodi\Bundle\CurrencyBundle\ElcodiCurrencyBundle(),new Elcodi\Bundle\LanguageBundle\ElcodiLanguageBundle(),new Elcodi\Bundle\AttributeBundle\ElcodiAttributeBundle(),new Elcodi\Bundle\ProductBundle\ElcodiProductBundle(),new Elcodi\Bundle\MediaBundle\ElcodiMediaBundle(),
with symfony-standardAppKernel.php
![Page 19: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/19.jpg)
doctrine_cache: providers: elcodi: type: arrayknp_gaufrette: adapters: images_storage_adapter: local: directory: %kernel.root_dir%/../web/images create: true filesystems: local: adapter: images_storage_adapter
with symfony-standardconfig.yml
![Page 20: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/20.jpg)
$ php app/console do:fi:lo \ -‐-‐fixtures=vendor/elcodi/bamboo-‐fixtures/\
src/Fixtures/DataFixtures/ORM/Product
![Page 21: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/21.jpg)
namespace Elcodi\TrainingBundle\Controller;use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Symfony\Component\HttpFoundation\Response;class HelloController extends Controller{ public function helloAction() { $productRepository = $this->container ->get('elcodi.repository.product'); $storedProduct = $productRepository->find(1); $productObjectManager = $this->container ->get('elcodi.object_manager.product'); $newProduct = $this->container ->get('elcodi.factory.product')->create() ->setName('SymfonyCon ticket')->setSlug(''); $productObjectManager->persist($newProduct); $productObjectManager->flush(); return new Response($newProduct->getId()); }}
![Page 22: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/22.jpg)
public function priceAction(){ $productObjectManager = $this->container ->get('elcodi.object_manager.product'); $productRepository = $this->container ->get('elcodi.repository.product'); $storedProduct = $productRepository->find(1); // Currency from a session based wrapper $currency = $this->container ->get('elcodi.currency_wrapper')->getCurrency(); // Money Value Object $newPrice = Money::create(1000, $currency); $storedProduct->setPrice($newPrice); $productObjectManager->flush(); return new Response("Changed price!"); }
![Page 23: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/23.jpg)
public function changeMediaAction(){ $productRepository = $this->container ->get('elcodi.repository.product'); $storedProduct = $productRepository->find(1); // This can also be an instance of UploadedFile $file = new File('/tmp/my_image.jpg'); // Factors an Image and sets media meta-data $image = $this->container ->get('elcodi.image_manager') ->createImage($file); $imageObjectManager = $this->container ->get('elcodi.object_manager.image'); $imageObjectManager->persist($image); $imageObjectManager->flush($image); // Stores the image using the underlying // Gaufrette adapter $this->container ->get('elcodi.file_manager') ->uploadFile($image, $image->getContent(), false); $storedProduct->addImage($image); $storedProduct->setPrincipalImage($image); $this->container ->get('elcodi.object_manager.product') ->flush(); return new Response("Changed image!");}
![Page 24: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/24.jpg)
extensibility?
![Page 25: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/25.jpg)
2.simple Doctrine MappingMaking it… easy :)
![Page 26: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/26.jpg)
premises
Assume that a lot of things will be overridden
Even an entity (Class, mapping, manager)
So… auto-mapping, you’re not welcomed!
Say hello to SimpleDoctrineMapping
![Page 27: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/27.jpg)
![Page 28: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/28.jpg)
auto-mapping = falseWooooo…
![Page 29: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/29.jpg)
Why?
We want the responsibility of mapping our model, even for foreign required bundles (like FOS)
Each entity must be defined by a class, a mapping file and the manager assigned
Anyone should be able to modify this information in a very simple way
![Page 30: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/30.jpg)
Compiler Pass
Using a compiler pass we add every single Entity configuration, even the Abstracts.
The CompilerPass must extend the foreign entities
Only one method available with 4 required parameters.
Bundle aliasing by short reference : @MyBundle
![Page 31: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/31.jpg)
use Mmoreram\SimpleDoctrineMapping\CompilerPass\Abstracts\AbstractMappingCompilerPass;use Symfony\Component\DependencyInjection\ContainerBuilder;/** * Class MappingCompilerPass */class MappingCompilerPass extends AbstractMappingCompilerPass{ /** * You can modify the container here before it is dumped to PHP code. * * @param ContainerBuilder $container * * @api */ public function process(ContainerBuilder $container) { $this ->addEntityMapping( $container, 'default', 'Elcodi\Component\Product\Entity\Product', '@ElcodiProductBundle/Resources/config/doctrine/product.orm.yml', true ) ->addEntityMapping( $container, 'default', 'Elcodi\Component\Product\Entity\Category', '@ElcodiProductBundle/Resources/config/doctrine/category.orm.xml', true ); }}
![Page 32: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/32.jpg)
It is not overridable!
![Page 33: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/33.jpg)
Let’s think about a way of overriding Symfony Bundle values
…
Oh, yes! Configuration + Parameters! Let’s do that!
WHAT IF We could override anything?
![Page 34: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/34.jpg)
use Mmoreram\SimpleDoctrineMapping\CompilerPass\Abstracts\AbstractMappingCompilerPass;use Symfony\Component\DependencyInjection\ContainerBuilder;/** * Class MappingCompilerPass */class MappingCompilerPass extends AbstractMappingCompilerPass{ /** * You can modify the container here before it is dumped to PHP code. * * @param ContainerBuilder $container * * @api */ public function process(ContainerBuilder $container) { $this ->addEntityMapping( $container, 'elcodi.core.product.entity.product.manager', 'elcodi.core.product.entity.product.class', 'elcodi.core.product.entity.product.mapping_file', 'elcodi.core.product.entity.product.enabled' ) ->addEntityMapping( $container, 'elcodi.core.product.entity.category.manager', 'elcodi.core.product.entity.category.class', 'elcodi.core.product.entity.category.mapping_file', 'elcodi.core.product.entity.category.enabled' ); }}
![Page 35: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/35.jpg)
Propose a mapping of a Bundle’s entities
Change the namespace of an entity
Change the specific mapping file (xml or yml)
Change the associated manager class
And now you can
And even… disable it!
![Page 36: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/36.jpg)
3.the cart systemEvents FTW!
![Page 37: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/37.jpg)
A Cart represents the transient state of a purchase before it is committed.
An Order can be seen as a persisted snapshot of a Cart
Transitions raise events
rationale
![Page 38: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/38.jpg)
new Elcodi\Bundle\CartBundle\ElcodiCartBundle(),new Elcodi\Bundle\UserBundle\ElcodiUserBundle(),new Elcodi\Bundle\GeoBundle\ElcodiGeoBundle()
more symfony-standardAppKernel.php
![Page 39: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/39.jpg)
$ php app/console do:sc:up -‐-‐force
lots of new tables…
![Page 40: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/40.jpg)
$ php app/console do:fi:lo \ -‐-‐fixtures=vendor/elcodi/bamboo-‐fixtures/\ src/Fixtures/DataFixtures/ORM/Customer \
-‐-‐append
![Page 41: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/41.jpg)
public function addProductAction(){ $productRepository = $this->container ->get('elcodi.repository.product'); $storedProduct = $productRepository->find(1); $cart = $this->container ->get('elcodi.cart_wrapper')->loadCart(); $this->container ->get('elcodi.cart_manager') ->addProduct($cart, $storedProduct, 1); return new Response('Added to cart!');}
![Page 42: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/42.jpg)
cartwrapper
Envelopes a Cart object and provides the logic to retrieve it
If the Customer has pending Carts, the last Cart form this collection is returned
If there is a Cart in session, it is associated with the Customer and is returned
When there is no Cart in session, a new one is factored
Overridable!
![Page 43: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/43.jpg)
A new CartLine is factored with the information of the product
“Cart added” events are raised
“Cart loaded” events are raised
The latter is used by specific event listeners to recalculate prices and to perform a flush()
when i add a product
![Page 44: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/44.jpg)
class ElcodiCartEvents{ const CART_PRELOAD = 'cart.preload'; const CART_ONLOAD = 'cart.onload'; const CART_ONEMPTY = 'cart.onempty'; const CART_INCONSISTENT = 'cart.inconsistent'; const CARTLINE_ONADD = 'cart_line.onadd'; const CARTLINE_ONEDIT = 'cart_line.onedit'; const CARTLINE_ONREMOVE = 'cart_line.onremove'; const ORDER_PRECREATED = 'order.precreated'; const ORDER_ONCREATED = 'order.oncreated'; const ORDERLINE_ONCREATED = 'order_line.oncreated'; const ORDER_STATE_PRECHANGE = 'order_state.prechange'; const ORDER_STATE_ONCHANGE = 'order_state.onchange'; const ORDERLINE_STATE_PRECHANGE = 'order_line_state.prechange'; const ORDERLINE_STATE_ONCHANGE = 'order_line_state.onchange'; }
![Page 45: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/45.jpg)
public function createOrderAction(){ // CartWrapper will look for a customer in order // to "resolve" current cart $customer = $this->container ->get('elcodi.customer_wrapper')->loadCustomer(); $cart = $this->container ->get('elcodi.cart_wrapper')->loadCart(); $order = $this->container ->get('elcodi.cart_order_transformer') ->createOrderFromCart($cart); return new Response( sprintf('Order %d created!', $order->getId()) );}
how do I create an order?
![Page 46: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/46.jpg)
more productivity tools?
![Page 47: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/47.jpg)
4.AnnotationsTelling stories
![Page 48: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/48.jpg)
Why?Always looking for a balance among smartness, efficiency and resolution.
Annotations are part of PHP. Why not?
Elcodi Core is a 3rd party project. Controllers as a services with no annotations
Bamboo is a project example on top of Elcodi, so Annotations would be nice
Symfony Best Practices. Thanks!
PDD principle
![Page 49: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/49.jpg)
Why??Oh man! You’re coupling the controllers with the framework.
Ok. How many of you have ever change from one FW to another one with same controllers.
If we use abstract controllers, some logic data is hidden in another file.
Annotations tell us a story in a simple and clean way.
![Page 50: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/50.jpg)
Controller Extra Bundle
Set of symfony framework controller annotations
Why ControllerExtraBundle instead of FrameworkExtraBundle?
Controller specific annotations and a platform for creating new ones.
We have the control of the repository. Important, right?
Documented with cool examples.
![Page 51: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/51.jpg)
installing
"require": { "mmoreram/controller-extra-bundle": "~1.0", }
composer.json
![Page 52: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/52.jpg)
@entity
Like FrameworkExtraBundle, but changes the way a class is defined
By namespace
By DIC parameter (yes, container dependency)
By factory with static or non-static method
By factory as a service with static or non-static method
![Page 53: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/53.jpg)
use Mmoreram\ControllerExtraBundle\Annotation\Entity as EntityAnnotation;use Symfony\Component\HttpKernel\Tests\Controller;class AnnotatedController extends Controller{ /** * Simple controller method * * This Controller matches pattern /user/edit/{id}/{username} * * @EntityAnnotation( * class = { * "factory" = my.bundle.factory.myentity_factory, * "method" = "create", * "static" = true, * }, * name = "user", * mapping = { * "id": "~id~", * "username": "~username~" * } * ) */ public function indexAction(User $user) { }}
![Page 54: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/54.jpg)
@form
Creates a FormType, a Form or FormView (depending on the parameter type-hinting)
Can be defined with the namespace or with the alias
Can handle the request with a previously defined entity (With @entity or @paramConverter)
Can validate the form and inject the result as an action parameter
![Page 55: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/55.jpg)
use Mmoreram\ControllerExtraBundle\Annotation\Form as FormAnnotation;use Symfony\Component\HttpKernel\Tests\Controller;class AnnotatedController extends Controller{ /** * Simple controller method * * @Route( * path = "/user/{id}", * name = "view_user" * ) * @ParamConverter("user", class="MmoreramCustomBundle:User") * @FormAnnotation( * class = "user_type", * entity = "user" * handleRequest = true, * name = "userForm", * validate = "isValid", * ) */ public function indexAction(User $user, Form $userForm, $isValid) { }
![Page 56: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/56.jpg)
@paginator
Given an URL, injects a Paginator
In current implementation, some extra info can be also injected, like total available pages.
Pagerfanta compatible (not used in Elcodi)
![Page 57: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/57.jpg)
use Mmoreram\ControllerExtraBundle\Annotation\Paginator;use Symfony\Component\HttpKernel\Tests\Controller;class AnnotatedController extends Controller{ /** * Simple controller method * * @Paginator( * class = "MmoreramCustomBundle:User", * wheres = { * {"x", "enabled", "=", true}, * {"x", "age", ">", “~age~”}, * {"x", "name", "LIKE", "Efervescencio"}, * } * ) */ public function indexAction(Paginator $paginator) { } }
![Page 58: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/58.jpg)
summing it up
Elcodi is a set of tools to speed up development
It helps you scale out your ideas
Pragmatic driven
Baked with♥
![Page 59: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/59.jpg)
questions?
![Page 60: Meet Elcodi, the flexible e-commerce components built on Symfony2](https://reader033.fdocuments.us/reader033/viewer/2022052700/55a249d21a28ab8e2b8b477d/html5/thumbnails/60.jpg)
ten-queue!See you in Github!