-
-
Notifications
You must be signed in to change notification settings - Fork 366
Expand file tree
/
Copy pathZipRequest.php
More file actions
149 lines (130 loc) · 4.34 KB
/
ZipRequest.php
File metadata and controls
149 lines (130 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
<?php
/**
* SPDX-License-Identifier: MIT
* Copyright (c) 2017-2018 Tobias Reich
* Copyright (c) 2018-2025 LycheeOrg.
*/
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, HasFromId
{
/** @use HasAlbumsTrait<AbstractAlbum> */
use HasAlbumsTrait;
use HasPhotosTrait;
use HasFromIdTrait;
use HasSizeVariantTrait;
/**
* {@inheritDoc}
*/
public function authorize(): bool
{
/** @var AbstractAlbum $album */
foreach ($this->albums as $album) {
if (!Gate::check(AlbumPolicy::CAN_DOWNLOAD, $album)) {
return false;
}
}
/** @var Photo $photo */
foreach ($this->photos as $photo) {
if (!Gate::check(PhotoPolicy::CAN_DOWNLOAD, $photo)) {
return false;
}
}
return true;
}
/**
* {@inheritDoc}
*/
public function rules(): array
{
return [
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)],
];
}
/**
* {@inheritDoc}
*/
protected function processValidatedValues(array $values, array $files): void
{
$album_ids = $values[RequestAttribute::ALBUM_IDS_ATTRIBUTE] ?? null;
$album_ids = $album_ids === null ? [] : explode(',', $album_ids);
$this->processAlbums($album_ids);
// only interesting if we have no albums
$this->size_variant = DownloadVariantType::tryFrom($values[RequestAttribute::SIZE_VARIANT_ATTRIBUTE] ?? '');
$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;
}
/**
* Process albums. Set to empty collection if no albums are requested.
*
* @param string[] $album_ids
*
* @return void
*/
private function processAlbums(array $album_ids): void
{
if (count($album_ids) === 0) {
$this->albums = collect();
return;
}
// TODO: `App\Actions\Album\Archive::compressAlbum` iterates over the original size variant of each photo in the album; we should eagerly load them for higher efficiency.
$this->albums = $this->album_factory->findAbstractAlbumsOrFail($album_ids);
}
/**
* Process photos. Set to empty collection if no photos are requested.
*
* @param string[] $photo_ids
*
* @return void
*/
private function processPhotos(array $photo_ids): void
{
if (count($photo_ids) === 0) {
$this->photos = collect();
return;
}
$photo_query = Photo::query()->with(['album']);
// The condition is required, because Lychee also supports to archive
// the "live video" as a size variant which is not a proper size variant
$variant = $this->size_variant->getSizeVariantType();
if ($variant !== null) { // NOT LIVE PHOTO
// If a proper size variant is requested, eagerly load the size
// variants but only the requested type due to efficiency reasons
$photo_query = $photo_query->with([
'size_variants' => fn ($r) => $r->where('type', '=', $variant),
]);
}
// `findOrFail` returns the union `Photo|Collection<int,Photo>`
// which is not assignable to `Collection<int,Photo>`; but as we query
// with an array of IDs we never get a single entity (even if the
// array only contains a single ID).
$this->photos = $photo_query->findOrFail($photo_ids);
}
}