Browse Source

feat: add tag management

master
parent
commit
20ea3fa16e
  1. 31
      DependencyInjection/Configuration.php
  2. 16
      DependencyInjection/ShadowareMatomoExtension.php
  3. 50
      EventListener/MatomoListener.php
  4. 19
      Resources/config/services.xml
  5. 14
      Resources/views/Default/async_matomo_js.html.twig
  6. 136
      Resources/views/Default/async_mtm_js.html.twig

31
DependencyInjection/Configuration.php

@ -31,14 +31,31 @@ class Configuration implements ConfigurationInterface @@ -31,14 +31,31 @@ class Configuration implements ConfigurationInterface
$rootNode->children()
->scalarNode('base_url')->isRequired()->cannotBeEmpty()->end()
->scalarNode('id_site')->isRequired()->cannotBeEmpty()->end()
->scalarNode('hideMatomo')->defaultFalse()->end()
->scalarNode('tokenId')->defaultNull()->end()
->arrayNode('heartbeat')
->arrayNode('analytics')
->children()
->scalarNode('enabled')->defaultFalse()->end()
->scalarNode('minimumVisitLength')->defaultValue(15)->end()
->scalarNode('delay')->defaultValue(30)->end()
->scalarNode('id_site')->cannotBeEmpty()->end()
->scalarNode('hideMatomo')->defaultFalse()->end()
->scalarNode('tokenId')->defaultNull()->end()
->arrayNode('heartbeat')
->children()
->scalarNode('enabled')->defaultFalse()->end()
->scalarNode('minimumVisitLength')->defaultValue(15)->end()
->scalarNode('delay')->defaultValue(30)->end()
->end()
->end()
->end()
->end()
->arrayValue('tag_management')
->children()
->scalarNode('id_container')->cannotBeEmpty()->end()
->arrayNode('variables')
->arrayPrototype()
->children()
->scalarNode('key')->cannotBeEmpty()->end()
->scalarNode('value')->end()
->end()
->end()
->end()
->end()
->end()
->end();

16
DependencyInjection/ShadowareMatomoExtension.php

@ -35,11 +35,15 @@ class ShadowareMatomoExtension extends Extension @@ -35,11 +35,15 @@ class ShadowareMatomoExtension extends Extension
$loader->load('services.xml');
$container->setParameter('shadoware_matomo.base_url', $config['base_url']);
$container->setParameter('shadoware_matomo.id_site', $config['id_site']);
$container->setParameter('shadoware_matomo.hideMatomo', $config['hideMatomo']);
$container->setParameter('shadoware_matomo.tokenId', $config['tokenId']);
$container->setParameter('shadoware_matomo.heartbeat.enabled', $config['heartbeat']['enabled']);
$container->setParameter('shadoware_matomo.heartbeat.minimumVisitLength', $config['heartbeat']['minimumVisitLength']);
$container->setParameter('shadoware_matomo.heartbeat.delay', $config['heartbeat']['delay']);
$container->setParameter('shadoware_matomo.analytics.id_site', $config['analytics']['id_site']);
$container->setParameter('shadoware_matomo.analytics.hideMatomo', $config['analytics']['hideMatomo']);
$container->setParameter('shadoware_matomo.analytics.tokenId', $config['analytics']['tokenId']);
$container->setParameter('shadoware_matomo.analytics.heartbeat.enabled', $config['analytics']['heartbeat']['enabled']);
$container->setParameter('shadoware_matomo.analytics.heartbeat.minimumVisitLength', $config['analytics']['heartbeat']['minimumVisitLength']);
$container->setParameter('shadoware_matomo.analytics.heartbeat.delay', $config['analytics']['heartbeat']['delay']);
$container->setParameter('shadoware_matomo.tag_management.id_container', $config['tag_management']['id_container']);
$container->setParameter('shadoware_matomo.tag_management.variables', $config['tag_management']['variables']);
}
}

50
EventListener/MatomoListener.php

@ -43,6 +43,9 @@ class MatomoListener implements EventSubscriberInterface @@ -43,6 +43,9 @@ class MatomoListener implements EventSubscriberInterface
protected $heartbeatEnabled = false;
protected $heartbeatMinimumVisitLength = 15;
protected $heartbeatDelay = 30;
protected $idContainer;
protected $variables;
protected $storage;
@ -129,6 +132,26 @@ class MatomoListener implements EventSubscriberInterface @@ -129,6 +132,26 @@ class MatomoListener implements EventSubscriberInterface
return $this->heartbeatDelay;
}
public function setIdContainer(string $value)
{
$this->idContainer = $value;
}
public function getIdContainer()
{
return $this->idContainer;
}
public function setVariables($value)
{
$this->variables = $value;
}
public function getVariables()
{
return $this->variables;
}
public function getStorage()
{
return $this->storage;
@ -234,10 +257,25 @@ class MatomoListener implements EventSubscriberInterface @@ -234,10 +257,25 @@ class MatomoListener implements EventSubscriberInterface
return;
}
$this->injectMatomo($response);
if ($this->matomoId) {
$this->injectMatomoAnalytics($response);
}
if ($this->idContainer) {
$this->injectMatomoTagManagement($response);
}
}
protected function injectMatomo(Response $response)
protected function injectMatomoAnalytics(Response $response)
{
$this->injectMatomoCode($response, '</body>', 'ShadowareMatomoBundle:Default:async_matomo_js.html.twig');
}
protected function injectMatomoTagManagement(Response $response)
{
$this->injectMatomoCode($response, '</head>', 'ShadowareMatomoBundle:Default:async_mtm_js.html.twig');
}
protected function injectMatomoCode(Response $response, string $balise, string $template)
{
if (function_exists('mb_stripos')) {
$posrFunction = 'mb_strripos';
@ -248,11 +286,11 @@ class MatomoListener implements EventSubscriberInterface @@ -248,11 +286,11 @@ class MatomoListener implements EventSubscriberInterface
}
$content = $response->getContent();
$posEndHead = $posrFunction($content, '</body>');
$posEndHead = $posrFunction($content, $balise);
if (false !== $posEndHead) {
$matomo_js = "\n".str_replace("\n", '', $this->templating->render(
'ShadowareMatomoBundle:Default:async_matomo_js.html.twig',
$template,
array(
'url' => $this->matomoUrl,
'id_site' => $this->matomoId,
@ -260,6 +298,8 @@ class MatomoListener implements EventSubscriberInterface @@ -260,6 +298,8 @@ class MatomoListener implements EventSubscriberInterface
'heartbeatMinimumVisitLength' => $this->heartbeatMinimumVisitLength,
'heartbeatDelay' => $this->heartbeatDelay,
'hideMatomo' => $this->hideMatomo,
'idContainer' => $this->idContainer,
'variables' => $this->variables,
'storage' => $this->storage
)
))."\n";
@ -271,7 +311,7 @@ class MatomoListener implements EventSubscriberInterface @@ -271,7 +311,7 @@ class MatomoListener implements EventSubscriberInterface
$this->session->remove(MatomoListener::MATOMO_STORAGE);
}
}
public static function getSubscribedEvents()
{
return array(

19
Resources/config/services.xml

@ -28,22 +28,29 @@ @@ -28,22 +28,29 @@
<argument>%shadoware_matomo.base_url%</argument>
</call>
<call method="setMatomoId">
<argument>%shadoware_matomo.id_site%</argument>
<argument>%shadoware_matomo.analytics.id_site%</argument>
</call>
<call method="setHideMatomo">
<argument>%shadoware_matomo.hideMatomo%</argument>
<argument>%shadoware_matomo.analytics.hideMatomo%</argument>
</call>
<call method="setTokenId">
<argument>%shadoware_matomo.tokenId%</argument>
<argument>%shadoware_matomo.analytics.tokenId%</argument>
</call>
<call method="setHeartbeatEnabled">
<argument>%shadoware_matomo.heartbeat.enabled%</argument>
<argument>%shadoware_matomo.analytics.heartbeat.enabled%</argument>
</call>
<call method="setHeartbeatMinimumVisitLength">
<argument>%shadoware_matomo.heartbeat.minimumVisitLength%</argument>
<argument>%shadoware_matomo.analytics.heartbeat.minimumVisitLength%</argument>
</call>
<call method="setHeartbeatDelay">
<argument>%shadoware_matomo.heartbeat.delay%</argument>
<argument>%shadoware_matomo.analytics.heartbeat.delay%</argument>
</call>
<call method="setIdContainer">
<argument>%shadoware_matomo.tag_management.id_container%</argument>
</call>
<call method="setVariables">
<argument>%shadoware_matomo.tag_management.variables%</argument>
</call>
</service>
<service id="shadoware_matomo.twig" class="%shadoware_matomo.twig.class%">

14
Resources/views/Default/async_matomo_js.html.twig

@ -9,7 +9,7 @@ @@ -9,7 +9,7 @@
{% spaceless %}
<!-- Matomo -->
<script type="text/javascript">/*<![CDATA[*/
var _paq = _paq || [];
var _paq = window._paq = window._paq || [];
{# Matomo user #}
{% if storage.matomoUser %}
_paq.push(['setUserId', '{{ storage.matomoUser }}']);
@ -96,18 +96,22 @@ var u="//{{ url }}/"; @@ -96,18 +96,22 @@ var u="//{{ url }}/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', {{ id_site }}]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
g.type='text/javascript'; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
{% else %}
(function(){
_paq.push(['setTrackerUrl', '{{ url('shadoware_matomo_default_track') }}']);
_paq.push(['setSiteId', {{ id_site }}]);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.defer=true; g.src='{{ url('shadoware_matomo_default_tracker', {'_format': 'js'}) }}'; s.parentNode.insertBefore(g,s);
g.type='text/javascript'; g.async=true; g.src='{{ url('shadoware_matomo_default_tracker', {'_format': 'js'}) }}'; s.parentNode.insertBefore(g,s);
})();
{% endif %}
/*]]>*/</script>
<noscript><p><img src="//{{ url }}/matomo.php?idsite={{ id_site }}" style="border:0;" alt="" /></p></noscript>
<!-- End Matomo Code -->
<noscript>
<!-- Matomo Image Tracker-->
<img referrerpolicy="no-referrer-when-downgrade" src="//{{ url }}/matomo.php?idsite={{ id_site }}&amp;rec=1" style="border:0" alt="" />
<!-- End Matomo -->
</noscript>
{% endspaceless %}

136
Resources/views/Default/async_mtm_js.html.twig

@ -0,0 +1,136 @@ @@ -0,0 +1,136 @@
{#
# This file is part of the ShadowareMatomoBundle package.
#
# (c) Ulrich VANDENHEKKE <ulrich.vdh@shadoware.org>
#
# For the full copyright and license information, please view the LICENSE
# file that was distributed with this source code.
#}
{% spaceless %}
<!-- Matomo Tag Manager -->
<script type="text/javascript">/*<![CDATA[*/
var _mtm = window._mtm = window._mtm || [];
{# Matomo user #}
{% if storage.matomoUser %}
_mtm.push({'username': '{{ storage.matomoUser }}' });
{% endif %}
{# Data #}
{% for scope, value in variables %}
_mtm.push({'{{ value.key | e('js') }}': '{{ value.value | raw }}' });
{% endfor %}
{# Custom variables #}
{% for scope, array in storage.customVariables %}
{% for index, customVariable in array %}
_mtm.push({'{{ customVariable.name | e('js') }}': '{{ customVariable.value | raw }}' });
{% endfor %}
{% endfor %}
{# Redefine page name #}
{% if storage.pageName %}
_mtm.push({'title': '{{ storage.pageName | e('js') }}' });
{% endif %}
{# Redefine page url #}
{% if storage.pageUrl %}
_mtm.push({'url': '{{ storage.pageUrl | e('js') }}' });
{% endif %}
{# Search keyword #}
{% if not storage.trackSiteSearchKeyword is empty %}
_mtm.push({
'event': 'search',
'search': {
'keyword': '{{ storage.trackSiteSearchKeyword | e('js') }}',
'category': '{{ storage.trackSiteSearchCategory | e('js') }}',
'count': {% if not storage.trackSiteSearchCount %}false{% else %}{{ storage.trackSiteSearchCount }}{% endif %}
}
});
{% endif %}
{# E-Commerce - View #}
{% if storage.ecommerceView %}
window._mtm.push({
'event': 'view',
'ecommerce': {
'product': {
'sku': {% if not storage.ecommerceView.productSKU %}false{% else %}'{{ storage.ecommerceView.productSKU | e('js') }}'{% endif %},
'name': {% if not storage.ecommerceView.productName %}false{% else %}'{{ storage.ecommerceView.productName | e('js') }}'{% endif %},
'category': {% if not storage.ecommerceView.productCategory %}''{% else %}'{{ storage.ecommerceView.productCategory | e('js') }}'{% endif %}
'price': {% if storage.ecommerceView.productPrice %},{{ storage.ecommerceView.productPrice }}{% endif %}
}
}
});
{% endif %}
{# E-Commerce - Items #}
{% if storage.ecommerceView | length > 0 %}
window._mtm.push({
'event': 'addItem',
'ecommerce': {
'products': [
{% for item in storage.ecommerceItems %}
{
'sku': '{{ item.productSKU }}',
'name': {% if not item.productName %}''{% else %}'{{ item.productName | e('js') }}'{% endif %},
'category': {% if not item.productCategory %}''{% else %}'{{ item.productCategory | e('js') }}'{% endif %},
'price': {% if not item.price %}''{% else %}{{ item.price }}{% endif %}
'quantity': {% if item.quantity %},{{ item.quantity }}{% endif %}
},
{% endfor %}
]
}
});
{% endif %}
{# E-Commerce - Final order #}
{% if storage.ecommerceOrder and storage.ecommerceItems | length > 0 %}
window._mtm.push({
'event': 'purchase',
'ecommerce': {
'purchase': {
'id': '{{ storage.ecommerceOrder.orderId }}',
'revenue': {{ storage.ecommerceOrder.grandTotal }},
'orderSubTotal': {% if storage.ecommerceOrder.subTotal %}{{ storage.ecommerceOrder.subTotal }}{% else %}''{% endif %},
'tax': {% if storage.ecommerceOrder.tax %}{{ storage.ecommerceOrder.tax }}{% else %}''{% endif %},
'shipping': {% if storage.ecommerceOrder.shipping %}{{ storage.ecommerceOrder.shipping }}{% else %}''{% endif %},
'discount': {% if storage.ecommerceOrder.discount %}{{ storage.ecommerceOrder.discount }}{% else %}false{% endif %},
}
}
});
{% endif %}
{# E-Commerce - Basket #}
{% if storage.ecommerceCartUpdate and storage.ecommerceItems | length > 0 %}
window._mtm.push({
'event': 'cartUpdate',
'ecommerce': {
'update': {
'revenue': {{ storage.ecommerceCartUpdate.amount }},
}
}
});
{% endif %}
{# Goals #}
{% for goal in storage.goals %}
window._mtm.push({
'event': 'trackGoal',
'goal': {
'id': {{ goal.id }},
'amount': {% if goal.amount %}, {{ goal.amount }}{% endif %},
}
});
{% endfor %}
(function(){
var u="//{{ url }}/";
_mtm.push({'mtm.startTime': (new Date().getTime()), 'event': 'mtm.Start'});
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.type='text/javascript'; g.async=true; g.src=u+'container_{{ idContainer }}.js'; s.parentNode.insertBefore(g,s);
})();
/*]]>*/</script>
<!-- End Matomo Tag Manager -->
{% endspaceless %}
Loading…
Cancel
Save