Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions Template/Trigger/RegexEventTrigger.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/

namespace Piwik\Plugins\TagManagerExtended\Template\Trigger;

use Piwik\Piwik;
use Piwik\Settings\FieldConfig;
use Piwik\Plugins\TagManager\Template\Trigger\BaseTrigger;

class RegexEventTrigger extends BaseTrigger
{
public function getName()
{
return parent::getName();
}

public function getDescription()
{
return parent::getDescription();
}

public function getHelp()
{
return parent::getHelp();
}

public function getCategory()
{
return self::CATEGORY_OTHERS;
}

public function getIcon()
{
return 'plugins/TagManagerExtended/images/RegexEventTrigger.svg';
}

public function getParameters()
{
return [
$this->makeSetting('eventNamePattern', '.*', FieldConfig::TYPE_STRING, function (FieldConfig $field) {
$field->title = Piwik::translate('TagManagerExtended_RegexEventTriggerPatternTitle');
$field->description = Piwik::translate('TagManagerExtended_RegexEventTriggerPatternDescription');
$field->uiControl = FieldConfig::UI_CONTROL_TEXT;
$field->inlineHelp = Piwik::translate('TagManagerExtended_RegexEventTriggerPatternHelp');
}),
];
}

public function getOrder()
{
return 50;
}
}
76 changes: 76 additions & 0 deletions Template/Trigger/RegexEventTrigger.web.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
(function () {
return function (parameters, TagManager) {

var pattern = parameters.get('eventNamePattern') || '.*';
var regex;

try {
regex = new RegExp(pattern);
} catch (e) {
// Invalid regex, fall back to match all
regex = new RegExp('.*');
}

/**
* Check if the dataLayer push matches our regex pattern.
* We match any object with an 'event' property that:
* 1. Is not a Matomo internal event (mtm.*)
* 2. Matches the user-defined regex pattern
*/
function isMatchingEvent(value) {
if (!TagManager.utils.isObject(value)) {
return false;
}

if (!('event' in value)) {
return false;
}

var eventName = value.event;

// Must be a string
if (typeof eventName !== 'string') {
return false;
}

// Skip Matomo Tag Manager internal events (they start with 'mtm.')
if (eventName.indexOf('mtm.') === 0) {
return false;
}

// Test against the regex pattern
return regex.test(eventName);
}

// Catch all events that were triggered before the container was fully set up
var missedEvents = [];
var index = parameters.container.dataLayer.on(function (value) {
if (isMatchingEvent(value)) {
missedEvents.push(value.event);
}
});

this.setUp = function (triggerEvent) {
// Stop listening to the initial listener
parameters.container.dataLayer.off(index);

// Replay any missed events
for (var i = 0; i < missedEvents.length; i++) {
triggerEvent({
event: 'mtm.RegexEvent',
'mtm.customEventMatch': missedEvents[i]
});
}

// Listen for all future dataLayer pushes
parameters.container.dataLayer.on(function (value) {
if (isMatchingEvent(value)) {
triggerEvent({
event: 'mtm.RegexEvent',
'mtm.customEventMatch': value.event
});
}
});
};
};
})();
4 changes: 4 additions & 0 deletions images/RegexEventTrigger.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@
"GoogleUserProvidedDataTagAddressPostalCodeTitle": "address.postal_code",
"GoogleUserProvidedDataTagAddressPostalCodeDescription": "User post code. Example: 'SO99 9XX'",
"GoogleUserProvidedDataTagAddressCountryTitle": "address.country",
"GoogleUserProvidedDataTagAddressCountryDescription": "User country code. Example: 'UK'. Use 2-letter country codes, per the ISO 3166-1 alpha-2 standard."
"GoogleUserProvidedDataTagAddressCountryDescription": "User country code. Example: 'UK'. Use 2-letter country codes, per the ISO 3166-1 alpha-2 standard.",
"RegexEventTriggerName": "Regex Event",
"RegexEventTriggerDescription": "Fires on custom events matching a regex pattern. Use .* to match all events.",
"RegexEventTriggerHelp": "This trigger fires when an event name matches your regex pattern. Use the built-in variable 'Event Name' in your tags to access the name of the event that triggered it.",
"RegexEventTriggerPatternTitle": "Event Name Pattern (Regex)",
"RegexEventTriggerPatternDescription": "Regular expression pattern to match event names. Use .* to match all events.",
"RegexEventTriggerPatternHelp": "Examples: .* (all events), ^form_ (events starting with 'form_'), click|submit (events containing 'click' or 'submit'), ^(purchase|checkout)$ (exactly 'purchase' or 'checkout')"
}
}