Files
moonwell-web/app/Services/NewsService.php
T
2026-03-22 17:28:14 +04:00

98 lines
2.6 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 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),
];
}
}