Skip to content

Commit 62018e9

Browse files
authored
Add fail safe for non-existing statistics & maintenance option (#3365)
1 parent 314f48e commit 62018e9

32 files changed

Lines changed: 448 additions & 1 deletion

app/Actions/Diagnostics/Errors.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
use App\Actions\Diagnostics\Pipes\Checks\PHPVersionCheck;
2929
use App\Actions\Diagnostics\Pipes\Checks\PlaceholderExistsCheck;
3030
use App\Actions\Diagnostics\Pipes\Checks\SmallMediumExistsCheck;
31+
use App\Actions\Diagnostics\Pipes\Checks\StatisticsIntegrityCheck;
3132
use App\Actions\Diagnostics\Pipes\Checks\SupporterCheck;
3233
use App\Actions\Diagnostics\Pipes\Checks\TimezoneCheck;
3334
use App\Actions\Diagnostics\Pipes\Checks\UpdatableCheck;
@@ -65,6 +66,7 @@ class Errors
6566
CacheTemporaryUrlCheck::class,
6667
SupporterCheck::class,
6768
ImagickPdfCheck::class,
69+
StatisticsIntegrityCheck::class,
6870
];
6971

7072
/**
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2025 LycheeOrg.
7+
*/
8+
9+
namespace App\Actions\Diagnostics\Pipes\Checks;
10+
11+
use App\Contracts\DiagnosticPipe;
12+
use App\DTO\DiagnosticData;
13+
use App\Http\Resources\Diagnostics\StatisticsCheckResource;
14+
use App\Models\Configs;
15+
use Illuminate\Support\Facades\DB;
16+
17+
/**
18+
* Check whether or not there are photos or albums without statistics.
19+
*/
20+
class StatisticsIntegrityCheck implements DiagnosticPipe
21+
{
22+
/**
23+
* {@inheritDoc}
24+
*/
25+
public function handle(array &$data, \Closure $next): array
26+
{
27+
$check = $this->get();
28+
29+
if ($check->missing_albums > 0) {
30+
$data[] = DiagnosticData::warn(sprintf('There are %d albums without statistics.', $check->missing_albums), self::class,
31+
['Go to the maintenance page to fix this.']);
32+
}
33+
34+
if ($check->missing_albums > 0) {
35+
$data[] = DiagnosticData::warn(sprintf('There are %d photos without statistics.', $check->missing_photos), self::class,
36+
['Go to the maintenance page to fix this.']);
37+
}
38+
39+
return $next($data);
40+
}
41+
42+
public function get(): StatisticsCheckResource
43+
{
44+
// Just skip the check, we don't care.
45+
if (!Configs::getValueAsBool('metrics_enabled')) {
46+
return new StatisticsCheckResource(0, 0);
47+
}
48+
49+
$num_albums = DB::table('base_albums')->leftJoin('statistics', 'base_albums.id', '=', 'statistics.album_id')
50+
->whereNull('statistics.id')
51+
->count();
52+
$num_photos = DB::table('photos')->leftJoin('statistics', 'photos.id', '=', 'statistics.photo_id')
53+
->whereNull('statistics.id')
54+
->count();
55+
56+
return new StatisticsCheckResource($num_albums, $num_photos);
57+
}
58+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2025 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Controllers\Admin\Maintenance;
10+
11+
use App\Actions\Diagnostics\Pipes\Checks\StatisticsIntegrityCheck;
12+
use App\Http\Requests\Maintenance\MaintenanceRequest;
13+
use App\Http\Resources\Diagnostics\StatisticsCheckResource;
14+
use App\Models\Configs;
15+
use Illuminate\Routing\Controller;
16+
use Illuminate\Support\Facades\DB;
17+
18+
/**
19+
* We may miss some statistics because of generation problem.
20+
* This module aims to solve this issue.
21+
*/
22+
class StatisticsCheck extends Controller
23+
{
24+
public function __construct(
25+
private StatisticsIntegrityCheck $check,
26+
) {
27+
}
28+
29+
/**
30+
* Create th emissing statistics.
31+
*
32+
* @return StatisticsCheckResource
33+
*/
34+
public function do(MaintenanceRequest $request): StatisticsCheckResource
35+
{
36+
// Just skip the check, we don't care.
37+
if (!Configs::getValueAsBool('metrics_enabled')) {
38+
return new StatisticsCheckResource(0, 0);
39+
}
40+
41+
DB::statement('INSERT INTO statistics (photo_id) SELECT photos.id FROM photos LEFT OUTER JOIN statistics ON photos.id = photo_id WHERE statistics.id IS NULL');
42+
DB::statement('INSERT INTO statistics (album_id) SELECT base_albums.id FROM base_albums LEFT OUTER JOIN statistics ON base_albums.id = album_id WHERE statistics.id IS NULL');
43+
44+
return $this->check->get();
45+
}
46+
47+
/**
48+
* Check how many statistics are missing for photos and albums.
49+
*
50+
* @return StatisticsCheckResource
51+
*/
52+
public function check(MaintenanceRequest $request): StatisticsCheckResource
53+
{
54+
return $this->check->get();
55+
}
56+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/**
4+
* SPDX-License-Identifier: MIT
5+
* Copyright (c) 2017-2018 Tobias Reich
6+
* Copyright (c) 2018-2025 LycheeOrg.
7+
*/
8+
9+
namespace App\Http\Resources\Diagnostics;
10+
11+
use Spatie\LaravelData\Data;
12+
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
13+
14+
#[TypeScript()]
15+
class StatisticsCheckResource extends Data
16+
{
17+
public function __construct(
18+
public int $missing_photos,
19+
public int $missing_albums,
20+
) {
21+
}
22+
}

app/Http/Resources/Models/PhotoStatisticsResource.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,12 @@ public function __construct(
2323
) {
2424
}
2525

26-
public static function fromModel(Statistics $stats): PhotoStatisticsResource
26+
public static function fromModel(Statistics|null $stats): PhotoStatisticsResource|null
2727
{
28+
if ($stats === null) {
29+
return null;
30+
}
31+
2832
return new self(
2933
$stats->visit_count,
3034
$stats->download_count,

app/Metadata/Cache/RouteCacheManager.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ public function __construct()
7171
'api/v2/Maintenance::update' => false,
7272
'api/v2/Maintenance::countDuplicates' => false,
7373
'api/v2/Maintenance::searchDuplicates' => false,
74+
'api/v2/Maintenance::statisticsIntegrity' => false,
7475

7576
'api/v2/Map' => new RouteCacheConfig(tag: CacheTag::GALLERY, user_dependant: true, extra: [RequestAttribute::ALBUM_ID_ATTRIBUTE]),
7677
'api/v2/Map::provider' => new RouteCacheConfig(tag: CacheTag::SETTINGS),

lang/ar/maintenance.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
'update-button' => '',
5959
'no-pending-updates' => '',
6060
],
61+
'statistics-check' => [
62+
'title' => 'Statistics integrity Check',
63+
'missing_photos' => '%d photo statistics missing.',
64+
'missing_albums' => '%d album statistics missing.',
65+
'button' => 'Create missing',
66+
],
6167
'flush-cache' => [
6268
'title' => '',
6369
'description' => '',

lang/cz/maintenance.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
'update-button' => 'Update',
6060
'no-pending-updates' => 'No pending update.',
6161
],
62+
'statistics-check' => [
63+
'title' => 'Statistics integrity Check',
64+
'missing_photos' => '%d photo statistics missing.',
65+
'missing_albums' => '%d album statistics missing.',
66+
'button' => 'Create missing',
67+
],
6268
'flush-cache' => [
6369
'title' => 'Flush Cache',
6470
'description' => 'Flush the cache of every user to solve invalidation problems.',

lang/de/maintenance.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@
5757
'update-button' => 'Update',
5858
'no-pending-updates' => 'Keine Updates verfügbar.',
5959
],
60+
'statistics-check' => [
61+
'title' => 'Statistics integrity Check',
62+
'missing_photos' => '%d photo statistics missing.',
63+
'missing_albums' => '%d album statistics missing.',
64+
'button' => 'Create missing',
65+
],
6066
'flush-cache' => [
6167
'title' => 'Cache leeren',
6268
'description' => 'Leeren Sie den Cache jedes Benutzers, um Ungültigkeitsprobleme zu lösen.',

lang/el/maintenance.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@
5959
'update-button' => 'Update',
6060
'no-pending-updates' => 'No pending update.',
6161
],
62+
'statistics-check' => [
63+
'title' => 'Statistics integrity Check',
64+
'missing_photos' => '%d photo statistics missing.',
65+
'missing_albums' => '%d album statistics missing.',
66+
'button' => 'Create missing',
67+
],
6268
'flush-cache' => [
6369
'title' => 'Flush Cache',
6470
'description' => 'Flush the cache of every user to solve invalidation problems.',

0 commit comments

Comments
 (0)