195 lines
6.0 KiB
PHP
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]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|