Elcodi Ecommerce Going Components (Symfony-based): Review and Startup your store!

Sometime ago I wrote a book on Symfony Ecommerce at http://pilotci.com. This blog post expands to cover a solution that has taken a good decision lately. The decision of Elcodi to go components. This is packages, somewhat decoupled at first but aiming to more decoupled type packages.

The quick way to see how a store can be put together with Elcodi components is by clonning its flag store https://github.com/elcodi/bamboo-store:

git clone git@github.com:elcodi/bamboo-store.git
cd bamboo-store
composer install

You will need my PR https://github.com/elcodi/bamboo-store/pull/29 to get the right dependencies and the basic store working.

Also you will need this https://github.com/elcodi/elcodi/pull/252/files. Because there is an error when the database is not setup and the command is set as a service.

After running creating the database and schema and running the fixtures:

~ php app/console doctrine:fixtures:load
Careful, database will be purged. Do you want to continue Y/N ?y
  > purging database
  > loading Elcodi\Bundle\LanguageBundle\DataFixtures\ORM\LanguageData
  > loading Elcodi\Bundle\AttributeBundle\DataFixtures\ORM\AttributeData
  > loading Elcodi\Bundle\RuleBundle\DataFixtures\ORM\ExpressionData
  > loading Elcodi\Bundle\MenuBundle\DataFixtures\ORM\NodeData
  > loading Elcodi\Bundle\UserBundle\DataFixtures\ORM\CustomerData
  > loading Elcodi\Bundle\BannerBundle\DataFixtures\ORM\BannerZoneData
  > loading Elcodi\Bundle\CurrencyBundle\DataFixtures\ORM\CurrencyData
  > loading Elcodi\Bundle\ProductBundle\DataFixtures\ORM\CategoryData
  > loading Elcodi\Bundle\ProductBundle\DataFixtures\ORM\ManufacturerData
  > loading Elcodi\Bundle\ProductBundle\DataFixtures\ORM\ProductData
  > loading Elcodi\Bundle\CartBundle\DataFixtures\ORM\CartData
  > loading Elcodi\Bundle\CouponBundle\DataFixtures\ORM\CouponData
  > loading Elcodi\Bundle\CartCouponBundle\DataFixtures\ORM\CartCouponData
  > loading Elcodi\Bundle\BannerBundle\DataFixtures\ORM\BannerData
  > loading Elcodi\Bundle\CurrencyBundle\DataFixtures\ORM\RatesData
  > loading Elcodi\Bundle\AttributeBundle\DataFixtures\ORM\ValueData
  > loading Elcodi\Bundle\ProductBundle\DataFixtures\ORM\VariantData
  > loading Elcodi\Bundle\RuleBundle\DataFixtures\ORM\RuleData
  > loading Elcodi\Bundle\RuleBundle\DataFixtures\ORM\RuleGroupData
  > loading Elcodi\Bundle\MenuBundle\DataFixtures\ORM\MenuData

You can see the store with php -S localhost:8000 -t web. And opening the browser on app_dev.php.

Screenshot 2014-08-28 18.57.30

The construction of the store is very simple and even though we can improve removing the nightmare of annotations, it seems like the power of the services is the real meat there:

     * Cart view
     * @param FormView      $formView Form view
     * @param CartInterface $cart     Cart
     * @return array
     * @Route(
     *      path = "",
     *      name = "store_cart_view"
     * )
     * @Method("GET")
     * @Template
     * @AnnotationEntity(
     *      class = {
     *          "factory" = "elcodi.cart_wrapper",
     *          "method" = "loadCart",
     *          "static" = false,
     *      },
     *      name = "cart"
     * )
     * @AnnotationForm(
     *      class = "store_cart_form_type_cart",
     *      name  = "formView",
     *      entity = "cart",
     * )
    public function viewAction(
        FormView $formView,
        CartInterface $cart
        $relatedProducts = [];
        if ($cart->getCartLines()->count()) {
            $relatedProducts = $this
                    , 3);
        $cartCoupons = $this
        return [
            'cart'             => $cart,
            'cartcoupon'       => $cartCoupons,
            'form'             => $formView,
            'related_products' => $relatedProducts

The annotations are basically boilerplate code for param converters and getting the form sorted out. All in all, it is spread out in various endpoints/links that do the work of the store. In the end is a clean simple store solution that does not get on the way. If you don’t understand or a component does not fit certain needs you can obliterate it by just unplugging the respective bundle. This latter of course can be further improved defining compiler passes in a respective package so that we can forget about bundles once and for all as it is the trend of modern developments.

The good thing is it is an open source project. I have seen various frameworks, sylius, vespolina, thelia, leaphly, akeneo and others, my advise is always to strive for simplicity and less strings attached. Readability of code is paramount because you cannot design with something you disagree with or cannot read very well. Just to name a few, vespolina is a bit dead, thelia is one unit and not exactly components, leaphly misses a bit of other components, and akeneo is more a backend, and sylius well it follows a similar approach to Elcodi and it has been for a bit longer but it is a bit hard to chew and challenging to implement features consistently with a different approach sometimes. All have pros and cons, but the idea of a good ecommerce is one does not get on the way, your app will be domain driven and so the components should just support your design not the other way around.

Next steps, homework, is to probably get rid of the annotations of the top layer in Elcodi bamboo and see how to make that more streamlined.

Hope you try elcodi!

One thought on “Elcodi Ecommerce Going Components (Symfony-based): Review and Startup your store!

  1. What i do not understood is in fact how you are no longer really a lot more smartly-appreciated than you
    might be now. You are very intelligent. You already know
    therefore considerably with regards to this matter, produced me
    in my opinion imagine it from a lot of various angles.
    Its like women and men aren’t involved except it’s something to do with Woman gaga!
    Your own stuffs nice. All the time maintain it up!

Leave a Reply to клипы в 3d для lg о природе через mediaget Cancel reply

Your email address will not be published. Required fields are marked *