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
28 changes: 28 additions & 0 deletions app/Policies/PhotoQueryPolicy.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,34 @@ public function applySearchabilityFilter(FixedQueryBuilder $query, ?Album $origi
});
}

/**
* Restricts the photo query to only non sensitive photos.
*
* @param FixedQueryBuilder $query
* @param Album|null $origin
*
* @return FixedQueryBuilder
*/
public function applySensitivityFilter(FixedQueryBuilder $query, ?Album $origin = null, bool $include_nsfw = true): FixedQueryBuilder
{
if ($include_nsfw) {
return $query;
}

$this->prepareModelQueryOrFail($query, true, false);

// If origin is set, also restrict the search result for admin
// to photos which are in albums below origin.
// This is not a security filter, but simply functional.
if ($origin !== null) {
$query
->where('albums._lft', '>=', $origin->_lft)
->where('albums._rgt', '<=', $origin->_rgt);
}

return $query->where(fn (Builder $query) => $this->appendSensitivityConditions($query->getQuery(), $origin?->_lft, $origin?->_rgt));
}

/**
* Adds the conditions of _searchable_ photos to the query.
*
Expand Down
39 changes: 27 additions & 12 deletions app/Relations/HasManyPhotosByTag.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,33 @@ public function addEagerConstraints(array $albums): void
$album = $albums[0];
$tags = $album->show_tags;

$this->photo_query_policy
->applySearchabilityFilter(
$this->getRelationQuery(),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)
->where(function (Builder $q) use ($tags): void {
// Filter for requested tags
foreach ($tags as $tag) {
$q->where('tags', 'like', '%' . trim($tag) . '%');
}
});
if (Configs::getValueAsBool('TA_override_visibility')) {
$this->photo_query_policy
->applySensitivityFilter(
$this->getRelationQuery(),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)
->where(function (Builder $q) use ($tags): void {
// Filter for requested tags
foreach ($tags as $tag) {
$q->where('tags', 'like', '%' . trim($tag) . '%');
}
});
} else {
$this->photo_query_policy
->applySearchabilityFilter(
$this->getRelationQuery(),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)
->where(function (Builder $q) use ($tags): void {
// Filter for requested tags
foreach ($tags as $tag) {
$q->where('tags', 'like', '%' . trim($tag) . '%');
}
});
}
}

/**
Expand Down
22 changes: 13 additions & 9 deletions app/SmartAlbums/BaseSmartAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,18 @@ public function get_photos(): Collection
*/
public function photos(): Builder
{
$query = $this->photo_query_policy
->applySearchabilityFilter(
query: Photo::query()->with(['album', 'size_variants', 'statistics']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums')
)->where($this->smart_photo_condition);

return $query;
$base_query = Photo::query()->with(['album', 'size_variants', 'statistics']);

if (!Configs::getValueAsBool('SA_override_visibility')) {
return $this->photo_query_policy
->applySearchabilityFilter(query: $base_query, origin: null, include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums'))
->where($this->smart_photo_condition);
}

// If the smart album visibility override is enabled, we do not need to apply any security filter, as all photos are visible
// in this smart album. We still need to apply the smart album condition, though.
return $this->photo_query_policy->applySensitivityFilter(query: $base_query, origin: null, include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_smart_albums'))
->where($this->smart_photo_condition);
}

/**
Expand Down Expand Up @@ -215,4 +219,4 @@ public function setPrivate(): void
$this->public_permissions = null;
$perm->delete();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

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

use App\Models\Extensions\BaseConfigMigration;

return new class() extends BaseConfigMigration {
public const CAT = 'Smart Albums';

public function getConfigs(): array
{
return [
[
'key' => 'SA_override_visibility',
'value' => '0',
'cat' => self::CAT,
'type_range' => self::BOOL,
'description' => 'Smart album visibility overrides the photo visibility.',
'details' => '<span class="pi pi-exclamation-triangle text-orange-500"></span> This will make any photos matching the smart album condition visible.',
'is_expert' => true,
'is_secret' => false,
'level' => 0,
'order' => 10,
],
[
'key' => 'TA_override_visibility',
'value' => '0',
'cat' => self::CAT,
'type_range' => self::BOOL,
'description' => 'Tag album visibility overrides the photo visibility.',
'details' => '<span class="pi pi-exclamation-triangle text-orange-500"></span> This will make any photos matching the tag album condition visible.',
'is_expert' => true,
'is_secret' => false,
'level' => 0,
'order' => 11,
],
];
}
};