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
14 changes: 8 additions & 6 deletions app/Actions/Metrics/GetMetrics.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,22 +21,26 @@ public function get(): Collection
/** @var User $user */
$user = Auth::user() ?? throw new UnauthorizedException();

// If this query becomes too slow, then we probably will need to refactor it for something that does not use
// relationship magic but instead extracts the values directly from the database.
return LiveMetrics::query()->with(['photo', 'photo.size_variants', 'album', 'album_impl', 'album.thumb'])
->join('photos', 'photos.id', '=', 'live_metrics.photo_id', 'left')
->join('base_albums', 'base_albums.id', '=', 'live_metrics.album_id', 'left')
->join('albums', 'albums.id', '=', 'live_metrics.album_id', 'left')

// Unnecessary but safer as that avoids some issues in the front-end if the migration failed for some reasons...
->whereNotNull('live_metrics.album_id')

// Owner check (if not admin)
->when(!$user->may_administrate, fn ($q_owner) => $q_owner
->where(fn ($q) => $q
->where('base_albums.owner_id', $user->id)
->orWhere('photos.owner_id', $user->id))
->where('base_albums.owner_id', '=', $user->id)
->orWhere('photos.owner_id', '=', $user->id))
)

// Do not fetch the visit for photos (too noisy)
->where(fn ($q) => $q->where('live_metrics.action', '!=', 'visit')
->orWhere(fn ($q1) => $q1->where('live_metrics.action', 'visit')
->whereNotNull('live_metrics.album_id')))
->orWhere(fn ($q1) => $q1->whereNull('live_metrics.photo_id')))

// Do not fetch the tag albums too.
// Maybe refactor if we decide to unify tag albums and normal albums...
Expand All @@ -45,8 +49,6 @@ public function get(): Collection

->select([
'live_metrics.*',
// // // 'photos.title as photo_title',
// // // 'base_albums.title as album_title',
])
->orderBy('live_metrics.created_at', 'desc')
->get();
Expand Down
17 changes: 17 additions & 0 deletions app/Contracts/Http/Requests/HasFromId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/**
* SPDX-License-Identifier: MIT
* Copyright (c) 2017-2018 Tobias Reich
* Copyright (c) 2018-2025 LycheeOrg.
*/

namespace App\Contracts\Http\Requests;

interface HasFromId
{
/**
* @return string|null
*/
public function from_id(): ?string;
}
1 change: 1 addition & 0 deletions app/Contracts/Http/Requests/RequestAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class RequestAttribute

public const PARENT_ID_ATTRIBUTE = 'parent_id';

public const FROM_ID_ATTRIBUTE = 'from_id';
public const ALBUM_ID_ATTRIBUTE = 'album_id';
public const ALBUM_IDS_ATTRIBUTE = 'album_ids';
public const ALBUM_DECORATION_ATTRIBUTE = 'album_decoration';
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/AlbumDownload.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when an album is downloaded.
*/
final class AlbumDownload extends BaseMetricsEvent
final class AlbumDownload extends BaseAlbumMetricsEvent
{
public function key(): string
{
return 'album_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::DOWNLOAD;
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/AlbumShared.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when a direct link to an album is used.
*/
final class AlbumShared extends BaseMetricsEvent
final class AlbumShared extends BaseAlbumMetricsEvent
{
public function key(): string
{
return 'album_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::SHARED;
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/AlbumVisit.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when an album is open.
*/
final class AlbumVisit extends BaseMetricsEvent
final class AlbumVisit extends BaseAlbumMetricsEvent
{
public function key(): string
{
return 'album_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::VISIT;
Expand Down
42 changes: 42 additions & 0 deletions app/Events/Metrics/BaseAlbumMetricsEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

/**
* SPDX-License-Identifier: MIT
* Copyright (c) 2017-2018 Tobias Reich
* Copyright (c) 2018-2025 LycheeOrg.
*/

namespace App\Events\Metrics;

use App\Enum\MetricsAction;
use Illuminate\Support\Carbon;

abstract class BaseAlbumMetricsEvent extends BaseMetricsEvent
{
/**
* Return the type of key : photo_id or album_id.
*
* @return string
*
* @codeCoverageIgnore, abstract method can't be covered
*/
final public function key(): string
{
return 'album_id';
}

/**
* Convert the event to an array for insertion into the database.
*
* @return array{visitor_id:string,action:MetricsAction,album_id:string,created_at:Carbon}
*/
final public function toArray(): array
{
return [
'visitor_id' => $this->visitor_id,
'action' => $this->metricAction(),
'album_id' => $this->id,
'created_at' => now(),
];
}
}
8 changes: 8 additions & 0 deletions app/Events/Metrics/BaseMetricsEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use App\Enum\MetricsAction;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Support\Carbon;

abstract class BaseMetricsEvent
{
Expand Down Expand Up @@ -40,4 +41,11 @@ abstract public function key(): string;
* @codeCoverageIgnore, abstract method can't be covered
*/
abstract public function metricAction(): MetricsAction;

/**
* Convert the event to an array for insertion into the database.
*
* @return array<string,string|MetricsAction|Carbon>
*/
abstract public function toArray(): array;
}
54 changes: 54 additions & 0 deletions app/Events/Metrics/BasePhotoMetricsEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

/**
* SPDX-License-Identifier: MIT
* Copyright (c) 2017-2018 Tobias Reich
* Copyright (c) 2018-2025 LycheeOrg.
*/

namespace App\Events\Metrics;

use App\Enum\MetricsAction;
use Illuminate\Support\Carbon;

abstract class BasePhotoMetricsEvent extends BaseMetricsEvent
{
public readonly string $album_id;

public function __construct(
string $visitor_id,
string $id,
string $album_id,
) {
parent::__construct($visitor_id, $id);
$this->album_id = $album_id;
}

/**
* Return the type of key : photo_id or album_id.
*
* @return string
*
* @codeCoverageIgnore, abstract method can't be covered
*/
final public function key(): string
{
return 'photo_id';
}

/**
* Convert the event to an array for insertion into the database.
*
* @return array{visitor_id:string,action:MetricsAction,album_id:string,photo_id:string,created_at:Carbon}
*/
final public function toArray(): array
{
return [
'visitor_id' => $this->visitor_id,
'action' => $this->metricAction(),
'album_id' => $this->album_id,
'photo_id' => $this->id,
'created_at' => now(),
];
}
}
7 changes: 1 addition & 6 deletions app/Events/Metrics/PhotoDownload.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when one or multiple photos are downloaded.
*/
final class PhotoDownload extends BaseMetricsEvent
final class PhotoDownload extends BasePhotoMetricsEvent
{
public function key(): string
{
return 'photo_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::DOWNLOAD;
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/PhotoFavourite.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when a photo is visited.
*/
class PhotoFavourite extends BaseMetricsEvent
class PhotoFavourite extends BasePhotoMetricsEvent
{
public function key(): string
{
return 'photo_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::FAVOURITE;
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/PhotoShared.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when a direct link to a photo is used.
*/
class PhotoShared extends BaseMetricsEvent
class PhotoShared extends BasePhotoMetricsEvent
{
public function key(): string
{
return 'photo_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::SHARED;
Expand Down
7 changes: 1 addition & 6 deletions app/Events/Metrics/PhotoVisit.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,8 @@
/**
* This event is fired when a photo is visited.
*/
final class PhotoVisit extends BaseMetricsEvent
final class PhotoVisit extends BasePhotoMetricsEvent
{
public function key(): string
{
return 'photo_id';
}

public function metricAction(): MetricsAction
{
return MetricsAction::VISIT;
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Gallery/AlbumController.php
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ public function getArchive(ZipRequest $request): StreamedResponse

// We dispatch one event per photo.
foreach ($request->photos() as $photo) {
PhotoDownload::dispatchIf($should_measure, $this->visitorId(), $photo->id);
PhotoDownload::dispatchIf($should_measure && $request->from_id() !== null, $this->visitorId(), $photo->id, $request->from_id());
}

return PhotoBaseArchive::resolve()->do($request->photos(), $request->sizeVariant());
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/MetricsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function get(MetricsRequest $request, GetMetrics $get_metrics, CleanupMet
*/
public function photo(PhotoMetricsRequest $request): void
{
PhotoVisit::dispatchIf(self::shouldMeasure(), $request->visitorId(), $request->photoIds()[0]);
PhotoVisit::dispatchIf(self::shouldMeasure() && $request->from_id() !== null, $request->visitorId(), $request->photoIds()[0], $request->from_id());

return;
}
Expand All @@ -59,7 +59,7 @@ public function photo(PhotoMetricsRequest $request): void
*/
public function favourite(PhotoMetricsRequest $request): void
{
PhotoFavourite::dispatchIf(self::shouldMeasure(), $request->visitorId(), $request->photoIds()[0]);
PhotoFavourite::dispatchIf(self::shouldMeasure() && $request->from_id() !== null, $request->visitorId(), $request->photoIds()[0], $request->from_id());

return;
}
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/VueController.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ public function gallery(?string $album_id = null, ?string $photo_id = null): Vie
}

if ($photo !== null) {
PhotoShared::dispatchIf(MetricsController::shouldMeasure(), $this->visitorId(), $photo->id);
PhotoShared::dispatchIf(MetricsController::shouldMeasure() && $album_id !== null, $this->visitorId(), $photo->id, $album_id);
} elseif ($album !== null) {
AlbumShared::dispatchIf(MetricsController::shouldMeasure(), $this->visitorId(), $album->get_id());
}
Expand Down
9 changes: 8 additions & 1 deletion app/Http/Requests/Album/ZipRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,35 @@
namespace App\Http\Requests\Album;

use App\Contracts\Http\Requests\HasAlbums;
use App\Contracts\Http\Requests\HasFromId;
use App\Contracts\Http\Requests\HasPhotos;
use App\Contracts\Http\Requests\HasSizeVariant;
use App\Contracts\Http\Requests\RequestAttribute;
use App\Contracts\Models\AbstractAlbum;
use App\Enum\DownloadVariantType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\HasAlbumsTrait;
use App\Http\Requests\Traits\HasFromIdTrait;
use App\Http\Requests\Traits\HasPhotosTrait;
use App\Http\Requests\Traits\HasSizeVariantTrait;
use App\Models\Photo;
use App\Policies\AlbumPolicy;
use App\Policies\PhotoPolicy;
use App\Rules\AlbumIDListRule;
use App\Rules\RandomIDListRule;
use App\Rules\RandomIDRule;
use Illuminate\Support\Facades\Gate;
use Illuminate\Validation\Rules\Enum;

/**
* @implements HasAlbums<AbstractAlbum>
*/
class ZipRequest extends BaseApiRequest implements HasAlbums, HasPhotos, HasSizeVariant
class ZipRequest extends BaseApiRequest implements HasAlbums, HasPhotos, HasSizeVariant, HasFromId
{
/** @use HasAlbumsTrait<AbstractAlbum> */
use HasAlbumsTrait;
use HasPhotosTrait;
use HasFromIdTrait;
use HasSizeVariantTrait;

/**
Expand Down Expand Up @@ -67,6 +71,7 @@ public function rules(): array
RequestAttribute::ALBUM_IDS_ATTRIBUTE => ['sometimes', new AlbumIDListRule()],
RequestAttribute::PHOTO_IDS_ATTRIBUTE => ['sometimes', new RandomIDListRule()],
RequestAttribute::SIZE_VARIANT_ATTRIBUTE => ['required_if_accepted:photos_ids', new Enum(DownloadVariantType::class)],
RequestAttribute::FROM_ID_ATTRIBUTE => ['required_if_accepted:photos_ids', new RandomIDRule(true)],
];
}

Expand All @@ -85,6 +90,8 @@ protected function processValidatedValues(array $values, array $files): void
$photo_ids = $values[RequestAttribute::PHOTO_IDS_ATTRIBUTE] ?? null;
$photo_ids = $photo_ids === null ? [] : explode(',', $photo_ids);
$this->processPhotos($photo_ids);

$this->from_id = $values[RequestAttribute::FROM_ID_ATTRIBUTE] ?? null;
}

/**
Expand Down
Loading