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.