Checking out Sylius: Symfony2 e-commerce

Last Friday we did a one day hackday with the goal of checking out the Symfony2 based e-commerce solution Sylius. Among the attendees were even two guests with Fabian and Stefano joining the Liipers David, Matteo, Patrick, Tobias and myself.

Getting started

We did not have any specific agenda and decided to just install and start exploring. For the most part this was a quite painless experience it just takes a while when 7 people clog up a wifi connection. Pawel had just completed the update for Symfony 2.3 the day before, so we found some minor bugs that we fixed. Stefano also submitted a PR to fix PDF generation on travis. Matteo spend some time updating the german translations.

Behat tests

Fabian decided to dig into the Behat tests which were failing on travis-ci.org due to memory issues. Sylius comes with a very extensive set of Behat tests. As a matter of fact maybe this is the best source of documentation of Sylius features. In the end his solution was to simply split the test execution by tag.

Adding some PHPCR love

One thing we noticed quickly while reviewing the database schema is the table used to store the ProductProperty class instances. It uses the Entity-Attribute-Value pattern, one of the reasons why its not so trivial to scale Magento. Essentially this is one commonly used approach to deal with unstructured data in an RDBMS while retaining some ability to run search queries. The big issues with the approach is that reading data out is quite hard but worse it basically requires one column for any kind of data being stored. In the case of Sylius its using a VARCHAR(255). So we figured we would simply use Doctrine listeners to modify the persisting to use PHPCR instead. The advantage being that with PHPCR it would allow to support all sorts of data types without length limitations. So this would for example allow to associated additional images, dates and longer descriptions with products. Stefano and I struggled a bit with the ORM listeners. We learned that persisted entities are not stored in the identity map until the RDBMS has actually generated an ID. Until then one has to use getScheduledEntityInsertions() to get access to the relevant entities. Once we figured that out the actual tasks of integrating PHPCR was comparatively trivial. Now it might however make sense to even go a step further and store the Product class itself in PHPCR as well using PHPCR ODM.

Dynamic routing

Sylius uses two “catchall” routes for products and categories. This is a quite common pattern found in CMS’s build on top of Symfony2 or many other general purpose web development frameworks. Basically one defines a route that simply catches anything below a specific pattern without knowing if anything even exists in the database that would match that. Then inside the controller a DB lookup is made and in case the data is missing a 404 is returned. In the Symfony2 CMF initiative we solved this need by introducing a chain router and dynamic router which has been adopted by ezPublish 5 and Drupal 8. It allows one to chain the standard Symfony2 router and any number of dynamic routers which means that static routes (like f.e. the homepage) do not need to be moved to the DB. The job of the dynamic router is to do a DB lookup during the routing stage. This means the controller is no longer responsible for this task. Stefano and I managed to implement this surprisingly quickly. One draw back of this approach is that now a DB lookup is also required to generate a route. Enabling the ORM entity cache however solved this problem quite easily.

Taxonomies for the CMF

So while Stefano and I worked in integration code form the CMF into Sylius, David attempted to do the opposite. He tried to integrate the SyliusTaxonomiesBundle into the CMF. However unfortunately he didn’t yet manage to get it to work.

Admintool

Matteo and Tobias looked a bit more deeply at the admin tool and unfortunately found several missing features. More over they quickly realized that the different tools allowed bringing the data to an inconsistent state. They then spend some time making the order status actually dynamic, at the time its was all hardcoded. They were still a bit unsure about the actual concept of how the order status relates to the relevant potentially several different shipping status states.

Sylius in the real world

Patrick is actually already running a Sylius web shop in a private project. So he spend some time investigating how to upgrade and what has changed. He found that indeed a lot of has changed but everything that has changed, changed for the better. However there are still things missing. For example in his project they needed additional notifications when an order is created.

Take away

Sylius looks really promising and we were positively surprised with the provided feature set. The code is clear and well structured and very easy to get started for a Symfony2 developer. However there are still important missing features making it very hard to plan the amount of time needed to do an actual real world project. The added fact that a lot of code is still very much in flux makes things even harder. It seems however that one could take the code at any point in time and complete a project with fairly well working code. In this regard the situation is quite similar to the CMF which has also already been used by several companies to build production applications. No doubt once Sylius has a stable release it will be a very viable alternative to Magento for projects that need very heavy customizations. In this sense it will also be interesting to see how OroCRM and Akeneo will turn out as these could provide some advanced CRM and product management capabilities that should be easily integrable since both of these applications are written in Symfony2 as well.

Thanks for organizing the event. See my review of the event here: http://www.ymc.ch/en/symfony2-and-hackdays-why-we-like-to-contribute

Thanks to Lukas & Liip for organizing the hackday and to all folks out there. Appreciate all the PR’s and suggestions!

updated my blog post

http://www.craftitonline.com/2013/08/vespolina-and-sylius-hacking-days-symfony2-ecommerce-tools/

to reflect this one. Thanks for the summary.

I think that is what the flexibility counts that even if its not stable one can take things and deploy real things. Of course is better to have something finished but lean does not forgive.

Also Vespolina is plugging some energy recently and it looks like is going to be an option too.

Hi Lukas,

I use to do some Magento so I like the idea of removing painfull EAV pattern and use PHPCR instead.
But as e-commerce applications requires a powerfull search system, do you think that PHPCR-ODM performances will be good enough to make queries on product attributes ?

Nico

That is a very good question.

First up can we agree that given the performance but more importantly feature requirements (facetting, language aware tokenization etc) of search, RDBMS based solution currently fall flat. This is why most shop, cms etc solutions these days adopt some Lucene based solution (Solr/ElasticSearch) into which all relevant content is denormalized. Sphinx is a popular choice for those who do not want to introduce Java but I am not so familiar with how flexible and feature rich that solution is.

Now PHPCR is just a set of interfaces, its not an implementation. So when talking about performance related to PHPCR (ODM) the question boils down to: 1) do you think that the overhead of all the different abstraction layers is too high 2) how fast is the fastest implementation that fits the resources I have at my disposal.

For 1) I can say that there is an overhead of course but I see no indication that it prevents low latency and certainly does not prevent scalability.

For 2) right now the fastest solution is Jackrabbit, which fairs pretty well in full text search (but has some issues there) and which lacks many features (f.e. no facetting). However the next version of Jackrabbit which will likely be released this year and for which we have already tested compatibility will allow direct indexing into Solr (and as its a pluggable system I assume ElasticSearch soon as well).

Now I imagine that there are some people willing to run Solr/ElasticSearch but maybe less willing to run Jackrabbit. Since PHPCR is just a set of interfaces, its actually not that hard to replace the current Doctrine DBAL based solution to use Solr/ElasticSearch for indexing. The beauty of all of this is that doing any of these changes will require no changes in business logic. For the most part it just boils down to a configuration change and some data migration. Done.

Thanks for your answer.

I think that adding a SimpleECommerceBundle in the cmf can be a really good POC to illustrate this.

As Catalog and product description is “content” I guess it can be a good thing.

Yes .. in fact kidsgoods.ch will soon be the first webshop powered by the CMF together with Foxycart. There isn’t really that much that is needed here. Essentially a product catalog is simply content that is associated with an inventory and a shopping cart. However the integration to a large degree can happen inside the templates for HTML and the serializer for REST. But sure someone putting this together in a demo would be nice. With LiipFoxycartBundle it should be easy to do .. not sure how hard it would be with Sylius but I would assume a day or two.

Hey, thanks for doing this! I enjoyed reading this writeup–we learned something about Sylius.

We have a client who has a heavily customized Magento interface that is simply past the breaking point. We are actively moving this functionality over to Sylius. Keep us in the loop.

We’re going to try to fix the problems we find, too.

Are the PHPCR and the Symfony2 CMF sufficiently mature and well documented for this?

Symfony CMF is very close to RC1 (we expect it will hit RC1 this month) and there is already quite a bit of documentation (though we need to update some of the configuration and class names due to recent refactorings):
http://symfony.com/doc/master/cmf/index.html

Furthermore most Bundles have pretty decent functional test coverage which can also help to get started.

Hey It is amazing but please anyone tell me about my question and my question is
Do you want to know more about payment gateways or multiple payments?

Payment isn’t ready but “Next week we will focus on the documentation and the payments integration, stay tuned” (http://sylius.org/blog/friday-update-23-08-2013)

Some more details about the plans for payment can be seen here:
http://sylius.org/blog/the-roadmap

There is sylius + payum integration PR https://github.com/Sylius/Sylius/pull/275

Currently it has two examples: paypal express checkout configuration and credit card (stripe via omnipay lib).

I am looking forward to get some feedback.

W00t .. a big PR that originated at this hackday, integrating the CMF Routing component into Sylius, has finally been merged https://github.com/Sylius/Sylius/pull/255