PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.2
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 / matomo.php
matomo Last commit date
app 2 years ago assets 2 years ago classes 2 years ago config 2 years ago languages 6 years ago node_modules 4 years ago plugins 2 years ago .htaccess 6 years ago LEGALNOTICE 2 years ago LICENSE 6 years ago matomo.php 2 years ago readme.txt 2 years ago shared.php 3 years ago uninstall.php 6 years ago wdio.conf.tracking.ts 2 years ago
matomo.php
232 lines
1 <?php
2 /**
3 * Plugin Name: Matomo Analytics - Ethical Stats. Powerful Insights.
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: 5.0.2
8 * Domain Path: /languages
9 * WC requires at least: 2.4.0
10 * WC tested up to: 8.5.2
11 *
12 * Matomo - free/libre analytics platform
13 *
14 * @link https://matomo.org
15 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
16 * @package matomo
17 * phpcs:disable WordPress.Security.ValidatedSanitizedInput
18 * phpcs:disable WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound
19 * phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
20 */
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit; // if accessed directly
23 }
24
25 load_plugin_textdomain( 'matomo', false, basename( dirname( __FILE__ ) ) . '/languages' );
26
27 if ( ! defined( 'MATOMO_ANALYTICS_FILE' ) ) {
28 define( 'MATOMO_ANALYTICS_FILE', __FILE__ );
29 }
30
31 if ( ! defined( 'MATOMO_MARKETPLACE_PLUGIN_NAME' ) ) {
32 define( 'MATOMO_MARKETPLACE_PLUGIN_NAME', 'matomo-marketplace-for-wordpress/matomo-marketplace-for-wordpress.php' );
33 }
34
35 $GLOBALS['MATOMO_PLUGINS_ENABLED'] = array();
36
37 /** MATOMO_PLUGIN_FILES => used to check for updates etc */
38 $GLOBALS['MATOMO_PLUGIN_FILES'] = array( MATOMO_ANALYTICS_FILE );
39
40 function matomo_has_compatible_content_dir() {
41 if ( ! empty( $_SERVER['MATOMO_WP_ROOT_PATH'] )
42 && file_exists( rtrim( $_SERVER['MATOMO_WP_ROOT_PATH'], '/' ) . '/wp-load.php' ) ) {
43 return true;
44 }
45
46 if ( ! defined( 'WP_CONTENT_DIR' ) ) {
47 return false;
48 }
49
50 $content_dir = rtrim( rtrim( WP_CONTENT_DIR, '/' ), DIRECTORY_SEPARATOR );
51 $content_dir = wp_normalize_path( $content_dir );
52 $abs_path = wp_normalize_path( ABSPATH );
53
54 $abs_paths = array(
55 $abs_path . 'wp-content',
56 $abs_path . '/wp-content',
57 $abs_path . DIRECTORY_SEPARATOR . 'wp-content',
58 );
59
60 if ( in_array( $content_dir, $abs_paths, true ) ) {
61 return true;
62 }
63
64 $wpload_base = '../../../wp-load.php';
65 $wpload_full = dirname( __FILE__ ) . '/' . $wpload_base;
66 if ( file_exists( $wpload_full ) && is_readable( $wpload_full ) ) {
67 return true;
68 } elseif ( realpath( $wpload_full ) && file_exists( realpath( $wpload_full ) ) && is_readable( realpath( $wpload_full ) ) ) {
69 return true;
70 } elseif ( ! empty( $_SERVER['SCRIPT_FILENAME'] ) && file_exists( $_SERVER['SCRIPT_FILENAME'] ) ) {
71 // seems symlinked... eg the wp-content dir or wp-content/plugins dir is symlinked from some very much other place...
72 $wpload_full = dirname( $_SERVER['SCRIPT_FILENAME'] ) . '/' . $wpload_base;
73 if ( file_exists( $wpload_full ) ) {
74 return true;
75 } elseif ( realpath( $wpload_full ) && file_exists( realpath( $wpload_full ) ) ) {
76 return true;
77 } elseif ( file_exists( dirname( $_SERVER['SCRIPT_FILENAME'] ) ) . '/wp-load.php' ) {
78 return true;
79 }
80 }
81
82 // look in plugins directory if there is a config file for us
83 $wpload_config = dirname( __FILE__ ) . '/../matomo.wpload_dir.php';
84 if ( file_exists( $wpload_config ) && is_readable( $wpload_config ) ) {
85 // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
86 $content = @file_get_contents( $wpload_config ); // we do not include that file for security reasons
87 if ( ! empty( $content ) ) {
88 $content = str_replace( array( '<?php', 'exit;' ), '', $content );
89 $content = preg_replace( '/\s/', '', $content );
90 $content = trim( ltrim( trim( $content ), '#' ) ); // the path may be commented out # /abs/path
91 if ( strpos( $content, DIRECTORY_SEPARATOR ) === 0 ) {
92 $wpload_file = rtrim( $content, DIRECTORY_SEPARATOR ) . '/wp-load.php';
93 return file_exists( $wpload_file ) && is_readable( $wpload_file );
94 }
95 }
96 }
97
98 return false;
99 }
100
101 function matomo_header_icon( $full = false ) {
102 $file = 'logo';
103 if ( $full ) {
104 $file = 'logo-full';
105 }
106 echo '<img height="32" src="' . esc_url( plugins_url( 'assets/img/' . $file . '.png', MATOMO_ANALYTICS_FILE ) ) . '" class="matomo-header-icon">';
107 }
108
109 function matomo_is_app_request() {
110 return ! empty( $_SERVER['SCRIPT_NAME'] )
111 && ( substr( $_SERVER['SCRIPT_NAME'], - 1 * strlen( 'matomo/app/index.php' ) ) === 'matomo/app/index.php' );
112 }
113
114 function matomo_has_tag_manager() {
115 if ( defined( 'MATOMO_ENABLE_TAG_MANAGER' ) ) {
116 return ! empty( MATOMO_ENABLE_TAG_MANAGER );
117 }
118
119 $is_multisite = function_exists( 'is_multisite' ) && is_multisite();
120 if ( $is_multisite ) {
121 return false;
122 }
123
124 return true;
125 }
126
127 function matomo_anonymize_value( $value ) {
128 if ( is_string( $value ) && ! empty( $value ) ) {
129 $values_to_anonymize = array(
130 ABSPATH => '$abs_path/',
131 str_replace( '/', '\/', ABSPATH ) => '$abs_path\/',
132 str_replace( '/', '\\', ABSPATH ) => '$abs_path\/',
133 WP_CONTENT_DIR => '$WP_CONTENT_DIR/',
134 str_replace( '/', '\\', WP_CONTENT_DIR ) => '$WP_CONTENT_DIR\\',
135 home_url() => '$home_url',
136 site_url() => '$site_url',
137 DB_PASSWORD => '$DB_PASSWORD',
138 DB_USER => '$DB_USER',
139 DB_HOST => '$DB_HOST',
140 DB_NAME => '$DB_NAME',
141 );
142 $keys = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'AUTH_SALT', 'NONCE_KEY', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT' );
143 foreach ( $keys as $key ) {
144 if ( defined( $key ) ) {
145 $const_value = constant( $key );
146 if ( ! empty( $const_value ) && is_string( $const_value ) && strlen( $key ) > 3 ) {
147 $values_to_anonymize[ $const_value ] = '$' . $key;
148 }
149 }
150 }
151 foreach ( $values_to_anonymize as $search => $replace ) {
152 if ( $search ) {
153 $value = str_replace( $search, $replace, $value );
154 }
155 }
156 // replace anything like token_auth etc or md5 or sha1 ...
157 $value = preg_replace( '/[[:xdigit:]]{31,80}/', 'TOKEN_REPLACED', $value );
158 }
159
160 return $value;
161 }
162
163 $GLOBALS['MATOMO_MARKETPLACE_PLUGINS'] = array();
164
165 function matomo_rel_path( $to_dir, $from_dir ) {
166 $to_dir_parts = array_values( array_filter( explode( DIRECTORY_SEPARATOR, $to_dir ) ) );
167 $from_dir_parts = array_values( array_filter( explode( DIRECTORY_SEPARATOR, $from_dir ) ) );
168
169 $to_index = 0;
170 $from_index = 0;
171
172 $to_dir_segment_count = count( $to_dir_parts );
173 $from_dir_segment_count = count( $from_dir_parts );
174
175 // skip over common parts of $to_dir and $from_dir
176 for ( ; $to_index < $to_dir_segment_count && $from_index < $from_dir_segment_count && $to_dir_parts[ $to_index ] === $from_dir_parts[ $from_index ]; ++$to_index, ++$from_index );
177
178 // ascend from $to_dir to common root it has with $from_dir
179 $relative_path = str_repeat( '..' . DIRECTORY_SEPARATOR, count( $from_dir_parts ) - $from_index );
180
181 // descend from common root to target in rest of $to_dir
182 $rest = array_slice( $to_dir_parts, $to_index );
183 if ( ! empty( $rest ) ) {
184 $relative_path = $relative_path . implode( DIRECTORY_SEPARATOR, $rest );
185 }
186
187 return $relative_path;
188 }
189
190 function matomo_add_plugin( $plugins_directory, $wp_plugin_file, $is_marketplace_plugin = false ) {
191 if ( ! in_array( $wp_plugin_file, $GLOBALS['MATOMO_PLUGIN_FILES'], true ) ) {
192 $GLOBALS['MATOMO_PLUGIN_FILES'][] = $wp_plugin_file;
193 }
194
195 if ( empty( $GLOBALS['MATOMO_PLUGIN_DIRS'] ) ) {
196 $GLOBALS['MATOMO_PLUGIN_DIRS'] = array();
197 }
198
199 if ( $is_marketplace_plugin && dirname( $wp_plugin_file ) === $plugins_directory ) {
200 $GLOBALS['MATOMO_MARKETPLACE_PLUGINS'][] = $wp_plugin_file;
201 }
202
203 $GLOBALS['MATOMO_PLUGINS_ENABLED'][] = basename( $plugins_directory );
204 $root_dir = dirname( $plugins_directory );
205 foreach ( $GLOBALS['MATOMO_PLUGIN_DIRS'] as $path ) {
206 if ( $path['pluginsPathAbsolute'] === $root_dir ) {
207 return; // already added
208 }
209 }
210
211 $matomo_dir = __DIR__ . DIRECTORY_SEPARATOR . 'app';
212 $webroot_dir = matomo_rel_path( $root_dir, $matomo_dir );
213
214 $GLOBALS['MATOMO_PLUGIN_DIRS'][] = array(
215 'pluginsPathAbsolute' => $root_dir,
216 'webrootDirRelativeToMatomo' => $webroot_dir,
217 );
218 }
219
220 if ( matomo_is_app_request() || ! empty( $GLOBALS['MATOMO_LOADED_DIRECTLY'] ) ) {
221 // prevent layout being broken when thegem theme is used. their lazy items class causes the reporting UI to not appear
222 // because it creates a JS error because of escaping " too often. only breaks when " Activate image loading optimization (for desktops)"
223 // is enabled in the general theme settings
224 add_filter( 'thegem_lazy_items_need_process_content', '__return_false', 99999999, $args = 0 );
225 }
226
227 require_once __DIR__ . DIRECTORY_SEPARATOR . 'classes' . DIRECTORY_SEPARATOR . 'WpMatomo.php';
228 require 'shared.php';
229 matomo_add_plugin( __DIR__ . '/plugins/WordPress', MATOMO_ANALYTICS_FILE );
230
231 new WpMatomo();
232