storing analytics data

This commit is contained in:
2026-02-27 09:46:51 +01:00
parent 15b7b77d20
commit f0cca76eb3
57 changed files with 3478 additions and 466 deletions

View File

@@ -175,8 +175,8 @@ final class ArtworkSearchService
// ── Discover section helpers ───────────────────────────────────────────────
/**
* Trending: most viewed artworks, weighted toward recent uploads.
* Uses views:desc + recency via created_at:desc as tiebreaker.
* Trending: sorted by pre-computed trending_score_24h (recalculated every 30 min).
* Falls back to views:desc if the column is not yet populated.
*/
public function discoverTrending(int $perPage = 24): LengthAwarePaginator
{
@@ -185,7 +185,7 @@ final class ArtworkSearchService
return Artwork::search('')
->options([
'filter' => self::BASE_FILTER,
'sort' => ['views:desc', 'created_at:desc'],
'sort' => ['trending_score_24h:desc', 'trending_score_7d:desc', 'views:desc', 'created_at:desc'],
])
->paginate($perPage);
});
@@ -239,6 +239,64 @@ final class ArtworkSearchService
});
}
/**
* Artworks matching any of the given tag slugs, sorted by trending score.
* Used for personalized "Because you like {tags}" homepage section.
*
* @param string[] $tagSlugs
*/
public function discoverByTags(array $tagSlugs, int $limit = 12): LengthAwarePaginator
{
if (empty($tagSlugs)) {
return $this->popular($limit);
}
$tagFilter = implode(' OR ', array_map(
fn (string $t): string => 'tags = "' . addslashes($t) . '"',
array_slice($tagSlugs, 0, 5)
));
$cacheKey = 'discover.by-tags.' . md5(implode(',', $tagSlugs));
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($tagFilter, $limit) {
return Artwork::search('')
->options([
'filter' => self::BASE_FILTER . ' AND (' . $tagFilter . ')',
'sort' => ['trending_score_7d:desc', 'likes:desc'],
])
->paginate($limit);
});
}
/**
* Fresh artworks in given categories, sorted by created_at desc.
* Used for personalized "Fresh in your favourite categories" section.
*
* @param string[] $categorySlugs
*/
public function discoverByCategories(array $categorySlugs, int $limit = 12): LengthAwarePaginator
{
if (empty($categorySlugs)) {
return $this->recent($limit);
}
$catFilter = implode(' OR ', array_map(
fn (string $c): string => 'category = "' . addslashes($c) . '"',
array_slice($categorySlugs, 0, 3)
));
$cacheKey = 'discover.by-cats.' . md5(implode(',', $categorySlugs));
return Cache::remember($cacheKey, self::CACHE_TTL, function () use ($catFilter, $limit) {
return Artwork::search('')
->options([
'filter' => self::BASE_FILTER . ' AND (' . $catFilter . ')',
'sort' => ['created_at:desc'],
])
->paginate($limit);
});
}
// -------------------------------------------------------------------------
private function parseSort(string $sort): array