|
25 | 25 | use Composer\InstalledVersions; |
26 | 26 | use Composer\Semver\VersionParser; |
27 | 27 | use Illuminate\Database\Eloquent\Model; |
| 28 | +use Illuminate\Pagination\LengthAwarePaginator; |
28 | 29 | use Illuminate\Support\Collection; |
29 | 30 | use Illuminate\Support\Facades\Gate; |
30 | 31 | use Safe\Exceptions\InfoException; |
@@ -229,6 +230,67 @@ private function compressAlbum(AbstractAlbum $album, array &$used_dir_names, ?st |
229 | 230 | // TODO: Ensure that the size variant `original` for each photo is eagerly loaded as it is needed below. This must be solved in close coordination with `ArchiveAlbumRequest`. |
230 | 231 | $photos = $album->get_photos(); |
231 | 232 |
|
| 233 | + // For smart albums, get_photos() returns a paginator. We need to iterate through all pages. |
| 234 | + if ($photos instanceof LengthAwarePaginator) { |
| 235 | + $this->compressPhotosFromPaginator($photos, $album, $full_name_of_directory, $used_file_names, $zip); |
| 236 | + } else { |
| 237 | + $this->compressPhotosFromCollection($photos, $album, $full_name_of_directory, $used_file_names, $zip); |
| 238 | + } |
| 239 | + |
| 240 | + // Recursively compress sub-albums |
| 241 | + if ($album instanceof Album) { |
| 242 | + $sub_dirs = []; |
| 243 | + // TODO: For higher efficiency, ensure that the photos of each child album together with the original size variant are eagerly loaded. |
| 244 | + $sub_albums = $album->children; |
| 245 | + foreach ($sub_albums as $sub_album) { |
| 246 | + try { |
| 247 | + $this->compressAlbum($sub_album, $sub_dirs, $full_name_of_directory, $zip); |
| 248 | + // @codeCoverageIgnoreStart |
| 249 | + } catch (\Throwable $e) { |
| 250 | + Handler::reportSafely($e); |
| 251 | + } |
| 252 | + // @codeCoverageIgnoreEnd |
| 253 | + } |
| 254 | + } |
| 255 | + } |
| 256 | + |
| 257 | + /** |
| 258 | + * Compresses photos from a paginator by iterating through all pages. |
| 259 | + * |
| 260 | + * @param LengthAwarePaginator<int,Photo> $paginator |
| 261 | + * @param AbstractAlbum $album |
| 262 | + * @param string $full_name_of_directory |
| 263 | + * @param array<string> $used_file_names |
| 264 | + * @param ZipStream $zip |
| 265 | + */ |
| 266 | + private function compressPhotosFromPaginator(LengthAwarePaginator $paginator, AbstractAlbum $album, string $full_name_of_directory, array &$used_file_names, ZipStream $zip): void |
| 267 | + { |
| 268 | + $current_page = 1; |
| 269 | + $last_page = $paginator->lastPage(); |
| 270 | + |
| 271 | + // Process first page (already loaded) |
| 272 | + $this->compressPhotosFromCollection($paginator->getCollection(), $album, $full_name_of_directory, $used_file_names, $zip); |
| 273 | + |
| 274 | + // Process remaining pages |
| 275 | + while ($current_page < $last_page) { |
| 276 | + $current_page++; |
| 277 | + /** @var LengthAwarePaginator<int,Photo> $next_page */ |
| 278 | + $next_page = $album->photos()->paginate($paginator->perPage(), ['*'], 'page', $current_page); |
| 279 | + $this->compressPhotosFromCollection($next_page->getCollection(), $album, $full_name_of_directory, $used_file_names, $zip); |
| 280 | + } |
| 281 | + } |
| 282 | + |
| 283 | + /** |
| 284 | + * Compresses photos from a collection. |
| 285 | + * |
| 286 | + * @param Collection<int,Photo>|iterable<Photo> $photos |
| 287 | + * @param AbstractAlbum $album |
| 288 | + * @param string $full_name_of_directory |
| 289 | + * @param array<string> $used_file_names |
| 290 | + * @param ZipStream $zip |
| 291 | + */ |
| 292 | + private function compressPhotosFromCollection(Collection|iterable $photos, AbstractAlbum $album, string $full_name_of_directory, array &$used_file_names, ZipStream $zip): void |
| 293 | + { |
232 | 294 | /** @var Photo $photo */ |
233 | 295 | foreach ($photos as $photo) { |
234 | 296 | try { |
@@ -265,22 +327,6 @@ private function compressAlbum(AbstractAlbum $album, array &$used_dir_names, ?st |
265 | 327 | } |
266 | 328 | // @codeCoverageIgnoreEnd |
267 | 329 | } |
268 | | - |
269 | | - // Recursively compress sub-albums |
270 | | - if ($album instanceof Album) { |
271 | | - $sub_dirs = []; |
272 | | - // TODO: For higher efficiency, ensure that the photos of each child album together with the original size variant are eagerly loaded. |
273 | | - $sub_albums = $album->children; |
274 | | - foreach ($sub_albums as $sub_album) { |
275 | | - try { |
276 | | - $this->compressAlbum($sub_album, $sub_dirs, $full_name_of_directory, $zip); |
277 | | - // @codeCoverageIgnoreStart |
278 | | - } catch (\Throwable $e) { |
279 | | - Handler::reportSafely($e); |
280 | | - } |
281 | | - // @codeCoverageIgnoreEnd |
282 | | - } |
283 | | - } |
284 | 330 | } |
285 | 331 |
|
286 | 332 | /** |
|
0 commit comments