Earlier today Spatie, the company where I work, launched a webshop polkadots.be.

When the project started one of the first choices that we had to make was if we were going to use an existing solution or build our own custom solution. For this project we took an extensive look at some existing solutions.  Allthough the existing webshop systems are very powerful, we wanted to use something less bloated. At Spatie we're big fans of simple, clean  and elegant solutions.To make a long story short we made the decision to build a shop ourselves.

Polkadots.be aims to be a very speedy application, that's simple to use. Customers can buy products without having to make a user profile. Shop owners are presented a very clean interface to administer their shop.

On the clientside Rogier and Willem made a beautiful design for the shop. The various productlists you see on the site are rendered with Angular. Because all filtering is done by the browser you'll never see "loading"-indicator on those pages. Your filter settings are stored in the local storage of your browser.

The serverside of the shop is built with Laravel 4.2 and leverages techniques such as repositories, domain events, presenters, factories, ... Using these design patterns makes the code more readable and self-documenting. Ultimately it leads to a flexible codebase that can be easily adapted to future business requirements.

Of course we didn't build everything from the ground up, many freely available packages were used. I'll highlight some of them:

  • baum/baum: an implementation of the nested set pattern. It's being used to store the hierarchical relation between productcategories.
  • davejamesmiller/laravel-breadcrumbs: offers a clean way to generate breadcrumbs.
  • gloudemans/shoppingcart: the basis for the cart. We built some methods on top of it so it can also store order options (such as "delivery method") .
  • dyaa/pushover: used to send push notifications to the mobile device of the shop administrator. In case of polkadots the shop admin gets immediately notified of new orders or when a stock shortage is imminent.
  • vespakoen/menu: generates all menu's you see on the site.
  • indatus/dispatcher: allows for the scheduling of artisan commands with the command itself so you don't have to modify a crontab.
  • laracasts/commander: enables us to use domain events.
  • imagine/imagine: used to convert the product images to the right size.
  • michelf/php-markdown: converts the markdown that stored in the external product system of our client to html on de product pages.
  • league/flysystem: offers filesystem abstraction. Is used to retrieve images from the ftp-server of our client.
  • cviebrock/eloquent-sluggable: generates slugs for eloquent models.
  • itsgoingd/clockwork: used extensively to track down and solve n+1 issues.
  • spatie/payment: allows for payments to made. Take a look at the code of the offical Europabank plugin to understand why we made a payment solution ourselves. I'd rather [insert something very unpleasant here]  than using the official code.

Let's take a look at the used infrastructure. The application is hosted on a Forge-provisioned Digital Ocean server. To cache some expensive queries we use Memcached. Mandrill is used to deliver all mails. All push notifications are being sent by Pushover.net. All communication with external systems is being done in Beanstalkd queues. We monitor the server with New Relic.  The site uses the SPDY protocol instead of regular http.

I believe our team did terrific job. Take a look at the shop and judge for yourself. If you have any remarks or questions let me know.