PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.13.2
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.13.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 / app / bootstrap.php
matomo / app Last commit date
config 3 years ago core 3 years ago js 3 years ago lang 3 years ago libs 3 years ago node_modules 3 years ago plugins 3 years ago vendor 3 years ago .htaccess 6 years ago DIObject.php 5 years ago LEGALNOTICE 4 years ago LICENSE 6 years ago LegacyAutoloader.php 5 years ago PRIVACY.md 5 years ago README.md 4 years ago SECURITY.md 5 years ago bootstrap.php 4 years ago console 6 years ago favicon.ico 6 years ago index.php 5 years ago matomo.js 3 years ago matomo.php 5 years ago offline-service-worker.js 5 years ago piwik.js 3 years ago piwik.php 5 years ago robots.txt 5 years ago
bootstrap.php
253 lines
1 <?php
2
3 $GLOBALS['CONFIG_INI_PATH_RESOLVER'] = function () {
4 if ( defined( 'ABSPATH' )
5 && defined( 'MATOMO_CONFIG_PATH' ) ) {
6 $paths = new \WpMatomo\Paths();
7
8 return $paths->get_config_ini_path();
9 }
10 };
11
12 $matomo_is_archive_request = !empty($_SERVER['argv'])
13 && is_array($_SERVER['argv'])
14 && in_array('climulti:request', $_SERVER['argv'], true);
15
16 if ( ! defined( 'PIWIK_ENABLE_ERROR_HANDLER' ) ) {
17 // we prefer using WP error handler... unless we are archiving where we want to prevent any warnings being printed
18 // as otherwise the archiving would be marked as failed because the cli archive output would contain a warning and
19 // the output would not be possible to do an unserialize anymore
20 if (!$matomo_is_archive_request) {
21 define( 'PIWIK_ENABLE_ERROR_HANDLER', false );
22 }
23 }
24
25 $GLOBALS['MATOMO_LOADED_DIRECTLY'] = ! defined( 'ABSPATH' );
26
27 if (!function_exists('matomo_ch_dir')) {
28 function matomo_ch_dir($file) {
29 if (function_exists('chdir') && is_dir(dirname($file))) {
30 @chdir(dirname($file));
31 }
32 }
33 }
34
35 if (!function_exists('matomo_log_message_no_display')) {
36 function matomo_log_message_no_display($message)
37 {
38 $message = 'Matomo ' . $message;
39
40 if ( defined( 'WP_DEBUG' ) && WP_DEBUG === true ) {
41 if (function_exists('ini_set') && function_exists('ini_get')) {
42 $value_orig = @ini_get('display_errors');
43 $value = @ini_set('display_errors', 'Off');
44 if (false !== $value) {
45 error_log( $message );
46 }
47 @ini_set('display_errors', $value_orig);
48 }
49 }
50
51 if (function_exists('update_option')
52 && class_exists('\WpMatomo\Logger')) {
53 // only if WordPress was bootstrapped by now... otherwise it will fail
54 try {
55 $logger = new \WpMatomo\Logger();
56 $logger->log_exception('archive_boot', new Exception($message));
57 } catch (Exception $e) {
58
59 }
60 }
61 }
62 }
63
64 if ( $GLOBALS['MATOMO_LOADED_DIRECTLY'] ) {
65
66 // prevent from loading twice
67 $matomo_wpload_base = '../../../../wp-load.php';
68 $matomo_wpload_full = dirname( __FILE__ ) . '/' . $matomo_wpload_base;
69
70 if ($matomo_is_archive_request) {
71 ob_start();
72 // the matomo error handler will be only loaded after WordPress has been loaded... here we want to prevent
73 // any warning/notice from being shown while bootstrapping WordPress or otherwise the unserialize of the response
74 // later in climulti will fail
75 set_error_handler(function ($errno, $errstr, $errfile, $errline) {
76 // if the error has been suppressed by the @ we don't handle the error
77 if (error_reporting() == 0) {
78 return;
79 }
80
81 if (in_array($errno, array(E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, E_USER_ERROR))) {
82 return false; //force standard behaviour
83 }
84
85 matomo_log_message_no_display( sprintf('error: %s: %s in %s:%s', $errno, $errstr, $errfile, $errline ) );
86 });
87 }
88
89 if (!empty($_SERVER['MATOMO_WP_ROOT_PATH']) && file_exists( rtrim($_SERVER['MATOMO_WP_ROOT_PATH'], '/') . '/wp-load.php')) {
90 $matomo_wp_root_file = rtrim($_SERVER['MATOMO_WP_ROOT_PATH'], '/') . '/wp-load.php';
91 matomo_ch_dir($matomo_wp_root_file);
92 require_once $matomo_wp_root_file;
93 } elseif (file_exists($matomo_wpload_full ) ) {
94 matomo_ch_dir($matomo_wpload_full);
95 require_once $matomo_wpload_full;
96 } elseif (realpath( $matomo_wpload_full ) && file_exists(realpath( $matomo_wpload_full ))) {
97 matomo_ch_dir(realpath( $matomo_wpload_full ));
98
99 require_once realpath( $matomo_wpload_full );
100 } elseif (!empty($_SERVER['SCRIPT_FILENAME']) && file_exists($_SERVER['SCRIPT_FILENAME'])) {
101 // seems symlinked... eg the wp-content dir or wp-content/plugins dir is symlinked from some very much other place...
102 $matomo_wpload_full = dirname($_SERVER['SCRIPT_FILENAME']) . '/' . $matomo_wpload_base;
103 if ( file_exists($matomo_wpload_full ) ) {
104 matomo_ch_dir($matomo_wpload_full);
105
106 require_once $matomo_wpload_full;
107 } elseif (realpath( $matomo_wpload_full ) && file_exists(realpath( $matomo_wpload_full ))) {
108 matomo_ch_dir(realpath( $matomo_wpload_full ));
109 require_once realpath( $matomo_wpload_full );
110 } elseif (file_exists(dirname(dirname(dirname(dirname(dirname( $_SERVER['SCRIPT_FILENAME'] ))))) . '/wp-load.php')) {
111 $matomo_relative_path = dirname(dirname(dirname(dirname(dirname( $_SERVER['SCRIPT_FILENAME'] ))))) . '/wp-load.php';
112
113 matomo_ch_dir($matomo_relative_path);
114 require_once $matomo_relative_path;
115 }
116 }
117
118 if (!defined( 'ABSPATH')) {
119 // still not loaded... look in plugins directory if there is a config file for us.
120 $matomo_wpload_config = dirname(__FILE__) . '/../../matomo.wpload_dir.php';
121 if (file_exists( $matomo_wpload_config) && is_readable($matomo_wpload_config)) {
122 $matomo_wpload_content = @file_get_contents($matomo_wpload_config); // we do not include that file for security reasons
123 if (!empty($matomo_wpload_content)) {
124 $matomo_wpload_content = str_replace(array('<?php', 'exit;', 'wp-load.php'), '', $matomo_wpload_content);
125 $matomo_wpload_content = preg_replace('/\s/', '', $matomo_wpload_content);
126 $matomo_wpload_content = trim(ltrim(trim($matomo_wpload_content), '#')); // the path may be commented out # /abs/path
127 if (strpos($matomo_wpload_content, DIRECTORY_SEPARATOR) === 0) {
128 $matomo_wpload_file = rtrim($matomo_wpload_content, DIRECTORY_SEPARATOR) . '/wp-load.php';
129 if (file_exists($matomo_wpload_file) && is_readable($matomo_wpload_file)) {
130 matomo_ch_dir($matomo_wpload_file);
131 require_once $matomo_wpload_file;
132 }
133 }
134 }
135 }
136 }
137
138 if ($matomo_is_archive_request) {
139 restore_error_handler();
140 if (ob_get_level()) {
141 $matomo_ob_end_clean_msg = @ob_get_clean();
142 if (!empty($matomo_ob_end_clean_msg)) {
143 matomo_log_message_no_display( $matomo_ob_end_clean_msg );
144 }
145 }
146 }
147 }
148
149 if ( ! defined( 'ABSPATH' ) ) {
150 echo 'Could not find wp-load. If your server uses symlinks or a custom content directory, Matomo may not work for you as we cannot detect the paths correctly. For more information see https://matomo.org/faq/wordpress/how-do-i-make-matomo-for-wordpress-work-when-i-have-a-custom-content-directory/';
151 if (!empty($_SERVER['MATOMO_WP_ROOT_PATH'])) {
152 echo ' Note: A custom WP root path was set.';
153 }
154 exit; // if accessed directly
155 }
156
157 if ( !is_plugin_active('matomo/matomo.php')
158 && (!defined( 'MATOMO_PHPUNIT_TEST' ) || !MATOMO_PHPUNIT_TEST) ) { // during tests the plugin may temporarily not be active
159 exit;
160 }
161
162 if ( $GLOBALS['MATOMO_LOADED_DIRECTLY'] ) {
163 // see https://github.com/matomo-org/wp-matomo/issues/190
164 // wp-external-links plugin would register an ob_start(function () {...}) and manipulate any of our API output
165 // and in some cases the output would get completely lost causing blank pages.
166 add_filter('wpel_apply_settings', '__return_false', 99999);
167
168 // do not strip slashes if we bootstrap matomo within a regular wordpress request
169 if (!empty($_GET)) {
170 $_GET = stripslashes_deep( $_GET );
171 }
172 if (!empty($_POST)) {
173 $_POST = stripslashes_deep( $_POST );
174 }
175 if (!empty($_COOKIE)) {
176 $_COOKIE = stripslashes_deep( $_COOKIE );
177 }
178 if (!empty($_SERVER)) {
179 $_SERVER = stripslashes_deep( $_SERVER );
180 }
181 if (!empty($_REQUEST)) {
182 $_REQUEST = stripslashes_deep( $_REQUEST );
183 }
184 }
185
186
187 if ( matomo_is_app_request() ) {
188 // pretend we are in the admin... potentially avoiding caching etc
189 $GLOBALS['hook_suffix'] = '';
190 include_once ABSPATH . '/wp-admin/includes/class-wp-screen.php';
191 $GLOBALS['current_screen'] = WP_Screen::get();
192
193 // we disable jsonp
194 unset($_GET['jsoncallback']);
195 unset($_GET['callback']);
196 unset($_POST['jsoncallback']);
197 unset($_POST['callback']);
198 }
199
200 if ( ! defined( 'PIWIK_USER_PATH' ) ) {
201 define( 'PIWIK_USER_PATH', dirname( MATOMO_ANALYTICS_FILE ) );
202 }
203
204 if (function_exists('wp_raise_memory_limit') && function_exists('wp_convert_hr_to_bytes')) {
205 $current_limit = ini_get( 'memory_limit' );
206 $current_limit_int = wp_convert_hr_to_bytes( $current_limit );
207 $memory128MbInt = 134217728;
208 if ($current_limit_int && $current_limit_int > 0 && $current_limit_int < $memory128MbInt) {
209 // we try increase memory if memory is less than 128mb
210 wp_raise_memory_limit('admin');
211 }
212 }
213
214 $GLOBALS['MATOMO_MODIFY_CONFIG_SETTINGS'] = function ($settings) {
215 $plugins = $settings['Plugins'];
216 if (is_array($settings['Plugins'])) {
217 $pluginsToRemove = array('Marketplace', 'MultiSites', 'TwoFactorAuth', 'Widgetize', 'Monolog', 'Feedback', 'ExamplePlugin', 'ExampleAPI', 'ProfessionalServices', 'MobileAppMeasurable', 'CustomPiwikJs');
218 foreach ($pluginsToRemove as $pluginToRemove) {
219 // Marketplace => this is instead done in wordpress
220 // MultiSites => doesn't really make sense since we have only one website per installation
221 // TwoFactorAuth => not needed as login is being handled by WordPress
222 // widgetize for now we don't want to allow widgetizing as it is based on the token_auth authentication
223 // Monolog => we use our own logger
224 // ProfessionalServices => we advertise in the WP plugin itself instead
225 // feedback => we want to hide things like Need help in the admin etc
226 // MobileAppMeasurable => for WP mobile apps are not a thing
227 // custom variables we don't want to enable as we will deprecate them in Matomo 4 anyway => used to be disabled but we need to make sure the columns get installed otherwise matomo has issues... need to wait to matomo 4 to remove it
228 $pos = array_search($pluginToRemove, $plugins['Plugins']);
229 if ($pos !== false) {
230 array_splice($plugins['Plugins'], $pos, 1);
231 }
232 }
233 if (matomo_has_tag_manager()) {
234 $plugins['Plugins'][] = 'TagManager';
235 }
236 $mustEnable = ['BulkTracking', 'CustomJsTracker'];
237 foreach ($mustEnable as $enable) {
238 if (!in_array($enable, $plugins['Plugins'])) {
239 $plugins['Plugins'][] = $enable;
240 }
241 }
242 }
243 if (!empty($GLOBALS['MATOMO_PLUGINS_ENABLED'])) {
244 foreach ($GLOBALS['MATOMO_PLUGINS_ENABLED'] as $plugin) {
245 if (!in_array($plugin, $plugins['Plugins'])) {
246 $plugins['Plugins'][] = $plugin;
247 }
248 }
249 }
250 $settings['Plugins'] = $plugins;
251 return $settings;
252 };
253