Skip to content

Commit

Permalink
Merge pull request #34 from Prometee/master
Browse files Browse the repository at this point in the history
[Feature] add checkout configuration
  • Loading branch information
stefandoorn authored Oct 4, 2019
2 parents ee7b109 + e631fd1 commit 34461db
Show file tree
Hide file tree
Showing 12 changed files with 359 additions and 39 deletions.
34 changes: 33 additions & 1 deletion docs/checkout.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,37 @@
# Checkout

## Configuration

You can customize the steps of checkout by creating your own. This is the default one:

```$yaml
# config/packages/sylius_gtm_enhanced_ecommerce.yaml
sylius_gtm_enhanced_ecommerce:
features:
checkout:
steps:
1:
-
event: "click"
selector: "a[href$='/checkout/']"
2:
-
selector: "form[name=sylius_checkout_address]"
3:
-
option: "enhancedEcommerceCheckoutGetChoiceValue"
selector: "form[name=sylius_checkout_select_shipping]"
4:
-
option: "enhancedEcommerceCheckoutGetChoiceValue"
selector: "form[name=sylius_checkout_select_payment]"
```

The configuration allow you to add or remove steps, choice a specific js event to listen,
a specific selector to put this event and finally allow you to give a global function which
give you the possibility to add additional information to GA.

## Google Documentation

https://developers.google.com/tag-manager/enhanced-ecommerce#checkout
Expand Down Expand Up @@ -59,4 +91,4 @@ Add a tag:
* Action: `Checkout Option`
* Enable Enhanced Ecommerce
* Use dataLayer
* Trigger on: see trigger above.
* Trigger on: see trigger above.
47 changes: 46 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,52 @@ public function getConfigTreeBuilder()
->booleanNode('product_detail_impressions')->defaultTrue()->end()
->booleanNode('product_clicks')->defaultTrue()->end()
->booleanNode('cart')->defaultTrue()->end()
->booleanNode('checkout')->defaultTrue()->end()
->arrayNode('checkout')
->canBeDisabled()
->addDefaultsIfNotSet()
->children()
->arrayNode('steps')
->defaultValue([
1 => [
[
'event' => 'click',
'selector' => 'a[href$=\'/checkout/\']',
]
],
2 => [
[
'event' => 'submit',
'selector' => 'form[name=sylius_checkout_address]',
]
],
3 => [
[
'event' => 'submit',
'selector' => 'form[name=sylius_checkout_select_shipping]',
'option' => 'enhancedEcommerceCheckoutGetChoiceValue',
]
],
4 => [
[
'event' => 'submit',
'selector' => 'form[name=sylius_checkout_select_payment]',
'option' => 'enhancedEcommerceCheckoutGetChoiceValue',
]
],
])
->arrayPrototype()
->arrayPrototype()
->addDefaultsIfNotSet()
->children()
->scalarNode('event')->defaultValue('submit')->end()
->scalarNode('selector')->isRequired()->end()
->scalarNode('option')->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end()
->end()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function load(array $configs, ContainerBuilder $container)

$container->setParameter($parameter, $setting);

if ($setting === true) {
if ($setting === true || (is_array($setting) && $setting['enabled'] === true)) {
$loader->load(sprintf('features/%s.yml', $feature));
}
}
Expand Down
7 changes: 7 additions & 0 deletions src/Resources/config/features/checkout.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,13 @@ services:
- "@sylius.google_tag_manager.enhanced_ecommerce_tracking.resolver.checkout_step"
tags:
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

sylius.google_tag_manager.enhanced_ecommerce_tracking.checkout.listener.sylius.shop.layout.head:
class: Sylius\Bundle\UiBundle\Block\BlockEventListener
arguments:
- '@@SyliusGtmEnhancedEcommercePlugin/Checkout/head.html.twig'
tags:
- { name: kernel.event_listener, event: sonata.block.event.sylius.shop.layout.head, method: onBlockEvent }

sylius.google_tag_manager_enhanced_ecommerce.checkout.block_event_listener.layout.javascripts:
class: Sylius\Bundle\UiBundle\Block\BlockEventListener
Expand Down
12 changes: 12 additions & 0 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,15 @@ services:

sylius.google_tag_manager.enhanced_ecommerce_tracking.object.factory.product_detail_impression:
class: StefanDoorn\SyliusGtmEnhancedEcommercePlugin\Object\Factory\ProductDetailImpressionFactory

sylius.google_tag_manager.enhanced_ecommerce_tracking.twig.extension.parameters:
class: StefanDoorn\SyliusGtmEnhancedEcommercePlugin\Twig\ParameterExtension
arguments:
- "%sylius_gtm_enhanced_ecommerce.features.purchases%"
- "%sylius_gtm_enhanced_ecommerce.features.product_impressions%"
- "%sylius_gtm_enhanced_ecommerce.features.product_detail_impressions%"
- "%sylius_gtm_enhanced_ecommerce.features.product_clicks%"
- "%sylius_gtm_enhanced_ecommerce.features.cart%"
- "%sylius_gtm_enhanced_ecommerce.features.checkout%"
tags:
- { name: "twig.extension" }
89 changes: 55 additions & 34 deletions src/Resources/public/gtm.enhancedEcommerce.checkout.js
Original file line number Diff line number Diff line change
@@ -1,44 +1,65 @@
(function ( $ ) {
'use strict';

var CHECKOUT_STEP_SHIPPING = 3;
var CHECKOUT_STEP_PAYMENT = 4;

$.fn.extend({
enhancedEcommerceCheckoutShipping: function () {
$(this).on('submit', function () {
enhancedEcommerceTrackCheckoutOption(CHECKOUT_STEP_SHIPPING, $('input[type=radio]:checked', $(this)).val());
});
},

enhancedEcommerceCheckoutPayment: function () {
$(this).on('submit', function () {
enhancedEcommerceTrackCheckoutOption(CHECKOUT_STEP_PAYMENT, $('input[type=radio]:checked', $(this)).val());
});
'use strict';
(function ($) {

if (typeof checkoutStepsConfiguration === "undefined") return;
if (typeof checkoutStepsConfiguration !== "object") return;
if (!checkoutStepsConfiguration.hasOwnProperty('enabled')) return;
if (checkoutStepsConfiguration.enabled === false) return;
if (!checkoutStepsConfiguration.hasOwnProperty('steps')) return;

for (var stepId in checkoutStepsConfiguration.steps) {
if (!checkoutStepsConfiguration.steps.hasOwnProperty(stepId)) continue;

checkoutStepsConfiguration.steps[stepId].forEach(function BindStep(conf) {
$(conf.selector).on(conf.event, function () {
var option = null;

if (
typeof conf.option !== "undefined"
&& typeof window[conf.option] === 'function'
) {
option = window[conf.option].call(this);
}

enhancedEcommerceTrackCheckoutOption(stepId, option);
});
});
}
})(jQuery);

$('form[name=sylius_checkout_select_shipping]').enhancedEcommerceCheckoutShipping();
$('form[name=sylius_checkout_select_payment]').enhancedEcommerceCheckoutPayment();
})( jQuery );
/**
* This function will be called above if the configuration of
* %sylius_gtm_enhanced_ecommerce.features.checkout.steps.*.*.option%
* contains a function accessible into the window var.
*
* The 'this' context is the context of
* %sylius_gtm_enhanced_ecommerce.features.checkout.steps.*.*.selector%
* So if 'this' represent the current checkout form you can use it
* to restrict what you want to be stored into GA
*
* @returns {string}
*/
function enhancedEcommerceCheckoutGetChoiceValue() {
return $('input[type=radio]:checked', this).val();
}

/**
* @param {integer} step
* @param {integer} stepId
* @param {string} checkoutOption
*/
function enhancedEcommerceTrackCheckoutOption(step, checkoutOption) {
var obj = {
'event': 'checkoutOption',
'ecommerce': {
'checkout_option': {
'actionField': {
'step': step,
'option': checkoutOption
}
}
function enhancedEcommerceTrackCheckoutOption(stepId, checkoutOption) {
var obj = {
'event': 'checkoutOption',
'ecommerce': {
'checkout_option': {
'actionField': {
'step': stepId,
'option': checkoutOption
}
};
}
}
};

/** global: dataLayer */
dataLayer.push(obj);
/** global: dataLayer */
dataLayer.push(obj);
}
3 changes: 3 additions & 0 deletions src/Resources/views/Checkout/head.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<script type="text/javascript">
var checkoutStepsConfiguration = window.checkoutStepsConfiguration || (window.checkoutStepsConfiguration = {{ sylius_gtm_enhanced_ecommerce_parameter('checkout')|json_encode|raw }});
</script>
67 changes: 67 additions & 0 deletions src/Twig/ParameterExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php declare(strict_types=1);

namespace StefanDoorn\SyliusGtmEnhancedEcommercePlugin\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

final class ParameterExtension extends AbstractExtension
{
/** @var array */
private $parameters;

/**
* @param bool $purchases
* @param bool $product_impressions
* @param bool $product_detail_impressions
* @param bool $product_clicks
* @param bool $cart
* @param array $checkout
*/
public function __construct(
bool $purchases,
bool $product_impressions,
bool $product_detail_impressions,
bool $product_clicks,
bool $cart,
array $checkout
)
{
$this->parameters = [
'purchases' => $purchases,
'product_impressions' => $product_impressions,
'product_detail_impressions' => $product_detail_impressions,
'product_clicks' => $product_clicks,
'cart' => $cart,
'checkout' => $checkout,
];
}

/**
* {@inheritdoc}
*/
public function getFunctions()
{
return array(
new TwigFunction('sylius_gtm_enhanced_ecommerce_parameter', array($this, 'getParameter')),
);
}

/**
* @param string $name
* @return bool|array|null
*/
public function getParameter(string $name)
{
return $this->hasParameter($name) ? $this->parameters[$name] : null;
}

/**
* @param string $name
* @return bool
*/
public function hasParameter(string $name): bool
{
return isset($this->parameters[$name]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php declare(strict_types=1);

namespace Tests\StefanDoorn\SyliusGtmEnhancedEcommercePlugin\DependencyInjection;

use PHPUnit\Framework\TestCase;
use StefanDoorn\SyliusGtmEnhancedEcommercePlugin\DependencyInjection\SyliusGtmEnhancedEcommerceExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

final class SyliusGtmEnhancedEcommerceExtensionTest extends TestCase
{
public function testMinimalConfig(): void
{
$container = $this->getContainer();
$extension = new SyliusGtmEnhancedEcommerceExtension();

$config = [];

$extension->load(['sylius_gtm_enhanced_ecommerce' => $config], $container);

$this->assertTrue(
$container->getParameter('sylius_gtm_enhanced_ecommerce.features.purchases')
);

$this->assertTrue(
$container->getParameter('sylius_gtm_enhanced_ecommerce.features.product_impressions')
);

$this->assertTrue(
$container->getParameter('sylius_gtm_enhanced_ecommerce.features.product_detail_impressions')
);

$this->assertTrue(
$container->getParameter('sylius_gtm_enhanced_ecommerce.features.product_clicks')
);

$this->assertTrue(
$container->getParameter('sylius_gtm_enhanced_ecommerce.features.cart')
);

$conf = $container->getParameter('sylius_gtm_enhanced_ecommerce.features.checkout');
$this->assertTrue($conf['enabled']);

$this->assertFalse(
$container->hasParameter('sylius_gtm_enhanced_ecommerce.cache_resolver.product_detail_impressions')
);
}

public function testWithCacheResolver(): void
{
$container = $this->getContainer();
$extension = new SyliusGtmEnhancedEcommerceExtension();

$config = [
'cache_resolvers'=>true,
];
$extension->load(['sylius_gtm_enhanced_ecommerce' => $config], $container);

$this->assertEquals(
3600,
$container->getParameter('sylius_gtm_enhanced_ecommerce.cache_resolver.product_detail_impressions')
);
}

private function getContainer(): ContainerBuilder
{
return new ContainerBuilder(new ParameterBag([
'kernel.debug' => false,
'kernel.bundles' => [],
'kernel.cache_dir' => sys_get_temp_dir(),
'kernel.environment' => 'test',
'kernel.root_dir' => __DIR__.'/../../src/',
]));
}
}
2 changes: 1 addition & 1 deletion tests/EventListener/ThankYouListenerTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);

namespace Tests\StefanDoorn\SyliusGtmEnhancedEcommercePlugin\EventListener;

Expand Down
2 changes: 1 addition & 1 deletion tests/TagManager/AddTransactionTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<?php
<?php declare(strict_types=1);

namespace Tests\StefanDoorn\SyliusGtmEnhancedEcommercePlugin\TagManager;

Expand Down
Loading

0 comments on commit 34461db

Please sign in to comment.