PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.3.3
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.3.3
5.13.0 5.12.1 5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / classes / WpMatomo / Admin / TrackingSettings.php
matomo / classes / WpMatomo / Admin Last commit date
TrackingSettings 1 year ago views 1 year ago AccessSettings.php 4 years ago Admin.php 1 year ago AdminSettings.php 2 years ago AdminSettingsInterface.php 6 years ago AdvancedSettings.php 1 year ago Chart.php 4 years ago CookieConsent.php 4 years ago Dashboard.php 4 years ago ExclusionSettings.php 4 years ago GeolocationSettings.php 2 years ago GetStarted.php 4 years ago ImportWpStatistics.php 4 years ago Info.php 4 years ago InvalidIpException.php 4 years ago Marketplace.php 2 years ago MarketplaceSetupWizard.php 1 year ago Menu.php 1 year ago PluginMeasurableSettings.php 2 years ago PrivacySettings.php 1 year ago SafeModeMenu.php 4 years ago Summary.php 1 year ago SystemReport.php 1 year ago TrackingSettings.php 1 year ago WhatsNewNotifications.php 1 year ago
TrackingSettings.php
456 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 * @package matomo
8 */
9
10 namespace WpMatomo\Admin;
11
12 use Exception;
13 use WpMatomo\Capabilities;
14 use WpMatomo\Settings;
15 use WpMatomo\Site;
16 use WpMatomo\Site\Sync\SyncConfig as SiteConfigSync;
17 use WpMatomo\TrackingCode\GeneratorOptions;
18 use WpMatomo\TrackingCode\TrackingCodeGenerator;
19
20 if ( ! defined( 'ABSPATH' ) ) {
21 exit; // if accessed directly
22 }
23 /**
24 * TODO: maybe we can move the form data collection to a single class
25 * Note: nonce verification exists, but phpcs can't tell since it's in a method
26 * that calls other methods that then access post data.
27 * phpcs:disable WordPress.Security.NonceVerification.Missing
28 */
29 class TrackingSettings implements AdminSettingsInterface {
30 const FORM_NAME = 'matomo';
31 const NONCE_NAME = 'matomo_settings';
32 const TRACK_MODE_DEFAULT = 'default';
33 const TRACK_MODE_DISABLED = 'disabled';
34 const TRACK_MODE_MANUALLY = 'manually';
35 const TRACK_MODE_TAGMANAGER = 'tagmanager';
36 const NONCE_NAME_GENERATE_TRACKING_CODE_AJAX = 'matomo-tracking-settings-code';
37
38 /**
39 * @var Settings
40 */
41 private $settings;
42
43 /**
44 * @param Settings $settings
45 */
46 public function __construct( $settings ) {
47 $this->settings = $settings;
48 $this->add_hooks();
49 }
50
51 public function get_title() {
52 return esc_html__( 'Tracking', 'matomo' );
53 }
54
55 private function update_if_submitted() {
56 if ( $this->form_submitted() === true
57 && check_admin_referer( self::NONCE_NAME ) ) {
58 $this->apply_settings();
59
60 return true;
61 }
62
63 return false;
64 }
65
66 public function can_user_manage() {
67 return current_user_can( Capabilities::KEY_SUPERUSER );
68 }
69
70 private function apply_settings() {
71 $keys_to_keep = [
72 'track_mode',
73 'track_across',
74 'track_across_alias',
75 'track_crossdomain_linking',
76 'track_feed',
77 'track_feed_addcampaign',
78 'track_feed_campaign',
79 'track_heartbeat',
80 'track_user_id',
81 'track_datacfasync',
82 'tagmanger_container_ids',
83 'set_download_extensions',
84 'set_download_classes',
85 'set_link_classes',
86 'track_admin',
87 'limit_cookies_referral',
88 'limit_cookies_session',
89 'limit_cookies_visitor',
90 'limit_cookies',
91 'force_post',
92 'disable_cookies',
93 'cookie_consent',
94 'add_download_extensions',
95 'track_404',
96 'track_search',
97 'add_post_annotations',
98 'track_content',
99 'track_ecommerce',
100 'track_noscript',
101 'noscript_code',
102 'track_codeposition',
103 'tracking_code',
104 'force_protocol',
105 'track_js_endpoint',
106 'track_jserrors',
107 'track_api_endpoint',
108 Settings::SITE_CURRENCY,
109 Settings::USE_SESSION_VISITOR_ID_OPTION_NAME,
110 ];
111
112 if ( matomo_has_tag_manager() ) {
113 $keys_to_keep[] = 'tagmanger_container_ids';
114 }
115
116 $values = [];
117
118 // default value in case no role/ post type is selected to make sure we unset it if no role /post type is selected
119 $values['add_post_annotations'] = [];
120 $values['tagmanger_container_ids'] = [];
121
122 $valid_currencies = $this->get_supported_currencies();
123
124 if ( ! empty( $_POST[ self::FORM_NAME ]['tracker_debug'] ) ) {
125 $site_config_sync = new SiteConfigSync( $this->settings );
126 switch ( $_POST[ self::FORM_NAME ]['tracker_debug'] ) {
127 case 'always':
128 $site_config_sync->set_config_value( 'Tracker', 'debug', 1 );
129 $site_config_sync->set_config_value( 'Tracker', 'debug_on_demand', 0 );
130 break;
131 case 'on_demand':
132 $site_config_sync->set_config_value( 'Tracker', 'debug', 0 );
133 $site_config_sync->set_config_value( 'Tracker', 'debug_on_demand', 1 );
134 break;
135 default:
136 $site_config_sync->set_config_value( 'Tracker', 'debug', 0 );
137 $site_config_sync->set_config_value( 'Tracker', 'debug_on_demand', 0 );
138 }
139 }
140
141 if ( empty( $_POST[ self::FORM_NAME ][ Settings::SITE_CURRENCY ] )
142 || ! array_key_exists( sanitize_text_field( wp_unslash( $_POST[ self::FORM_NAME ][ Settings::SITE_CURRENCY ] ) ), $valid_currencies ) ) {
143 $_POST[ self::FORM_NAME ][ Settings::SITE_CURRENCY ] = 'USD';
144 }
145
146 if ( ! empty( $_POST[ self::FORM_NAME ]['track_mode'] ) ) {
147 $track_mode = $this->get_track_mode();
148 if ( self::TRACK_MODE_TAGMANAGER === $track_mode ) {
149 // no noscript mode in this case
150 $_POST[ self::FORM_NAME ]['track_noscript'] = '';
151 $_POST[ self::FORM_NAME ]['noscript_code'] = '';
152 } else {
153 unset( $_POST['tagmanger_container_ids'] );
154 }
155 if ( $this->must_update_tracker() === true ) {
156 // We want to keep the tracking code when user switches between disabled and manually or disabled to disabled.
157 if ( ! empty( $_POST[ self::FORM_NAME ]['tracking_code'] ) ) {
158 // don't process, this is a script
159 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
160 $_POST[ self::FORM_NAME ]['tracking_code'] = stripslashes( $_POST[ self::FORM_NAME ]['tracking_code'] );
161 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
162 } else {
163 $_POST[ self::FORM_NAME ]['tracking_code'] = '';
164 }
165 if ( ! empty( $_POST[ self::FORM_NAME ]['noscript_code'] ) ) {
166 // don't process, this is a script
167 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
168 $_POST[ self::FORM_NAME ]['noscript_code'] = stripslashes( $_POST[ self::FORM_NAME ]['noscript_code'] );
169 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
170 } else {
171 $_POST[ self::FORM_NAME ]['noscript_code'] = '';
172 }
173 } else {
174 $_POST[ self::FORM_NAME ]['noscript_code'] = '';
175 $_POST[ self::FORM_NAME ]['tracking_code'] = '';
176 }
177 }
178 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
179 foreach ( $_POST[ self::FORM_NAME ] as $name => $value ) {
180 if ( in_array( $name, $keys_to_keep, true ) ) {
181 $values[ $name ] = $value;
182 }
183 }
184 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
185 $this->settings->apply_tracking_related_changes( $values );
186
187 return true;
188 }
189
190 private function get_track_mode() {
191 if ( ! empty( $_POST[ self::FORM_NAME ]['track_mode'] ) ) {
192 return sanitize_text_field( wp_unslash( $_POST[ self::FORM_NAME ]['track_mode'] ) );
193 }
194 return '';
195 }
196 /**
197 * Reauires form to be posted
198 *
199 * @return bool
200 */
201 private function must_update_tracker() {
202 $track_mode = $this->get_track_mode();
203 $previus_track_mode = $this->settings->get_global_option( 'track_mode' );
204 $must_update = false;
205 if ( self::TRACK_MODE_MANUALLY === $track_mode
206 || ( self::TRACK_MODE_DISABLED === $track_mode &&
207 in_array( $previus_track_mode, [ self::TRACK_MODE_DISABLED, self::TRACK_MODE_MANUALLY ], true ) ) ) {
208 // We want to keep the tracking code when user switches between disabled and manually or disabled to disabled.
209 $must_update = true;
210 }
211
212 return $must_update;
213 }
214
215 /**
216 * @return bool
217 */
218 private function form_submitted() {
219 return isset( $_POST ) && ! empty( $_POST[ self::FORM_NAME ] )
220 && is_admin()
221 && $this->can_user_manage();
222 }
223
224 /**
225 * @param string $field
226 *
227 * @return bool
228 */
229 private function has_valid_html_comments( $field ) {
230 $valid = true;
231 if ( $this->form_submitted() === true ) {
232 if ( $this->must_update_tracker() === true ) {
233 if ( ! empty( $_POST[ self::FORM_NAME ][ $field ] ) ) {
234 // phpcs:disable WordPress.Security.ValidatedSanitizedInput
235 $valid = $this->validate_html_comments( $_POST[ self::FORM_NAME ][ $field ] );
236 // phpcs:enable WordPress.Security.ValidatedSanitizedInput
237 }
238 }
239 }
240
241 return $valid;
242 }
243
244 /**
245 * @param string $html html content to validate
246 *
247 * @returns boolean
248 */
249 public function validate_html_comments( $html ) {
250 $opening = substr_count( $html, '<!--' );
251 $closing = substr_count( $html, '-->' );
252
253 return ( $opening === $closing );
254 }
255
256 public function show_settings() {
257 $was_updated = false;
258 $settings_errors = [];
259 if ( $this->has_valid_html_comments( 'tracking_code' ) !== true ) {
260 $settings_errors[] = __( 'Settings have not been saved. There is an issue with the HTML comments in the field "Tracking code". Make sure all opened comments (<!--) are closed (-->) correctly.', 'matomo' );
261 }
262 if ( $this->has_valid_html_comments( 'noscript_code' ) !== true ) {
263 $settings_errors[] = __( 'Settings have not been saved. There is an issue with the HTML comments in the field "Noscript code". Make sure all opened comments (<!--) are closed (-->) correctly.', 'matomo' );
264 }
265 if ( count( $settings_errors ) === 0 ) {
266 $was_updated = $this->update_if_submitted();
267 }
268
269 $settings = $this->settings;
270
271 $containers = $this->get_active_containers();
272
273 $track_modes = [
274 self::TRACK_MODE_DEFAULT => [
275 'name' => esc_html__( 'Auto (recommended)', 'matomo' ),
276 'disabled' => false,
277 ],
278 self::TRACK_MODE_MANUALLY => [
279 'name' => esc_html__( 'Manual', 'matomo' ),
280 'disabled' => false,
281 ],
282 self::TRACK_MODE_TAGMANAGER => [
283 'name' => esc_html__( 'Tag Manager', 'matomo' ),
284 'disabled' => false,
285 ],
286 self::TRACK_MODE_DISABLED => [
287 'name' => esc_html__( 'Disabled', 'matomo' ),
288 'disabled' => false,
289 ],
290 ];
291
292 $matomo_track_mode_descriptions = [
293 self::TRACK_MODE_DISABLED => esc_html__( 'Matomo will not add the tracking code itself. Use this mode if you want to add the tracking code by hand to your template files or you want to use another plugin to add the tracking code.', 'matomo' ),
294 self::TRACK_MODE_DEFAULT => esc_html__( 'Matomo will automatically generate and embed the tracking code based on the Auto Tracking settings below.', 'matomo' ) . ' ' . esc_html__( 'This is the recommended mode for most users.', 'matomo' ),
295 self::TRACK_MODE_MANUALLY => sprintf(
296 esc_html__( '%1$sDefine your own tracking JavaScript by hand below%2$s, and Matomo will embed it into your website.', 'matomo' ) . ( $settings->is_network_enabled() ? ' ' . esc_html__( 'Make sure to use the placeholder {ID} to add the Matomo site ID.', 'matomo' ) : '' ),
297 '<a href="#manual-tracking-settings">',
298 '</a>'
299 ),
300 self::TRACK_MODE_TAGMANAGER => esc_html__( 'If you\'ve created containers in the Tag Manager, you can use this tracking mode to embed one or more of them into your website automatically.', 'matomo' ),
301 ];
302
303 if ( empty( $containers ) ) {
304 $track_modes[ self::TRACK_MODE_TAGMANAGER ]['disabled'] = true;
305 $track_modes[ self::TRACK_MODE_TAGMANAGER ]['tooltip'] = esc_html__( 'No containers were found. Create one to be able to use the Tag Manager tracking mode.', 'matomo' );
306 $matomo_track_mode_descriptions[ self::TRACK_MODE_TAGMANAGER ] .= ' ' . esc_html__( 'This mode is not selectable since no containers have been created in the Tag Manager.', 'matomo' );
307 } else {
308 $container_select = '<div style="margin-left:1.5em" class="tagmanager-container-select">'
309 . '<label for="tagmanger_container_ids">' . esc_html__( 'Select which Tag Manager containers will be added to each page', 'matomo' ) . ':</label>';
310
311 $selected_container_ids = $settings->get_global_option( 'tagmanger_container_ids' );
312 foreach ( $containers as $container_id => $container_name ) {
313 $container_select .= '<input type="checkbox" ' . ( isset( $selected_container_ids [ $container_id ] ) && $selected_container_ids [ $container_id ] ? 'checked="checked" ' : '' ) . 'value="1" name="matomo[tagmanger_container_ids][' . esc_attr( $container_id ) . ']" /> <strong>' . esc_html( $container_name ) . '</strong> (ID: ' . esc_html( $container_id ) . ')&nbsp; <br />';
314 }
315
316 $container_select .= '<a style="margin-top:.5em;display:inline-block;" href="' . esc_url( menu_page_url( \WpMatomo\Admin\Menu::SLUG_TAGMANAGER, false ) ) . '" rel="noreferrer noopener" target="_blank">Edit containers <span class="dashicons-before dashicons-external"></span></a>';
317 $container_select .= '<p style="margin-top:1em"><span class="dashicons dashicons-info-outline"></span> ' . sprintf( esc_html__( 'For Matomo to track you will need to %1$sadd a Matomo Tag to the container%2$s. It otherwise won\'t track automatically.', 'matomo' ), '<a href="https://matomo.org/faq/tag-manager/how-do-i-track-pageviews-of-my-website-using-matomo-tag-manager/" target="_blank" rel="noreferrer noopener">', '</a>' ) . '</p>';
318 $container_select .= '</div>';
319
320 $matomo_track_mode_descriptions[ self::TRACK_MODE_TAGMANAGER ] .= $container_select;
321 }
322
323 $matomo_track_mode_descriptions[ self::TRACK_MODE_TAGMANAGER ] .= '<a id="tagmanager-read-more-link" style="display:inline-block" href="https://matomo.org/guide/tag-manager/getting-started-with-tag-manager/" target="_blank" rel="noreferrer noopener">' . esc_html__( 'Read our documentation on the Matomo Tag Manager to learn more.', 'matomo' ) . '</a>';
324
325 // /var/www/html/test/wp-content/uploads/wp-statistics/GeoLite2-City.mmdb
326 $site = new Site();
327 $idsite = $site->get_current_matomo_site_id();
328
329 $matomo_currencies = $this->get_supported_currencies();
330
331 $cookie_consent_modes = $this->get_cookie_consent_modes();
332
333 $tracking_code_generator = new TrackingCodeGenerator( $this->settings, new GeneratorOptions( $this->settings ) );
334 $matomo_default_tracking_code = $tracking_code_generator->prepare_tracking_code( $idsite );
335
336 $matomo_exclusion_settings_url = home_url( '/wp-admin/admin.php?page=matomo-settings&tab=exlusions' );
337
338 include dirname( __FILE__ ) . '/views/tracking.php';
339 }
340
341 /**
342 * @return string[]
343 */
344 private function get_cookie_consent_modes() {
345 $modes = [];
346 foreach ( CookieConsent::get_available_options() as $option => $description ) {
347 $modes[ $option ] = $description;
348 }
349
350 return $modes;
351 }
352
353 private function get_supported_currencies() {
354 $all = include dirname( MATOMO_ANALYTICS_FILE ) . '/app/core/Intl/Data/Resources/currencies.php';
355 $currencies = [];
356 foreach ( $all as $key => $single ) {
357 $currencies[ $key ] = $single[0] . ' ' . $single[1];
358 }
359
360 return $currencies;
361 }
362
363 public function get_active_containers() {
364 // we don't use Matomo API here to avoid needing to bootstrap Matomo which is slow and could break things
365 $containers = [];
366 if ( matomo_has_tag_manager() ) {
367 global $wpdb;
368 $db_settings = new \WpMatomo\Db\Settings();
369 $container_table = $db_settings->prefix_table_name( 'tagmanager_container' );
370 try {
371 // phpcs:disable WordPress.DB
372 $containers = $wpdb->get_results( sprintf( 'SELECT `idcontainer`, `name` FROM %s where `status` = "active"', $container_table ) );
373 // phpcs:enable WordPress.DB
374 } catch ( Exception $e ) {
375 // table may not exist yet etc
376 $containers = [];
377 }
378 }
379 $by_id = [];
380 foreach ( $containers as $container ) {
381 $by_id[ $container->idcontainer ] = $container->name;
382 }
383
384 return $by_id;
385 }
386
387 private function add_hooks() {
388 add_action(
389 'admin_enqueue_scripts',
390 function ( $page ) {
391 if ( 'matomo-analytics_page_matomo-settings' !== $page ) {
392 return;
393 }
394
395 wp_enqueue_script(
396 'matomo-tracking-settings',
397 plugins_url( '/assets/js/settings.js', MATOMO_ANALYTICS_FILE ),
398 [ 'jquery' ],
399 '1.0.1',
400 true
401 );
402
403 wp_localize_script(
404 'matomo-tracking-settings',
405 'mtmTrackingSettingsAjax',
406 [
407 'ajax_url' => admin_url( 'admin-ajax.php' ),
408 'nonce' => wp_create_nonce( self::NONCE_NAME_GENERATE_TRACKING_CODE_AJAX ),
409 ]
410 );
411 }
412 );
413 }
414
415 public static function register_ajax() {
416 add_action( 'wp_ajax_matomo_generate_tracking_code', [ self::class, 'generate_tracking_code' ] );
417 }
418
419 public static function generate_tracking_code() {
420 check_ajax_referer( self::NONCE_NAME_GENERATE_TRACKING_CODE_AJAX );
421
422 $blog_id = get_current_blog_id();
423 $idsite = Site::get_matomo_site_id( $blog_id );
424
425 // phpcs complains if reading from $_POST is not done this way
426 $overrides = [
427 'track_datacfasync' => isset( $_POST['track_datacfasync'] ) ? ( boolval( wp_unslash( $_POST['track_datacfasync'] ) ) ) : false,
428 'track_content' => isset( $_POST['track_content'] ) ? ( sanitize_text_field( wp_unslash( $_POST['track_content'] ) ) ) : '',
429 'track_heartbeat' => isset( $_POST['track_heartbeat'] ) ? ( intval( wp_unslash( $_POST['track_heartbeat'] ) ) ) : 0,
430 'limit_cookies' => isset( $_POST['limit_cookies'] ) ? ( boolval( wp_unslash( $_POST['limit_cookies'] ) ) ) : false,
431 'limit_cookies_visitor' => isset( $_POST['limit_cookies_visitor'] ) ? ( intval( wp_unslash( $_POST['limit_cookies_visitor'] ) ) ) : 0,
432 'limit_cookies_session' => isset( $_POST['limit_cookies_session'] ) ? ( intval( wp_unslash( $_POST['limit_cookies_session'] ) ) ) : 0,
433 'limit_cookies_referral' => isset( $_POST['limit_cookies_referral'] ) ? ( intval( wp_unslash( $_POST['limit_cookies_referral'] ) ) ) : 0,
434 'cookie_consent' => isset( $_POST['cookie_consent'] ) ? ( sanitize_text_field( wp_unslash( $_POST['cookie_consent'] ) ) ) : '',
435 'force_post' => isset( $_POST['force_post'] ) ? ( wp_unslash( boolval( $_POST['force_post'] ) ) ) : false,
436 'track_across_alias' => isset( $_POST['track_across_alias'] ) ? ( boolval( wp_unslash( $_POST['track_across_alias'] ) ) ) : false,
437 'track_across' => isset( $_POST['track_across'] ) ? ( boolval( wp_unslash( $_POST['track_across'] ) ) ) : false,
438 'track_crossdomain_linking' => isset( $_POST['track_crossdomain_linking'] ) ? ( boolval( wp_unslash( $_POST['track_crossdomain_linking'] ) ) ) : false,
439 'track_jserrors' => isset( $_POST['track_jserrors'] ) ? ( boolval( wp_unslash( $_POST['track_jserrors'] ) ) ) : false,
440 'disable_cookies' => isset( $_POST['disable_cookies'] ) ? ( boolval( wp_unslash( $_POST['disable_cookies'] ) ) ) : false,
441 'set_link_classes' => isset( $_POST['set_link_classes'] ) ? ( sanitize_text_field( wp_unslash( $_POST['set_link_classes'] ) ) ) : '',
442 'set_download_classes' => isset( $_POST['set_download_classes'] ) ? ( sanitize_text_field( wp_unslash( $_POST['set_download_classes'] ) ) ) : '',
443 'add_download_extensions' => isset( $_POST['add_download_extensions'] ) ? ( sanitize_text_field( wp_unslash( $_POST['add_download_extensions'] ) ) ) : '',
444 'track_api_endpoint' => isset( $_POST['track_api_endpoint'] ) ? ( sanitize_text_field( wp_unslash( $_POST['track_api_endpoint'] ) ) ) : '',
445 'force_protocol' => isset( $_POST['force_protocol'] ) ? ( boolval( wp_unslash( $_POST['force_protocol'] ) ) ) : false,
446 'track_js_endpoint' => isset( $_POST['track_js_endpoint'] ) ? ( sanitize_text_field( wp_unslash( $_POST['track_js_endpoint'] ) ) ) : '',
447 'set_download_extensions' => isset( $_POST['set_download_extensions'] ) ? ( sanitize_text_field( wp_unslash( $_POST['set_download_extensions'] ) ) ) : '',
448 ];
449
450 $generator = new TrackingCodeGenerator( \WpMatomo::$settings, new GeneratorOptions( \WpMatomo::$settings, $overrides ) );
451 $tracking_code = $generator->prepare_tracking_code( $idsite );
452
453 wp_send_json( $tracking_code );
454 }
455 }
456