Changeset 3309525
- Timestamp:
- 06/11/2025 05:34:32 AM (8 months ago)
- Location:
- matomo/trunk
- Files:
-
- 2 added
- 14 edited
-
assets/js/asset_manager_core_js.js (modified) (1 diff)
-
classes/WpMatomo/Admin/PrivacySettings.php (modified) (1 diff)
-
classes/WpMatomo/Admin/SystemReport.php (modified) (6 diffs)
-
classes/WpMatomo/Admin/views/marketplace_setup_wizard.php (modified) (1 diff)
-
classes/WpMatomo/Admin/views/systemreport.php (modified) (3 diffs)
-
classes/WpMatomo/AjaxTracker.php (modified) (3 diffs)
-
classes/WpMatomo/Ecommerce/Base.php (modified) (1 diff)
-
classes/WpMatomo/Ecommerce/Woocommerce.php (modified) (6 diffs)
-
classes/WpMatomo/OptOut.php (modified) (3 diffs)
-
classes/WpMatomo/TrackingCode/TrackingCodeGenerator.php (modified) (3 diffs)
-
classes/WpMatomo/Updater.php (modified) (4 diffs)
-
matomo.php (modified) (1 diff)
-
plugins/WordPress/Html (added)
-
plugins/WordPress/Html/PluginUrlReplacer.php (added)
-
plugins/WordPress/WordPress.php (modified) (2 diffs)
-
readme.txt (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
matomo/trunk/assets/js/asset_manager_core_js.js
r3258789 r3309525 1 /* Matomo Javascript - cb= 3967b01739c9861ba9da246d5bf73e9a*/1 /* Matomo Javascript - cb=04b91cff3165f8f0de28f3124352978e*/ 2 2 3 3 /*! -
matomo/trunk/classes/WpMatomo/Admin/PrivacySettings.php
r2594597 r3309525 17 17 18 18 class PrivacySettings implements AdminSettingsInterface { 19 const EXAMPLE_MINIMAL = '[matomo_opt_out ]';20 const EXAMPLE_FULL = '[matomo_opt_out language=de]';19 const EXAMPLE_MINIMAL = '[matomo_opt_out_form]'; 20 const EXAMPLE_FULL = '[matomo_opt_out_form language=de]'; 21 21 22 22 /** -
matomo/trunk/classes/WpMatomo/Admin/SystemReport.php
r3250097 r3309525 19 19 use Piwik\DeviceDetector\DeviceDetectorFactory; 20 20 use Piwik\Filesystem; 21 use Piwik\Piwik; 21 22 use Piwik\Plugin; 22 23 use Piwik\Plugins\CoreAdminHome\API; … … 26 27 use Piwik\Plugins\UserCountry\LocationProvider; 27 28 use Piwik\Plugins\WordPress\WordPress; 29 use Piwik\Scheduler\Scheduler; 30 use Piwik\Scheduler\Task; 31 use Piwik\Scheduler\TaskLoader; 28 32 use Piwik\SettingsPiwik; 29 33 use Piwik\Tracker\Failures; … … 71 75 const TROUBLESHOOT_CLEAR_LOGS = 'matomo_troubleshooting_action_clear_logs'; 72 76 const TROUBLESHOOT_RUN_UPDATER = 'matomo_troubleshooting_action_run_updater'; 77 const REGENERATE_TRACKING_CODE = 'matomo_troubleshooting_action_regen_tracking_code'; 78 const RUN_SCHEDULED_TASK = 'matomo_troubleshooting_action_run_task'; 73 79 74 80 private $not_compatible_plugins = [ … … 230 236 $sync = new UserSync(); 231 237 $sync->sync_all(); 238 } 239 } 240 241 if ( ! empty( $_POST[ self::REGENERATE_TRACKING_CODE ] ) ) { 242 try { 243 Bootstrap::do_bootstrap(); 244 245 // regenerate tracker.js file in Matomo 246 Piwik::postEvent( 'CustomJsTracker.updateTracker' ); 247 248 // regenerate embed tracking code in MWP 249 $options = new WpMatomo\TrackingCode\GeneratorOptions( $this->settings ); 250 $tracking_code_generator = new WpMatomo\TrackingCode\TrackingCodeGenerator( $this->settings, $options ); 251 252 $tracking_code_generator->update_tracking_code( true ); 253 254 echo '<div class="notice notice-success"><p>' . esc_html__( 'JavaScript tracking code regenerated successfully.', 'matomo' ) . '</p></div>'; 255 } catch ( \Exception $ex ) { 256 echo '<div class="error"><p>' . esc_html__( 'Matomo Error', 'matomo' ) . ': ' . esc_html( matomo_anonymize_value( $e->getMessage() . ' =>' . $this->logger->get_readable_trace( $e ) ) ) . '</p></div>'; 257 } 258 } 259 260 if ( ! empty( $_POST[ self::RUN_SCHEDULED_TASK ] ) ) { 261 try { 262 Bootstrap::do_bootstrap(); 263 264 if ( empty( $_POST['matomo_troubleshooting_run_task'] ) ) { 265 throw new \Exception( __( 'No task specified.', 'matomo' ) ); 266 } 267 268 $task_to_run = sanitize_text_field( wp_unslash( $_POST['matomo_troubleshooting_run_task'] ) ); 269 270 $scheduler = StaticContainer::get( Scheduler::class ); 271 $message = $scheduler->runTaskNow( $task_to_run ); 272 273 echo '<div class="notice notice-success"><p>' . esc_html__( 'Task ran successfully', 'matomo' ) . ': ' . esc_html( $message ) . '</p></div>'; 274 } catch ( \Exception $e ) { 275 echo '<div class="error"><p>' . esc_html__( 'Matomo Error', 'matomo' ) . ': ' . esc_html( matomo_anonymize_value( $e->getMessage() . ' =>' . $this->logger->get_readable_trace( $e ) ) ) . '</p></div>'; 232 276 } 233 277 } … … 319 363 $matomo_has_exception_logs = []; 320 364 $matomo_has_warning_and_no_errors = false; 321 322 if ( empty( $matomo_active_tab ) ) { 365 $matomo_scheduled_tasks = []; 366 367 if ( empty( $matomo_active_tab ) ) { // system report 323 368 // phpcs:ignore WordPress.PHP.DevelopmentFunctions.prevent_path_disclosure_error_reporting 324 369 $this->initial_error_reporting = @error_reporting(); … … 331 376 $matomo_has_warning_and_no_errors = $this->has_only_warnings_no_error( $matomo_tables ); 332 377 $matomo_has_exception_logs = $this->logger->get_last_logged_entries(); 378 } else { // troubleshooting 379 try { 380 Bootstrap::do_bootstrap(); 381 $scheduler = StaticContainer::get( Scheduler::class ); 382 $matomo_scheduled_tasks = $scheduler->getTaskList(); 383 } catch ( \Exception $e ) { 384 $this->logger->log_exception( 'troubleshooting', $e ); 385 } 333 386 } 334 387 -
matomo/trunk/classes/WpMatomo/Admin/views/marketplace_setup_wizard.php
r3100184 r3309525 121 121 <p><?php echo sprintf( esc_html__( 'Download the %1$sMatomo Marketplace for WordPress%2$s plugin.', 'matomo' ), '<em>', '</em>' ); ?></p> 122 122 123 <a class="button-primary download-plugin" rel="noreferrer noopener" target="_blank" href="http ://builds.matomo.org/matomo-marketplace-for-wordpress-latest.zip">123 <a class="button-primary download-plugin" rel="noreferrer noopener" target="_blank" href="https://builds.matomo.org/matomo-marketplace-for-wordpress-latest.zip"> 124 124 <?php esc_html_e( 'Download', 'matomo' ); ?> 125 125 </a> -
matomo/trunk/classes/WpMatomo/Admin/views/systemreport.php
r3221938 r3309525 33 33 /** @var string $matomo_active_tab */ 34 34 /** @var \WpMatomo\Settings $settings */ 35 /** @var array $matomo_scheduled_tasks */ 35 36 36 37 if ( ! function_exists( 'matomo_format_value_text' ) ) { … … 234 235 class='button-primary' 235 236 title="<?php esc_attr_e( 'Force trigger a Matomo update in case it failed error', 'matomo' ); ?>" 236 value="<?php esc_ html_e( 'Run Updater', 'matomo' ); ?>">237 value="<?php esc_attr_e( 'Run Updater', 'matomo' ); ?>"> 237 238 <label for="matomo_troubleshooting_update_from">Run updates from version:</label> 238 239 <input id="matomo_troubleshooting_update_from" … … 247 248 class='button-primary' 248 249 title="<?php esc_attr_e( 'Users are synced automatically. If for some reason a user cannot access Matomo pages even though the user has the permission, then triggering a manual sync may help to fix this issue immediately or it may show which error prevents the automatic syncing.', 'matomo' ); ?>" 249 value="<?php esc_ html_e( 'Sync all users across sites / blogs', 'matomo' ); ?>">250 value="<?php esc_attr_e( 'Sync all users across sites / blogs', 'matomo' ); ?>"> 250 251 <br/><br/> 251 252 <input name="<?php echo esc_attr( SystemReport::TROUBLESHOOT_SYNC_ALL_SITES ); ?>" type="submit" 252 253 title="<?php esc_attr_e( 'Sites / blogs are synced automatically. If for some reason Matomo is not showing up for a specific blog, then triggering a manual sync may help to fix this issue immediately or it may show which error prevents the automatic syncing.', 'matomo' ); ?>" 253 254 class='button-primary' 254 value="<?php esc_html_e( 'Sync all sites (blogs)', 'matomo' ); ?>"> 255 value="<?php esc_attr_e( 'Sync all sites (blogs)', 'matomo' ); ?>"> 256 <br/><br/> 255 257 <?php } ?> 258 <input name="<?php echo esc_attr( SystemReport::REGENERATE_TRACKING_CODE ); ?>" type="submit" 259 class="button-primary" 260 title="<?php esc_attr_e( 'Force the cached tracking code to be regenerated. The tracking code is usually regenerated on update and after changing tracking settings, or if a Matomo plugin is installed/updated, but if you need to do it manually, you can do it here.', 'matomo' ); ?>" 261 value="<?php esc_attr_e( 'Regenerate tracking code', 'matomo' ); ?>"> 262 <br/> 263 <br/> 264 265 <input name="<?php echo esc_attr( SystemReport::RUN_SCHEDULED_TASK ); ?>" type="submit" 266 class="button-primary" 267 title="<?php esc_attr_e( 'Run a scheduled task by name.', 'matomo' ); ?>" 268 value="<?php esc_attr_e( 'Run scheduled task', 'matomo' ); ?>" 269 /> 270 <label for="matomo_troubleshooting_run_task">Task to run:</label> 271 <select 272 id="matomo_troubleshooting_run_task" 273 name="matomo_troubleshooting_run_task" 274 title="<?php esc_attr_e( 'Pick a task to run', 'matomo' ); ?>" 275 > 276 <?php foreach ( $matomo_scheduled_tasks as $matomo_task ) { ?> 277 <option value="<?php echo esc_attr( $matomo_task ); ?>"><?php echo esc_html( $matomo_task ); ?></option> 278 <?php } ?> 279 </select> 280 <br/> 281 <br/> 256 282 </form> 257 283 -
matomo/trunk/classes/WpMatomo/AjaxTracker.php
r3250097 r3309525 99 99 if ( ! $this->idSite ) { 100 100 $this->logger->log('ecommerce tracking could not find idSite, cannot send request'); 101 return ; // not installed or synced yet101 return null; // not installed or synced yet 102 102 } 103 104 if ( $this->is_prerender() ) { 105 // do not track if for some reason we are prerendering 106 return null; 107 } 108 103 109 $args = array( 104 110 'method' => $method, … … 113 119 // 2) Never exit at any point 114 120 115 $response = wp_remote_request( $url . '&bots=1', $args ); 121 $url = $url . '&bots=1'; 122 123 $response = $this->wp_remote_request( $url, $args ); 116 124 117 125 if (is_wp_error($response)) { … … 125 133 return strpos( $ex->getMessage(), 'setVisitorId() expects' ) === 0; 126 134 } 135 136 /** 137 * See https://developer.chrome.com/docs/web-platform/prerender-pages 138 * @return bool 139 */ 140 private function is_prerender() { 141 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized 142 $purpose = strtolower( isset( $_SERVER['HTTP_SEC_PURPOSE'] ) ? wp_unslash( $_SERVER['HTTP_SEC_PURPOSE'] ) : '' ); 143 return strpos( $purpose, 'prefetch' ) !== false 144 || strpos( $purpose, 'prerender' ) !== false; 145 } 146 147 /** 148 * for tests to override 149 * @param string $url 150 * @param array $args 151 * @return array|\WP_Error 152 */ 153 protected function wp_remote_request( $url, $args ) { 154 return wp_remote_request( $url, $args ); 155 } 127 156 } -
matomo/trunk/classes/WpMatomo/Ecommerce/Base.php
r3250097 r3309525 122 122 } 123 123 } 124 124 125 $this->ajax_tracker_calls = []; 125 126 -
matomo/trunk/classes/WpMatomo/Ecommerce/Woocommerce.php
r3250097 r3309525 36 36 $server_side_visitor_id->register_hooks(); 37 37 } 38 39 // compatibility with the All In One SEO plugin 40 add_filter( 'aioseo_schema_woocommerce_add_to_cart_skip_hooks', [ $this, 'aioseo_add_to_cart_skip' ] ); 38 41 39 42 add_action( 'wp_head', [ $this, 'maybe_track_order_complete' ], 99999 ); … … 72 75 } 73 76 77 /** 78 * The All In One SEO plugin temporarily adds products to the WooCommerce cart, calculates 79 * some things, then empties the cart. This results in WooCommerce hooks being fired for 80 * a cart change, even though the user never actually added anything to their cart. 81 * 82 * The All In One SEO plugin works around this by removing certain add_to_cart hooks 83 * then re-adding them. To avoid tracking an ecommerce cart update during this temporary 84 * cart addition, we have to tell AIOSEO to skip our add_to_cart hook. 85 * 86 * Note: this isn't documented in the AIOSEO plugin, so it's possible the way they do 87 * this can change in the future. 88 * 89 * @param array $hooks_to_skip 90 * @return array 91 */ 92 public function aioseo_add_to_cart_skip( $hooks_to_skip ) { 93 $hooks_to_skip[ __CLASS__ ] = 'on_cart_updated_safe'; 94 return $hooks_to_skip; 95 } 96 74 97 public function after_calculate_totals() { 75 98 if ( ! $this->track_next_totals_change ) { … … 342 365 343 366 $product = wc_get_product( $product_id ); 367 if ( ! is_object( $product ) ) { 368 $order_id = $order ? $this->get_order_id( $order ) : 'unspecified'; 369 $this->logger->log( "Failed to get product for product ID = $product_id (order ID = $order_id)." ); 370 return; 371 } 344 372 345 373 $pr = $product_or_variation ? $product_or_variation : $product; … … 436 464 return $order->get_meta( $name ); 437 465 } else { 438 $id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;466 $id = $this->get_order_id( $order ); 439 467 return get_post_meta( $id, $name, true ); 440 468 } … … 451 479 $order->update_meta_data( $name, $value ); 452 480 } else { 453 $id = method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id;481 $id = $this->get_order_id( $order ); 454 482 update_post_meta( $id, $name, $value ); 455 483 } … … 460 488 } 461 489 } 490 491 private function get_order_id( $order ) { 492 return method_exists( $order, 'get_id' ) ? $order->get_id() : $order->id; 493 } 462 494 } -
matomo/trunk/classes/WpMatomo/OptOut.php
r2617445 r3309525 19 19 20 20 class OptOut { 21 const OPT_OUT_DIV_ID = 'matomo-opt-out-form-embed'; 22 21 23 private $language = null; 22 24 23 25 public function register_hooks() { 24 add_shortcode( 'matomo_opt_out', array( $this, 'show_opt_out' ) ); 26 add_shortcode( 'matomo_opt_out', [ $this, 'show_classic_opt_out' ] ); 27 add_shortcode( 'matomo_opt_out_form', [ $this, 'show_opt_out' ] ); 25 28 add_action( 'wp_enqueue_scripts', array( $this, 'load_scripts' ) ); 26 29 add_action( 'init', [ $this, 'load_block' ] ); … … 38 41 39 42 public function show_opt_out( $atts ) { 40 $a = shortcode_atts( 41 [ 42 'language' => null, 43 ], 44 $atts 45 ); 46 if ( ! empty( $a['language'] ) && strlen( $a['language'] ) < 6 ) { 47 $this->language = $a['language']; 48 } 43 $this->language = $this->get_language_from_atts( $atts ); 44 $this->language = isset( $this->language ) ? $this->language : 'auto'; 45 46 $div_id = self::OPT_OUT_DIV_ID; 47 48 $url = 'app/index.php?module=CoreAdminHome&action=optOutJS&divId=' . $div_id . '&language=' . rawurlencode( $this->language ) . '&showIntro=1'; 49 $url = plugins_url( $url, MATOMO_ANALYTICS_FILE ); 50 51 wp_enqueue_script( 'matomo_opt_out_form_js', $url, [], 1, true ); // output in the footer 52 53 // phpcs:disable WordPress.WP.EnqueuedResources.NonEnqueuedScript 54 $content = "<div id=\"$div_id\"></div>"; 55 return $content; 56 } 57 58 public function show_classic_opt_out( $atts ) { 59 $this->language = $this->get_language_from_atts( $atts ); 49 60 50 61 try { … … 115 126 ); 116 127 } 128 129 private function get_language_from_atts( $atts ) { 130 $a = shortcode_atts( 131 [ 132 'language' => null, 133 ], 134 $atts 135 ); 136 if ( ! empty( $a['language'] ) && strlen( $a['language'] ) < 6 ) { 137 return $a['language']; 138 } 139 return null; 140 } 117 141 } -
matomo/trunk/classes/WpMatomo/TrackingCode/TrackingCodeGenerator.php
r3148286 r3309525 64 64 } 65 65 66 public function update_tracking_code() { 67 if ( $this->settings->is_current_tracking_code() 68 && $this->settings->get_option( 'tracking_code' ) ) { 66 public function update_tracking_code( $force = false ) { 67 if ( 68 $this->settings->is_current_tracking_code() 69 && $this->settings->get_option( 'tracking_code' ) 70 && ! $force 71 ) { 69 72 return false; 70 73 } … … 81 84 82 85 if ( ! $idsite ) { 83 $this->logger->log( ' Not foundrelated idSite for blog ' . get_current_blog_id() );86 $this->logger->log( 'Found no related idSite for blog ' . get_current_blog_id() ); 84 87 85 88 return false; … … 322 325 $script .= "var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; 323 326 g.type='text/javascript'; g.async=true; g.src=" . wp_json_encode( $js_endpoint ) . '; s.parentNode.insertBefore(g,s);'; 327 328 $script = <<<EOF 329 (function () { 330 function initTracking() { 331 $script 332 } 333 if (document.prerendering) { 334 document.addEventListener('prerenderingchange', initTracking, {once: true}); 335 } else { 336 initTracking(); 337 } 338 })(); 339 EOF; 324 340 325 341 if ( function_exists( 'wp_get_inline_script_tag' ) ) { -
matomo/trunk/classes/WpMatomo/Updater.php
r3250097 r3309525 21 21 use Piwik\Version; 22 22 use WP_Upgrader; 23 use WpMatomo\TrackingCode\GeneratorOptions; 24 use WpMatomo\TrackingCode\TrackingCodeGenerator; 23 25 use WpMatomo\Updater\UpdateInProgressException; 24 26 … … 83 85 84 86 public function update_if_needed() { 85 $executed_updates = [];86 87 87 $plugins_requiring_update = $this->get_plugins_requiring_update(); 88 foreach ( $plugins_requiring_update as $key => $plugin_version) {88 if ( ! empty( $plugins_requiring_update ) ) { 89 89 try { 90 90 $this->update(); … … 95 95 } catch ( Exception $e ) { 96 96 $this->logger->log_exception( 'plugin_update', $e ); 97 continue; 98 } 99 $executed_updates[] = $key; 97 return; 98 } 100 99 101 100 // we're scheduling another update in case there are some dimensions to be updated or anything … … 105 104 wp_schedule_single_event( time() + 15, ScheduledTasks::EVENT_UPDATE ); 106 105 107 update_option( $key, $plugin_version );108 109 106 // we make sure to delete cache even if no component was updated eg there may be translation updates etc 110 107 // and caches need to be invalidated 111 108 Filesystem::deleteAllCacheOnUpdate(); 112 } 113 114 return $executed_updates; 109 110 $tracking_code_generator = new TrackingCodeGenerator( $this->settings, new GeneratorOptions( $this->settings ) ); 111 $tracking_code_generator->update_tracking_code( true ); 112 } 113 114 foreach ( $plugins_requiring_update as $key => $plugin_version ) { 115 update_option( $key, $plugin_version ); 116 } 117 118 return array_keys( $plugins_requiring_update ); 115 119 } 116 120 -
matomo/trunk/matomo.php
r3258789 r3309525 5 5 * Author: Matomo 6 6 * Author URI: https://matomo.org 7 * Version: 5.3. 07 * Version: 5.3.1 8 8 * Domain Path: /languages 9 9 * WC requires at least: 2.4.0 10 * WC tested up to: 9. 7.110 * WC tested up to: 9.9.3 11 11 * 12 12 * Matomo - free/libre analytics platform -
matomo/trunk/plugins/WordPress/WordPress.php
r3258789 r3309525 20 20 use Piwik\Plugin\Manager; 21 21 use Piwik\Plugins\CoreHome\SystemSummary\Item; 22 use Piwik\Plugins\WordPress\Html\PluginUrlReplacer; 22 23 use Piwik\Scheduler\Task; 23 24 use Piwik\Url; … … 356 357 } 357 358 358 public function onDispatchRequestEnd(&$result, $module, $action, $parameters) { 359 public function onDispatchRequestEnd(&$result, $module, $action, $parameters) 360 { 359 361 if (!empty($result) && is_string($result)) { 360 362 // https://wordpress.org/support/topic/bugged-favicon/#post-12995669 361 363 $result = str_replace('<link rel="mask-icon"', '<link rel="ignore-mask-icon-ignore"', $result); 362 364 $result = str_replace('plugins/CoreHome/images/applePinnedTab.svg', '', $result); 365 366 $pluginUrlReplacer = new PluginUrlReplacer(); 367 $result = $pluginUrlReplacer->replaceThirdPartyPluginUrls( $result ); 363 368 } 364 369 } -
matomo/trunk/readme.txt
r3258789 r3309525 3 3 Tags: matomo,analytics,statistics,stats,ecommerce 4 4 Requires at least: 4.8 5 Tested up to: 6. 7.26 Stable tag: 5.3. 05 Tested up to: 6.8.1 6 Stable tag: 5.3.1 7 7 Requires PHP: 7.2.5 8 8 License: GPLv3 or later
Note: See TracChangeset
for help on using the changeset viewer.