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 |