immersion in the sylius

71
Immersion in the Sylius Paweł Jędrzejewski

Upload: pawel-jedrzejewski

Post on 10-May-2015

2.278 views

Category:

Technology


5 download

DESCRIPTION

Sylius is an open source e-commerce solution for PHP, based on the great Symfony2 framework. My first talk ever, at Symfony CAMP UA 2013.

TRANSCRIPT

Page 1: Immersion in the Sylius

Immersion in the SyliusPaweł Jędrzejewski

Page 2: Immersion in the Sylius

Who am I?Paweł Jędrzejewski

Huge beliver in Open Source

Symfony & BDD evangelist

Creator of Sylius

Working for Opensoft on

Page 3: Immersion in the Sylius

ŁÓDŹ, POLAND

Page 4: Immersion in the Sylius

?

Page 5: Immersion in the Sylius

THE PROBLEMPHP has changed

This change created the market for a new e-commerce solution among developers

With the flexibility of modern frameworks and the new way of collaboration we can build something interesting for the business

Sylius reflects this evolution

Page 6: Immersion in the Sylius
Page 7: Immersion in the Sylius

WHAT IS SYLIUSA short history

Open sourced in 2011 as a set of bundles

Main application in development for ~9 months

Already used in production by developers and companies

Page 8: Immersion in the Sylius

FLEXIBILITY QUALITY PEOPLE

Page 9: Immersion in the Sylius
Page 10: Immersion in the Sylius
Page 11: Immersion in the Sylius

FLEXIBILITY QUALITY PEOPLE

Page 12: Immersion in the Sylius

QUALITYBehat and phpspec, perfect combination

Most of new features start with an RFC issue

Discussion about the idea and eventual implementation

Behat features

Implementation

Page 13: Immersion in the Sylius
Page 14: Immersion in the Sylius
Page 15: Immersion in the Sylius
Page 16: Immersion in the Sylius
Page 17: Immersion in the Sylius

FLEXIBILITY QUALITY PEOPLE

Page 18: Immersion in the Sylius

BUNDLES vs. MAIN APPLICATION

Set of 19 decoupled and independent bundles

Can be used to create a custom platform

Integrate e-commerce into existing application

Standard webshop experience

Highly customizable

Easy to understand for every Symfony2 developer

Page 19: Immersion in the Sylius

Sylius BundlesWhat they can do for you?

EVERY SINGLE SYLIUS FEATURE AVAILABLE FOR YOUR PROJECt

Page 20: Immersion in the Sylius

Simpler CRUD for symfonySyliusResourceBundle

Removing tons of duplicated code in controllers for basic CRUD actions.

Removing the manager and manipulator classes, relying on Doctrine instead.

Removing the "frontend" and "backend" controllers.

Supporting different persistence layers.

Make the controllers format agnostic. (API)

Page 21: Immersion in the Sylius

ADD YOUR RESOURCE

sylius_resource:

resources:

acme.user:

driver: doctrine/orm

templates: AcmeShopBundle:User

classes:

model: Acme\ShopBundle\Entity\User

repository: Acme\ShopBundle\Entity\UserRepository

controller: Acme\ShopBundle\Controller\UserController

Page 22: Immersion in the Sylius

acme.controller.user

showAction

indexAction

createAction

updateAction

deleteAction

Page 23: Immersion in the Sylius

acme_user_show:

pattern: /users/{id}

methods: [GET]

defaults:

_controller: acme.controller.user:showAction

acme_profile_show:

pattern: /profile/{username}

methods: [GET]

defaults:

_controller: acme.controller.user:showAction

_sylius:

template: AcmeShopBundle:Profile:show.html.twig

criteria: { username: $username, enabled: true }

Page 24: Immersion in the Sylius

acme_profile_show:

pattern: /profile/{username}

methods: [GET]

defaults:

_controller: acme.controller.user:showAction

_sylius:

template: AcmeShopBundle:Profile:show.html.twig

method: findOneForProfilePage

arguments: [$username]

acme_user_disabled_index:

pattern: /users/disabled

methods: [GET]

defaults:

_controller: acme.controller.user:indexAction

_sylius:

template: AcmeShopBundle:User:disabled.html.twig

criteria: { enabled: false }

Page 25: Immersion in the Sylius

acme_user_recently_registered:

pattern: /users/recently-registered

methods: [GET]

defaults:

_controller: acme.controller.user:indexAction

_sylius:

template: AcmeShopBundle:User:recentlyRegistered.html.twig

criteria: { enabled: true }

sorting: { createdAt: desc }

paginate: false

limit: 5

Page 26: Immersion in the Sylius

acme_user_update_addresses:

pattern: /users/{id}/update-addresses

methods: [GET]

defaults:

_controller: acme.controller.user:updateAction

_sylius:

template: AcmeShopBundle:User:updateAddresses.html.twig

form: acme_user_addresses

redirect:

route: acme_user_index

Page 27: Immersion in the Sylius

Docs.sylius.org

Page 28: Immersion in the Sylius

CONFIGURATION

sylius_taxation:

driver: doctrine/orm

classes:

tax_rate:

model: Acme\ShopBundle\Entity\TaxRate

controller: Acme\ShopBundle\Controller\TaxRateController

repository: Acme\ShopBundle\Entity\TaxRateRepository

form: Acme\ShopBundle\Form\Type\TaxRateType

validation_groups:

tax_rate: [sylius, acme]

Page 29: Immersion in the Sylius

USING CUSTOM MODELS and FORMS

Every model class can be overridden

All repositories, managers and forms are updated automatically

Form class can be customized

Page 30: Immersion in the Sylius

OVERRIDING CONTROLLERS

All models use default or slightly customized CRUD controller

Add your own methods

Page 31: Immersion in the Sylius

YOUR OWN REPOSITORY

Sylius repositories extend native Doctrine implementations

Override the repositories through configuration

Repositories are services

Page 32: Immersion in the Sylius

CHANGE THE RULES, VALIDATION

All Sylius models ship with their own validation mapping under group „sylius”

You can easily override it with your own rules

Consistent translation messages

Page 33: Immersion in the Sylius

DOCTRINE RTEL, DYNAMIC RELATIONS

We're using interfaces instead of implementation to define the relations

When you override the model class, all relations get updated automatically

Defaults are turned into entities if you don't provide your own class

Page 34: Immersion in the Sylius

WE LOVE EVENTS, YOU SHOULD TOO

The default controller triggers multiple useful events during CRUD actions

sylius.product.pre_createsylius.product.post_create

Page 35: Immersion in the Sylius

PRODUCTSSyliusProductBundle

Page 36: Immersion in the Sylius
Page 37: Immersion in the Sylius

ORDERS AND CARTSyliusOrderBundle + SyliusCartBundle

Generic Order model with support of Adjustments

Cart bundle provides actions and services for customer to interact with the Order entity

The order/cart items can be easily customized to handle different options

Page 38: Immersion in the Sylius
Page 39: Immersion in the Sylius

COUNTRIES, ZONES AND ADDRESSESSyliusAddressingBundle

Provides a very basic Address model

Countries and their Provinces management

Zones system with a ZoneMatcher service

Useful for taxation and shipping zones

Page 40: Immersion in the Sylius

$billingAddress = $order->getBillingAddress();

$zone = $this->zoneMatcher->match($billingAddress);

$address = $location->getAddress();

$zones = $this->zoneMatcher->matchAll($address);

Page 41: Immersion in the Sylius

TAKE CARE OF YOUR INVENTORYSyliusInventoryBundle

Built around 1 interface you need to implement

Tracks every single inventory unit

Based on events

Items available on demand

Backorders

Page 42: Immersion in the Sylius

HATE IT OR LOVE IT, TAXATIONSyliusTaxationBundle

TaxableInterface = heart of the bundle

Multiple tax categories and rates support

Customizable tax calculators

Tax included in price

Page 43: Immersion in the Sylius

MERCHANDISE NEEDS TO BE SHIPPEDSyliusShippingBundle

Integrate through one interface

Manage Shipments and Shipping Methods

Custom shipping rules

Flexible calculators system

Page 44: Immersion in the Sylius

class PerItemRateCalculator extends Calculator

{

public function calculate(ShippingSubjectInterface $subject, array $configuration)

{

return $configuration['amount'] * $subject->getShippingItemCount();

}

public function getConfigurationFormType()

{

return 'sylius_shipping_calculator_per_item_rate_configuration';

}

public function setConfiguration(OptionsResolverInterface $resolver)

{

$resolver

->setRequired(array( 'amount'))

->setAllowedTypes(array('amount' => array('numeric')))

;

}

}

Page 45: Immersion in the Sylius
Page 46: Immersion in the Sylius

CATEGORIZE ALL THIS STUFF, NOWSyliusTaxonomiesBundle

Classify any Model using different Taxonomies

Flexible forms

Based on DoctrineExtensions

Page 47: Immersion in the Sylius
Page 48: Immersion in the Sylius

JUST FEW STEPS MORESyliusFlowBundle

Useful for anything which takes more than 1

action to complete

Checkouts, installation wizards, complex actions

Used by OroCRM and Akeneo PIM for installers

Page 49: Immersion in the Sylius

PROCESS SCENARIO<?php

class CheckoutProcessScenario implements ProcessScenarioInterface

{

public function build(ProcessBuilderInterface $builder)

{

$builder

->add('security', 'sylius_checkout_security')

->add('addressing', 'sylius_checkout_addressing')

->add('shipping', 'sylius_checkout_shipping')

->add('payment', 'sylius_checkout_payment')

->add('finalize', 'sylius_checkout_finalize')

->add('purchase', 'sylius_checkout_purchase')

;

}

}

Page 50: Immersion in the Sylius

PAYUM INTEGRATIONSyliusPayumBundle NEW!

Integrates Payum library into Sylius checkout

Replaceable by other bundles in future

PayPal Express Checkout and Stripe support

Omnipay usage through a bridge

Page 51: Immersion in the Sylius

Make your app configurable, EASILYSyliusSettingsBundle

You can define settings schema and the form

User edits the settings through UI

You get the access via services and Twig

Page 52: Immersion in the Sylius

Settings schema

class GeneralSettingsSchema implements SchemaInterface

{

public function buildSettings(SettingsBuilderInterface $builder)

{

$builder

->setDefaults(array(

'meta_keywords' => 'symfony, sylius, ecommerce, webshop, shopping cart',

'meta_description' => 'Sylius is modern ecommerce solution for PHP.',

))

->setAllowedTypes(array(

'meta_keywords' => array('string'),

'meta_description' => array('string'),

))

;

}

Page 53: Immersion in the Sylius

EDITING VIA FORM

public function buildForm(FormBuilderInterface $builder)

{

$builder

->add('meta_keywords', 'text', array(

'constraints' => array(new NotBlank())

))

->add('meta_description', 'textarea', array(

'constraints' => array(new NotBlank())

))

;

}

Page 54: Immersion in the Sylius
Page 55: Immersion in the Sylius

PROMOTIONS ARE NICESyliusPromotionsBundle

Can be integrated with any Model

Very flexible Actions and Rules system

Support for promotion coupons

Page 56: Immersion in the Sylius

PROMOTION STRUCTURE

SUPER AWESOME PROMOTION

ACTION

ACTION

ACTION

RULE

RULE

Page 57: Immersion in the Sylius

CUSTOM RULES

interface RuleCheckerInterface

{

/**

* @param PromotionSubjectInterface $subject

* @param array $configuration

*

* @return Boolean

*/

public function isEligible(PromotionSubjectInterface $subject, array $configuration);

/**

* @return string

*/

public function getConfigurationFormType();

}

Page 58: Immersion in the Sylius

YOUR OWN ACTIONS

class AddPackageAction implements PromotionActionInterface

{

public function execute(PromotionSubjectInterface $subject, array $configuration)

{

$package = $this->findPackage($configuration);

$item = $this->cartItemRepository->createNew();

$item->setQuantity(1);

$item->setUnitPrice(isset($configuration['price']) ? $configuration['price'] : $package->getGrossPrice());

$item->setPackage($package);

$subject->addItem($item);

}

public function getConfigurationFormType()

{

return 'xyz_promotion_action_add_package_configuration';

}

}

Page 59: Immersion in the Sylius
Page 60: Immersion in the Sylius

Sylius ApplicationHow to bootstrap Symfony2 shop in minutes? (soon)

Bringing smile back to developer's faces

Page 61: Immersion in the Sylius

INSTALLATION

$ composer create-project sylius/sylius -s dev path/to/install

$ cd path/to/install

$ app/console sylius:install

$ composer create-project sylius/sylius-standard -s dev path/to/install

$ cd path/to/install

$ app/console sylius:install

Page 62: Immersion in the Sylius

ONE CORE TO RULE THEM ALLSyliusCoreBundle

Integrates all the bundles together

Standard webshop application

Contains all the models and services

Page 63: Immersion in the Sylius

THE WEB INTERFACESyliusWebBundle

Provides the default web interface for Sylius

Contains all the templates and menu builders

Splitted into Frontend & Backend parts

Page 64: Immersion in the Sylius
Page 65: Immersion in the Sylius

THE BACKEND

Page 66: Immersion in the Sylius

public function forwardAction(ProcessContextInterface $context)

{

$request = $this->getRequest();

$order = $this->getCurrentCart();

$this->dispatchCheckoutEvent(SyliusCheckoutEvents::ADDRESSING_INITIALIZE, $order);

$form = $this->createCheckoutAddressingForm($order);

if ($request->isMethod('POST') && $form->bind($request)->isValid()) {

$this->dispatchCheckoutEvent(SyliusCheckoutEvents::ADDRESSING_PRE_COMPLETE, $order);

$this->getManager()->persist($order);

$this->getManager()->flush();

$this->dispatchCheckoutEvent(SyliusCheckoutEvents::ADDRESSING_COMPLETE, $order);

return $this->complete();

}

return $this->renderStep($context, $order, $form);

}

Page 67: Immersion in the Sylius
Page 68: Immersion in the Sylius

TO DO

Documentation, documentation, documentation

New default store look

Rework translations and integrate with CrowdIn

Polish the checkout process

Integrate BazingaHateoasBundle for API

Integrate Symfony CMF and Create.js

Page 69: Immersion in the Sylius

COMING SOON...Pull Requests

Customer groups

Subscriptions support

Product reviews

Symfony CMF integration (editable blocks and pages)

Facebook/Amazon and so on...

Page 70: Immersion in the Sylius
Page 71: Immersion in the Sylius

Www.sylius.orgGithub.com/sylius

@pjedrzejewski

THANK YOUQuestions?