Matomo Analytics – Ethical Stats. Powerful Insights. - Version 1.1.1

Version Description

Download this release

Release Info

Developer matomoteam
Plugin Icon 128x128 Matomo Analytics – Ethical Stats. Powerful Insights.
Version 1.1.1
Comparing to
See all releases

Code changes from version 1.1.0 to 1.1.1

app/core/Updates/3.13.6-b1.php CHANGED
@@ -21,8 +21,30 @@ class Updates_3_13_6_b1 extends PiwikUpdates
21
 
22
  if ($wpdb->charset === 'utf8mb4') {
23
  $db_settings = new \WpMatomo\Db\Settings();
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  $installed_tables = $db_settings->get_installed_matomo_tables();
 
25
  if (!empty($installed_tables)) {
 
 
 
 
 
 
 
 
26
  foreach ($installed_tables as $installed_table) {
27
  try {
28
  $wpdb->query('ALTER TABLE `'.$installed_table.'` CONVERT TO CHARACTER SET utf8mb4');
21
 
22
  if ($wpdb->charset === 'utf8mb4') {
23
  $db_settings = new \WpMatomo\Db\Settings();
24
+ $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE `%s` `%s` %s',
25
+ $db_settings->prefix_table_name('session'),
26
+ 'id', 'id', 'VARCHAR(191)'
27
+ ));
28
+ $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE `%s` `%s` %s',
29
+ $db_settings->prefix_table_name('site_url'),
30
+ 'url', 'url', 'VARCHAR(190)'
31
+ ));
32
+ $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE `%s` `%s` %s',
33
+ $db_settings->prefix_table_name('option'),
34
+ 'option_name', 'option_name', 'VARCHAR(191)'
35
+ ));
36
+
37
  $installed_tables = $db_settings->get_installed_matomo_tables();
38
+
39
  if (!empty($installed_tables)) {
40
+ foreach ($installed_tables as $table) {
41
+ if (preg_match('/archive_/', $table) == 1) {
42
+ $wpdb->query(sprintf('ALTER TABLE `%s` CHANGE `%s` `%s` %s',
43
+ $table, 'name', 'name', 'VARCHAR(190)'
44
+ ));
45
+ }
46
+ }
47
+
48
  foreach ($installed_tables as $installed_table) {
49
  try {
50
  $wpdb->query('ALTER TABLE `'.$installed_table.'` CONVERT TO CHARACTER SET utf8mb4');
classes/WpMatomo/Admin/AdminSettings.php CHANGED
@@ -9,6 +9,9 @@
9
 
10
  namespace WpMatomo\Admin;
11
 
 
 
 
12
  use WpMatomo\Access;
13
  use WpMatomo\Settings;
14
 
@@ -17,12 +20,12 @@ if ( ! defined( 'ABSPATH' ) ) {
17
  }
18
 
19
  class AdminSettings {
20
- const TAB_TRACKING = 'tracking';
21
- const TAB_ACCESS = 'access';
22
  const TAB_EXCLUSIONS = 'exlusions';
23
- const TAB_PRIVACY = 'privacy';
24
  const TAB_GEOLOCATION = 'geolocation';
25
- const TAB_ADVANCED = 'advanced';
26
 
27
  /**
28
  * @var Settings
@@ -34,35 +37,63 @@ class AdminSettings {
34
  }
35
 
36
  public static function make_url( $tab ) {
37
- return add_query_arg( array( 'tab' => $tab ), menu_page_url( Menu::SLUG_SETTINGS, false ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
 
40
  public function show() {
41
- $access = new Access( $this->settings );
42
  $access_settings = new AccessSettings( $access, $this->settings );
43
- $tracking = new TrackingSettings( $this->settings );
44
- $exclusions = new ExclusionSettings( $this->settings );
45
- $geolocation = new GeolocationSettings( $this->settings );
46
- $privacy = new PrivacySettings();
47
- $advanced = new AdvancedSettings( $this->settings );
48
- $setting_tabs = array(
49
  self::TAB_TRACKING => $tracking,
50
- self::TAB_ACCESS => $access_settings,
51
- self::TAB_PRIVACY => $privacy,
52
  self::TAB_EXCLUSIONS => $exclusions,
53
  self::TAB_GEOLOCATION => $geolocation,
54
- self::TAB_ADVANCED => $advanced,
55
  );
56
 
 
 
 
 
 
 
 
 
 
 
57
  $setting_tabs = apply_filters( 'matomo_setting_tabs', $setting_tabs, $this->settings );
58
 
59
  if ( ! empty( $_GET['tab'] ) && isset( $setting_tabs[ $_GET['tab'] ] ) ) {
60
  $active_tab = $_GET['tab'];
61
- } else {
62
- $active_tab = self::TAB_TRACKING;
63
  }
64
 
65
  $content_tab = $setting_tabs[ $active_tab ];
 
66
 
67
  include dirname( __FILE__ ) . '/views/settings.php';
68
  }
9
 
10
  namespace WpMatomo\Admin;
11
 
12
+ use Piwik\Cache;
13
+ use Piwik\Option;
14
+ use Piwik\Plugins\SitesManager\API;
15
  use WpMatomo\Access;
16
  use WpMatomo\Settings;
17
 
20
  }
21
 
22
  class AdminSettings {
23
+ const TAB_TRACKING = 'tracking';
24
+ const TAB_ACCESS = 'access';
25
  const TAB_EXCLUSIONS = 'exlusions';
26
+ const TAB_PRIVACY = 'privacy';
27
  const TAB_GEOLOCATION = 'geolocation';
28
+ const TAB_ADVANCED = 'advanced';
29
 
30
  /**
31
  * @var Settings
37
  }
38
 
39
  public static function make_url( $tab ) {
40
+ global $_parent_pages;
41
+ $menu_slug = Menu::SLUG_SETTINGS;
42
+
43
+ if (is_multisite() && is_network_admin()) {
44
+ if ( isset( $_parent_pages[$menu_slug] ) ) {
45
+ $parent_slug = $_parent_pages[$menu_slug];
46
+ if ( $parent_slug && ! isset( $_parent_pages[$parent_slug] ) ) {
47
+ $url = network_admin_url( add_query_arg( 'page', $menu_slug, $parent_slug ) );
48
+ } else {
49
+ $url = network_admin_url( 'admin.php?page=' . $menu_slug );
50
+ }
51
+ } else {
52
+ $url = '';
53
+ }
54
+
55
+ $url = esc_url( $url );
56
+ } else {
57
+ $url = menu_page_url( $menu_slug, false );
58
+ }
59
+ return add_query_arg( array( 'tab' => $tab ), $url );
60
  }
61
 
62
  public function show() {
63
+ $access = new Access( $this->settings );
64
  $access_settings = new AccessSettings( $access, $this->settings );
65
+ $tracking = new TrackingSettings( $this->settings );
66
+ $exclusions = new ExclusionSettings( $this->settings );
67
+ $geolocation = new GeolocationSettings( $this->settings );
68
+ $privacy = new PrivacySettings( $this->settings );
69
+ $advanced = new AdvancedSettings( $this->settings );
70
+ $setting_tabs = array(
71
  self::TAB_TRACKING => $tracking,
72
+ self::TAB_ACCESS => $access_settings,
73
+ self::TAB_PRIVACY => $privacy,
74
  self::TAB_EXCLUSIONS => $exclusions,
75
  self::TAB_GEOLOCATION => $geolocation,
76
+ self::TAB_ADVANCED => $advanced,
77
  );
78
 
79
+ $active_tab = self::TAB_TRACKING;
80
+
81
+ if ($this->settings->is_network_enabled() && !is_network_admin()){
82
+ $active_tab = self::TAB_EXCLUSIONS;
83
+ $setting_tabs = array(
84
+ self::TAB_EXCLUSIONS => $exclusions,
85
+ self::TAB_PRIVACY => $privacy,
86
+ );
87
+ }
88
+
89
  $setting_tabs = apply_filters( 'matomo_setting_tabs', $setting_tabs, $this->settings );
90
 
91
  if ( ! empty( $_GET['tab'] ) && isset( $setting_tabs[ $_GET['tab'] ] ) ) {
92
  $active_tab = $_GET['tab'];
 
 
93
  }
94
 
95
  $content_tab = $setting_tabs[ $active_tab ];
96
+ $matomo_settings = $this->settings;
97
 
98
  include dirname( __FILE__ ) . '/views/settings.php';
99
  }
classes/WpMatomo/Admin/AdvancedSettings.php CHANGED
@@ -14,6 +14,7 @@ use Piwik\IP;
14
  use WpMatomo\Bootstrap;
15
  use WpMatomo\Capabilities;
16
  use WpMatomo\Settings;
 
17
 
18
  if ( ! defined( 'ABSPATH' ) ) {
19
  exit; // if accessed directly
@@ -40,11 +41,17 @@ class AdvancedSettings implements AdminSettingsInterface {
40
  */
41
  private $settings;
42
 
 
 
 
 
 
43
  /**
44
  * @param Settings $settings
45
  */
46
  public function __construct( $settings ) {
47
  $this->settings = $settings;
 
48
  }
49
 
50
  public function get_title() {
@@ -57,6 +64,7 @@ class AdvancedSettings implements AdminSettingsInterface {
57
  && is_admin()
58
  && check_admin_referer( self::NONCE_NAME )
59
  && $this->can_user_manage() ) {
 
60
  $this->apply_settings();
61
 
62
  return true;
@@ -70,25 +78,21 @@ class AdvancedSettings implements AdminSettingsInterface {
70
  }
71
 
72
  private function apply_settings() {
73
- if (!defined('MATOMO_REMOVE_ALL_DATA')) {
74
- $this->settings->apply_changes(array(
75
- Settings::DELETE_ALL_DATA_ON_UNINSTALL => !empty($_POST['matomo']['delete_all_data'])
76
- ));
77
- }
78
-
79
- Bootstrap::do_bootstrap();
80
- $config = Config::getInstance();
81
- $general = $config->General;
82
- $general['proxy_client_headers'] = array();
83
-
84
- if (!empty($_POST[ self::FORM_NAME ]['proxy_client_header'])) {
85
- $client_header = $_POST[ self::FORM_NAME ]['proxy_client_header'];
86
- if (in_array($client_header, self::$valid_host_headers, true)) {
87
- $general['proxy_client_headers'][] = $client_header;
88
- }
89
- }
90
- $config->General = $general;
91
- $config->forceSave();
92
 
93
  return true;
94
  }
@@ -96,14 +100,12 @@ class AdvancedSettings implements AdminSettingsInterface {
96
  public function show_settings() {
97
  $was_updated = $this->update_if_submitted();
98
 
99
- $matomo_client_headers = array();
100
- Bootstrap::do_bootstrap();
101
- $config = Config::getInstance();
102
- $general = $config->General;
103
- if (!empty($general['proxy_client_headers']) && is_array($general['proxy_client_headers'])) {
104
- $matomo_client_headers = $general['proxy_client_headers'];
105
  }
106
 
 
107
  $matomo_detected_ip = IP::getIpFromHeader();
108
  $matomo_delete_all_data = $this->settings->should_delete_all_data_on_uninstall();
109
 
14
  use WpMatomo\Bootstrap;
15
  use WpMatomo\Capabilities;
16
  use WpMatomo\Settings;
17
+ use WpMatomo\Site\Sync\SyncConfig as SiteConfigSync;
18
 
19
  if ( ! defined( 'ABSPATH' ) ) {
20
  exit; // if accessed directly
41
  */
42
  private $settings;
43
 
44
+ /**
45
+ * @var SiteConfigSync
46
+ */
47
+ private $site_config_sync;
48
+
49
  /**
50
  * @param Settings $settings
51
  */
52
  public function __construct( $settings ) {
53
  $this->settings = $settings;
54
+ $this->site_config_sync = new SiteConfigSync( $settings );
55
  }
56
 
57
  public function get_title() {
64
  && is_admin()
65
  && check_admin_referer( self::NONCE_NAME )
66
  && $this->can_user_manage() ) {
67
+
68
  $this->apply_settings();
69
 
70
  return true;
78
  }
79
 
80
  private function apply_settings() {
81
+ if (!defined('MATOMO_REMOVE_ALL_DATA')) {
82
+ $this->settings->apply_changes(array(
83
+ Settings::DELETE_ALL_DATA_ON_UNINSTALL => !empty($_POST['matomo']['delete_all_data'])
84
+ ));
85
+ }
86
+
87
+ $client_headers = [];
88
+ if (!empty($_POST[ self::FORM_NAME ]['proxy_client_header'])) {
89
+ $client_header = $_POST[ self::FORM_NAME ]['proxy_client_header'];
90
+ if (in_array($client_header, self::$valid_host_headers, true)) {
91
+ $client_headers[] = $client_header;
92
+ }
93
+ }
94
+
95
+ $this->site_config_sync->set_config_value('General', 'proxy_client_headers', $client_headers);
 
 
 
 
96
 
97
  return true;
98
  }
100
  public function show_settings() {
101
  $was_updated = $this->update_if_submitted();
102
 
103
+ $matomo_client_headers = $this->site_config_sync->get_config_value('General', 'proxy_client_headers');
104
+ if (empty($matomo_client_headers)) {
105
+ $matomo_client_headers = array();
 
 
 
106
  }
107
 
108
+ Bootstrap::do_bootstrap();
109
  $matomo_detected_ip = IP::getIpFromHeader();
110
  $matomo_delete_all_data = $this->settings->should_delete_all_data_on_uninstall();
111
 
classes/WpMatomo/Admin/Menu.php CHANGED
@@ -75,17 +75,19 @@ class Menu {
75
  add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' );
76
 
77
  if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) {
78
- add_submenu_page(
79
- self::$parent_slug,
80
- __( 'Get Started', 'matomo' ),
81
- __( 'Get Started', 'matomo' ),
82
- Capabilities::KEY_SUPERUSER,
83
- self::SLUG_GET_STARTED,
84
- array(
85
- $get_started,
86
- 'show',
87
- )
88
- );
 
 
89
  }
90
 
91
  if ( is_network_admin() ) {
@@ -142,11 +144,8 @@ class Menu {
142
 
143
  }
144
 
145
- // managing matomo only works when
146
- // * Network mode is enabled and then it works only in the network mode
147
- // * Network mode is not enabled then it works only for individual blogs as they manage it themselves
148
- $can_matomo_be_managed = ( $this->settings->is_network_enabled() && is_network_admin() )
149
- || ( ! $this->settings->is_network_enabled() && ! is_network_admin() );
150
 
151
  if ( $can_matomo_be_managed ) {
152
  add_submenu_page(
75
  add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' );
76
 
77
  if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) {
78
+ if (!is_multisite() || !is_network_admin()) {
79
+ add_submenu_page(
80
+ self::$parent_slug,
81
+ __( 'Get Started', 'matomo' ),
82
+ __( 'Get Started', 'matomo' ),
83
+ Capabilities::KEY_SUPERUSER,
84
+ self::SLUG_GET_STARTED,
85
+ array(
86
+ $get_started,
87
+ 'show',
88
+ )
89
+ );
90
+ }
91
  }
92
 
93
  if ( is_network_admin() ) {
144
 
145
  }
146
 
147
+ // we always show settings except when multi site is used, plugin is not network enabled, and we are in network admin
148
+ $can_matomo_be_managed = ( !is_multisite() || $this->settings->is_network_enabled() || !is_network_admin() );
 
 
 
149
 
150
  if ( $can_matomo_be_managed ) {
151
  add_submenu_page(
classes/WpMatomo/Admin/PrivacySettings.php CHANGED
@@ -9,6 +9,8 @@
9
 
10
  namespace WpMatomo\Admin;
11
 
 
 
12
  if ( ! defined( 'ABSPATH' ) ) {
13
  exit; // if accessed directly
14
  }
@@ -17,11 +19,22 @@ class PrivacySettings implements AdminSettingsInterface {
17
  const EXAMPLE_MINIMAL = '[matomo_opt_out]';
18
  const EXAMPLE_FULL = '[matomo_opt_out language=de background_color=red font_color=fff font_size=34 font_family=Arial width=500px height=100px]';
19
 
 
 
 
 
 
 
 
 
 
20
  public function get_title() {
21
  return esc_html__( 'Privacy & GDPR', 'matomo' );
22
  }
23
 
24
  public function show_settings() {
 
 
25
  include dirname( __FILE__ ) . '/views/privacy_gdpr.php';
26
  }
27
  }
9
 
10
  namespace WpMatomo\Admin;
11
 
12
+ use WpMatomo\Settings;
13
+
14
  if ( ! defined( 'ABSPATH' ) ) {
15
  exit; // if accessed directly
16
  }
19
  const EXAMPLE_MINIMAL = '[matomo_opt_out]';
20
  const EXAMPLE_FULL = '[matomo_opt_out language=de background_color=red font_color=fff font_size=34 font_family=Arial width=500px height=100px]';
21
 
22
+ /**
23
+ * @var Settings
24
+ */
25
+ private $settings;
26
+
27
+ public function __construct( Settings $settings ) {
28
+ $this->settings = $settings;
29
+ }
30
+
31
  public function get_title() {
32
  return esc_html__( 'Privacy & GDPR', 'matomo' );
33
  }
34
 
35
  public function show_settings() {
36
+ $matomo_settings = $this->settings;
37
+
38
  include dirname( __FILE__ ) . '/views/privacy_gdpr.php';
39
  }
40
  }
classes/WpMatomo/Admin/SystemReport.php CHANGED
@@ -13,8 +13,10 @@ use Piwik\CliMulti;
13
  use Piwik\Common;
14
  use Piwik\Config;
15
  use Piwik\Container\StaticContainer;
 
16
  use Piwik\Filesystem;
17
  use Piwik\MetricsFormatter;
 
18
  use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult;
19
  use Piwik\Plugins\Diagnostics\DiagnosticService;
20
  use Piwik\Plugins\UserCountry\LocationProvider;
@@ -83,6 +85,21 @@ class SystemReport {
83
  define('PIWIK_ARCHIVE_NO_TRUNCATE', 1); // when triggering it manually, we prefer the full error message
84
  }
85
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  try {
87
  $errors = $scheduled_tasks->archive( $force = true, $throw_exception = false );
88
  } catch (\Exception $e) {
13
  use Piwik\Common;
14
  use Piwik\Config;
15
  use Piwik\Container\StaticContainer;
16
+ use Piwik\Date;
17
  use Piwik\Filesystem;
18
  use Piwik\MetricsFormatter;
19
+ use Piwik\Plugins\CoreAdminHome\API;
20
  use Piwik\Plugins\Diagnostics\Diagnostic\DiagnosticResult;
21
  use Piwik\Plugins\Diagnostics\DiagnosticService;
22
  use Piwik\Plugins\UserCountry\LocationProvider;
85
  define('PIWIK_ARCHIVE_NO_TRUNCATE', 1); // when triggering it manually, we prefer the full error message
86
  }
87
 
88
+ try {
89
+ // force invalidation of archive to ensure it actually will rearchive the data
90
+ $site = new Site();
91
+ $idsite = $site->get_current_matomo_site_id();
92
+ if ($idsite) {
93
+ $timezone = \Piwik\Site::getTimezoneFor($idsite);
94
+ $now_string = \Piwik\Date::factory('now', $timezone)->toString();
95
+ foreach (array('day', 'week', 'month') as $period) {
96
+ API::getInstance()->invalidateArchivedReports($idsite, $now_string, $period, false, false);
97
+ }
98
+ }
99
+ } catch (\Exception $e) {
100
+ $this->logger->log_exception('archive_invalidate', $e);
101
+ }
102
+
103
  try {
104
  $errors = $scheduled_tasks->archive( $force = true, $throw_exception = false );
105
  } catch (\Exception $e) {
classes/WpMatomo/Admin/views/exclusion_settings.php CHANGED
@@ -34,6 +34,15 @@ if ( $was_updated ) {
34
  include 'update_notice_clear_cache.php';
35
  }
36
  ?>
 
 
 
 
 
 
 
 
 
37
  <form method="post">
38
  <?php wp_nonce_field( ExclusionSettings::NONCE_NAME ); ?>
39
 
@@ -55,6 +64,9 @@ if ( $was_updated ) {
55
  </td>
56
  <td width="50%">
57
  <?php echo sprintf( esc_html__( 'Choose users by user role you do %1$snot%2$s want to track.', 'matomo' ), '<strong>', '</strong>' ); ?>
 
 
 
58
  </td>
59
  </tr>
60
  <tr>
@@ -137,3 +149,5 @@ if ( $was_updated ) {
137
  </tbody>
138
  </table>
139
  </form>
 
 
34
  include 'update_notice_clear_cache.php';
35
  }
36
  ?>
37
+ <?php if ($settings->is_network_enabled() && is_network_admin()) { ?>
38
+ <h2>Exclusion settings</h2>
39
+ <p>
40
+ Exclusion settings have to be configured on a per blog basis.
41
+ Should you wish to change any setting, please go to the Matomo exclusion settings within each blog.
42
+ We are hoping to improve this in the future.
43
+ </p>
44
+ <?php } else { ?>
45
+
46
  <form method="post">
47
  <?php wp_nonce_field( ExclusionSettings::NONCE_NAME ); ?>
48
 
64
  </td>
65
  <td width="50%">
66
  <?php echo sprintf( esc_html__( 'Choose users by user role you do %1$snot%2$s want to track.', 'matomo' ), '<strong>', '</strong>' ); ?>
67
+ <?php if ($settings->is_network_enabled()) { ?>
68
+ <br><p><strong>This setting will be applied to all blogs. Changing it here also changes it for other blogs.</strong></p>
69
+ <?php } ?>
70
  </td>
71
  </tr>
72
  <tr>
149
  </tbody>
150
  </table>
151
  </form>
152
+
153
+ <?php } ?>
classes/WpMatomo/Admin/views/info_multisite.php CHANGED
@@ -22,13 +22,10 @@ if ( ! defined( 'ABSPATH' ) ) {
22
  <p><?php esc_html_e( 'In this mode, the tracking and access settings are managed in the network admin in one place and apply to all blogs.', 'matomo' ); ?>
23
  <?php esc_html_e( 'An administrator of a blog cannot view or change these settings.', 'matomo' ); ?>
24
  <br/><br/>
25
- <?php esc_html_e( 'The license code for any possible premium features is applied across blogs and can only be managed by a super admin.', 'matomo' ); ?>
26
  </p>
27
  <h2><?php esc_html_e( 'Matomo is not network enabled', 'matomo' ); ?></h2>
28
  <p><?php esc_html_e( 'In this mode, the tracking and access settings are managed by each individual blog. They cannot be managed in one central place for all blogs. An administrator or any user with the "Matomo super user" role can change these settings.', 'matomo' ); ?>
29
- <br/>
30
- <br/>
31
- <?php esc_html_e( 'The license code for any possible premium features is applied across blogs and can only be managed by a super admin.', 'matomo' ); ?>
32
  </p>
33
  <h2><?php esc_html_e( 'Managing many sites?', 'matomo' ); ?></h2>
34
  <p>
22
  <p><?php esc_html_e( 'In this mode, the tracking and access settings are managed in the network admin in one place and apply to all blogs.', 'matomo' ); ?>
23
  <?php esc_html_e( 'An administrator of a blog cannot view or change these settings.', 'matomo' ); ?>
24
  <br/><br/>
25
+ <?php esc_html_e( 'The privacy settings have to be configured per blog currently.', 'matomo' ); ?>
26
  </p>
27
  <h2><?php esc_html_e( 'Matomo is not network enabled', 'matomo' ); ?></h2>
28
  <p><?php esc_html_e( 'In this mode, the tracking and access settings are managed by each individual blog. They cannot be managed in one central place for all blogs. An administrator or any user with the "Matomo super user" role can change these settings.', 'matomo' ); ?>
 
 
 
29
  </p>
30
  <h2><?php esc_html_e( 'Managing many sites?', 'matomo' ); ?></h2>
31
  <p>
classes/WpMatomo/Admin/views/privacy_gdpr.php CHANGED
@@ -15,12 +15,7 @@ use WpMatomo\Admin\PrivacySettings;
15
  if ( ! defined( 'ABSPATH' ) ) {
16
  exit;
17
  }
18
- /** @var bool $was_updated */
19
- /** @var string $current_ip */
20
- /** @var string $excluded_ips */
21
- /** @var string $excluded_user_agents */
22
- /** @var string $excluded_query_params */
23
- /** @var bool|string|int $keep_url_fragments */
24
 
25
  ?>
26
 
@@ -40,6 +35,15 @@ if ( ! defined( 'ABSPATH' ) ) {
40
  );
41
  ?>
42
  </p>
 
 
 
 
 
 
 
 
 
43
  <h2>
44
  <?php esc_html_e( 'Ways Matomo protects the privacy of your users and customers', 'matomo' ); ?>
45
  </h2>
@@ -67,6 +71,7 @@ if ( ! defined( 'ABSPATH' ) ) {
67
  <a href="<?php echo Menu::get_matomo_goto_url( Menu::REPORTING_GOTO_GDPR_TOOLS ); ?>"><?php esc_html_e( 'GDPR tools', 'matomo' ); ?></a>
68
  </li>
69
  </ul>
 
70
  <h2>
71
  <?php esc_html_e( 'Let users opt-out of tracking', 'matomo' ); ?>
72
  </h2>
15
  if ( ! defined( 'ABSPATH' ) ) {
16
  exit;
17
  }
18
+ /** @var \WpMatomo\Settings $matomo_settings */
 
 
 
 
 
19
 
20
  ?>
21
 
35
  );
36
  ?>
37
  </p>
38
+ <?php if ($matomo_settings->is_network_enabled() && is_network_admin()) { ?>
39
+ <h2>Configure privacy settings</h2>
40
+ <p>
41
+ Currently, privacy settings have to be configured on a per blog basis.
42
+ IP addresses are anonmyised by default. Should you wish to change any privacy setting, please go to the Matomo privacy settings within each blog.
43
+ We are hoping to improve this in the future.
44
+ </p>
45
+ <?php } else { ?>
46
+
47
  <h2>
48
  <?php esc_html_e( 'Ways Matomo protects the privacy of your users and customers', 'matomo' ); ?>
49
  </h2>
71
  <a href="<?php echo Menu::get_matomo_goto_url( Menu::REPORTING_GOTO_GDPR_TOOLS ); ?>"><?php esc_html_e( 'GDPR tools', 'matomo' ); ?></a>
72
  </li>
73
  </ul>
74
+ <?php } ?>
75
  <h2>
76
  <?php esc_html_e( 'Let users opt-out of tracking', 'matomo' ); ?>
77
  </h2>
classes/WpMatomo/Admin/views/settings.php CHANGED
@@ -18,10 +18,21 @@ if ( ! defined( 'ABSPATH' ) ) {
18
  /** @var AdminSettingsInterface[] $setting_tabs */
19
  /** @var AdminSettingsInterface $content_tab */
20
  /** @var string $active_tab */
 
21
  ?>
22
  <div class="wrap">
23
  <div id="icon-plugins" class="icon32"></div>
24
  <h1><?php matomo_header_icon(); ?> <?php esc_html_e( 'Settings', 'matomo' ); ?></h1>
 
 
 
 
 
 
 
 
 
 
25
  <h2 class="nav-tab-wrapper">
26
  <?php foreach ( $setting_tabs as $matomo_setting_slug => $matomo_setting_tab ) { ?>
27
  <a href="<?php echo AdminSettings::make_url( $matomo_setting_slug ); ?>"
18
  /** @var AdminSettingsInterface[] $setting_tabs */
19
  /** @var AdminSettingsInterface $content_tab */
20
  /** @var string $active_tab */
21
+ /** @var \WpMatomo\Settings $matomo_settings */
22
  ?>
23
  <div class="wrap">
24
  <div id="icon-plugins" class="icon32"></div>
25
  <h1><?php matomo_header_icon(); ?> <?php esc_html_e( 'Settings', 'matomo' ); ?></h1>
26
+ <?php
27
+ if ( $matomo_settings->is_network_enabled() && is_network_admin() ) {
28
+ echo '<div class="notice notice-info is-dismissible"><br>You are running Matomo in network mode. This means below settings will be applied to all blogs in your network.<br><br></div>';
29
+ } elseif ($matomo_settings->is_network_enabled() && !is_network_admin()) {
30
+ echo '<div class="notice notice-info is-dismissible"><br>';
31
+ esc_html_e('You are running Matomo in network mode.', 'matomo');
32
+ echo ' ';
33
+ echo 'Below settings aren\'t applied for all blogs but have to be configured for each blog separately. We are hoping to improve this in the future. Any setting within the Matomo admin is configured on a per blog basis as well. Only you as a Matomo super user can see these settings.<br><br></div>';
34
+ }
35
+ ?>
36
  <h2 class="nav-tab-wrapper">
37
  <?php foreach ( $setting_tabs as $matomo_setting_slug => $matomo_setting_tab ) { ?>
38
  <a href="<?php echo AdminSettings::make_url( $matomo_setting_slug ); ?>"
classes/WpMatomo/Admin/views/tracking.php CHANGED
@@ -35,12 +35,7 @@ if ( $was_updated ) {
35
  <form method="post">
36
  <?php wp_nonce_field( TrackingSettings::NONCE_NAME ); ?>
37
  <p>
38
- <?php esc_html_e( 'Configure the tracking to your liking.', 'matomo' );
39
- if ( $settings->is_network_enabled() ) {
40
- echo ' ';
41
- esc_html_e( 'These settings will be applied to all blogs in your network.', 'matomo' );
42
- }
43
- ?>
44
  </p>
45
  <table class="matomo-tracking-form widefat">
46
  <tbody>
35
  <form method="post">
36
  <?php wp_nonce_field( TrackingSettings::NONCE_NAME ); ?>
37
  <p>
38
+ <?php esc_html_e( 'Configure the tracking to your liking.', 'matomo' );?>
 
 
 
 
 
39
  </p>
40
  <table class="matomo-tracking-form widefat">
41
  <tbody>
classes/WpMatomo/Settings.php CHANGED
@@ -31,6 +31,7 @@ class Settings {
31
  const OPTION_LAST_TRACKING_CODE_UPDATE = 'last_tracking_code_update';
32
  const SHOW_GET_STARTED_PAGE = 'show_get_started_page';
33
  const DELETE_ALL_DATA_ON_UNINSTALL = 'delete_all_data_uninstall';
 
34
 
35
  public static $is_doing_action_tracking_related = false;
36
 
@@ -53,6 +54,7 @@ class Settings {
53
  self::OPTION_LAST_TRACKING_SETTINGS_CHANGE => 0,
54
  self::OPTION_KEY_STEALTH => array(),
55
  self::OPTION_KEY_CAPS_ACCESS => array(),
 
56
  self::DELETE_ALL_DATA_ON_UNINSTALL => true,
57
  // User settings: Stats configuration
58
  // User settings: Tracking configuration
31
  const OPTION_LAST_TRACKING_CODE_UPDATE = 'last_tracking_code_update';
32
  const SHOW_GET_STARTED_PAGE = 'show_get_started_page';
33
  const DELETE_ALL_DATA_ON_UNINSTALL = 'delete_all_data_uninstall';
34
+ const NETWORK_CONFIG_OPTIONS = 'config_options';
35
 
36
  public static $is_doing_action_tracking_related = false;
37
 
54
  self::OPTION_LAST_TRACKING_SETTINGS_CHANGE => 0,
55
  self::OPTION_KEY_STEALTH => array(),
56
  self::OPTION_KEY_CAPS_ACCESS => array(),
57
+ self::NETWORK_CONFIG_OPTIONS => array(),
58
  self::DELETE_ALL_DATA_ON_UNINSTALL => true,
59
  // User settings: Stats configuration
60
  // User settings: Tracking configuration
classes/WpMatomo/Site/Sync.php CHANGED
@@ -18,6 +18,7 @@ use WpMatomo\Installer;
18
  use WpMatomo\Logger;
19
  use WpMatomo\Settings;
20
  use WpMatomo\Site;
 
21
 
22
  if ( ! defined( 'ABSPATH' ) ) {
23
  exit; // if accessed directly
@@ -36,9 +37,15 @@ class Sync {
36
  */
37
  private $settings;
38
 
 
 
 
 
 
39
  public function __construct( Settings $settings ) {
40
  $this->logger = new Logger();
41
  $this->settings = $settings;
 
42
  }
43
 
44
  public function register_hooks() {
@@ -76,6 +83,7 @@ class Sync {
76
  continue;
77
  }
78
  }
 
79
  $success = $this->sync_site( $site->blog_id, $site->blogname, $site->siteurl );
80
  } catch ( \Exception $e ) {
81
  $success = false;
@@ -110,24 +118,35 @@ class Sync {
110
  $blog_name = substr( $blog_name, 0, self::MAX_LENGTH_SITE_NAME );
111
  }
112
 
 
 
 
113
  if ( ! empty( $idsite ) ) {
114
- // todo only update site when name or URL (or maybe also when timezone)changes!
115
  $this->logger->log( 'Matomo site is known for blog (' . $idsite . ')... will update' );
116
 
117
- /** @var \WP_Site $site */
118
- $params = array(
119
- 'name' => $blog_name,
120
- 'main_url' => $blog_url,
121
- 'ecommerce' => (int) $this->settings->get_global_option( 'track_ecommerce' ),
122
- 'timezone' => $this->detect_timezone(),
123
- );
124
- $sites_manager_model = new Model();
125
- $sites_manager_model->updateSite( $params, $idsite );
 
 
 
 
 
 
126
 
127
- do_action( 'matomo_site_synced', $idsite, $blog_id );
128
 
129
- // no actual setting changed but we make sure the tracking code will be updated after an update
130
- $this->settings->apply_tracking_related_changes( array() );
 
 
 
131
 
132
  return true;
133
  }
@@ -135,20 +154,17 @@ class Sync {
135
  $this->logger->log( 'Matomo site is not known for blog... will create site' );
136
 
137
  /** @var \WP_Site $site */
138
- $timezone = $this->detect_timezone();
139
  $idsite = null;
140
 
141
  $this->set_enable_sites_admin( 1 );
142
 
143
- $track_ecommerce = (int) $this->settings->get_global_option( 'track_ecommerce' );
144
-
145
  Access::doAsSuperUser(
146
- function () use ( $blog_name, $blog_url, $timezone, $track_ecommerce, &$idsite ) {
147
  SitesManager\API::unsetInstance();
148
  // we need to unset the instance to make sure it fetches the
149
  // up to date dependencies eg current plugin manager etc
150
 
151
- $idsite = SitesManager\API::getInstance()->addSite(
152
  $blog_name,
153
  array( $blog_url ),
154
  $track_ecommerce,
@@ -157,7 +173,7 @@ class Sync {
157
  $search_category_parameters = null,
158
  $excluded_ips = null,
159
  $excluded_query_parameters = null,
160
- $timezone
161
  );
162
  }
163
  );
@@ -173,6 +189,8 @@ class Sync {
173
  return false;
174
  }
175
 
 
 
176
  do_action( 'matomo_site_synced', $idsite, $blog_id );
177
 
178
  return true;
18
  use WpMatomo\Logger;
19
  use WpMatomo\Settings;
20
  use WpMatomo\Site;
21
+ use WpMatomo\Site\Sync\SyncConfig;
22
 
23
  if ( ! defined( 'ABSPATH' ) ) {
24
  exit; // if accessed directly
37
  */
38
  private $settings;
39
 
40
+ /**
41
+ * @var SyncConfig
42
+ */
43
+ private $config_sync;
44
+
45
  public function __construct( Settings $settings ) {
46
  $this->logger = new Logger();
47
  $this->settings = $settings;
48
+ $this->config_sync = new SyncConfig( $settings );
49
  }
50
 
51
  public function register_hooks() {
83
  continue;
84
  }
85
  }
86
+
87
  $success = $this->sync_site( $site->blog_id, $site->blogname, $site->siteurl );
88
  } catch ( \Exception $e ) {
89
  $success = false;
118
  $blog_name = substr( $blog_name, 0, self::MAX_LENGTH_SITE_NAME );
119
  }
120
 
121
+ $track_ecommerce = (int) $this->settings->get_global_option( 'track_ecommerce' );
122
+ $detected_timezone = $this->detect_timezone();
123
+
124
  if ( ! empty( $idsite ) ) {
 
125
  $this->logger->log( 'Matomo site is known for blog (' . $idsite . ')... will update' );
126
 
127
+ $sites_manager_model = new Model();
128
+ $site = $sites_manager_model->getSiteFromId($idsite);
129
+ if ($site['name'] != $blog_name
130
+ || $site['main_url'] != $blog_url
131
+ || $site['ecommerce'] != $track_ecommerce
132
+ || $site['timezone'] != $detected_timezone) {
133
+
134
+ /** @var \WP_Site $site */
135
+ $params = array(
136
+ 'name' => $blog_name,
137
+ 'main_url' => $blog_url,
138
+ 'ecommerce' => $track_ecommerce,
139
+ 'timezone' => $detected_timezone,
140
+ );
141
+ $sites_manager_model->updateSite( $params, $idsite );
142
 
143
+ do_action( 'matomo_site_synced', $idsite, $blog_id );
144
 
145
+ // no actual setting changed but we make sure the tracking code will be updated after an update
146
+ $this->settings->apply_tracking_related_changes( array() );
147
+ }
148
+
149
+ $this->config_sync->sync_config_for_current_site();
150
 
151
  return true;
152
  }
154
  $this->logger->log( 'Matomo site is not known for blog... will create site' );
155
 
156
  /** @var \WP_Site $site */
 
157
  $idsite = null;
158
 
159
  $this->set_enable_sites_admin( 1 );
160
 
 
 
161
  Access::doAsSuperUser(
162
+ function () use ( $blog_name, $blog_url, $detected_timezone, $track_ecommerce, &$idsite ) {
163
  SitesManager\API::unsetInstance();
164
  // we need to unset the instance to make sure it fetches the
165
  // up to date dependencies eg current plugin manager etc
166
 
167
+ $idsite = SitesManager\API::getInstance()->addSite(
168
  $blog_name,
169
  array( $blog_url ),
170
  $track_ecommerce,
173
  $search_category_parameters = null,
174
  $excluded_ips = null,
175
  $excluded_query_parameters = null,
176
+ $detected_timezone
177
  );
178
  }
179
  );
189
  return false;
190
  }
191
 
192
+ $this->config_sync->sync_config_for_current_site();
193
+
194
  do_action( 'matomo_site_synced', $idsite, $blog_id );
195
 
196
  return true;
classes/WpMatomo/Site/Sync/SyncConfig.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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\Site\Sync;
11
+
12
+ use Piwik\Config as PiwikConfig;
13
+ use WpMatomo\Bootstrap;
14
+ use WpMatomo\Logger;
15
+ use WpMatomo\ScheduledTasks;
16
+ use WpMatomo\Settings;
17
+
18
+ if ( ! defined( 'ABSPATH' ) ) {
19
+ exit; // if accessed directly
20
+ }
21
+
22
+ class SyncConfig
23
+ {
24
+ /**
25
+ * @var Logger
26
+ */
27
+ private $logger;
28
+
29
+ /**
30
+ * @var Settings
31
+ */
32
+ private $settings;
33
+
34
+ public function __construct(Settings $settings)
35
+ {
36
+ $this->logger = new Logger();
37
+ $this->settings = $settings;
38
+ }
39
+
40
+ public function sync_config_for_current_site()
41
+ {
42
+ if ($this->settings->is_network_enabled()) {
43
+ $config = PiwikConfig::getInstance();
44
+ $has_change = false;
45
+ foreach ($this->get_all() as $category => $keys) {
46
+ $cat = $config->{$category};
47
+ if (empty($cat)) {
48
+ $cat = array();
49
+ }
50
+
51
+ if (empty($keys) && !empty($cat)) {
52
+ // need to unset all values
53
+ $has_change = true;
54
+ $config->{$category} = array();
55
+ }
56
+
57
+ if (!empty($keys)) {
58
+ foreach ($keys as $key => $value) {
59
+ if (!isset($cat[$key]) || $cat[$key] != $value) {
60
+ $has_change = true;
61
+ $cat[$key] = $value;
62
+ $config->{$category} = $cat;
63
+ }
64
+ }
65
+ }
66
+ }
67
+ if ($has_change) {
68
+ $config->forceSave();
69
+ }
70
+ }
71
+ }
72
+
73
+ private function get_all()
74
+ {
75
+ $options = $this->settings->get_global_option(Settings::NETWORK_CONFIG_OPTIONS);
76
+
77
+ if (empty($options) || !is_array($options)) {
78
+ $options = array();
79
+ }
80
+
81
+ return $options;
82
+ }
83
+
84
+ public function get_config_value($group, $key)
85
+ {
86
+ if ($this->settings->is_network_enabled()) {
87
+ $config = $this->get_all();
88
+ if (isset($config[$group][$key])) {
89
+ return $config[$group][$key];
90
+ }
91
+ } else {
92
+ Bootstrap::do_bootstrap();
93
+ $config = PiwikConfig::getInstance();
94
+ $the_group = $config->{$group};
95
+ if (!empty($the_group) && isset($the_group[$key])) {
96
+ return $the_group[$key];
97
+ }
98
+ }
99
+ }
100
+
101
+ public function set_config_value($group, $key, $value)
102
+ {
103
+ if ($this->settings->is_network_enabled()) {
104
+ $config = $this->get_all();
105
+
106
+ if (!isset($config[$group])) {
107
+ $config[$group] = array();
108
+ }
109
+ $config[$group][$key] = $value;
110
+
111
+ $this->settings->apply_changes(array(
112
+ Settings::NETWORK_CONFIG_OPTIONS => $config
113
+ ));
114
+ // need to update all config files
115
+ wp_schedule_single_event( time() + 5, ScheduledTasks::EVENT_SYNC );
116
+
117
+ } else {
118
+ Bootstrap::do_bootstrap();
119
+ $config = PiwikConfig::getInstance();
120
+ $the_group = $config->{$group};
121
+ if (empty($the_group)) {
122
+ $the_group = array();
123
+ }
124
+ $the_group[$key] = $value;
125
+ $config->{$group} = $the_group;
126
+ $config->forceSave();
127
+ }
128
+ }
129
+
130
+ }
config/common.config.ini.php CHANGED
@@ -19,9 +19,9 @@ enable_sql_optimize_queries = 0
19
  enable_general_settings_admin = 0
20
  enable_browser_archiving_triggering = 0
21
  time_before_today_archive_considered_outdated = 1800
22
- time_before_week_archive_considered_outdated = 3600
23
- time_before_month_archive_considered_outdated = 3600
24
- time_before_year_archive_considered_outdated = 3600
25
  time_before_range_archive_considered_outdated = 3600
26
  enable_load_data_infile = 0
27
  enable_tracking_failures_notification = 0
@@ -53,4 +53,4 @@ allowedRetriesTimeRange = 60
53
  showInEmbeddedWidgets = 0
54
 
55
  [TagManager]
56
- environments[] = 'live'
19
  enable_general_settings_admin = 0
20
  enable_browser_archiving_triggering = 0
21
  time_before_today_archive_considered_outdated = 1800
22
+ time_before_week_archive_considered_outdated = 3500
23
+ time_before_month_archive_considered_outdated = 7100
24
+ time_before_year_archive_considered_outdated = 14300
25
  time_before_range_archive_considered_outdated = 3600
26
  enable_load_data_infile = 0
27
  enable_tracking_failures_notification = 0
53
  showInEmbeddedWidgets = 0
54
 
55
  [TagManager]
56
+ environments[] = 'live'
config/config.php CHANGED
@@ -4,6 +4,10 @@ if (!defined( 'ABSPATH')) {
4
  exit; // if accessed directly
5
  }
6
 
 
 
 
 
7
  use WpMatomo\Capabilities;
8
  use WpMatomo\Paths;
9
  use WpMatomo\Settings;
@@ -75,13 +79,24 @@ return array(
75
  }
76
  $previous->General = $general;
77
 
78
- add_action('switch_blog', function ($new_blog) {
79
- global $wpdb;
80
- $config = \Piwik\Config::getInstance();
81
- $database = $config->database;
82
- $database['tables_prefix'] = $wpdb->prefix . MATOMO_DATABASE_PREFIX;
83
- $config->database = $database;
84
- });
 
 
 
 
 
 
 
 
 
 
 
85
  }
86
 
87
  return $previous;
4
  exit; // if accessed directly
5
  }
6
 
7
+ use Piwik\Cache;
8
+ use Piwik\Container\StaticContainer;
9
+ use Piwik\Option;
10
+ use Piwik\Plugin\API;
11
  use WpMatomo\Capabilities;
12
  use WpMatomo\Paths;
13
  use WpMatomo\Settings;
79
  }
80
  $previous->General = $general;
81
 
82
+ if (empty($GLOBALS['MATOMO_SWITCH_BLOG_SET_UP'])) {
83
+ // only execute it once since we might init this several times...
84
+ $GLOBALS['MATOMO_SWITCH_BLOG_SET_UP'] = true;
85
+
86
+ add_action('switch_blog', function ($new_blog, $prev_blog) {
87
+ if ($new_blog == $prev_blog) {
88
+ return;
89
+ }
90
+ // ensure correct path to config is set, ensure to update tables_prefix etc.
91
+ $container = StaticContainer::getContainer();
92
+ $container->set(\Piwik\Application\Kernel\GlobalSettingsProvider::class, $container->make(\Piwik\Application\Kernel\GlobalSettingsProvider::class));
93
+ $container->set(\Piwik\Config::class, $container->make(\Piwik\Config::class));
94
+ Option::clearCache();
95
+ \Piwik\Site::clearCache();
96
+ Cache::getTransientCache()->flushAll();
97
+ API::unsetAllInstances();
98
+ }, 10, 2);
99
+ }
100
  }
101
 
102
  return $previous;
matomo.php CHANGED
@@ -4,7 +4,7 @@
4
  * Description: The #1 Google Analytics alternative that gives you full control over your data and protects the privacy for your users. Free, secure and open.
5
  * Author: Matomo
6
  * Author URI: https://matomo.org
7
- * Version: 1.1.0
8
  * Domain Path: /languages
9
  * WC requires at least: 2.4.0
10
  * WC tested up to: 4.0.0
4
  * Description: The #1 Google Analytics alternative that gives you full control over your data and protects the privacy for your users. Free, secure and open.
5
  * Author: Matomo
6
  * Author URI: https://matomo.org
7
+ * Version: 1.1.1
8
  * Domain Path: /languages
9
  * WC requires at least: 2.4.0
10
  * WC tested up to: 4.0.0
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: matomo,piwik,analytics,statistics,stats,tracking,ecommerce
5
  Requires at least: 4.8
6
  Tested up to: 5.4
7
- Stable tag: 1.1.0
8
  Requires PHP: 7.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
4
  Tags: matomo,piwik,analytics,statistics,stats,tracking,ecommerce
5
  Requires at least: 4.8
6
  Tested up to: 5.4
7
+ Stable tag: 1.1.1
8
  Requires PHP: 7.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html