PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.4.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.4.1
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 / Settings.php
matomo / classes / WpMatomo Last commit date
Admin 5 years ago Commands 5 years ago Db 5 years ago Ecommerce 5 years ago Report 6 years ago Site 5 years ago TrackingCode 5 years ago Updater 5 years ago User 5 years ago views 6 years ago API.php 5 years ago Access.php 6 years ago AjaxTracker.php 5 years ago Annotations.php 6 years ago Bootstrap.php 6 years ago Capabilities.php 6 years ago Compatibility.php 6 years ago Email.php 5 years ago Installer.php 5 years ago Logger.php 5 years ago OptOut.php 6 years ago Paths.php 6 years ago PrivacyBadge.php 6 years ago RedirectOnActivation.php 5 years ago Referral.php 6 years ago Roles.php 6 years ago ScheduledTasks.php 5 years ago Settings.php 5 years ago Site.php 6 years ago TrackingCode.php 5 years ago Uninstaller.php 6 years ago Updater.php 5 years ago User.php 6 years ago
Settings.php
490 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 * Code Based on
9 * @author Andr&eacute; Br&auml;kling
10 * https://github.com/braekling/matomo
11 *
12 */
13
14 namespace WpMatomo;
15
16 use WpMatomo\Admin\CookieConsent;
17 use WpMatomo\Admin\TrackingSettings;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // if accessed directly
21 }
22
23 class Settings {
24
25 const OPTION_PREFIX = 'matomo-';
26 const GLOBAL_OPTION_PREFIX = 'matomo_global-';
27 const OPTION = 'matomo-option';
28 const OPTION_GLOBAL = 'matomo-global-option';
29 const OPTION_KEY_CAPS_ACCESS = 'caps_access';
30 const OPTION_KEY_STEALTH = 'caps_tracking';
31 const OPTION_LAST_TRACKING_SETTINGS_CHANGE = 'last_tracking_settings_update';
32 const OPTION_LAST_TRACKING_CODE_UPDATE = 'last_tracking_code_update';
33 const SHOW_GET_STARTED_PAGE = 'show_get_started_page';
34 const DELETE_ALL_DATA_ON_UNINSTALL = 'delete_all_data_uninstall';
35 const SITE_CURRENCY = 'site_currency';
36 const NETWORK_CONFIG_OPTIONS = 'config_options';
37
38 public static $is_doing_action_tracking_related = false;
39 /**
40 * @internal tests only
41 * @var bool
42 */
43 public $force_disable_addhandler = false;
44
45 /**
46 * Tests only
47 *
48 * @ignore
49 * @var bool
50 */
51 private $assume_is_network_enabled_in_tests = false;
52
53 /**
54 * Register default configuration set
55 *
56 * @var array
57 */
58 private $default_global_settings = array(
59 // Plugin settings
60 'last_settings_update' => 0,
61 self::OPTION_LAST_TRACKING_SETTINGS_CHANGE => 0,
62 self::OPTION_KEY_STEALTH => array(),
63 self::OPTION_KEY_CAPS_ACCESS => array(),
64 self::NETWORK_CONFIG_OPTIONS => array(),
65 self::DELETE_ALL_DATA_ON_UNINSTALL => true,
66 self::SITE_CURRENCY => 'USD',
67 // User settings: Stats configuration
68 // User settings: Tracking configuration
69 'track_mode' => 'disabled',
70 'track_js_endpoint' => 'default',
71 'track_api_endpoint' => 'default',
72 'track_codeposition' => 'footer',
73 'track_noscript' => false,
74 'track_content' => 'disabled',
75 'track_ecommerce' => true,
76 'track_search' => false,
77 'track_404' => false,
78 'tagmanger_container_ids' => array(),
79 'add_post_annotations' => array(),
80 'add_customvars_box' => false,
81 'js_manually' => '',
82 'noscript_manually' => '',
83 'add_download_extensions' => '',
84 'set_download_extensions' => '',
85 'set_link_classes' => '',
86 'set_download_classes' => '',
87 'core_version' => '',
88 'version_history' => array(),
89 'mail_history' => array(),
90 'disable_cookies' => false,
91 'cookie_consent' => CookieConsent::REQUIRE_NONE,
92 'force_post' => false,
93 'limit_cookies' => false,
94 'limit_cookies_visitor' => 34186669, // Matomo default 13 months
95 'limit_cookies_session' => 1800, // Matomo default 30 minutes
96 'limit_cookies_referral' => 15778463, // Matomo default 6 months
97 'track_admin' => false,
98 'track_across' => false,
99 'track_across_alias' => false,
100 'track_crossdomain_linking' => false,
101 'track_feed' => false,
102 'track_feed_addcampaign' => false,
103 'track_feed_campaign' => 'feed',
104 'track_heartbeat' => 0,
105 'track_user_id' => 'disabled',
106 'track_datacfasync' => false,
107 'track_jserrors' => false,
108 'force_protocol' => 'disabled',
109 'maxmind_license_key' => '',
110 self::SHOW_GET_STARTED_PAGE => 1,
111 );
112
113 /**
114 * Settings stored per blog
115 *
116 * @var array
117 */
118 private $default_blog_settings = array(
119 'noscript_code' => '',
120 'tracking_code' => '',
121 self::OPTION_LAST_TRACKING_CODE_UPDATE => 0,
122 );
123
124 private $global_settings = array();
125 private $blog_settings = array();
126
127 private $settings_changed = array();
128
129 /**
130 * @var Logger
131 */
132 private $logger;
133
134 /**
135 * Constructor class to prepare settings manager
136 *
137 */
138 public function __construct() {
139 $this->logger = new Logger();
140
141 $this->init_settings();
142 }
143
144 public function init_settings() {
145 $this->settings_changed = array();
146 $this->global_settings = array();
147 $this->blog_settings = array();
148
149 if ( $this->is_network_enabled() ) {
150 $global_settings = get_site_option( self::OPTION_GLOBAL, array() );
151 } else {
152 $global_settings = get_option( self::OPTION_GLOBAL, array() );
153 }
154
155 if ( ! empty( $global_settings ) && is_array( $global_settings ) ) {
156 $this->global_settings = $global_settings;
157 }
158
159 $settings = get_option( self::OPTION, array() );
160
161 if ( ! empty( $settings ) && is_array( $settings ) ) {
162 $this->blog_settings = $settings;
163 }
164 }
165
166 public function get_customised_global_settings() {
167 $custom_settings = array();
168
169 foreach ( $this->global_settings as $key => $val ) {
170 if ( isset( $this->default_global_settings[ $key ] )
171 && $this->default_global_settings[ $key ] != $val ) {
172 $custom_settings[ $key ] = $val;
173 }
174 }
175
176 return $custom_settings;
177 }
178
179 public function uninstall() {
180 Uninstaller::uninstall_options( self::OPTION_PREFIX );
181 Uninstaller::uninstall_options( self::GLOBAL_OPTION_PREFIX );
182 Uninstaller::uninstall_site_meta( self::GLOBAL_OPTION_PREFIX );
183 $this->init_settings();
184 }
185
186 public function is_multisite() {
187 return function_exists( 'is_multisite' ) && is_multisite();
188 }
189
190 /**
191 * @api
192 */
193 public function is_network_enabled() {
194 if ( $this->assume_is_network_enabled_in_tests ) {
195 return true;
196 }
197
198 if ( ! function_exists( 'is_plugin_active_for_network' ) ) {
199 require_once ABSPATH . 'wp-admin/includes/plugin.php';
200 }
201
202 return is_plugin_active_for_network( 'matomo/matomo.php' );
203 }
204
205 /**
206 * Save all settings as WordPress options
207 */
208 public function save() {
209 if ( empty( $this->settings_changed ) ) {
210 $this->logger->log( 'No settings changed yet' );
211
212 return;
213 }
214
215 $this->logger->log( 'Save settings' );
216
217 if ( $this->is_network_enabled() ) {
218 update_site_option( self::OPTION_GLOBAL, $this->global_settings );
219 } else {
220 update_option( self::OPTION_GLOBAL, $this->global_settings );
221 }
222
223 update_option( self::OPTION, $this->blog_settings );
224
225 $keys_changed = array_values( array_unique( $this->settings_changed ) );
226 $this->settings_changed = array();
227
228 foreach ( $keys_changed as $key_changed ) {
229 do_action( 'matomo_setting_change_' . $key_changed );
230 }
231 }
232
233 /**
234 * Get a global option's value
235 *
236 * @param string $key
237 * option key
238 *
239 * @return string|array option value
240 * @api
241 */
242 public function get_global_option( $key ) {
243 if ( isset( $this->global_settings[ $key ] ) ) {
244 return $this->global_settings[ $key ];
245 }
246
247 if ( isset( $this->default_global_settings[ $key ] ) ) {
248 return $this->default_global_settings[ $key ];
249 }
250 }
251
252 /**
253 * Get an option's value related to a specific blog
254 *
255 * @param string $key option key
256 *
257 * @return string|array
258 * @api
259 */
260 public function get_option( $key ) {
261 if ( isset( $this->blog_settings[ $key ] ) ) {
262 return $this->blog_settings[ $key ];
263 }
264
265 if ( isset( $this->default_blog_settings[ $key ] ) ) {
266 return $this->default_blog_settings[ $key ];
267 }
268 }
269
270 private function convert_type( $value, $type ) {
271 if ( $type === 'array' && empty( $value ) ) {
272 $value = array(); // prevent eg converting '' to array('')
273 } else {
274 settype( $value, $type );
275 }
276 return $value;
277 }
278
279 /**
280 * Set a global option's value
281 *
282 * @param string $key option key
283 * @param string|array $value new option value
284 */
285 public function set_global_option( $key, $value ) {
286 if ( isset( $this->default_global_settings[ $key ] ) ) {
287 $type = gettype( $this->default_global_settings[ $key ] );
288 $value = $this->convert_type( $value, $type );
289 }
290
291 if ( ! isset( $this->global_settings[ $key ] )
292 || $this->global_settings[ $key ] !== $value ) {
293 $this->settings_changed[] = $key;
294 $this->logger->log( 'Changed global option ' . $key . ': ' . ( is_array( $value ) ? wp_json_encode( $value ) : $value ) );
295
296 $this->global_settings[ $key ] = $value;
297 }
298 }
299
300 /**
301 * Set an option's value related to a specific blog
302 *
303 * @param string $key option key
304 * @param string $value new option value
305 */
306 public function set_option( $key, $value ) {
307 if ( isset( $this->default_blog_settings[ $key ] ) ) {
308 $type = gettype( $this->default_blog_settings[ $key ] );
309 $value = $this->convert_type( $value, $type );
310 }
311
312 if ( ! isset( $this->blog_settings[ $key ] )
313 || $this->blog_settings[ $key ] !== $value ) {
314 $this->settings_changed[] = $key;
315 $this->logger->log( 'Changed option ' . $key . ': ' . $value );
316 $this->blog_settings[ $key ] = $value;
317 }
318 }
319
320 /**
321 * @param $values
322 *
323 * @api
324 */
325 public function apply_tracking_related_changes( $values ) {
326 $this->set_global_option( self::OPTION_LAST_TRACKING_SETTINGS_CHANGE, time() );
327
328 $this->apply_changes( $values );
329
330 if ( ! self::$is_doing_action_tracking_related ) {
331 // prevent recurison if any plugin was listening to this event and calling this method again
332 self::$is_doing_action_tracking_related = true;
333 do_action( 'matomo_tracking_settings_changed', $this, $values );
334 self::$is_doing_action_tracking_related = false;
335 }
336 }
337
338 public function should_disable_addhandler()
339 {
340 if ($this->force_disable_addhandler) {
341 return true;
342 }
343 return defined('MATOMO_DISABLE_ADDHANDLER') && MATOMO_DISABLE_ADDHANDLER;
344 }
345
346 /**
347 * Apply new configuration
348 *
349 * @param array $settings
350 * new configuration set
351 *
352 * @api
353 */
354 public function apply_changes( $settings ) {
355 $this->logger->log( 'Apply changed settings:' );
356 foreach ( $this->default_global_settings as $key => $val ) {
357 if ( isset( $settings[ $key ] ) ) {
358 $this->set_global_option( $key, $settings[ $key ] );
359 }
360 }
361 foreach ( $this->default_blog_settings as $key => $val ) {
362 if ( isset( $settings[ $key ] ) ) {
363 $this->set_option( $key, $settings[ $key ] );
364 }
365 }
366 $this->set_global_option( 'last_settings_update', time() );
367
368 if ( $this->should_save_tracking_code_across_sites() ) {
369 // special case for when the same tracking code needs to be used across all instances
370 $this->set_global_option( 'js_manually', $this->get_option( 'tracking_code' ) );
371 $this->set_global_option( 'noscript_manually', $this->get_option( 'noscript_code' ) );
372 }
373
374 $this->save();
375 }
376
377 private function should_save_tracking_code_across_sites() {
378 return $this->is_network_enabled()
379 && $this->get_global_option( 'track_mode' ) === TrackingSettings::TRACK_MODE_MANUALLY;
380 }
381
382 public function get_js_tracking_code() {
383 if ( $this->should_save_tracking_code_across_sites() ) {
384 return $this->get_global_option( 'js_manually' );
385 }
386
387 return $this->get_option( 'tracking_code' );
388 }
389
390 public function get_noscript_tracking_code() {
391 if ( $this->should_save_tracking_code_across_sites() ) {
392 return $this->get_global_option( 'noscript_manually' );
393 }
394
395 return $this->get_option( 'noscript_code' );
396 }
397
398 public function is_cross_domain_linking_enabled() {
399 return $this->get_global_option( 'track_crossdomain_linking' );
400 }
401
402 public function get_tracking_cookie_domain() {
403 if ( $this->get_global_option( 'track_across' )
404 || $this->get_global_option( 'track_crossdomain_linking' ) ) {
405 $host = @parse_url( home_url(), PHP_URL_HOST );
406 if ( ! empty( $host ) ) {
407 return '*.' . $host;
408 }
409 }
410
411 return '';
412 }
413
414 public function should_delete_all_data_on_uninstall()
415 {
416 if (defined( 'MATOMO_REMOVE_ALL_DATA' )) {
417 return (bool) MATOMO_REMOVE_ALL_DATA;
418 }
419
420 return (bool) $this->get_global_option(self::DELETE_ALL_DATA_ON_UNINSTALL);
421 }
422
423 /**
424 * Check if feed tracking is enabled
425 *
426 * @return boolean Is feed tracking enabled?
427 */
428 public function is_track_feed() {
429 return $this->get_global_option( 'track_feed' );
430 }
431
432 /**
433 * Check if admin tracking is enabled
434 *
435 * @return boolean Is admin tracking enabled?
436 */
437 public function is_admin_tracking_enabled() {
438 return $this->get_global_option( 'track_admin' ) && is_admin();
439 }
440
441 public function is_current_tracking_code() {
442 $last_tracking_code_update = $this->get_option( self::OPTION_LAST_TRACKING_CODE_UPDATE );
443 $last_tracking_settings_update = $this->get_global_option( self::OPTION_LAST_TRACKING_SETTINGS_CHANGE );
444
445 return $last_tracking_code_update && $last_tracking_code_update > $last_tracking_settings_update;
446 }
447
448 /**
449 * Check if feed permalinks get a campaign parameter
450 *
451 * @return boolean Add campaign parameter to feed permalinks?
452 */
453 public function is_add_feed_campaign() {
454 return $this->get_global_option( 'track_feed_addcampaign' );
455 }
456
457 public function is_tracking_enabled() {
458 return $this->get_global_option( 'track_mode' ) != 'disabled';
459 }
460
461 /**
462 * Check if noscript code insertion is enabled
463 *
464 * @return boolean Insert noscript code?
465 */
466 public function is_add_no_script_code() {
467 return $this->get_global_option( 'track_noscript' );
468 }
469
470 public function get_tracking_code_position() {
471 return $this->get_global_option( 'track_codeposition' );
472 }
473
474 public function track_404_enabled() {
475 return $this->get_global_option( 'track_404' );
476 }
477
478 public function track_user_id_enabled() {
479 return $this->get_global_option( 'track_user_id' ) != 'disabled';
480 }
481
482 public function track_search_enabled() {
483 return ( is_search() && $this->get_global_option( 'track_search' ) );
484 }
485
486 public function set_assume_is_network_enabled_in_tests( $network_enabled = true ) {
487 $this->assume_is_network_enabled_in_tests = $network_enabled;
488 }
489 }
490