Skip to content

Commit d60921e

Browse files
authored
Refactoring photo-album relation (#3359)
1 parent 403fb9e commit d60921e

File tree

72 files changed

+996
-679
lines changed

Some content is hidden

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

72 files changed

+996
-679
lines changed

app/Actions/Album/Delete.php

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,9 @@
2323
use App\Models\BaseAlbumImpl;
2424
use App\Models\Statistics;
2525
use App\Models\TagAlbum;
26-
use App\SmartAlbums\UnsortedAlbum;
2726
use Illuminate\Database\Eloquent\Collection;
2827
use Illuminate\Database\Eloquent\ModelNotFoundException;
2928
use Illuminate\Database\Query\Builder as BaseBuilder;
30-
use Illuminate\Support\Facades\Auth;
3129
use Safe\Exceptions\ArrayException;
3230

3331
/**
@@ -73,18 +71,6 @@ class Delete
7371
public function do(array $album_ids): FileDeleter
7472
{
7573
try {
76-
$unsorted_photo_ids = [];
77-
78-
// Among the smart albums, the unsorted album is special,
79-
// because it provides deletion of photos
80-
if (in_array(UnsortedAlbum::ID, $album_ids, true)) {
81-
$query = UnsortedAlbum::getInstance()->photos();
82-
if (Auth::user()?->may_administrate !== true) {
83-
$query->where('owner_id', '=', Auth::id() ?? throw new UnauthenticatedException());
84-
}
85-
$unsorted_photo_ids = $query->pluck('id')->all();
86-
}
87-
8874
// Only regular albums are owners of photos, so we only need to
8975
// find all photos in those and their descendants
9076
// Only load necessary attributes for tree; in particular avoid
@@ -111,7 +97,7 @@ public function do(array $album_ids): FileDeleter
11197

11298
// Delete the photos from DB and obtain the list of files which need
11399
// to be deleted later
114-
$file_deleter = (new PhotoDelete())->do($unsorted_photo_ids, $recursive_album_ids);
100+
$file_deleter = (new PhotoDelete())->do([], null, $recursive_album_ids);
115101
$file_deleter->addFiles($recursive_album_tracks, StorageDiskType::LOCAL->value);
116102

117103
// Remove the sub-forest spanned by the regular albums

app/Actions/Album/Merge.php

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@
88

99
namespace App\Actions\Album;
1010

11+
use App\Constants\PhotoAlbum as PA;
1112
use App\Exceptions\Internal\QueryBuilderException;
1213
use App\Exceptions\ModelDBException;
1314
use App\Models\Album;
14-
use App\Models\Photo;
1515
use Illuminate\Database\Eloquent\ModelNotFoundException;
1616
use Illuminate\Support\Collection;
17+
use Illuminate\Support\Facades\DB;
1718

1819
class Merge
1920
{
@@ -27,10 +28,28 @@ class Merge
2728
*/
2829
public function do(Album $target_album, Collection $albums): void
2930
{
30-
// Merge photos of source albums into target
31-
Photo::query()
32-
->whereIn('album_id', $albums->pluck('id'))
33-
->update(['album_id' => $target_album->id]);
31+
$origin_ids = $albums->pluck('id')->all();
32+
33+
// Select all photos ids of the source albums
34+
$photos_ids = DB::table(PA::PHOTO_ALBUM)
35+
->whereIn(PA::ALBUM_ID, $origin_ids)
36+
->pluck(PA::PHOTO_ID)->all();
37+
38+
// Delete the existing links at destination (avoid duplicates key contraint)
39+
DB::table(PA::PHOTO_ALBUM)
40+
->whereIn(PA::PHOTO_ID, $photos_ids)
41+
->where(PA::ALBUM_ID, '=', $target_album->id)
42+
->delete();
43+
44+
// Insert the new links
45+
DB::table(PA::PHOTO_ALBUM)
46+
->insert(array_map(fn (string $id) => ['photo_id' => $id, 'album_id' => $target_album->id], $photos_ids));
47+
48+
// Delete the existing links from the origins
49+
DB::table(PA::PHOTO_ALBUM)
50+
->whereIn(PA::PHOTO_ID, $photos_ids)
51+
->whereIn(PA::ALBUM_ID, $origin_ids)
52+
->delete();
3453

3554
// Merge sub-albums of source albums into target
3655
/** @var Album $album */

app/Actions/Album/PositionData.php

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
use App\Enum\SizeVariantType;
1313
use App\Http\Resources\Collections\PositionDataResource;
1414
use App\Models\Album;
15-
use Illuminate\Database\Eloquent\Relations\BelongsTo;
1615
use Illuminate\Database\Eloquent\Relations\HasMany;
1716

1817
class PositionData
@@ -25,13 +24,6 @@ public function get(AbstractAlbum $album, bool $include_sub_albums = false): Pos
2524

2625
$photo_relation
2726
->with([
28-
'album' => function (BelongsTo $b): void {
29-
// The album is required for photos to properly
30-
// determine access and visibility rights; but we
31-
// don't need to determine the cover and thumbnail for
32-
// each album
33-
$b->without(['cover', 'thumb']);
34-
},
3527
'statistics',
3628
'size_variants' => function (HasMany $r): void {
3729
// The web GUI only uses the small and thumb size
@@ -47,6 +39,6 @@ public function get(AbstractAlbum $album, bool $include_sub_albums = false): Pos
4739
->whereNotNull('latitude')
4840
->whereNotNull('longitude');
4941

50-
return new PositionDataResource($album->get_id(), $album->get_title(), $photo_relation->get(), $album instanceof Album ? $album->track_url : null);
42+
return new PositionDataResource($album, $photo_relation->get(), $album instanceof Album ? $album->track_url : null);
5143
}
5244
}

app/Actions/Albums/PositionData.php

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,6 @@ public function do(): PositionDataResource
3838
$photo_query = $this->photo_query_policy->applySearchabilityFilter(
3939
query: Photo::query()
4040
->with([
41-
'album' => function ($b): void {
42-
// The album is required for photos to properly
43-
// determine access and visibility rights; but we
44-
// don't need to determine the cover and thumbnail for
45-
// each album
46-
$b->without(['cover', 'thumb']);
47-
},
4841
'statistics',
4942
'size_variants' => function ($r): void {
5043
// The web GUI only uses the small and thumb size
@@ -63,6 +56,6 @@ public function do(): PositionDataResource
6356
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_map')
6457
);
6558

66-
return new PositionDataResource(null, null, $photo_query->get(), null);
59+
return new PositionDataResource(null, $photo_query->get(), null);
6760
}
6861
}

app/Actions/Diagnostics/Pipes/Checks/DBIntegrityCheck.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ public function handle(array &$data, \Closure $next): array
3333

3434
$sub_join = DB::table('size_variants')->where('size_variants.type', '=', 0);
3535
$photos = Photo::query()
36-
->with(['album'])
37-
->select(['photos.id', 'title', 'album_id'])
36+
->with(['albums'])
37+
->select(['photos.id', 'title'])
3838
->joinSub($sub_join, 'size_variants', 'size_variants.photo_id', '=', 'photos.id', 'left')
3939
->whereNull('size_variants.id')
4040
->get();
4141

4242
foreach ($photos as $photo) {
43-
$data[] = DiagnosticData::error('Photo without Original found -- ' . $photo->title . ' in ' . ($photo->album?->title ?? __('gallery.smart_album.unsorted')), self::class);
43+
$data[] = DiagnosticData::error('Photo without Original found -- ' . $photo->title . ' in ' . ($photo->albums?->first()?->title ?? __('gallery.smart_album.unsorted')), self::class);
4444
}
4545

4646
return $next($data);

app/Actions/Photo/Create.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,9 @@ private function handleDuplicate(InitDTO $init_dto): Photo
139139
$pipes[] = Duplicate\SaveIfDirty::class;
140140
}
141141
$pipes[] = Duplicate\ThrowSkipDuplicate::class;
142-
$pipes[] = Duplicate\ReplicateAsPhoto::class;
143142
$pipes[] = Shared\SetStarred::class;
144-
$pipes[] = Shared\SetParentAndOwnership::class;
145143
$pipes[] = Shared\Save::class;
144+
$pipes[] = Shared\SetParent::class;
146145
$pipes[] = Shared\SaveStatistics::class;
147146
$pipes[] = Shared\NotifyAlbums::class;
148147

@@ -167,14 +166,15 @@ private function handleStandalone(InitDTO $init_dto): Photo
167166
Standalone\InitNamingStrategy::class,
168167
Shared\HydrateMetadata::class,
169168
Shared\SetStarred::class,
170-
Shared\SetParentAndOwnership::class,
169+
Shared\SetOwnership::class,
171170
Standalone\SetOriginalChecksum::class,
172171
Standalone\FetchSourceImage::class,
173172
Standalone\ExtractGoogleMotionPictures::class,
174173
Standalone\PlacePhoto::class,
175174
Standalone\PlaceGoogleMotionVideo::class,
176175
Standalone\SetChecksum::class,
177176
Shared\Save::class,
177+
Shared\SetParent::class,
178178
Shared\SaveStatistics::class,
179179
Standalone\CreateOriginalSizeVariant::class,
180180
Standalone\CreateSizeVariants::class,
@@ -258,14 +258,15 @@ private function handlePhotoLivePartner(InitDTO $init_dto): Photo
258258
Standalone\InitNamingStrategy::class,
259259
Shared\HydrateMetadata::class,
260260
Shared\SetStarred::class,
261-
Shared\SetParentAndOwnership::class,
261+
Shared\SetOwnership::class,
262262
Standalone\SetOriginalChecksum::class,
263263
Standalone\FetchSourceImage::class,
264264
Standalone\ExtractGoogleMotionPictures::class,
265265
Standalone\PlacePhoto::class,
266266
Standalone\PlaceGoogleMotionVideo::class,
267267
Standalone\SetChecksum::class,
268268
Shared\Save::class,
269+
Shared\SetParent::class,
269270
Standalone\CreateOriginalSizeVariant::class,
270271
Standalone\CreateSizeVariants::class,
271272
Standalone\EncodePlaceholder::class,

0 commit comments

Comments
 (0)