Skip to content

Commit

Permalink
Stacked 13: Statistics per album (#2577)
Browse files Browse the repository at this point in the history
* Stacked 14: Allow to chose the photo layout per album (#2575)
* Stacked 15: Show owner instead of just Shared albums (#2574)
* Stacked 16: Composer update + fixing phpstan / Ts checker (#2580)
* Stacked 17: Various fixes. (#2581)

---------

Co-authored-by: Martin Stone <1611702+d7415@users.noreply.github.com>
  • Loading branch information
ildyria and d7415 authored Oct 26, 2024
1 parent 7bf4e09 commit 9c19087
Show file tree
Hide file tree
Showing 118 changed files with 1,580 additions and 818 deletions.
8 changes: 4 additions & 4 deletions app/Actions/Album/ListAlbums.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ public function do(?int $lft, ?int $rgt, ?string $parent_id): array
$query = (new SortingDecorator($unfiltered))
->orderBy($sorting->column, $sorting->order);

/** @var NsCollection<int,string,Album> $albums */
/** @var NsCollection<Album> $albums */
$albums = $query->get();
/** @var NsCollection<int,string,Album> $tree */
/** @var NsCollection<Album> $tree */
$tree = $albums->toTree(null);

$flat_tree = $this->flatten($tree);
Expand All @@ -66,8 +66,8 @@ public function do(?int $lft, ?int $rgt, ?string $parent_id): array
/**
* Flatten the tree and create bread crumb paths.
*
* @param NsCollection<int,string,Album>|Collection<int,Album> $collection
* @param string $prefix
* @param NsCollection<Album>|Collection<int,Album> $collection
* @param string $prefix
*
* @return TAlbumSaved[]
*/
Expand Down
1 change: 1 addition & 0 deletions app/Actions/Album/PositionData.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ public function get(AbstractAlbum $album, bool $includeSubAlbums = false): Posit
$album->all_photos() :
$album->photos();

// @phpstan-ignore-next-line
$photoRelation
->with([
'album' => function (BelongsTo $b) {
Expand Down
75 changes: 72 additions & 3 deletions app/Actions/Statistics/Spaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public function getFullSpacePerUser(?int $owner_id = null): Collection
*
* @return Collection<int,array{type:SizeVariantType,size:int}>
*/
public function getSpacePerSizeVariantType(?int $owner_id = null): Collection
public function getSpacePerSizeVariantTypePerUser(?int $owner_id = null): Collection
{
return DB::table('size_variants')
->when($owner_id !== null, fn ($query) => $query
Expand All @@ -88,6 +88,53 @@ public function getSpacePerSizeVariantType(?int $owner_id = null): Collection
]);
}

/**
* Return the amount of data stored on the server (optionally for an album).
*
* @param string $album_id
*
* @return Collection<int,array{type:SizeVariantType,size:int}>
*/
public function getSpacePerSizeVariantTypePerAlbum(string $album_id): Collection
{
$query = DB::table('albums')
->where('albums.id', '=', $album_id)
->joinSub(
query: DB::table('albums', 'descendants')->select('descendants.id', 'descendants._lft', 'descendants._rgt'),
as: 'descendants',
first: function (JoinClause $join) {
$join->on('albums._lft', '<=', 'descendants._lft')
->on('albums._rgt', '>=', 'descendants._rgt');
}
)
->joinSub(
query: DB::table('photos'),
as: 'photos',
first: 'photos.album_id',
operator: '=',
second: 'descendants.id',
)
->joinSub(
query: DB::table('size_variants')->select(['size_variants.id', 'size_variants.photo_id', 'size_variants.type', 'size_variants.filesize']),
as: 'size_variants',
first: 'size_variants.photo_id',
operator: '=',
second: 'photos.id',
)
->select(
'size_variants.type',
DB::raw('SUM(size_variants.filesize) as size')
)
->groupBy('size_variants.type')
->orderBy('size_variants.type', 'asc');

return $query->get()
->map(fn ($item) => [
'type' => SizeVariantType::from($item->type),
'size' => intval($item->size),
]);
}

/**
* Return size statistics per album.
*
Expand All @@ -99,7 +146,18 @@ public function getSpacePerSizeVariantType(?int $owner_id = null): Collection
public function getSpacePerAlbum(?string $album_id = null, ?int $owner_id = null)
{
$query = DB::table('albums')
->when($album_id !== null, fn ($query) => $query->where('albums.id', '=', $album_id))
->when($album_id !== null,
fn ($query) => $query
->joinSub(
query: DB::table('albums', 'parent')->select('parent.id', 'parent._lft', 'parent._rgt'),
as: 'parent',
first: function (JoinClause $join) {
$join->on('albums._lft', '>=', 'parent._lft')
->on('albums._rgt', '<=', 'parent._rgt');
}
)
->where('parent.id', '=', $album_id)
)
->when($owner_id !== null, fn ($query) => $query->joinSub(
query: DB::table('base_albums')->select(['base_albums.id', 'base_albums.owner_id']),
as: 'base_albums',
Expand Down Expand Up @@ -211,7 +269,18 @@ public function getTotalSpacePerAlbum(?string $album_id = null, ?int $owner_id =
public function getPhotoCountPerAlbum(?string $album_id = null, ?int $owner_id = null)
{
$query = DB::table('albums')
->when($album_id !== null, fn ($query) => $query->where('albums.id', '=', $album_id))
->when($album_id !== null,
fn ($query) => $query
->joinSub(
query: DB::table('albums', 'parent')->select('parent.id', 'parent._lft', 'parent._rgt'),
as: 'parent',
first: function (JoinClause $join) {
$join->on('albums._lft', '>=', 'parent._lft')
->on('albums._rgt', '<=', 'parent._rgt');
}
)
->where('parent.id', '=', $album_id)
)
->joinSub(
query: DB::table('base_albums')->select(['base_albums.id', 'base_albums.owner_id', 'base_albums.title', 'base_albums.is_nsfw']),
as: 'base_albums',
Expand Down
13 changes: 13 additions & 0 deletions app/Contracts/Http/Requests/HasPhotoLayout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Contracts\Http\Requests;

use App\Enum\PhotoLayoutType;

interface HasPhotoLayout
{
/**
* @return PhotoLayoutType|null
*/
public function photoLayout(): ?PhotoLayoutType;
}
1 change: 1 addition & 0 deletions app/Contracts/Http/Requests/RequestAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class RequestAttribute
public const PHOTO_SORTING_ORDER_ATTRIBUTE = 'photo_sorting_order';
public const ALBUM_SORTING_COLUMN_ATTRIBUTE = 'album_sorting_column';
public const ALBUM_SORTING_ORDER_ATTRIBUTE = 'album_sorting_order';
public const ALBUM_PHOTO_LAYOUT = 'photo_layout';

public const PERMISSION_ID = 'perm_id';
public const IS_COMPACT_ATTRIBUTE = 'is_compact';
Expand Down
3 changes: 2 additions & 1 deletion app/Contracts/Models/AbstractAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use App\Models\Photo;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Relation;

/**
Expand All @@ -31,7 +32,7 @@
interface AbstractAlbum
{
/**
* @return Relation<Photo>|Builder<Photo>
* @return Relation<Photo,AbstractAlbum&Model,Collection<int,Photo>>|Builder<Photo>
*/
public function photos(): Relation|Builder;

Expand Down
16 changes: 8 additions & 8 deletions app/Eloquent/FixedQueryBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
namespace App\Eloquent;

use App\Exceptions\Internal\QueryBuilderException;
use Illuminate\Contracts\Database\Query\Expression;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Query\Builder as BaseBuilder;
use Illuminate\Database\Query\Expression;

/**
* Fixed Eloquent query builder.
Expand Down Expand Up @@ -50,10 +50,10 @@ trait FixedQueryBuilderTrait
/**
* Add a basic where clause to the query.
*
* @param \Closure|string|array<string>|Expression $column
* @param mixed $operator
* @param mixed $value
* @param string $boolean
* @param \Closure|string|array<int|string,mixed>|Expression $column
* @param mixed $operator
* @param mixed $value
* @param string $boolean
*
* @return $this
*
Expand Down Expand Up @@ -268,9 +268,9 @@ public function addSelect($column): static
/**
* Add an "or where" clause to the query.
*
* @param \Closure|array<string>|string|Expression $column
* @param mixed $operator
* @param mixed $value
* @param \Closure|string|array<int|string,mixed>|Expression $column
* @param mixed $operator
* @param mixed $value
*
* @return $this
*
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Admin/Maintenance/Model/Album.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
* This is necessary to fix the tree of the album model.
* We do not want to have to deal with the relationships here.
*
* @implements Node<string,Album>
* @implements Node<Album>
*/
class Album extends Model implements Node
{
/** @phpstan-use NodeTrait<string,Album> */
/** @phpstan-use NodeTrait<Album> */
use NodeTrait;
public $timestamps = false;
}
2 changes: 2 additions & 0 deletions app/Http/Controllers/Gallery/AlbumController.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public function updateAlbum(UpdateAlbumRequest $request, SetHeader $setHeader):
$album->copyright = $request->copyright();
$album->photo_sorting = $request->photoSortingCriterion();
$album->album_sorting = $request->albumSortingCriterion();
$album->photo_layout = $request->photoLayout();

$album = $setHeader->do(
album: $album,
Expand All @@ -131,6 +132,7 @@ public function updateTagAlbum(UpdateTagAlbumRequest $request): EditableBaseAlbu
$album->show_tags = $request->tags();
$album->copyright = $request->copyright();
$album->photo_sorting = $request->photoSortingCriterion();
$album->photo_layout = $request->photoLayout();
$album->save();

return EditableBaseAlbumResource::fromModel($album);
Expand Down
16 changes: 10 additions & 6 deletions app/Http/Controllers/StatisticsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Actions\Statistics\Spaces;
use App\Http\Requests\Statistics\SpacePerAlbumRequest;
use App\Http\Requests\Statistics\SpacePerUserRequest;
use App\Http\Requests\Statistics\SpaceSizeVariantRequest;
use App\Http\Resources\Statistics\Album;
use App\Http\Resources\Statistics\Sizes;
use App\Http\Resources\Statistics\UserSpace;
Expand All @@ -29,16 +30,19 @@ public function getSpacePerUser(SpacePerUserRequest $request, Spaces $spaces): C
}

/**
* @param SpacePerUserRequest $request
* @param Spaces $spaces
* @param SpaceSizeVariantRequest $request
* @param Spaces $spaces
*
* @return Collection<int,Sizes>
*/
public function getSpacePerSizeVariantType(SpacePerUserRequest $request, Spaces $spaces): Collection
public function getSpacePerSizeVariantType(SpaceSizeVariantRequest $request, Spaces $spaces): Collection
{
$spaceData = $spaces->getSpacePerSizeVariantType(
owner_id: $request->ownerId()
);
$albumId = $request->album()?->id;
$ownerId = $albumId === null ? $request->ownerId() : null;

$spaceData = $albumId === null
? $spaces->getSpacePerSizeVariantTypePerUser(owner_id: $ownerId)
: $spaces->getSpacePerSizeVariantTypePerAlbum(album_id: $albumId);

return Sizes::collect($spaceData);
}
Expand Down
8 changes: 7 additions & 1 deletion app/Http/Requests/Album/UpdateAlbumRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Contracts\Http\Requests\HasDescription;
use App\Contracts\Http\Requests\HasLicense;
use App\Contracts\Http\Requests\HasPhoto;
use App\Contracts\Http\Requests\HasPhotoLayout;
use App\Contracts\Http\Requests\HasPhotoSortingCriterion;
use App\Contracts\Http\Requests\HasTitle;
use App\Contracts\Http\Requests\RequestAttribute;
Expand All @@ -20,6 +21,7 @@
use App\Enum\ColumnSortingPhotoType;
use App\Enum\LicenseType;
use App\Enum\OrderSortingType;
use App\Enum\PhotoLayoutType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\HasAlbumSortingCriterionTrait;
use App\Http\Requests\Traits\HasAlbumTrait;
Expand All @@ -28,6 +30,7 @@
use App\Http\Requests\Traits\HasCopyrightTrait;
use App\Http\Requests\Traits\HasDescriptionTrait;
use App\Http\Requests\Traits\HasLicenseTrait;
use App\Http\Requests\Traits\HasPhotoLayoutTrait;
use App\Http\Requests\Traits\HasPhotoSortingCriterionTrait;
use App\Http\Requests\Traits\HasPhotoTrait;
use App\Http\Requests\Traits\HasTitleTrait;
Expand All @@ -42,7 +45,7 @@
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\ValidationException;

class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, HasDescription, HasLicense, HasPhotoSortingCriterion, HasAlbumSortingCriterion, HasCopyright, HasPhoto, HasCompactBoolean
class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, HasDescription, HasLicense, HasPhotoSortingCriterion, HasAlbumSortingCriterion, HasCopyright, HasPhoto, HasCompactBoolean, HasPhotoLayout
{
use HasAlbumTrait;
use HasLicenseTrait;
Expand All @@ -54,6 +57,7 @@ class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, H
use HasPhotoSortingCriterionTrait;
use HasAlbumSortingCriterionTrait;
use HasCopyrightTrait;
use HasPhotoLayoutTrait;

public function authorize(): bool
{
Expand Down Expand Up @@ -84,6 +88,7 @@ public function rules(): array
'nullable', new Enum(OrderSortingType::class),
],
RequestAttribute::ALBUM_ASPECT_RATIO_ATTRIBUTE => ['present', 'nullable', new Enum(AspectRatioType::class)],
RequestAttribute::ALBUM_PHOTO_LAYOUT => ['present', 'nullable', new Enum(PhotoLayoutType::class)],
RequestAttribute::COPYRIGHT_ATTRIBUTE => ['present', 'nullable', new CopyrightRule()],
RequestAttribute::IS_COMPACT_ATTRIBUTE => ['required', 'boolean'],
RequestAttribute::HEADER_ID_ATTRIBUTE => ['present', new RandomIDRule(true)],
Expand Down Expand Up @@ -123,6 +128,7 @@ protected function processValidatedValues(array $values, array $files): void
new AlbumSortingCriterion($albumColumn->toColumnSortingType(), $albumOrder);

$this->aspectRatio = AspectRatioType::tryFrom($values[RequestAttribute::ALBUM_ASPECT_RATIO_ATTRIBUTE]);
$this->photoLayout = PhotoLayoutType::tryFrom($values[RequestAttribute::ALBUM_PHOTO_LAYOUT]);
$this->copyright = $values[RequestAttribute::COPYRIGHT_ATTRIBUTE];

$this->is_compact = static::toBoolean($values[RequestAttribute::IS_COMPACT_ATTRIBUTE]);
Expand Down
8 changes: 7 additions & 1 deletion app/Http/Requests/Album/UpdateTagAlbumRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Contracts\Http\Requests\HasCopyright;
use App\Contracts\Http\Requests\HasDescription;
use App\Contracts\Http\Requests\HasPhotoLayout;
use App\Contracts\Http\Requests\HasPhotoSortingCriterion;
use App\Contracts\Http\Requests\HasTagAlbum;
use App\Contracts\Http\Requests\HasTags;
Expand All @@ -12,10 +13,12 @@
use App\DTO\PhotoSortingCriterion;
use App\Enum\ColumnSortingPhotoType;
use App\Enum\OrderSortingType;
use App\Enum\PhotoLayoutType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\Authorize\AuthorizeCanEditAlbumTrait;
use App\Http\Requests\Traits\HasCopyrightTrait;
use App\Http\Requests\Traits\HasDescriptionTrait;
use App\Http\Requests\Traits\HasPhotoLayoutTrait;
use App\Http\Requests\Traits\HasPhotoSortingCriterionTrait;
use App\Http\Requests\Traits\HasTagAlbumTrait;
use App\Http\Requests\Traits\HasTagsTrait;
Expand All @@ -28,14 +31,15 @@
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\ValidationException;

class UpdateTagAlbumRequest extends BaseApiRequest implements HasTagAlbum, HasTitle, HasDescription, HasPhotoSortingCriterion, HasCopyright, HasTags
class UpdateTagAlbumRequest extends BaseApiRequest implements HasTagAlbum, HasTitle, HasDescription, HasPhotoSortingCriterion, HasCopyright, HasTags, HasPhotoLayout
{
use HasTagAlbumTrait;
use HasTitleTrait;
use HasDescriptionTrait;
use HasPhotoSortingCriterionTrait;
use HasCopyrightTrait;
use HasTagsTrait;
use HasPhotoLayoutTrait;
use AuthorizeCanEditAlbumTrait;

/**
Expand All @@ -55,6 +59,7 @@ public function rules(): array
RequestAttribute::TAGS_ATTRIBUTE => 'required|array|min:1',
RequestAttribute::TAGS_ATTRIBUTE . '.*' => 'required|string|min:1',
RequestAttribute::COPYRIGHT_ATTRIBUTE => ['present', 'nullable', new CopyrightRule()],
RequestAttribute::ALBUM_PHOTO_LAYOUT => ['present', 'nullable', new Enum(PhotoLayoutType::class)],
];
}

Expand Down Expand Up @@ -82,6 +87,7 @@ protected function processValidatedValues(array $values, array $files): void
null :
new PhotoSortingCriterion($photoColumn->toColumnSortingType(), $photoOrder);

$this->photoLayout = PhotoLayoutType::tryFrom($values[RequestAttribute::ALBUM_PHOTO_LAYOUT]);
$this->copyright = $values[RequestAttribute::COPYRIGHT_ATTRIBUTE];
$this->tags = $values[RequestAttribute::TAGS_ATTRIBUTE];
}
Expand Down
Loading

0 comments on commit 9c19087

Please sign in to comment.