Admin
3 years ago
Commands
4 years ago
Db
4 years ago
Ecommerce
3 years ago
Report
4 years ago
Site
3 years ago
TrackingCode
4 years ago
Updater
4 years ago
User
3 years ago
WpStatistics
4 years ago
views
4 years ago
API.php
4 years ago
Access.php
4 years ago
AjaxTracker.php
5 years ago
Annotations.php
4 years ago
Bootstrap.php
4 years ago
Capabilities.php
4 years ago
Compatibility.php
4 years ago
Email.php
4 years ago
Installer.php
4 years ago
Logger.php
4 years ago
OptOut.php
4 years ago
Paths.php
4 years ago
PrivacyBadge.php
4 years ago
RedirectOnActivation.php
4 years ago
Referral.php
4 years ago
Roles.php
4 years ago
ScheduledTasks.php
4 years ago
Settings.php
4 years ago
Site.php
3 years ago
TrackingCode.php
4 years ago
Uninstaller.php
4 years ago
Updater.php
4 years ago
User.php
4 years ago
Paths.php
254 lines
| 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; |
| 11 | |
| 12 | use stdClass; |
| 13 | use WP_Filesystem_Direct; |
| 14 | |
| 15 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | exit; // if accessed directly |
| 17 | } |
| 18 | |
| 19 | class Paths { |
| 20 | |
| 21 | private static $host_init_filesystem = false; |
| 22 | |
| 23 | public function get_file_system() { |
| 24 | if ( ! function_exists( 'WP_Filesystem' ) ) { |
| 25 | require_once ABSPATH . '/wp-admin/includes/file.php'; |
| 26 | } |
| 27 | |
| 28 | if ( ! self::$host_init_filesystem ) { |
| 29 | self::$host_init_filesystem = true; |
| 30 | WP_Filesystem(); |
| 31 | } |
| 32 | if ( ! class_exists( '\WP_Filesystem_Direct' ) ) { |
| 33 | require_once ABSPATH . '/wp-admin/includes/class-wp-filesystem-base.php'; |
| 34 | require_once ABSPATH . '/wp-admin/includes/class-wp-filesystem-direct.php'; |
| 35 | } |
| 36 | |
| 37 | return new WP_Filesystem_Direct( new stdClass() ); |
| 38 | } |
| 39 | |
| 40 | public function get_upload_base_url() { |
| 41 | $upload_dir = wp_upload_dir(); |
| 42 | $path_upload_url = $upload_dir['baseurl']; |
| 43 | |
| 44 | return rtrim( $path_upload_url, '/' ) . '/' . MATOMO_UPLOAD_DIR; |
| 45 | } |
| 46 | |
| 47 | public function get_upload_base_dir() { |
| 48 | $upload_dir = wp_upload_dir(); |
| 49 | $path_upload_dir = $upload_dir['basedir']; |
| 50 | $path_upload_dir = rtrim( $path_upload_dir, '/' ) . '/' . MATOMO_UPLOAD_DIR; |
| 51 | |
| 52 | return $path_upload_dir; |
| 53 | } |
| 54 | |
| 55 | public function get_matomo_js_upload_path() { |
| 56 | return $this->get_upload_base_dir() . '/' . MATOMO_JS_NAME; |
| 57 | } |
| 58 | |
| 59 | public function get_config_ini_path() { |
| 60 | return $this->get_upload_base_dir() . '/' . MATOMO_CONFIG_PATH; |
| 61 | } |
| 62 | |
| 63 | public function get_tracker_api_rest_api_endpoint() { |
| 64 | return path_join( get_rest_url(), API::VERSION . '/' . API::ROUTE_HIT . '/' ); |
| 65 | } |
| 66 | |
| 67 | public function get_tracker_api_url_in_matomo_dir() { |
| 68 | return plugins_url( 'app/matomo.php', MATOMO_ANALYTICS_FILE ); |
| 69 | } |
| 70 | |
| 71 | public function get_js_tracker_rest_api_endpoint() { |
| 72 | return $this->get_tracker_api_rest_api_endpoint(); |
| 73 | } |
| 74 | |
| 75 | public function get_js_tracker_url_in_matomo_dir() { |
| 76 | $paths = new Paths(); |
| 77 | |
| 78 | if ( file_exists( $paths->get_matomo_js_upload_path() ) ) { |
| 79 | return $this->get_upload_base_url() . '/' . MATOMO_JS_NAME; |
| 80 | } |
| 81 | |
| 82 | return plugins_url( 'app/matomo.js', MATOMO_ANALYTICS_FILE ); |
| 83 | } |
| 84 | |
| 85 | public function get_tmp_dir() { |
| 86 | $is_multi_site = function_exists( 'is_multisite' ) && is_multisite(); |
| 87 | |
| 88 | $cache_dir_alternative = $this->get_upload_base_dir() . '/tmp'; |
| 89 | $base_cache_dir = WP_CONTENT_DIR . '/cache'; |
| 90 | $default_cache_dir = $base_cache_dir . '/' . MATOMO_UPLOAD_DIR; |
| 91 | |
| 92 | if ( ! $is_multi_site && |
| 93 | ( ( is_writable( WP_CONTENT_DIR ) && ! is_dir( $base_cache_dir ) ) |
| 94 | || is_writable( $base_cache_dir ) ) ) { |
| 95 | // we prefer wp-content/cache |
| 96 | $cache_dir = $default_cache_dir; |
| 97 | |
| 98 | if ( ! is_dir( $cache_dir ) ) { |
| 99 | wp_mkdir_p( $cache_dir ); |
| 100 | } |
| 101 | |
| 102 | if ( ! is_writable( $cache_dir ) ) { |
| 103 | // wasn't made writable for some reason so we prefer to use the upload dir just to be safe |
| 104 | $cache_dir = $cache_dir_alternative; |
| 105 | } |
| 106 | } else { |
| 107 | // fallback wp-content/uploads/matomo/tmp if $defaultCacheDir is not writable or if multisite is used |
| 108 | // with multisite we need to make sure to cache files per site |
| 109 | $cache_dir = $cache_dir_alternative; |
| 110 | |
| 111 | if ( ! is_dir( $cache_dir ) ) { |
| 112 | wp_mkdir_p( $cache_dir ); |
| 113 | } |
| 114 | } |
| 115 | |
| 116 | return $cache_dir; |
| 117 | } |
| 118 | |
| 119 | /** |
| 120 | * parameter matomo_file is required for the unit test cases (when checking with a path including the string matomo) |
| 121 | * |
| 122 | * @param $target_dir |
| 123 | * @param string $matomo_file |
| 124 | * |
| 125 | * @return string |
| 126 | */ |
| 127 | public function get_relative_dir_to_matomo( $target_dir, $matomo_file = MATOMO_ANALYTICS_FILE ) { |
| 128 | $matomo_dir = plugin_dir_path( $matomo_file ) . 'app'; |
| 129 | $matomo_dir_parts = explode( DIRECTORY_SEPARATOR, $matomo_dir ); |
| 130 | $target_dir_parts = explode( DIRECTORY_SEPARATOR, $target_dir ); |
| 131 | $relative_directory = ''; |
| 132 | $add_at_the_end = []; |
| 133 | $was_previous_same = false; |
| 134 | $path = ''; |
| 135 | |
| 136 | /* |
| 137 | * don't use DOCUMENT_ROOT as it does not work for cli access |
| 138 | * don't use ABSPATH as it does not match when running unit test cases |
| 139 | * |
| 140 | * hide php errors for open_basedir restrictions |
| 141 | */ |
| 142 | // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged |
| 143 | $root = @realpath( plugin_dir_path( $matomo_file ) . '/../../../' ) . '/'; |
| 144 | foreach ( $target_dir_parts as $index => $part ) { |
| 145 | $path .= $part . '/'; |
| 146 | |
| 147 | /* |
| 148 | * exclude the document root which could contains matomo |
| 149 | * @see https://github.com/matomo-org/matomo-for-wordpress/issues/515 |
| 150 | */ |
| 151 | if ( strpos( $root, $path ) === 0 ) { |
| 152 | continue; |
| 153 | } |
| 154 | if ( isset( $matomo_dir_parts[ $index ] ) |
| 155 | && 'matomo' !== $part // not when matomo is same part cause it's the plugin name but eg also the upload folder name and it would generate wrong path |
| 156 | && $matomo_dir_parts[ $index ] === $part |
| 157 | && ! $was_previous_same ) { |
| 158 | continue; |
| 159 | } |
| 160 | |
| 161 | $was_previous_same = true; |
| 162 | |
| 163 | if ( isset( $matomo_dir_parts[ $index ] ) ) { |
| 164 | $relative_directory .= '../'; |
| 165 | } |
| 166 | $add_at_the_end[] = $part; |
| 167 | } |
| 168 | |
| 169 | return $relative_directory . implode( '/', $add_at_the_end ); |
| 170 | } |
| 171 | |
| 172 | public function get_gloal_upload_dir_if_possible( $file_to_look_for = '' ) { |
| 173 | if ( defined( 'MATOMO_GLOBAL_UPLOAD_DIR' ) ) { |
| 174 | return MATOMO_GLOBAL_UPLOAD_DIR; |
| 175 | } |
| 176 | |
| 177 | $path_upload_dir = $this->get_upload_base_dir(); |
| 178 | |
| 179 | if ( ! is_multisite() || is_network_admin() ) { |
| 180 | return $path_upload_dir; |
| 181 | } |
| 182 | |
| 183 | if ( preg_match( '/sites\/(\d)+$/', $path_upload_dir ) ) { |
| 184 | $path_upload_dir = preg_replace( '/sites\/(\d)+$/', '', $path_upload_dir ); |
| 185 | } else { |
| 186 | // re-implement _wp_upload_dir to find hopefully the upload_dir for the network site |
| 187 | $upload_path = trim( get_option( 'upload_path' ) ); |
| 188 | if ( empty( $upload_path ) || 'wp-content/uploads' === $upload_path ) { |
| 189 | $path_upload_dir = WP_CONTENT_DIR . '/uploads'; |
| 190 | } elseif ( 0 !== strpos( $upload_path, ABSPATH ) ) { |
| 191 | // $dir is absolute, $upload_path is (maybe) relative to ABSPATH |
| 192 | $path_upload_dir = path_join( ABSPATH, $upload_path ); |
| 193 | } else { |
| 194 | $path_upload_dir = $upload_path; |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | if ( ! empty( $file_to_look_for ) ) { |
| 199 | $file_to_look_for = MATOMO_UPLOAD_DIR . '/' . ltrim( $file_to_look_for, '/' ); |
| 200 | } |
| 201 | |
| 202 | $path_upload_dir = rtrim( $path_upload_dir, '/' ) . '/'; |
| 203 | if ( ! empty( $file_to_look_for ) |
| 204 | && ! file_exists( $path_upload_dir . $file_to_look_for ) ) { |
| 205 | // seems we haven't auto detected the right one yet... (or it is not yet installed) |
| 206 | // we go up the site upload dir step by step to try and find the network upload dir |
| 207 | $parent_dir = $path_upload_dir; |
| 208 | do { |
| 209 | $parent_dir = dirname( $parent_dir ); |
| 210 | if ( file_exists( $parent_dir . $file_to_look_for ) ) { |
| 211 | return $parent_dir; |
| 212 | } |
| 213 | } while ( strpos( $parent_dir, ABSPATH ) === 0 ); // we don't go outside WP dir |
| 214 | } |
| 215 | |
| 216 | $path_upload_dir = rtrim( $path_upload_dir, '/' ) . '/' . MATOMO_UPLOAD_DIR; |
| 217 | |
| 218 | return $path_upload_dir; |
| 219 | } |
| 220 | |
| 221 | public function clear_assets_dir() { |
| 222 | $tmp_dir = $this->get_tmp_dir() . '/assets'; |
| 223 | if ( $tmp_dir && is_dir( $tmp_dir ) ) { |
| 224 | $file_system_direct = $this->get_file_system(); |
| 225 | $file_system_direct->rmdir( $tmp_dir, true ); |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | public function clear_cache_dir() { |
| 230 | $tmp_dir = $this->get_tmp_dir(); |
| 231 | if ( $tmp_dir |
| 232 | && is_dir( $tmp_dir ) |
| 233 | && is_dir( $tmp_dir . '/cache' ) ) { |
| 234 | // we make sure it's a matomo cache dir to not delete something falsely |
| 235 | $file_system_direct = $this->get_file_system(); |
| 236 | $file_system_direct->rmdir( $tmp_dir, true ); |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | public function uninstall() { |
| 241 | $this->clear_cache_dir(); |
| 242 | |
| 243 | $dir = $this->get_upload_base_dir(); |
| 244 | |
| 245 | $file_system_direct = $this->get_file_system(); |
| 246 | $file_system_direct->rmdir( $dir, true ); |
| 247 | |
| 248 | $global_dir = $this->get_upload_base_dir(); |
| 249 | if ( $global_dir && $global_dir !== $dir ) { |
| 250 | $file_system_direct->rmdir( $dir ); |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 |