PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.0.0
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.0.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 / app / bootstrap.php
matomo / app Last commit date
config 5 years ago core 5 years ago js 5 years ago lang 5 years ago libs 5 years ago node_modules 5 years ago plugins 5 years ago vendor 5 years ago .htaccess 6 years ago DIObject.php 5 years ago LEGALNOTICE 5 years ago LICENSE 6 years ago LegacyAutoloader.php 5 years ago PRIVACY.md 5 years ago README.md 5 years ago SECURITY.md 6 years ago bootstrap.php 5 years ago console 6 years ago favicon.ico 6 years ago index.php 5 years ago matomo.js 5 years ago matomo.php 5 years ago offline-service-worker.js 5 years ago package-lock.json 5 years ago piwik.js 5 years ago piwik.php 5 years ago robots.txt 5 years ago
bootstrap.php
250 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 exit; // if accessed directly
152 }
153
154 if ( !is_plugin_active('matomo/matomo.php')
155 && (!defined( 'MATOMO_PHPUNIT_TEST' ) || !MATOMO_PHPUNIT_TEST) ) { // during tests the plugin may temporarily not be active
156 exit;
157 }
158
159 if ( $GLOBALS['MATOMO_LOADED_DIRECTLY'] ) {
160 // see https://github.com/matomo-org/wp-matomo/issues/190
161 // wp-external-links plugin would register an ob_start(function () {...}) and manipulate any of our API output
162 // and in some cases the output would get completely lost causing blank pages.
163 add_filter('wpel_apply_settings', '__return_false', 99999);
164
165 // do not strip slashes if we bootstrap matomo within a regular wordpress request
166 if (!empty($_GET)) {
167 $_GET = stripslashes_deep( $_GET );
168 }
169 if (!empty($_POST)) {
170 $_POST = stripslashes_deep( $_POST );
171 }
172 if (!empty($_COOKIE)) {
173 $_COOKIE = stripslashes_deep( $_COOKIE );
174 }
175 if (!empty($_SERVER)) {
176 $_SERVER = stripslashes_deep( $_SERVER );
177 }
178 if (!empty($_REQUEST)) {
179 $_REQUEST = stripslashes_deep( $_REQUEST );
180 }
181 }
182
183
184 if ( matomo_is_app_request() ) {
185 // pretend we are in the admin... potentially avoiding caching etc
186 $GLOBALS['hook_suffix'] = '';
187 include_once ABSPATH . '/wp-admin/includes/class-wp-screen.php';
188 $GLOBALS['current_screen'] = WP_Screen::get();
189
190 // we disable jsonp
191 unset($_GET['jsoncallback']);
192 unset($_GET['callback']);
193 unset($_POST['jsoncallback']);
194 unset($_POST['callback']);
195 }
196
197 if ( ! defined( 'PIWIK_USER_PATH' ) ) {
198 define( 'PIWIK_USER_PATH', dirname( MATOMO_ANALYTICS_FILE ) );
199 }
200
201 if (function_exists('wp_raise_memory_limit') && function_exists('wp_convert_hr_to_bytes')) {
202 $current_limit = ini_get( 'memory_limit' );
203 $current_limit_int = wp_convert_hr_to_bytes( $current_limit );
204 $memory128MbInt = 134217728;
205 if ($current_limit_int && $current_limit_int > 0 && $current_limit_int < $memory128MbInt) {
206 // we try increase memory if memory is less than 128mb
207 wp_raise_memory_limit('admin');
208 }
209 }
210
211 $GLOBALS['MATOMO_MODIFY_CONFIG_SETTINGS'] = function ($settings) {
212 $plugins = $settings['Plugins'];
213 if (is_array($settings['Plugins'])) {
214 $pluginsToRemove = array('Marketplace', 'MultiSites', 'TwoFactorAuth', 'Widgetize', 'Monolog', 'Feedback', 'ExamplePlugin', 'ExampleAPI', 'ProfessionalServices', 'MobileAppMeasurable', 'CustomPiwikJs');
215 foreach ($pluginsToRemove as $pluginToRemove) {
216 // Marketplace => this is instead done in wordpress
217 // MultiSites => doesn't really make sense since we have only one website per installation
218 // TwoFactorAuth => not needed as login is being handled by WordPress
219 // widgetize for now we don't want to allow widgetizing as it is based on the token_auth authentication
220 // Monolog => we use our own logger
221 // ProfessionalServices => we advertise in the WP plugin itself instead
222 // feedback => we want to hide things like Need help in the admin etc
223 // MobileAppMeasurable => for WP mobile apps are not a thing
224 // 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
225 $pos = array_search($pluginToRemove, $plugins['Plugins']);
226 if ($pos !== false) {
227 array_splice($plugins['Plugins'], $pos, 1);
228 }
229 }
230 if (matomo_has_tag_manager()) {
231 $plugins['Plugins'][] = 'TagManager';
232 }
233 $mustEnable = ['BulkTracking', 'CustomJsTracker'];
234 foreach ($mustEnable as $enable) {
235 if (!in_array($enable, $plugins['Plugins'])) {
236 $plugins['Plugins'][] = $enable;
237 }
238 }
239 }
240 if (!empty($GLOBALS['MATOMO_PLUGINS_ENABLED'])) {
241 foreach ($GLOBALS['MATOMO_PLUGINS_ENABLED'] as $plugin) {
242 if (!in_array($plugin, $plugins['Plugins'])) {
243 $plugins['Plugins'][] = $plugin;
244 }
245 }
246 }
247 $settings['Plugins'] = $plugins;
248 return $settings;
249 };
250