Markus Michalski FAQ

Matomo Analytics: Technical Details

Matomo Analytics for Sylius - flow of the tracking configuration as a diagram, fault tolerance when the table is missing, plugin structure and the database table with all columns

Deutsche Version

Back to overview

Matomo Analytics: Technical Details

This documentation always describes the latest published version.

Flow

All consumers, that is the storefront hooks and the Shop API, ask the same place: the resolver for the tracking configuration. It reads the settings of the channel and checks them with a single validity check. An incomplete entry therefore behaves like a disabled one everywhere, and no consumer derives its own idea of "configured enough".

graph TD
    A["Twig hook or Shop API request"] --> B["Tracking configuration resolver"]
    B --> C["Channel settings from the database"]
    C --> D{"Row present?"}
    D -->|"No"| N["null: render nothing / 404"]
    D -->|"Yes"| E{"Main switch on, HTTPS URL, site ID above 0?"}
    E -->|"No"| N
    E -->|"Yes"| F{"Klaro gating on?"}
    F -->|"No"| G["Render script directly"]
    F -->|"Yes"| H["Script blocked as text/plain + consent bridge"]
    H --> I["Klaro unlocks after consent"]

The resolver remembers the result per channel for the duration of the request, even if the hooks ask several times. There is therefore one database query per channel and request. The cache is cleared when the kernel is reset (important for long-running workers).

If the database access fails, for example because the table is still missing, the resolver returns null and writes a warning to the log channel mmd_matomo. This result is not cached: once the database is back, tracking resumes.

Output safety

Plugin structure

src/
β”œβ”€β”€ Api/                  Shop API resource and provider
β”œβ”€β”€ Command/              Setup command
β”œβ”€β”€ DependencyInjection/  Extension (mapping, hooks, grid, migrations), empty Configuration
β”œβ”€β”€ Entity/               ChannelSettings and interface
β”œβ”€β”€ EventListener/        Create the Klaro service on save
β”œβ”€β”€ Form/Type/            Form of the channel settings
β”œβ”€β”€ Klaro/                Availability, catalog interface, provisioning
β”œβ”€β”€ Menu/                 Sidebar entry
β”œβ”€β”€ Migrations/           Create the table
β”œβ”€β”€ Settings/             Repository
β”œβ”€β”€ Tracking/             Configuration, resolver, code renderer, order data
└── Twig/                 Twig functions
config/
β”œβ”€β”€ grids/                Settings grid
β”œβ”€β”€ routes/               Admin routes
β”œβ”€β”€ twig_hooks/           Hooks for admin, storefront and e-commerce
└── services.php          Service definitions
templates/                Tracking script, e-commerce snippets, admin title
translations/             German and English

Database

The plugin creates exactly one table: mmd_sylius_matomo_channel_settings, with one row per channel. The assignment runs through the channel code (text), not through a foreign key. A unique index on channel_code enforces one row per channel.

All columns are NOT NULL. The defaults in the table are set by the entity when a row is created, the database itself has no DEFAULT values. If you write rows into the table bypassing the plugin, you have to fill all columns yourself.

The admin routes are named mmd_sylius_matomo_integration_plugin_admin_channel_settings_index, _create, _update and _delete, the path is /<admin-path>/matomo-channel-settings (the admin path comes from the parameter sylius_admin.path_name).

Column Type Entity default
id integer, primary key
channel_code varchar(255), unique
enabled boolean false
matomo_url varchar(255) empty
site_id integer 0
cookieless_tracking boolean true
respect_do_not_track boolean true
use_klaro_consent boolean false
klaro_service_name varchar(255) matomo
ecommerce_enabled boolean true
track_product_views boolean true
track_orders boolean true
heartbeat_enabled boolean true
heartbeat_interval integer 15
track_outbound_links boolean true

Entity validation is deliberately loose: an incomplete entry can be saved, and whether it actually tracks is decided solely by the validity check at runtime.

The migration lives in the namespace Mmd\SyliusMatomoIntegrationPlugin\Migrations and not in the default namespace DoctrineMigrations, so that it does not collide with your project's migrations. It requires the Sylius core migrations to have run.