259 lines
9.3 KiB
PHP
259 lines
9.3 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Entry;
|
|
use App\Models\EntryReview;
|
|
use App\Models\News;
|
|
use App\View\Components\EntryCard;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Cache;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ActivityService
|
|
{
|
|
private const CACHE_ENTRIES = 300; // seconds.
|
|
private const CACHE_NEWS = 300; // seconds.
|
|
private const CACHE_MESSAGES = 300; // seconds.
|
|
private const CACHE_THREADS = 300; // seconds.
|
|
private const CACHE_CLUBS = 300; // seconds.
|
|
private const CACHE_REVIEWS = 300; // seconds.
|
|
private const ITEMS_PER_TYPE = 15;
|
|
|
|
public function getActivities( array $activities = [ 'entries', 'news', 'messages', 'threads', 'clubs', 'reviews' ] ): Collection
|
|
{
|
|
$c = collect();
|
|
if( in_array( 'entries', $activities ) ) {
|
|
$c = $c->merge($this->getEntries());
|
|
}
|
|
if( in_array( 'news', $activities ) ) {
|
|
$c = $c->merge($this->getNews());
|
|
}
|
|
if( in_array( 'messages', $activities ) ) {
|
|
$c = $c->merge($this->getMessages());
|
|
}
|
|
if( in_array( 'threads', $activities ) ) {
|
|
$c = $c->merge($this->getThreads());
|
|
}
|
|
if( in_array( 'clubs', $activities ) ) {
|
|
$c = $c->merge($this->getClubs());
|
|
}
|
|
if( in_array( 'reviews', $activities ) ) {
|
|
$c = $c->merge($this->getReviews());
|
|
}
|
|
|
|
return $c->sortByDesc('date')
|
|
->values()
|
|
->take(30)
|
|
->map(function(array $item){
|
|
$obj = (object) $item;
|
|
$obj->date = Carbon::createFromTimestamp($obj->date);
|
|
return $obj;
|
|
});
|
|
}
|
|
|
|
private function formatEntry( Entry $entry ): array
|
|
{
|
|
return [
|
|
'type' => 'entry',
|
|
'title' => $entry->complete_title ?? $entry->title,
|
|
'url' => route('entries.show', ['section' => $entry->type, 'entry' => $entry]),
|
|
'image' => $entry->main_image ? \Storage::url($entry->main_image) : null,
|
|
'date' => $entry->created_at->timestamp,
|
|
'author' => $entry->authors->pluck('name')->implode(', '),
|
|
'user_id' => $entry->user_id,
|
|
'badge' => EntryCard::ENTRY_TYPES_BADGE[$entry->type],
|
|
'badge_class' => $entry->type,
|
|
'excerpt' => $entry->description ? \Str::limit(strip_tags($entry->description), 80) : null,
|
|
'meta' => $entry->getRealPlatform()?->name
|
|
];
|
|
}
|
|
|
|
private function formatNews( News $news ): array
|
|
{
|
|
return [
|
|
'type' => 'news',
|
|
'title' => $news->title,
|
|
'url' => route('news.show', ['news' => $news]),
|
|
'image' => $news->gallery()->first() ? \Storage::url($news->gallery()->first()->image) : null,
|
|
'date' => $news->created_at->timestamp,
|
|
'author' => null,
|
|
'user_id' => $news->user_id,
|
|
'badge' => 'News',
|
|
'badge_class' => 'news',
|
|
'excerpt' => $news->description ? \Str::limit(strip_tags($news->description), 80) : null,
|
|
'meta' => $news->category?->name
|
|
];
|
|
}
|
|
|
|
private function formatMessage( object $message ): array
|
|
{
|
|
return [
|
|
'type' => 'message',
|
|
'title' => $message->title,
|
|
'url' => xfRoute('threads/.' ) . $message->thread_id . '/post-' . $message->post_id,
|
|
'image' => null,
|
|
'date' => $message->post_date,
|
|
'author' => null,
|
|
'user_id' => $message->user_id,
|
|
'badge' => 'Post',
|
|
'badge_class' => 'message',
|
|
'excerpt' => $message->message ? \Str::limit(strip_tags($message->message), 80) : null,
|
|
'meta' => null
|
|
];
|
|
|
|
}
|
|
|
|
private function formatThread( object $thread ): array
|
|
{
|
|
return [
|
|
'type' => 'thread',
|
|
'title' => $thread->title,
|
|
'url' => xfRoute('threads/.' ) . $thread->thread_id,
|
|
'image' => null,
|
|
'date' => $thread->post_date,
|
|
'author' => null,
|
|
'user_id' => $thread->user_id,
|
|
'badge' => 'Thread',
|
|
'badge_class' => 'thread',
|
|
'excerpt' => $thread->message ? \Str::limit(strip_tags($thread->message), 80) : null,
|
|
'meta' => null
|
|
];
|
|
|
|
}
|
|
|
|
private function formatClub( object $club ): array
|
|
{
|
|
return [
|
|
'type' => 'club',
|
|
'title' => $club->title,
|
|
'url' => xfRoute('forums/.' ) . $club->node_id,
|
|
'image' => null, // TODO: Remplacer par banner_date
|
|
'date' => $club->club_creation_date,
|
|
'author' => null,
|
|
'user_id' => $club->user_id,
|
|
'badge' => 'Club',
|
|
'badge_class' => 'club',
|
|
'excerpt' => $club->description ? \Str::limit(strip_tags($club->description), 80) : null,
|
|
'meta' => null
|
|
];
|
|
}
|
|
|
|
private function formatReview( EntryReview $review ): array
|
|
{
|
|
return [
|
|
'type' => 'review',
|
|
'title' => $review->title,
|
|
'url' => $review->entry()->exists() ? route('entries.show', ['section' => $review->entry->type, 'entry' => $review->entry]) : '',
|
|
'image' => null,
|
|
'date' => $review->created_at->timestamp,
|
|
'author' => null,
|
|
'user_id' => $review->user_id,
|
|
'badge' => 'Review',
|
|
'badge_class' => 'review',
|
|
'excerpt' => $review->description ? \Str::limit(strip_tags($review->description), 80) : null,
|
|
'meta' => $review->entry()->exists() ? ( $review->entry->complete_title ?? $review->entry->title ) : null,
|
|
];
|
|
}
|
|
|
|
private function getEntries(): array
|
|
{
|
|
return Cache::remember('activity_entries', self::CACHE_ENTRIES, function() {
|
|
return Entry::published()
|
|
->with(['authors', 'game.platform'])
|
|
->latest('created_at')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->get()
|
|
->map($this->formatEntry(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
|
|
private function getNews(): array
|
|
{
|
|
return Cache::remember('activity_news', self::CACHE_NEWS, function() {
|
|
return News::published()
|
|
->with('gallery')
|
|
->latest('created_at')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->get()
|
|
->map($this->formatNews(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
|
|
private function getMessages(): array
|
|
{
|
|
return Cache::remember('activity_messages', self::CACHE_MESSAGES, function() {
|
|
return DB::connection('xenforo')
|
|
->table('post')
|
|
->join('user', 'post.user_id', '=', 'user.user_id')
|
|
->join('thread', 'post.thread_id', '=', 'thread.thread_id')
|
|
->where('post.message_state', 'visible')
|
|
->where('thread.first_post_id', '!=', 'post.post_id')
|
|
->orderByDesc('post.post_date')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->select([
|
|
'thread.title', 'thread.thread_id', 'post.post_id', 'post.post_date',
|
|
'post.user_id', 'post.message'
|
|
])
|
|
->get()
|
|
->map($this->formatMessage(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
|
|
private function getThreads(): array
|
|
{
|
|
return Cache::remember('activity_threads', self::CACHE_THREADS, function() {
|
|
return DB::connection('xenforo')
|
|
->table('thread')
|
|
->join('user', 'thread.user_id', '=', 'user.user_id')
|
|
->join('post', 'thread.first_post_id', '=', 'post.post_id')
|
|
->where('thread.discussion_state', 'visible')
|
|
->where('thread.discussion_type', '!=', 'redirect' )
|
|
->where('thread.node_id', '!=', config('xenforo.comments_node_id') )
|
|
->orderByDesc('thread.post_date')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->select([
|
|
'thread.title', 'thread.thread_id', 'thread.post_date', 'thread.user_id',
|
|
'post.message'
|
|
])
|
|
->get()
|
|
->map($this->formatThread(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
|
|
private function getClubs(): array
|
|
{
|
|
return Cache::remember('activity_clubs', self::CACHE_CLUBS, function() {
|
|
return DB::connection('xenforo')
|
|
->table('club')
|
|
->where('club_state', 'visible')
|
|
->orderByDesc('club_creation_date')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->select([
|
|
'club.title', 'club.description', 'club.node_id',
|
|
'club.club_creation_date', 'club.user_id'
|
|
])
|
|
->get()
|
|
->map($this->formatClub(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
|
|
private function getReviews(): array
|
|
{
|
|
return Cache::remember('activity_reviews', self::CACHE_REVIEWS, function() {
|
|
return EntryReview::with(['entry'])
|
|
->latest('created_at')
|
|
->limit(self::ITEMS_PER_TYPE)
|
|
->get()
|
|
->map($this->formatReview(...))
|
|
->toArray();
|
|
});
|
|
}
|
|
}
|