*/ public function prepareOldFiles( ?Entry $entry = null ): array { if( $entry === null ){ $files = old( 'files_uuid', [] ); } else { $files = old( 'files_uuid', $entry->files->pluck('file_uuid')->toArray() ); } if( $files === [] ) return []; return array_map( function( string $uuid ) { $file = EntryFile::where('file_uuid', $uuid)->first(); if( $file ) return [ 'name' => $file->filename, 'totalChunks' => 0, // Already uploaded. 'rawFile' => null, 'progressValue' => 0, 'currentChunk' => 0, 'done' => true, 'error' => null, 'uuid' => $uuid ]; $file = Cache::get("uploaded_file_{$uuid}"); if( $file ) return [ 'name' => $file['filename'], 'totalChunks' => 0, // Already uploaded. 'rawFile' => null, 'progressValue' => 0, 'currentChunk' => 0, 'done' => true, 'error' => null, 'uuid' => $uuid ]; return null; }, $files ); } /** * @param StoreEntryRequest $request * @param string $section * * @return Entry * @throws SubmissionException * @throws \Throwable */ public function storeEntry( StoreEntryRequest $request, string $section ){ // STEP 1 : Prepare basic fields. $this->request = $request; $this->section = $section; $user_id = 0; // TODO: Replace that. $entry = DB::transaction(function () use ( $user_id ) { // STEP 2 : Create game. $gameId = null; if( section_must_be( ['romhacks', 'translations'], $this->section ) ){ $gameId = $this->Step2_CreateAndReturnGameId(); } // STEP 3 : Create Complete title. $completeTitle = $this->Step3_BuildCompleteTitle( $gameId ); // STEP 4 : Generate slug and entry title. $entrySlug = EntryHelpers::uniqueSlug( $completeTitle, Entry::class ); if( section_must_be( 'translations', $this->section ) && !$this->request->input('entry_title') ){ $entryTitle = Game::find($gameId)->name; } else { $entryTitle = $this->request->input('entry_title'); } // STEP 5 : Removed / Delayed. // $mainImage = $this->Step5_MoveMainImage(); // STEP 6 : Prepare entry fields and save entry. $fields = [ 'type' => $this->section, 'title' => $entryTitle, 'slug' => $entrySlug, 'description' => $this->request->input('description'), 'main_image' => $this->request->input('main-image'), 'state' => $this->request->input('submit-state'), 'game_id' => $gameId, 'status_id' => $this->request->input('status'), 'version' => $this->request->input('version'), 'release_date' => $this->request->input('release-date'), 'staff_credits' => $this->request->input('staff_credits'), 'relevant_link' => $this->request->input('release_site'), 'youtube_link' => $this->request->input('youtube_video'), 'user_id' => $user_id, 'complete_title' => $completeTitle, ]; $entry = Entry::create( $fields ); // STEP 7 : Save entry fields. $this->Step7_SaveEntryFiles( $entry->id ); // STEP 8 : Save hashes. $this->Step8_SaveHashes( $entry->id ); // STEP 9 : Save Authors. $this->Step9_SaveAuthors( $entry ); // STEP 10 : Save Modifications. if( section_must_be( 'romhacks', $this->section ) ){ $this->Step10_SaveRomhacksModifications( $entry ); } // STEP 11 : Save Languages $this->Step11_SaveLanguages( $entry ); // STEP 12 : Prepare Gallery images. $this->Step12a_PrepareGalleryImages( $entry ); return $entry; }); // Step 12, Move main image and gallery. $this->Step12b_MoveMainImage( $entry ); $this->Step12c_SaveGalleryImages( $entry ); return $entry; } /** * @return int * * @throws SubmissionException */ private function Step2_CreateAndReturnGameId(): int { // Already existing game. if( $this->request->input('game_id') ) return $this->request->input('game_id'); // Need to create a game. if( !$this->request->input('new-game-title') || !$this->request->input('new-game-platform') || !$this->request->input('new-game-genre') ) throw new SubmissionException( "New game informations is missing" ); $platform = Platform::find( $this->request->input('new-game-platform') ); $genre = Genre::find( $this->request->input('new-game-genre') ); if( !$platform || !$genre ) throw new SubmissionException( "Incorrect game platform id" ); $gameSlug = EntryHelpers::uniqueSlug( $this->request->input('new-game-title'), Game::class ); $game = Game::create([ 'name' => trim( $this->request->input('new-game-title') ), 'slug' => $gameSlug, 'platform_id' => $platform->id, 'genre_id' => $genre->id, ]); return $game->id; } /** * Prepare and build complete title. * * @param int|null $gameId * * @return string */ private function Step3_BuildCompleteTitle( ?int $gameId = null ): string { $fields = []; $fields['entry_title'] = $this->request->input('entry_title') ?? null; if( section_must_be( [ 'homebrew', 'translations' ], $this->section ) && $gameId ){ $fields['game_name'] = Game::find( $gameId )->name; } if( section_must_be( 'translations', $this->section ) ) { $fields['languages_string'] = Language::whereIn('id', $this->request->input('languages', []))->pluck('name')->implode(', '); } if( section_must_be(['romhacks', 'homebrew', 'lua-scripts', 'tutorials'], $this->section ) ) { // TODO: Add single platform ID compatibility. $fields['platform_name'] = Game::find( $gameId )->platform->name; } return EntryHelpers::buildCompleteTitle( $this->section, $fields ); } /** * @param int $entryId * * @return void * @throws SubmissionException */ private function Step7_SaveEntryFiles( int $entryId ): void { foreach ( $this->request->input('files_uuid', [] ) as $uuid ) { $fileData = Cache::pull("uploaded_file_{$uuid}"); if( !$fileData ) throw new SubmissionException( "File {$uuid} has expired. Please delete all your files and retry." ); EntryFile::create([ 'entry_id' => $entryId, 'file_uuid' => $uuid, 'filename' => $fileData['filename'], 'filepath' => $fileData['filepath'], 'favorite_server' => $fileData['favorite_server'], 'favorite_at' => \DateTimeImmutable::createFromTimestamp( $fileData['favorite_at'] ), 'filesize' => $fileData['filesize'], 'state' => 'public' ]); } } /** * @param int $entryId * * @return void */ private function Step8_SaveHashes( int $entryId ): void { foreach ( $this->request->input('hashes', [] ) as $hash ) { if( !isset($hash['filename'], $hash['hash_crc32'], $hash['hash_sha1'], $hash['verified']) ) { continue; } EntryHash::create([ 'entry_id' => $entryId, 'filename' => $hash['filename'], 'hash_crc32' => $hash['hash_crc32'], 'hash_sha1' => $hash['hash_sha1'], 'verified' => $hash['verified'], ]); } } /** * @param Entry $entry * * @return void * @throws SubmissionException */ private function Step9_SaveAuthors( Entry $entry ): void { // Existing authors. foreach ( $this->request->input('authors', [] ) as $authorId ) { $author = Author::find( $authorId ); if( !$author ) throw new SubmissionException( "Author {$authorId} does not exist." ); $entry->authors()->attach( $author->id ); } // New Authors foreach ( $this->request->input('new-authors', [] ) as $authorName ) { $authorName = trim( $authorName ); if( $authorName === '' ) continue; $author = Author::firstOrCreate( ['slug' => EntryHelpers::uniqueSlug( $authorName, Author::class )], ['name' => $authorName] ); $entry->authors()->attach( $author->id ); } } /** * @param Entry $entry * * @return void * @throws SubmissionException */ private function Step10_SaveRomhacksModifications( Entry $entry ): void { foreach ( $this->request->input('modifications', [] ) as $modificationId ) { $modification = Modification::find( $modificationId ); if( !$modification ) throw new SubmissionException( "Modification {$modificationId} does not exist." ); $entry->modifications()->attach( $modification->id ); } } /** * @param Entry $entry * * @return void * @throws SubmissionException */ private function Step11_SaveLanguages( Entry $entry ): void { foreach ( $this->request->input('languages', [] ) as $languageId ) { $language = Language::find( $languageId ); if( !$language ) throw new SubmissionException( "Language {$languageId} does not exist." ); $entry->languages()->attach( $language->id ); } } private function Step12a_PrepareGalleryImages( Entry $entry ): void { foreach ( $this->request->input('gallery', [] ) as $imagePath ) { EntryGallery::create([ 'entry_id' => $entry->id, 'image' => $imagePath, ]); } } /** * @param Entry $entry * * @return void */ private function Step12b_MoveMainImage( Entry $entry ): void { $mainImage = $entry->main_image; $newPath = 'entries/main-images/' . basename($mainImage); if( !Storage::disk('public')->move($mainImage, $newPath) ) return; $entry->update(['main_image' => $newPath]); } private function Step12c_SaveGalleryImages( Entry $entry ): void { foreach ( $entry->gallery as $galleryItem ) { $newPath = 'entries/gallery-images/' . $entry->id . '/' . basename($galleryItem->image); if( !Storage::disk('public')->move($galleryItem->image, $newPath) ) continue; $galleryItem->update(['image' => $newPath]); } } }