=== Pagemetrics for Matomo === Contributors: pagemachine, maltamirano Tags: matomo, analytics, tracking, server-side, privacy, ai Requires at least: 6.1 Tested up to: 7.1 Requires PHP: 8.1 Stable tag: 1.1.2 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Pagemetrics for Matomo adds server-side, privacy-friendly analytics to WordPress. It tracks page views, downloads, and AI assistant bot crawls without using JavaScript. == Description == Pagemetrics for Matomo adds privacy-friendly, server-side analytics to WordPress by leveraging the `pagemachine/matomo-tracking` PHP library. When enabled, the plugin sends page view and optional download events from your WordPress site directly to a Matomo instance without loading Matomo's JavaScript tracker. Key benefits: * Track page views on the server with full control over attributes such as title, URL and referrer. * Optional download tracking rewrites file links and records the click before redirecting visitors. * Optional AI assistant bot tracking detects crawls from ChatGPT, Claude, Perplexity and others and forwards them to Matomo's dedicated AI Assistants report. * Multisite aware – network admins can define defaults, individual sites can override them. * Respects Do Not Track and Global Privacy Control headers through the underlying library. * Logs issues to the WordPress debug log when `WP_DEBUG` is enabled. Looking for expert help with Matomo or server-side tracking? **Pagemachine** offers consulting, implementation and ongoing support via our **Pagemetrics** solution. More info: [Pagemetrics.eu](https://pagemetrics.eu/) == Installation == 1. Upload the `pagemetrics-for-matomo` plugin directory (including the bundled `vendor/` folder) to your site's `wp-content/plugins` path. 2. Activate the plugin through the **Plugins → Pagemetrics for Matomo** screen in WordPress. 3. Open **Settings → Pagemetrics for Matomo** and configure: * Matomo URL (e.g. `https://matomo.example.com/`) * Default Matomo site ID * Optional auth token (required for IP tracking and other privileged attributes) * HTTP timeout for Matomo requests * Download tracking toggle, if you want the plugin to rewrite file links automatically * AI assistant bot tracking toggle, to send AI crawler hits to Matomo's AI Assistants report (requires Matomo 5.8.0 or later) 4. (Multisite) Network administrators can define defaults under **Network Admin → Settings → Pagemetrics for Matomo**. Individual sites can override those values on their local settings page. The plugin starts sending data as soon as the Matomo URL and site ID are set. == Frequently Asked Questions == = Do I need to share my Matomo auth token? = No. The auth token is optional. Provide it only if you need to forward visitor IP addresses or rely on Matomo parameters that require authentication. The token is stored server-side and never exposed to browsers. = How is the visitor IP forwarded behind a proxy or CDN? = When an auth token is set, the plugin forwards the visitor IP to Matomo as the `cip` parameter, resolved from `REMOTE_ADDR` by default. If your site is behind a reverse proxy or CDN, use the `pm_matomo_tracking_visitor_ip` filter to return the real client IP from your trusted forwarded header. = Can I disable download link rewriting? = Yes. Leave the _Track downloads_ toggle unchecked in the settings page. You can also use the `pm_matomo_tracking_should_rewrite_downloads` filter to disable rewriting programmatically for specific posts or file types. = How does AI assistant bot tracking work? = When the _Track AI assistant bots_ toggle is enabled, the plugin inspects the User-Agent header of every front-end request. If it matches a known AI crawler (ChatGPT, Claude, Perplexity, MistralAI, Gemini, GoogleAgent, NovaAct), a server-side telemetry hit is sent to Matomo using `recMode=1`. The hit is recorded in Matomo's dedicated AI Assistants report and does not count as a normal visit. Requires Matomo 5.8.0 or later. = Can I add custom AI bot User-Agents? = Yes. Use the `pm_matomo_tracking_ai_bot_user_agents` filter to extend or replace the default list of User-Agent substrings: add_filter('pm_matomo_tracking_ai_bot_user_agents', static function (array $substrings): array { $substrings[] = 'MyCustomBot'; return $substrings; }); = What happens if Matomo is down? = Requests use a configurable HTTP timeout (default three seconds). When Matomo is unreachable, tracking is skipped and a warning is logged (only when `WP_DEBUG` is enabled). Page rendering continues normally. == Screenshots == 1. Pagemetrics for Matomo settings == Developer Hooks == Page view tracking: * `pm_matomo_tracking_should_track_request` — Return `false` to skip page view tracking for the current request. * `pm_matomo_tracking_visitor_ip` — Override the visitor IP forwarded to Matomo as `cip` (defaults to `REMOTE_ADDR`; used for page views and downloads when an auth token is set). Return an empty string to skip IP forwarding. Download tracking: * `pm_matomo_tracking_should_rewrite_downloads` — Return `false` to keep original download URLs for the current post. * `pm_matomo_tracking_is_download_url` — Decide whether a specific URL should be rewritten (receives URL and default extension list). * `pm_matomo_tracking_download_extensions` — Adjust the list of file extensions that count as downloads. * `pm_matomo_tracking_download_url` — Customize the generated redirect URL used for download tracking. * `pm_matomo_tracking_download_redirect_status` — Change the HTTP status code used when redirecting to the original file. AI assistant bot tracking: * `pm_matomo_tracking_ai_bot_user_agents` — Extend or replace the list of User-Agent substrings used to detect AI bots. General: * `pm_matomo_tracking_log_message` — Listen to debug messages emitted while `WP_DEBUG` is enabled. === Example usages === // Skip tracking for administrators. add_filter('pm_matomo_tracking_should_track_request', static function ($shouldTrack) { return current_user_can('manage_options') ? false : $shouldTrack; }); // Keep original download URLs on the privacy policy page. add_filter('pm_matomo_tracking_should_rewrite_downloads', static function ($shouldRewrite) { return is_page('privacy-policy') ? false : $shouldRewrite; }); // Force CDN assets to be treated as downloads. add_filter('pm_matomo_tracking_is_download_url', static function ($decision, $url) { return str_contains($url, 'cdn.example.com/assets/') ? true : $decision; }, 10, 2); // Add extra file types to download tracking. add_filter('pm_matomo_tracking_download_extensions', static function ($extensions) { $extensions = array_merge($extensions, ['svg', 'heic']); return array_unique($extensions); }); // Append a checksum to rewritten download URLs. add_filter('pm_matomo_tracking_download_url', static function ($trackingUrl, $target, $label) { $checksum = substr(hash('sha256', $target . $label), 0, 12); return add_query_arg('pm_checksum', $checksum, $trackingUrl); }, 10, 3); // Use a 307 redirect instead of the default 302. add_filter('pm_matomo_tracking_download_redirect_status', static function () { return 307; }); // Add a custom bot to AI assistant tracking. add_filter('pm_matomo_tracking_ai_bot_user_agents', static function (array $substrings): array { $substrings[] = 'MyCustomBot'; return $substrings; }); // Behind a reverse proxy: forward the real client IP from X-Forwarded-For. add_filter('pm_matomo_tracking_visitor_ip', static function ($ip, $request) { $forwarded = $request->getHeaderLine('X-Forwarded-For'); if ($forwarded === '') { return $ip; } // Use the first (client) address in the list. return trim(explode(',', $forwarded)[0]); }, 10, 2); // Forward debug messages to the PHP error log while developing. add_action('pm_matomo_tracking_log_message', static function ($level, $message) { if (!defined('WP_DEBUG') || WP_DEBUG !== true) { return; } // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log error_log(sprintf('[Pagemetrics for Matomo][%s] %s', strtoupper((string) $level), $message)); }, 10, 2); == Changelog == = 1.1.2 = * Tested with WordPress 7.1. * No functional changes. = 1.1.1 = * Fixed: the real visitor IP is now forwarded to Matomo as the `cip` parameter when an auth token is set, so page views and downloads geolocate the visitor instead of the WordPress server. * New `pm_matomo_tracking_visitor_ip` filter to override the forwarded IP (e.g. from a trusted proxy header) or disable IP forwarding. = 1.1.0 = * Added AI assistant bot tracking: detects crawls from ChatGPT, Claude, Perplexity and other AI agents and forwards them to Matomo's AI Assistants report (requires Matomo 5.8.0+). * New `pm_matomo_tracking_ai_bot_user_agents` filter to extend the list of detected bot User-Agents. = 1.0.0 = * Initial release with server-side page view tracking, optional download tracking and multisite support.