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]); } } }