110 lines
2.9 KiB
PHP
110 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\GameAccountUser;
|
|
use App\Models\News;
|
|
use Illuminate\Support\Collection;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class NewsService
|
|
{
|
|
/**
|
|
* @return \Illuminate\Support\Collection<int, \App\Models\News>
|
|
*/
|
|
public function listForAdmin(): Collection
|
|
{
|
|
return News::query()->ordered()->get();
|
|
}
|
|
|
|
/**
|
|
* @return \Illuminate\Support\Collection<int, \App\Models\News>
|
|
*/
|
|
public function listForLanding(int $limit = 6): Collection
|
|
{
|
|
return News::query()
|
|
->published()
|
|
->ordered()
|
|
->limit($limit)
|
|
->get();
|
|
}
|
|
|
|
/**
|
|
* @return array{total: int, published: int, draft: int}
|
|
*/
|
|
public function stats(): array
|
|
{
|
|
$total = News::query()->count();
|
|
$published = News::query()->published()->count();
|
|
|
|
return [
|
|
'total' => $total,
|
|
'published' => $published,
|
|
'draft' => $total - $published,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* @param array{title: string, body: string, sort_order: int, is_published?: bool} $attributes
|
|
*/
|
|
public function create(array $attributes, ?GameAccountUser $actor, ?\Illuminate\Http\UploadedFile $image = null): News
|
|
{
|
|
$data = [
|
|
...$this->normalizeAttributes($attributes),
|
|
'created_by_account_id' => $actor?->id,
|
|
'created_by_username' => $actor?->username,
|
|
];
|
|
|
|
if ($image) {
|
|
$data['image_path'] = $image->store('news', 'public');
|
|
}
|
|
|
|
return News::query()->create($data);
|
|
}
|
|
|
|
/**
|
|
* @param array{title: string, body: string, sort_order: int, is_published?: bool} $attributes
|
|
*/
|
|
public function update(News $news, array $attributes, ?\Illuminate\Http\UploadedFile $image = null): News
|
|
{
|
|
$data = $this->normalizeAttributes($attributes);
|
|
|
|
if ($image) {
|
|
if ($news->image_path) {
|
|
Storage::disk('public')->delete($news->image_path);
|
|
}
|
|
|
|
$data['image_path'] = $image->store('news', 'public');
|
|
}
|
|
|
|
$news->forceFill($data)->save();
|
|
|
|
return $news->refresh();
|
|
}
|
|
|
|
public function delete(News $news): void
|
|
{
|
|
if ($news->image_path) {
|
|
Storage::disk('public')->delete($news->image_path);
|
|
}
|
|
|
|
$news->delete();
|
|
}
|
|
|
|
/**
|
|
* @param array{title: string, body: string, sort_order: int, is_published?: bool} $attributes
|
|
* @return array{title: string, body: string, sort_order: int, is_published: bool}
|
|
*/
|
|
private function normalizeAttributes(array $attributes): array
|
|
{
|
|
return [
|
|
'title' => trim($attributes['title']),
|
|
'body' => trim($attributes['body']),
|
|
'sort_order' => (int) $attributes['sort_order'],
|
|
'is_published' => (bool) ($attributes['is_published'] ?? false),
|
|
];
|
|
}
|
|
|
|
|
|
}
|