Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Attention: this is a major release with breaking changes.
- Event and content tracking requests now send `&ca=1` (custom action), so Matomo no longer falls back to recording them as page views if the handling plugin is disabled (#80).
- The `cip` (override IP) tracking parameter is now URL-encoded like every other value (#151).
- No longer calls the deprecated `curl_close()` (it was already a no-op on the supported PHP versions) (#149).
- Auto-detection of the tracked page URL now uses `REQUEST_URI` as the source instead of `PATH_INFO`. With front-controller / path-info routing (e.g. `/dir1/page` handled by `dir1/index.php`), `PATH_INFO` only holds the trailing `/page`, so the tracker previously recorded a truncated URL; it now records the full requested path. `PATH_INFO` is no longer used at all (`SCRIPT_NAME` remains the fallback when `REQUEST_URI` is unavailable) (#141).

### Added
- PHPStan static analysis at max level (`phpstan.neon.dist`) and the Matomo coding standard via PHP_CodeSniffer (`phpcs.xml.dist`), both enforced for every pull request through GitHub Actions.
Expand Down
26 changes: 14 additions & 12 deletions MatomoTracker.php
Original file line number Diff line number Diff line change
Expand Up @@ -2621,24 +2621,26 @@ protected function getCookieMatchingName(string $name): string|false
}

/**
* If current URL is "http://example.org/dir1/dir2/index.php?param1=value1&param2=value2"
* will return "/dir1/dir2/index.php"
* Returns the path portion of the URL the visitor requested (everything between the host and
* the query string). For "http://example.org/dir1/dir2/index.php?param1=value1" this returns
* "/dir1/dir2/index.php"; for a front-controller URL such as "http://example.org/dir1/page"
* (where "/page" is handled by dir1/index.php) it returns "/dir1/page".
*
* The full request path is taken from REQUEST_URI. PATH_INFO is deliberately not used: it only
* holds the trailing path-info segment (e.g. "/page"), so it would drop the directory/script
* prefix and yield a truncated URL. SCRIPT_NAME is the fallback when REQUEST_URI is unavailable.
*
* @ignore
*/
protected static function getCurrentScriptName(): string
{
$url = '';
if (!empty($_SERVER['PATH_INFO'])) {
$url = self::toStringValue($_SERVER['PATH_INFO']);
} else {
if (!empty($_SERVER['REQUEST_URI'])) {
$requestUri = self::toStringValue($_SERVER['REQUEST_URI']);
if (($pos = strpos($requestUri, '?')) !== false) {
$url = substr($requestUri, 0, $pos);
} else {
$url = $requestUri;
}
if (!empty($_SERVER['REQUEST_URI'])) {
$requestUri = self::toStringValue($_SERVER['REQUEST_URI']);
if (($pos = strpos($requestUri, '?')) !== false) {
$url = substr($requestUri, 0, $pos);
} else {
$url = $requestUri;
}
}
if (empty($url) && isset($_SERVER['SCRIPT_NAME'])) {
Expand Down
14 changes: 11 additions & 3 deletions tests/Unit/MatomoTrackerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1848,17 +1848,24 @@ public function testGetCurrentScriptName(): void
unset($_SERVER['PATH_INFO'], $_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']);
$this->assertSame('/', TestableMatomoTracker::callGetCurrentScriptName());

// SCRIPT_NAME is only the fallback when REQUEST_URI is unavailable.
$_SERVER['SCRIPT_NAME'] = 'script.php';
$this->assertSame('/script.php', TestableMatomoTracker::callGetCurrentScriptName());

// REQUEST_URI is the primary source; the query string is stripped.
$_SERVER['REQUEST_URI'] = '/dir/page.php?query=1';
$this->assertSame('/dir/page.php', TestableMatomoTracker::callGetCurrentScriptName());

$_SERVER['REQUEST_URI'] = '/dir/other.php';
$this->assertSame('/dir/other.php', TestableMatomoTracker::callGetCurrentScriptName());

$_SERVER['PATH_INFO'] = '/path/info';
$this->assertSame('/path/info', TestableMatomoTracker::callGetCurrentScriptName());
// Front-controller / path-info routing: with a request for /dir1/page handled by
// dir1/index.php, PATH_INFO is only "/page". The full requested path must still be tracked,
// so REQUEST_URI wins and PATH_INFO is ignored (previously it truncated the URL to "/page").
$_SERVER['REQUEST_URI'] = '/dir1/page';
$_SERVER['PATH_INFO'] = '/page';
$_SERVER['SCRIPT_NAME'] = '/dir1/index.php';
$this->assertSame('/dir1/page', TestableMatomoTracker::callGetCurrentScriptName());
}

public function testGetCurrentQueryStringAndUrl(): void
Expand All @@ -1871,7 +1878,8 @@ public function testGetCurrentQueryStringAndUrl(): void

$_SERVER['HTTPS'] = 'on';
$_SERVER['HTTP_HOST'] = 'matomo.example';
$_SERVER['PATH_INFO'] = '/page';
unset($_SERVER['PATH_INFO']);
$_SERVER['REQUEST_URI'] = '/page';
$this->assertSame('https://matomo.example/page?a=b&c=d', TestableMatomoTracker::callGetCurrentUrl());
}

Expand Down
Loading