Skip to content

Commit c4d2be3

Browse files
authored
correctly map 3rd party Matomo plugin's links to WP's plugin directory (#1296)
* initial working solution * extract and refactor * add unit and e2e test * update expected screenshots * update woocommerce tested against version * add bug fix to changelog * fix random e2e test failure * update expected screenshots
1 parent 1418585 commit c4d2be3

File tree

236 files changed

+700
-434
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

236 files changed

+700
-434
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions

matomo.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Version: 5.3.1
88
* Domain Path: /languages
99
* WC requires at least: 2.4.0
10-
* WC tested up to: 9.8.5
10+
* WC tested up to: 9.9.3
1111
*
1212
* Matomo - free/libre analytics platform
1313
*
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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+
*
8+
*/
9+
10+
namespace Piwik\Plugins\WordPress\Html;
11+
12+
use Piwik\Common;
13+
14+
class PluginUrlReplacer
15+
{
16+
public function replaceThirdPartyPluginUrls($html): string
17+
{
18+
// replace all links to third party Matomo plugin files with their proper WordPress URLs
19+
$html = preg_replace_callback(
20+
'%\"((?:\\./)?plugins/.*?)\"%',
21+
function ($matches) {
22+
// $url looks like plugins/SearchEngineKeywordsPerformance/images/...
23+
$url = $matches[1];
24+
$replace = $this->rewritePathIfThirdPartyPluginUrl($url);
25+
if (!empty($replace)) {
26+
return '"' . $replace . '"';
27+
}
28+
29+
return $matches[0];
30+
},
31+
$html
32+
);
33+
34+
// replace URLs to third party Matomo plugin files in JSON values (used to initiate Vue components)
35+
$html = preg_replace_callback(
36+
'%&quot;(?:\\.\\\\/)?plugins\\\\/.*?&quot;%',
37+
function ($matches) {
38+
// $url looks like plugins/SearchEngineKeywordsPerformance/images/...
39+
$url = Common::unsanitizeInputValue( $matches[0] );
40+
$url = json_decode($url, true);
41+
if (empty($url) || !is_string($url)) { // sanity check
42+
return $matches[0];
43+
}
44+
45+
$replace = $this->rewritePathIfThirdPartyPluginUrl($url);
46+
if (!empty($replace)) {
47+
$replace = json_encode($replace);
48+
$replace = Common::sanitizeInputValue($replace);
49+
return $replace;
50+
}
51+
52+
return $matches[0];
53+
},
54+
$html
55+
);
56+
57+
return $html;
58+
}
59+
60+
private function rewritePathIfThirdPartyPluginUrl(string $url): ?string
61+
{
62+
if (substr($url, 0, 2) === './') {
63+
$url = substr($url, 2);
64+
}
65+
66+
$segments = explode('/', $url);
67+
$plugin = $segments[1] ?? '';
68+
69+
// entries in this array will look like:
70+
// /path/to/wordpress/wp-content/plugins/SearchEngineKeywordsPerformance/SearchEngineKeywordsPerformance.php
71+
$allPluginsInstalledInWp = $GLOBALS['MATOMO_PLUGIN_FILES'] ?? [];
72+
foreach ($allPluginsInstalledInWp as $matomoPluginFile) {
73+
if (basename($matomoPluginFile) === $plugin . '.php') {
74+
array_shift($segments);
75+
array_shift($segments);
76+
$urlRelativeToPlugin = implode('/', $segments);
77+
78+
$replace = plugins_url($urlRelativeToPlugin, $matomoPluginFile);
79+
return $replace;
80+
}
81+
}
82+
83+
return null;
84+
}
85+
}

plugins/WordPress/WordPress.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Piwik\Plugin;
2020
use Piwik\Plugin\Manager;
2121
use Piwik\Plugins\CoreHome\SystemSummary\Item;
22+
use Piwik\Plugins\WordPress\Html\PluginUrlReplacer;
2223
use Piwik\Scheduler\Task;
2324
use Piwik\Url;
2425
use Piwik\Version;
@@ -355,11 +356,15 @@ public function onGetSystemSettingsEnd(&$settings)
355356
});
356357
}
357358

358-
public function onDispatchRequestEnd(&$result, $module, $action, $parameters) {
359+
public function onDispatchRequestEnd(&$result, $module, $action, $parameters)
360+
{
359361
if (!empty($result) && is_string($result)) {
360362
// https://wordpress.org/support/topic/bugged-favicon/#post-12995669
361363
$result = str_replace('<link rel="mask-icon"', '<link rel="ignore-mask-icon-ignore"', $result);
362364
$result = str_replace('plugins/CoreHome/images/applePinnedTab.svg', '', $result);
365+
366+
$pluginUrlReplacer = new PluginUrlReplacer();
367+
$result = $pluginUrlReplacer->replaceThirdPartyPluginUrls( $result );
363368
}
364369
}
365370
public function onDispatchRequest(&$module, &$action, &$parameters)
Lines changed: 2 additions & 2 deletions
Lines changed: 2 additions & 2 deletions
Lines changed: 2 additions & 2 deletions
Lines changed: 2 additions & 2 deletions
Lines changed: 2 additions & 2 deletions
Lines changed: 2 additions & 2 deletions

0 commit comments

Comments
 (0)