Save workspace changes
This commit is contained in:
@@ -6,6 +6,8 @@ namespace App\Http\Controllers\Web;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Artwork;
|
||||
use App\Models\Group;
|
||||
use App\Models\User;
|
||||
use App\Services\ArtworkSearchService;
|
||||
use App\Services\ContentTypes\ContentTypeSlugResolver;
|
||||
use App\Services\EarlyGrowth\EarlyGrowth;
|
||||
@@ -77,10 +79,12 @@ final class ExploreController extends Controller
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$ttl = self::SORT_TTL[$sort] ?? 300;
|
||||
$cacheVersion = $this->cacheVersion();
|
||||
$filter = $this->buildExploreFilterExpression($request);
|
||||
$cacheSuffix = $this->requestCacheSuffix($request);
|
||||
|
||||
$artworks = Cache::remember("explore.all.v{$cacheVersion}.{$sort}.{$page}", $ttl, fn () =>
|
||||
$artworks = Cache::remember("explore.all.v{$cacheVersion}.{$cacheSuffix}.{$page}", $ttl, fn () =>
|
||||
$this->search->searchWithThumbnailPreference([
|
||||
'filter' => 'is_public = true AND is_approved = true',
|
||||
'filter' => $filter,
|
||||
'sort' => self::SORT_MAP[$sort] ?? ['created_at:desc'],
|
||||
], $perPage, false, $page)
|
||||
);
|
||||
@@ -148,13 +152,10 @@ final class ExploreController extends Controller
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$ttl = self::SORT_TTL[$sort] ?? 300;
|
||||
$cacheVersion = $this->cacheVersion();
|
||||
$filter = $this->buildExploreFilterExpression($request, $isAll ? null : $resolvedTypeSlug);
|
||||
$cacheSuffix = $this->requestCacheSuffix($request);
|
||||
|
||||
$filter = 'is_public = true AND is_approved = true';
|
||||
if (!$isAll) {
|
||||
$filter .= ' AND content_type = "' . $type . '"';
|
||||
}
|
||||
|
||||
$artworks = Cache::remember("explore.{$resolvedTypeSlug}.v{$cacheVersion}.{$sort}.{$page}", $ttl, fn () =>
|
||||
$artworks = Cache::remember("explore.{$resolvedTypeSlug}.v{$cacheVersion}.{$cacheSuffix}.{$page}", $ttl, fn () =>
|
||||
$this->search->searchWithThumbnailPreference([
|
||||
'filter' => $filter,
|
||||
'sort' => self::SORT_MAP[$sort] ?? ['created_at:desc'],
|
||||
@@ -288,11 +289,122 @@ final class ExploreController extends Controller
|
||||
return max(12, min($v, 80));
|
||||
}
|
||||
|
||||
private function requestCacheSuffix(Request $request): string
|
||||
{
|
||||
$query = $request->query();
|
||||
unset($query['grid'], $query['page']);
|
||||
ksort($query);
|
||||
|
||||
return md5(json_encode($query, JSON_THROW_ON_ERROR));
|
||||
}
|
||||
|
||||
private function cacheVersion(): int
|
||||
{
|
||||
return max(1, (int) Cache::get('explore.cache.version', 1));
|
||||
}
|
||||
|
||||
private function buildExploreFilterExpression(Request $request, ?string $contentType = null): string
|
||||
{
|
||||
$filterParts = [
|
||||
'is_public = true',
|
||||
'is_approved = true',
|
||||
];
|
||||
|
||||
if ($contentType !== null && $contentType !== '') {
|
||||
$filterParts[] = 'content_type = "' . addslashes($contentType) . '"';
|
||||
}
|
||||
|
||||
$orientation = strtolower(trim((string) $request->query('orientation', '')));
|
||||
if (in_array($orientation, ['landscape', 'portrait', 'square'], true)) {
|
||||
$filterParts[] = 'orientation = "' . addslashes($orientation) . '"';
|
||||
}
|
||||
|
||||
$resolution = $this->resolutionFilterValue((string) $request->query('resolution', ''));
|
||||
if ($resolution !== null) {
|
||||
$filterParts[] = 'resolution = "' . addslashes($resolution) . '"';
|
||||
}
|
||||
|
||||
$dateFrom = $this->normalizeDateQuery((string) $request->query('date_from', ''));
|
||||
if ($dateFrom !== null) {
|
||||
$filterParts[] = 'created_at >= "' . $dateFrom . '"';
|
||||
}
|
||||
|
||||
$dateTo = $this->normalizeDateQuery((string) $request->query('date_to', ''));
|
||||
if ($dateTo !== null) {
|
||||
$filterParts[] = 'created_at <= "' . $dateTo . '"';
|
||||
}
|
||||
|
||||
$authorFilter = $this->authorFilterExpression((string) $request->query('author', ''));
|
||||
if ($authorFilter !== null) {
|
||||
$filterParts[] = $authorFilter;
|
||||
}
|
||||
|
||||
return implode(' AND ', $filterParts);
|
||||
}
|
||||
|
||||
private function resolutionFilterValue(string $resolution): ?string
|
||||
{
|
||||
return match (strtolower(trim($resolution))) {
|
||||
'hd' => '1280x720',
|
||||
'fhd' => '1920x1080',
|
||||
'2k' => '2560x1440',
|
||||
'4k' => '3840x2160',
|
||||
default => null,
|
||||
};
|
||||
}
|
||||
|
||||
private function normalizeDateQuery(string $value): ?string
|
||||
{
|
||||
$value = trim($value);
|
||||
|
||||
if (! preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
private function authorFilterExpression(string $author): ?string
|
||||
{
|
||||
$author = trim($author);
|
||||
|
||||
if ($author === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$userIds = User::query()
|
||||
->where(function ($query) use ($author): void {
|
||||
$query->where('username', 'like', '%' . $author . '%')
|
||||
->orWhere('name', 'like', '%' . $author . '%');
|
||||
})
|
||||
->limit(20)
|
||||
->pluck('id');
|
||||
|
||||
$groupIds = Group::query()
|
||||
->where(function ($query) use ($author): void {
|
||||
$query->where('name', 'like', '%' . $author . '%')
|
||||
->orWhere('slug', 'like', '%' . $author . '%');
|
||||
})
|
||||
->limit(20)
|
||||
->pluck('id');
|
||||
|
||||
$clauses = [];
|
||||
|
||||
foreach ($userIds as $userId) {
|
||||
$clauses[] = '(author_id = ' . (int) $userId . ' AND published_as_type = "user")';
|
||||
}
|
||||
|
||||
foreach ($groupIds as $groupId) {
|
||||
$clauses[] = '(author_id = ' . (int) $groupId . ' AND published_as_type = "group")';
|
||||
}
|
||||
|
||||
if ($clauses === []) {
|
||||
return 'id = 0';
|
||||
}
|
||||
|
||||
return '(' . implode(' OR ', $clauses) . ')';
|
||||
}
|
||||
|
||||
private function filterBrowsableArtworks(AbstractPaginator $paginator): AbstractPaginator
|
||||
{
|
||||
$paginator->setCollection(
|
||||
|
||||
Reference in New Issue
Block a user