Overview

The product callouts plugin for Sylius allows you to configure nice badges for different set of products based on specific rules. It provides a common set of configuration by default and is very flexible when it comes to adding new ones.

Installation

$ composer require setono/callouts-plugin
  1. Add plugin dependencies to your bundles.php file:
$bundles = [
    ...
    
    OldSound\RabbitMqBundle\OldSoundRabbitMqBundle::class => ['all' => true],
    Setono\SyliusCalloutsPlugin\SetonoSyliusCalloutsPlugin:class => ['all' => true],
]);
  1. Import required config in your app/config/config.yml file:
# config/packages/_sylius.yaml

imports:
    ...
    
    - { resource: "@SetonoSyliusCalloutsPlugin/Resources/config/config.yml" }
  1. Import routing on top of your app/config/routing.yml file:
# config/routes/routes.yaml

setono_product_callouts_plugin:
    resource: "@SetonoSyliusCalloutsPlugin/Resources/config/routing.yml"
  1. Install assets
$ bin/console assets:install --symlink
  1. Customize your product model. Read more about Sylius models customization here.
  • add a Setono\SyliusCalloutsPlugin\Model\CalloutsAwareTrait trait to your App\Entity\Product class (check our this path for a reference),
  • add callouts relation to your Product.orm.xml like here,
  • if you haven't done so already, configure the sylius_product resource to point to your App\Entity\Product like we did in an example here.

Note: We are using .orm.xml file format for entities configuration. You can use whatever format you wish. For more details read the official Symfony Doctrine configuration reference or check out our configuration here.

  1. Add callouts to your product box template. By default, you should use templates/bundles/SyliusShopBundle/Product/_box.html.twig path. Check out our _box.html.twig file for a reference. Note the setono_render_callouts Twig function that uses Setono\SyliusCalloutsPlugin\Model\CalloutsAwareInterface as a first parameter and position as a second one. Currently available positions are:
  • top_left_corner
  • top_right_corner
  • bottom_right_corner
  • bottom_left_corner
  1. Configure Async assigns product callouts

    This plugin assigns product callouts when the administrator create/update the product or callout. With a large number of products this can result in slower page performance. To circumvent this problem you can use an async transport with Symfony Messenger to assigns product callouts.

    Follow the installation instructions here: How to Use the Messenger and then configure a transport.

    Basically you should do:

    $ composer req symfony/messenger symfony/serializer-pack

    Then configure the Messenger component:

    # config/packages/messenger.yaml
    framework:
        messenger:
            transports:
                amqp: "%env(MESSENGER_TRANSPORT_DSN)%"
    # .env
    ###> symfony/messenger ###
    MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
    ###< symfony/messenger ###

    And finally configure the plugin to use your transport:

    setono_sylius_callouts:
        messenger:
            transport: amqp

    After this, the Messenger will be automatically enabled in this plugin and subsequently, it will assign product callouts asynchronously.

  2. For the performance reasons, configure a cron job on your production server to execute $ bin/console setono:callouts:assign command once in a while in order to rebuild the index for callouts. In most cases it should be done by the resource event listener triggered anytime you create/update a product or callout, but it is worth to have it covered if something goes wrong.

Usage

From now on you should be able to add new callouts in the admin panel. Once you add one, you just need to configure.

Customization

Adding a new rule form

  1. Configure a new form under App\Form\Type\Rule namespace like this IsOnSaleConfigurationType,
  2. Add a rule checker under App\Checker\Rule namespace like this IsOnSaleRuleChecker and make sure it implements Setono\SyliusCalloutsPlugin\Checker\Rule\ProductCalloutRuleCheckerInterface interface and has a public const TYPE set corresponding to the below service configuration
  3. Register and tag new services:
<!-- services.xml -->
<services>
    ...
    
    <service id="setono_sylius_callouts_plugin.callout_rule_checker.is_on_sale" class="Setono\SyliusCalloutsPlugin\Checker\Rule\IsOnSaleRuleChecker">
        <argument type="service" id="setono_sylius_callouts_plugin.checker.product_promotion" />
        <tag name="setono_sylius_callouts_plugin.callout_rule_checker" type="is_on_sale" label="setono_sylius_callouts_plugin.ui.is_on_sale" form-type="Setono\SyliusCalloutsPlugin\Form\Type\Rule\IsOnSaleConfigurationType" />
    </service>
    
    <service id="setono.form.type.rule.is_on_sale" class="Setono\SyliusCalloutsPlugin\Form\Type\Rule\IsOnSaleConfigurationType">
        <tag name="form.type" />
    </service>
</services>

Available services you can decorate and forms you can extend

$ bin/console debug:container | grep setono_sylius_callouts_plugin

Running plugin tests

  • PHPSpec
$ vendor/bin/phpspec run
  • Behat (non-JS scenarios)
$ vendor/bin/behat --tags="~@javascript"
  • Behat (JS scenarios)
  1. Download Chromedriver
  2. Download Selenium Standalone Server.
  3. Run Selenium server with previously downloaded Chromedriver:
$ java -Dwebdriver.chrome.driver=chromedriver -jar selenium-server-standalone.jar
  1. Run test application's webserver on localhost:8080:
$ (cd tests/Application && bin/console server:run localhost:8080 -d public -e test)
  1. Run Behat:
$ vendor/bin/behat

Opening Sylius with your plugin

  • Using test environment:
$ (cd tests/Application && bin/console sylius:fixtures:load -e test)
$ (cd tests/Application && bin/console server:run -d public -e test)
  • Using dev environment:
$ (cd tests/Application && bin/console sylius:fixtures:load -e dev)
$ (cd tests/Application && bin/console server:run -d public -e dev)

Contribution

Learn more about our contribution workflow on http://docs.sylius.org/en/latest/contributing/.