Files
RomhackPlaza/app/Services/NewsService.php
2026-06-16 16:21:43 +02:00

195 lines
6.0 KiB
PHP

<?php
namespace App\Services;
use App\Helpers\EntryHelpers;
use App\Jobs\CreateXenForoCommentsThread;
use App\Models\Entry;
use App\Models\News;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class NewsService
{
/**
* Request for store/edit.
* @var Request|null
*/
private ?Request $request = null;
/**
* Entry for edit.
* @var News|null
*/
private ?News $news = null;
public function storeNews(Request $request): News
{
$this->request = $request;
$user_id = \Auth::user()->user_id;
$news = DB::transaction(function () use ($user_id) {
// STEP 1 : Slug
$slug = EntryHelpers::uniqueSlug( $this->request->input('title'), News::class );
$fields = [
'title' => $this->request->input('title'),
'slug' => $slug,
'category_id' => $this->request->input('category'),
'description' => $this->request->input('description'),
'state' => $this->request->input('submit-state'),
'entry_id' => $this->request->input('entry_id'),
'relevant_link' => $this->request->input('release_site'),
'youtube_link' => $this->request->input('youtube_link'),
'user_id' => $user_id,
];
$news = News::create( $fields );
// STEP 3 : Prepare Gallery images.
$this->Step3a_PrepareGalleryImages( $news );
return $news;
});
$this->Step3b_SaveGalleryImages( $news );
$this->Step4_CreateCommentsThread( $news );
return $news;
}
private function Step3a_PrepareGalleryImages(News $news): void
{
foreach( $this->request->input('gallery', [] ) ?? [] as $i => $imagePath ){
$news->gallery()->create([
'image' => $imagePath,
'order' => $i
]);
}
}
private function Step3b_SaveGalleryImages(News $news): void
{
foreach ( $news->gallery ?? [] as $galleryItem ) {
$newPath = 'news/gallery-images/' . $news->id . '/' . basename($galleryItem->image);
if( !Storage::disk('public')->move($galleryItem->image, $newPath) )
continue;
$galleryItem->update(['image' => $newPath]);
}
}
private function Step4_CreateCommentsThread( News $news ): void
{
if( $news->state !== 'published' )
return;
if( !$news->comments_thread_id )
CreateXenForoCommentsThread::dispatch( $news );
}
public function editNews(Request $request, News $news): News
{
$this->request = $request;
$this->news = $news;
if( \Auth::user()->can('moderate', $news) ){
$user_id = $this->request->input('owner_user_id');
} else {
$user_id = \Auth::user()->user_id;
}
$galleryPaths = [];
$news = DB::transaction(function () use ($user_id, &$galleryPaths) {
// STEP 1 : Refresh slug.
if( $this->request->input('title') !== $this->news->title ){
$this->news->slug = EntryHelpers::uniqueSlug( $this->request->input('title'), News::class, $this->news->id );
}
$fields = [
'title' => $this->request->input('title'),
'slug' => $this->news->slug,
'category_id' => $this->request->input('category'),
'description' => $this->request->input('description'),
'state' => $this->request->input('submit-state'),
'entry_id' => $this->request->input('entry_id'),
'relevant_link' => $this->request->input('release_site'),
'youtube_link' => $this->request->input('youtube_link'),
'user_id' => $user_id,
];
if( \Auth::user()->can('moderate', $this->news) ){
$fields['staff_comment'] = $this->request->input('staff_comment');
$fields['comments_thread_id'] = $this->request->input('comments_thread_id');
}
$this->news->update( $fields );
$galleryPaths = $this->eStep3a_UpdateGalleryImages();
return $this->news;
});
$this->eStep3b_UpdateGalleryImages( $galleryPaths );
$this->step4_CreateCommentsThread( $news );
return $news;
}
private function eStep3a_UpdateGalleryImages(): array
{
$requestGallery = $this->request->input('gallery', [] ) ?? [];
$existingGalleryPaths = $this->news->gallery->pluck('image')->toArray();
$needDeletion = array_diff( $existingGalleryPaths, $requestGallery );
if( !empty( $needDeletion ) ){
$this->news->gallery()->whereIn('image', $needDeletion )->delete();
}
$needAddition = array_diff( $requestGallery, $existingGalleryPaths );
$images = [];
foreach( $needAddition as $imagePath ){
$images[] = $this->news->gallery()->create([
'image' => $imagePath,
]);
}
foreach( $requestGallery as $i => $imagePath ){
$this->news->gallery()->where('image', $imagePath )->update(['order' => $i]);
}
return [ 'addition' => $images, 'deletion' => $needDeletion ];
}
private function eStep3b_UpdateGalleryImages( array $pathsChanges ): void
{
foreach ( $pathsChanges['deletion'] as $deletePath ){
if( Storage::disk('public')->exists($deletePath) )
Storage::disk('public')->delete($deletePath);
}
foreach ( $pathsChanges['addition'] as $galleryItem ){
$newPath = 'news/gallery-images/' . $this->news->id . '/' . basename( $galleryItem->image );
if( !Storage::disk('public')->move( $galleryItem->image, $newPath ) ){
continue;
}
$galleryItem->update(['image' => $newPath]);
}
}
}