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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
## Changelog

# 5.2.4 - 2026-09-14
- Fixed imports stalling once they reached the oldest available date, without importing recent data

# 5.2.3 - 2026-08-24
- Added escapeshell for matomo domain argument

Expand Down
31 changes: 29 additions & 2 deletions ImportStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public function startingImport($propertyId, $accountId, $viewId, $idSite, $extra
'import_end_time' => null,
'last_job_start_time' => $now,
'last_day_archived' => null,
'import_range_start' => null,
'import_range_start' => $this->getDefaultImportRangeStart($idSite),
'import_range_end' => null,
'extra_custom_dimensions' => $extraCustomDimensions,
'days_finished_since_rate_limit' => 0,
Expand All @@ -81,6 +81,28 @@ public function startingImport($propertyId, $accountId, $viewId, $idSite, $extra
$this->saveStatus($status);
return $status;
}
/**
* The oldest date there is data to import, used as the start of the import range.
*
* Imports run backwards, from the end date towards this one. Both finishing an import and switching over
* to importing recent days compare progress against the recorded range start, so an import that never
* records one can reach the oldest date and then neither finish nor move forward - it just stops making
* progress. Both importers create the Matomo site from the GA property's create time immediately before
* starting the import, so the site creation date is the property's first day.
*
* @param int $idSite
* @return string|null The date as YYYY-MM-DD, or null if no creation date could be read.
*/
private function getDefaultImportRangeStart($idSite)
{
try {
return Date::factory(Site::getCreationDateFor($idSite))->toString();
} catch (\Exception $ex) {
// Best effort only - starting an import must not fail over an unreadable creation date. The import
// command makes the same lookup as its own fallback, so it still knows where to stop.
return null;
}
}
public function getImportedDateRange($idSite)
{
$optionName = self::IMPORTED_DATE_RANGE_PREFIX . $idSite;
Expand Down Expand Up @@ -115,7 +137,12 @@ public function dayImportFinished($idSite, Date $date, $isMainImport = \true, $s
public function setImportDateRange($idSite, Date $startDate = null, Date $endDate = null)
{
$status = $this->getImportStatus($idSite);
$status['import_range_start'] = $startDate ? $startDate->toString() : '';
// Callers that pass no start date mean "leave it as it is", not "clear it" - Controller::startImportGA4()
// calls this whenever either date is given, so blanking here would drop the range start set when the
// import began.
if ($startDate !== null) {
$status['import_range_start'] = $startDate->toString();
}
$status['import_range_end'] = $endDate ? $endDate->toString() : '';
if (!empty($status['import_range_start']) && !empty($status['import_range_end']) && Date::factory($status['import_range_start'])->isLater(Date::factory($status['import_range_end']))) {
throw new \Exception("The start date cannot be past the end date.");
Expand Down
2 changes: 1 addition & 1 deletion plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "GoogleAnalyticsImporter",
"description": "Import reports from a Google Analytics account into Matomo.",
"version": "5.2.3",
"version": "5.2.4",
"theme": false,
"require": {
"matomo": ">=5.0.0-rc5,<6.0.0-b1"
Expand Down
Loading
Loading