Update Submissions and add fields

This commit is contained in:
2026-06-10 11:04:26 +02:00
parent 1d8ea70b72
commit 4f9f6c63b3
64 changed files with 2278 additions and 174 deletions

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Filament\Resources\Categories;
use App\Filament\Resources\Categories\Pages\CreateCategory;
use App\Filament\Resources\Categories\Pages\EditCategory;
use App\Filament\Resources\Categories\Pages\ListCategories;
use App\Filament\Resources\Categories\Schemas\CategoryForm;
use App\Filament\Resources\Categories\Tables\CategoriesTable;
use App\Models\Category;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Table;
class CategoryResource extends Resource
{
protected static ?string $model = Category::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
public static function form(Schema $schema): Schema
{
return CategoryForm::configure($schema);
}
public static function table(Table $table): Table
{
return CategoriesTable::configure($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => ListCategories::route('/'),
'create' => CreateCategory::route('/create'),
'edit' => EditCategory::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\Categories\Pages;
use App\Filament\Resources\Categories\CategoryResource;
use Filament\Resources\Pages\CreateRecord;
class CreateCategory extends CreateRecord
{
protected static string $resource = CategoryResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Categories\Pages;
use App\Filament\Resources\Categories\CategoryResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditCategory extends EditRecord
{
protected static string $resource = CategoryResource::class;
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Categories\Pages;
use App\Filament\Resources\Categories\CategoryResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListCategories extends ListRecords
{
protected static string $resource = CategoryResource::class;
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace App\Filament\Resources\Categories\Schemas;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Textarea;
use Filament\Schemas\Schema;
class CategoryForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name')
->required(),
TextInput::make('slug')
->required(),
Textarea::make('restricted_to')
->default(null)
->columnSpanFull(),
]);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Filament\Resources\Categories\Tables;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class CategoriesTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->searchable(),
TextColumn::make('slug')
->searchable(),
TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->recordActions([
EditAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Filament\Resources\Levels;
use App\Filament\Resources\Levels\Pages\CreateLevel;
use App\Filament\Resources\Levels\Pages\EditLevel;
use App\Filament\Resources\Levels\Pages\ListLevels;
use App\Filament\Resources\Levels\Schemas\LevelForm;
use App\Filament\Resources\Levels\Tables\LevelsTable;
use App\Models\Level;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Table;
class LevelResource extends Resource
{
protected static ?string $model = Level::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
public static function form(Schema $schema): Schema
{
return LevelForm::configure($schema);
}
public static function table(Table $table): Table
{
return LevelsTable::configure($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => ListLevels::route('/'),
'create' => CreateLevel::route('/create'),
'edit' => EditLevel::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\Levels\Pages;
use App\Filament\Resources\Levels\LevelResource;
use Filament\Resources\Pages\CreateRecord;
class CreateLevel extends CreateRecord
{
protected static string $resource = LevelResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Levels\Pages;
use App\Filament\Resources\Levels\LevelResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditLevel extends EditRecord
{
protected static string $resource = LevelResource::class;
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Levels\Pages;
use App\Filament\Resources\Levels\LevelResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListLevels extends ListRecords
{
protected static string $resource = LevelResource::class;
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\Levels\Schemas;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;
class LevelForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name')
->required(),
TextInput::make('slug')
->required(),
]);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Filament\Resources\Levels\Tables;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class LevelsTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->searchable(),
TextColumn::make('slug')
->searchable(),
TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->recordActions([
EditAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
}

View File

@@ -0,0 +1,11 @@
<?php
namespace App\Filament\Resources\Systems\Pages;
use App\Filament\Resources\Systems\SystemResource;
use Filament\Resources\Pages\CreateRecord;
class CreateSystem extends CreateRecord
{
protected static string $resource = SystemResource::class;
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Systems\Pages;
use App\Filament\Resources\Systems\SystemResource;
use Filament\Actions\DeleteAction;
use Filament\Resources\Pages\EditRecord;
class EditSystem extends EditRecord
{
protected static string $resource = SystemResource::class;
protected function getHeaderActions(): array
{
return [
DeleteAction::make(),
];
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace App\Filament\Resources\Systems\Pages;
use App\Filament\Resources\Systems\SystemResource;
use Filament\Actions\CreateAction;
use Filament\Resources\Pages\ListRecords;
class ListSystems extends ListRecords
{
protected static string $resource = SystemResource::class;
protected function getHeaderActions(): array
{
return [
CreateAction::make(),
];
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace App\Filament\Resources\Systems\Schemas;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;
class SystemForm
{
public static function configure(Schema $schema): Schema
{
return $schema
->components([
TextInput::make('name')
->required(),
TextInput::make('slug')
->required(),
]);
}
}

View File

@@ -0,0 +1,48 @@
<?php
namespace App\Filament\Resources\Systems;
use App\Filament\Resources\Systems\Pages\CreateSystem;
use App\Filament\Resources\Systems\Pages\EditSystem;
use App\Filament\Resources\Systems\Pages\ListSystems;
use App\Filament\Resources\Systems\Schemas\SystemForm;
use App\Filament\Resources\Systems\Tables\SystemsTable;
use App\Models\System;
use BackedEnum;
use Filament\Resources\Resource;
use Filament\Schemas\Schema;
use Filament\Support\Icons\Heroicon;
use Filament\Tables\Table;
class SystemResource extends Resource
{
protected static ?string $model = System::class;
protected static string|BackedEnum|null $navigationIcon = Heroicon::OutlinedRectangleStack;
public static function form(Schema $schema): Schema
{
return SystemForm::configure($schema);
}
public static function table(Table $table): Table
{
return SystemsTable::configure($table);
}
public static function getRelations(): array
{
return [
//
];
}
public static function getPages(): array
{
return [
'index' => ListSystems::route('/'),
'create' => CreateSystem::route('/create'),
'edit' => EditSystem::route('/{record}/edit'),
];
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\Filament\Resources\Systems\Tables;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
use Filament\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
class SystemsTable
{
public static function configure(Table $table): Table
{
return $table
->columns([
TextColumn::make('name')
->searchable(),
TextColumn::make('slug')
->searchable(),
TextColumn::make('created_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')
->dateTime()
->sortable()
->toggleable(isToggledHiddenByDefault: true),
])
->filters([
//
])
->recordActions([
EditAction::make(),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
}

View File

@@ -44,7 +44,64 @@ class FormHelpers {
'homebrew' => [
'page_title' => "Submit an homebrew",
'about_the' => "About the homebrew",
'version' => "Patch version",
'version' => "Version",
'status' => "Status",
'release_date' => "Release date",
'release_date_helper' => "If only initial release exist, the release date.",
'description' => "Description",
'about_game' => "Game Information",
'attachments' => "Attachments",
'authors' => "Team members",
'related_links' => "Related links",
'release_site' => "Release site",
'release_site_helper' => "Project entry on site/blog/forum/Github.",
'youtube_video' => "YouTube video",
],
'utilities' => [
'page_title' => "Submit a utility",
'entry_title' => "Title",
'about_the' => "About the utility",
'version' => "Version",
'status' => "Status",
'system' => "OS",
'categories' => "Categories",
'level' => "Experience Level",
'release_date' => "Release date",
'release_date_helper' => "If only initial release exist, the release date.",
'description' => "Description",
'about_game' => "Game Information",
'attachments' => "Attachments",
'authors' => "Team members",
'related_links' => "Related links",
'release_site' => "Release site",
'release_site_helper' => "Project entry on site/blog/forum/Github.",
'youtube_video' => "YouTube video",
],
'documents' => [
'page_title' => "Submit a document",
'entry_title' => "Title",
'about_the' => "About the document",
'version' => "Version",
'status' => "Status",
'categories' => "Categories",
'level' => "Experience Level",
'release_date' => "Release date",
'release_date_helper' => "If only initial release exist, the release date.",
'description' => "Description",
'about_game' => "Game Information",
'attachments' => "Attachments",
'authors' => "Team members",
'related_links' => "Related links",
'release_site' => "Release site",
'release_site_helper' => "Project entry on site/blog/forum/Github.",
'youtube_video' => "YouTube video",
],
'lua-scripts' => [
'page_title' => "Submit a LUA Script",
'about_the' => "About the script",
'entry_title' => "Title",
'type_of_hack' => "Modifications",
'version' => "Version",
'status' => "Status",
'release_date' => "Release date",
'release_date_helper' => "If only initial release exist, the release date.",

View File

@@ -10,14 +10,16 @@ use App\Jobs\DeleteXenForoCommentsThread;
use App\Models\Author;
use App\Models\Entry;
use App\Models\EntryFile;
use App\Models\EntryGallery;
use App\Models\Gallery;
use App\Models\EntryHash;
use App\Models\Game;
use App\Models\Genre;
use App\Models\Language;
use App\Models\Level;
use App\Models\Modification;
use App\Models\Platform;
use App\Models\Status;
use App\Models\System;
use App\Services\SubmissionsService;
use App\Services\XenforoApiService;
use Illuminate\Http\Request;
@@ -39,19 +41,27 @@ class SubmissionController extends Controller
'words' => FormHelpers::getEntryFormWords($section),
'isEdit' => false,
'oldModifications' => old( 'modifications', [] ),
'oldSystems' => old( 'systems', [] ),
'oldLanguages' => old( 'languages', [] ),
'oldCategories' => old( 'categories', [] ),
'oldFilesArray' => $this->services->prepareOldFiles( null )
];
if( $data['words'] === [] )
abort(500);
if( section_must_be( 'romhacks', $section ) ){
if( section_must_be( ['romhacks', 'lua-scripts'], $section ) ){
$data['modifications'] = Modification::orderBy('name')->get();
}
if( section_must_be( [ 'romhacks', 'translations', 'homebrew' ], $section ) ){
if( section_must_be( [ 'romhacks', 'translations', 'homebrew', 'lua-scripts' ], $section ) ){
$data['statuses'] = Status::orderBy('id')->get();
}
if( section_must_be( 'utilities' , $section ) ){
$data['systems'] = System::orderBy('name')->get();
}
if( section_must_be( [ 'utilities', 'documents' ], $section ) ) {
$data['levels'] = Level::orderBy('id')->get();
}
return view('submissions.create', $data);
}
@@ -68,19 +78,27 @@ class SubmissionController extends Controller
'words' => FormHelpers::getEntryFormWords($section),
'isEdit' => true,
'oldModifications' => old('modifications', $entry->modifications->pluck('id')->toArray() ?? [] ),
'oldSystems' => old( 'systems', $entry->systems->pluck('id')->toArray() ?? [] ),
'oldLanguages' => old('languages', $entry->languages->pluck('id')->toArray() ?? [] ),
'oldCategories' => old('categories', $entry->categories->pluck('id')->toArray() ?? [] ),
'oldFilesArray' => $this->services->prepareOldFiles( $entry )
];
if( $data['words'] === [] )
abort(500);
if( section_must_be( 'romhacks', $section ) ){
if( section_must_be( [ 'romhacks', 'lua-scripts' ], $section ) ){
$data['modifications'] = Modification::orderBy('name')->get();
}
if( section_must_be( [ 'romhacks', 'translations' ], $section ) ){
if( section_must_be( [ 'romhacks', 'translations', 'homebrew', 'lua-scripts' ], $section ) ){
$data['statuses'] = Status::orderBy('id')->get();
}
if( section_must_be( 'utilities' , $section ) ){
$data['systems'] = System::orderBy('name')->get();
}
if( section_must_be( [ 'utilities', 'documents' ], $section ) ) {
$data['levels'] = Level::orderBy('id')->get();
}
return view('submissions.edit', $data);
}

View File

@@ -70,28 +70,49 @@ class StoreEntryRequest extends FormRequest
$rules['entry_title'] = "nullable|string|max:255";
}
if( section_must_be( 'romhacks', $section ) ){
if( section_must_be( ['romhacks', 'lua-scripts'], $section ) ){
$rules['modifications'] = 'array|required|min:1';
$rules['modifications.*'] = 'integer|exists:modifications,id';
} else if( section_must_be( 'utilities', $section ) ){
$rules['categories'] = 'array|required|min:1';
$rules['categories.*'] = 'integer|exists:categories,id';
}
if( section_must_be( 'utilities', $section ) ){
$rules['systems'] = 'array|required|min:1';
$rules['systems.*'] = 'integer|exists:systems,id';
}
$rules['version'] = 'required|string|max:50';
$rules['release-date'] = 'required|date';
$rules['status'] = 'required|integer|exists:statuses,id';
if( section_must_not_be( 'utilities', $section ) ){
$rules['status'] = 'required|integer|exists:statuses,id';
} else {
$rules['level'] = 'required|integer|exists:levels,id';
}
$rules['description'] = 'required|string';
if( section_must_be( ['romhacks', 'translations' ], $section ) ){
$rules['game_selection_mode'] = 'required|string|in:game,platform,none';
$gameSelectionMode = $this->input('game_selection_mode') !== '' ? $this->input('game_selection_mode') : 'game';
if( $gameSelectionMode === 'none' ){
// ...
} else if( $gameSelectionMode === 'platform' ){
$rules['platform_only_id'] = 'required|integer|exists:platforms,id';
} else {
$rules['game_id'] = 'required_without:new-game-title|nullable|integer|exists:games,id';
$rules['new-game-title'] = 'required_without:game_id|nullable|string|max:255';
$rules['new-game-platform'] = 'required_with:new-game-title|nullable|integer|exists:platforms,id';
$rules['new-game-genre'] = 'required_with:new-game-title|integer|nullable|exists:genres,id';
}
$rules['hashes'] = 'array|required|min:1';
$rules['hashes.*.filename'] = 'required|string|max:512';
$rules['hashes.*.hash_crc32'] = 'required|string|max:512';
$rules['hashes.*.hash_sha1'] = 'required|string|max:512';
$rules['hashes.*.verified'] = 'required|string|max:512';
if( section_must_be( ['translations', 'romhacks'], $section ) ){
$rules['hashes'] = 'array|required|min:1';
$rules['hashes.*.filename'] = 'required|string|max:512';
$rules['hashes.*.hash_crc32'] = 'required|string|max:512';
$rules['hashes.*.hash_sha1'] = 'required|string|max:512';
$rules['hashes.*.verified'] = 'required|string|max:512';
}
$rules['languages'] = 'array|required|min:1';
$rules['languages.*'] = 'integer|exists:languages,id';

View File

@@ -3,13 +3,16 @@
namespace App\Livewire;
use App\Models\Author;
use App\Models\Category;
use App\Models\Entry;
use App\Models\Game;
use App\Models\Genre;
use App\Models\Language;
use App\Models\Level;
use App\Models\Modification;
use App\Models\Platform;
use App\Models\Status;
use App\Models\System;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;
@@ -114,6 +117,41 @@ class Database extends Component
#[Url(except:'or')]
public string $modificationsMode = 'or';
/**
* Categories IDs filter.
* @var array
*/
#[Url(except:[])]
public array $categories = [];
/**
* Categories mode and/or
* @var string
*/
#[Url(except:['or'])]
public string $categoriesMode = 'or';
/**
* Systems IDs filter.
* @var array
*/
#[Url(except:[])]
public array $systems = [];
/**
* Systems mode and/or
* @var string
*/
#[Url(except:['or'])]
public string $systemsMode = 'or';
/**
* Levels IDs filter.
* @var array
*/
#[Url(except:[])]
public array $levels = [];
/**
* Sort by field.
* @var string
@@ -164,11 +202,16 @@ class Database extends Component
public function updatedLanguagesMode(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedModifications(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedModificationsMode(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedCategories(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedCategoriesMode(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedSystems(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedSystemsMode(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function updatedLevels(): void { $this->resetPage(); $this->dispatch('filters-updated'); }
public function clearFilters(): void
{
$this->reset([
'search', 'types', 'platforms', 'genres', 'statuses', 'authors', 'authorsMode', 'languages', 'languagesMode', 'modifications', 'modificationsMode'
'search', 'types', 'platforms', 'genres', 'statuses', 'authors', 'authorsMode', 'languages', 'languagesMode', 'modifications', 'modificationsMode', 'categories', 'categoriesMode', 'systems', 'systemsMode', 'levels'
]);
$this->resetPage();
}
@@ -188,7 +231,7 @@ class Database extends Component
private function buildQuery()
{
$query = Entry::query()->published()->with([
'game.platform', 'game.genre', 'status', 'authors', 'languages'
'game.platform', 'game.genre', 'status', 'authors', 'languages', 'level', 'systems', 'categories', 'modifications'
]);
if( $this->search ) {
@@ -253,6 +296,30 @@ class Database extends Component
}
}
if( $this->levels ) {
$query->whereIn('level_id', $this->levels);
}
if( $this->categories ) {
if( $this->categoriesMode === 'and' ) {
foreach ( $this->categories as $categoryId ) {
$query->whereHas('categories', fn($q) => $q->where('categories.id', $categoryId));
}
} else {
$query->whereHas('categories', fn($q) => $q->whereIn('categories.id', $this->categories));
}
}
if( $this->systems ) {
if( $this->systemsMode === 'and' ) {
foreach ( $this->systems as $systemId ) {
$query->whereHas('systems', fn($q) => $q->where('systems.id', $systemId));
}
} else {
$query->whereHas('systems', fn($q) => $q->whereIn('systems.id', $this->systems));
}
}
return $query->orderBy($this->sortBy, $this->sortDir);
}
@@ -267,6 +334,9 @@ class Database extends Component
'allAuthors' => Author::orderBy('name')->get(),
'allLanguages' => Language::orderBy('name')->get(),
'allModifications' => Modification::orderBy('name')->get(),
'allCategories' => Category::orderBy('name')->get(),
'allLevels' => Level::orderBy('name')->get(),
'allSystems' => System::orderBy('name')->get(),
]);
}
}

View File

@@ -16,6 +16,17 @@ class GameSelector extends Component
public const int REQUIRED_CHARS = 3;
/**
* Which section we can change selection mode.
*/
public const array CHANGE_SECTION_MODE = [ 'utilities', 'documents' ];
/**
* Selection mode between game|platform|none.
* @var string
*/
public string $selectionMode = 'game';
/**
* If we are in new game mode.
* @var bool
@@ -70,9 +81,25 @@ class GameSelector extends Component
*/
public bool $dropdown = false;
public function mount( ?int $gameId = null, ?string $newGameTitle = null, ?int $newGamePlatform = null, ?int $newGameGenre = null ): void
/**
* In platform mode.
* @var int|null
*/
public ?int $platformModeId = null;
/**
* In platform mode.
* @var string|null
*/
public ?string $platformModeName = null;
public ?string $section = null;
public function mount( ?int $gameId = null, ?string $newGameTitle = null, ?int $newGamePlatform = null, ?int $newGameGenre = null, ?string $section, ?int $platformOnlyId ): void
{
$this->section = $section;
// If we selected an existent game.
if( $gameId ){
$game = Game::with(['platform','genre'])->find($gameId);
@@ -93,6 +120,36 @@ class GameSelector extends Component
$this->gamePlatformId = is_numeric($newGamePlatform) ? (int) $newGamePlatform : null;
$this->gameGenreId = is_numeric($newGameGenre) ? (int) $newGameGenre : null;
}
if( in_array( $section, self::CHANGE_SECTION_MODE ) ) {
if ($platformOnlyId) {
$this->selectionMode = 'platform';
$this->platformModeId = $platformOnlyId;
$platform = Platform::find($platformOnlyId);
if ($platform) {
$this->platformModeName = $platform->name;
} else {
$this->platformModeId = null;
}
}
}
}
public function setSelectionMode(string $mode): void
{
if( !in_array( $this->section, self::CHANGE_SECTION_MODE ) )
return;
$this->selectionMode = $mode;
if( $mode !== 'game' ){
$this->clearGame();
$this->newGame = false;
}
if( $mode !== 'platform' ){
$this->platformModeId = null;
$this->platformModeName = null;
}
}
/**
@@ -134,6 +191,15 @@ class GameSelector extends Component
}
public function selectPlatformOnly( int $id ): void
{
$platform = Platform::find($id);
if( $platform ){
$this->platformModeId = $platform->id;
$this->platformModeName = $platform->name;
}
}
/**
* Clear existent game selection.
* @return void
@@ -179,6 +245,10 @@ class GameSelector extends Component
}
$data['hasOldNewGame'] = old('new-game-title') || old('new-game-platform') || old('new-game-genre');
$data['canChangeSelection'] = in_array( $this->section, self::CHANGE_SECTION_MODE );
if( in_array( $this->section, self::CHANGE_SECTION_MODE ) )
$data['platforms'] = Platform::orderBy('name')->get();
return view('livewire.game-selector', $data );
}
}

View File

@@ -8,6 +8,28 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property string|null $website
* @property int|null $user_id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Entry> $entries
* @property-read int|null $entries_count
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereUserId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Author whereWebsite($value)
* @mixin \Eloquent
*/
class Author extends Model
{
protected $fillable = [

33
app/Models/Category.php Normal file
View File

@@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property array<array-key, mixed>|null $restricted_to
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereRestrictedTo($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Category whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Category extends Model
{
protected $fillable = ['name', 'slug', 'restricted_to'];
protected $casts = [
'restricted_to' => 'array',
];
}

View File

@@ -2,17 +2,100 @@
namespace App\Models;
use App\Traits\HasGallery;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Monolog\Level;
/**
* @property int $id
* @property string $type
* @property string|null $title
* @property string|null $slug
* @property string|null $description
* @property string|null $main_image
* @property string $state
* @property string|null $staff_comment
* @property \Illuminate\Support\Carbon|null $rejected_at
* @property bool $featured
* @property int|null $game_id
* @property int|null $platform_id
* @property int|null $status_id
* @property string|null $version
* @property \Illuminate\Support\Carbon|null $release_date
* @property string|null $staff_credits
* @property string|null $relevant_link
* @property string|null $youtube_link
* @property int $user_id
* @property int|null $comments_thread_id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string|null $complete_title
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property int|null $level_id
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Author> $authors
* @property-read int|null $authors_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Category> $categories
* @property-read int|null $categories_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EntryFile> $files
* @property-read int|null $files_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Gallery> $gallery
* @property-read int|null $gallery_count
* @property-read \App\Models\Game|null $game
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\EntryHash> $hashes
* @property-read int|null $hashes_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Language> $languages
* @property-read int|null $languages_count
* @property-read \App\Models\Level|null $level
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Modification> $modifications
* @property-read int|null $modifications_count
* @property-read \App\Models\Platform|null $platform
* @property-read \App\Models\Status|null $status
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\System> $systems
* @property-read int|null $systems_count
* @method static Builder<static>|Entry inQueue(int $daysRejected = 7)
* @method static Builder<static>|Entry newModelQuery()
* @method static Builder<static>|Entry newQuery()
* @method static Builder<static>|Entry onlyTrashed()
* @method static Builder<static>|Entry published()
* @method static Builder<static>|Entry query()
* @method static Builder<static>|Entry whereCommentsThreadId($value)
* @method static Builder<static>|Entry whereCompleteTitle($value)
* @method static Builder<static>|Entry whereCreatedAt($value)
* @method static Builder<static>|Entry whereDeletedAt($value)
* @method static Builder<static>|Entry whereDescription($value)
* @method static Builder<static>|Entry whereFeatured($value)
* @method static Builder<static>|Entry whereGameId($value)
* @method static Builder<static>|Entry whereId($value)
* @method static Builder<static>|Entry whereLevelId($value)
* @method static Builder<static>|Entry whereMainImage($value)
* @method static Builder<static>|Entry wherePlatformId($value)
* @method static Builder<static>|Entry whereRejectedAt($value)
* @method static Builder<static>|Entry whereReleaseDate($value)
* @method static Builder<static>|Entry whereRelevantLink($value)
* @method static Builder<static>|Entry whereSlug($value)
* @method static Builder<static>|Entry whereStaffComment($value)
* @method static Builder<static>|Entry whereStaffCredits($value)
* @method static Builder<static>|Entry whereState($value)
* @method static Builder<static>|Entry whereStatusId($value)
* @method static Builder<static>|Entry whereTitle($value)
* @method static Builder<static>|Entry whereType($value)
* @method static Builder<static>|Entry whereUpdatedAt($value)
* @method static Builder<static>|Entry whereUserId($value)
* @method static Builder<static>|Entry whereVersion($value)
* @method static Builder<static>|Entry whereYoutubeLink($value)
* @method static Builder<static>|Entry withTrashed(bool $withTrashed = true)
* @method static Builder<static>|Entry withoutTrashed()
* @mixin \Eloquent
*/
class Entry extends Model
{
use SoftDeletes;
use SoftDeletes, HasGallery;
/**
* @var string[]
@@ -38,6 +121,7 @@ class Entry extends Model
'comments_thread_id',
'staff_comment',
'rejected_at',
'level_id'
];
/**
@@ -81,6 +165,10 @@ class Entry extends Model
return $this->belongsTo(Status::class );
}
public function level(): BelongsTo {
return $this->belongsTo(\App\Models\Level::class);
}
public function authors(): BelongsToMany {
return $this->belongsToMany(Author::class, 'entry_authors');
}
@@ -93,12 +181,16 @@ class Entry extends Model
return $this->belongsToMany( Modification::class, 'entry_modifications');
}
public function files(): HasMany {
return $this->hasMany(EntryFile::class)->orderBy('filename');
public function categories(): BelongsToMany {
return $this->belongsToMany(Category::class, 'entry_categories');
}
public function gallery(): HasMany {
return $this->hasMany(EntryGallery::class)->orderBy('id');
public function systems(): BelongsToMany {
return $this->belongsToMany(System::class, 'entry_systems');
}
public function files(): HasMany {
return $this->hasMany(EntryFile::class)->orderBy('filename');
}
public function hashes(): HasMany {

View File

@@ -5,6 +5,39 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $id
* @property int $entry_id
* @property string $filename
* @property string $filepath
* @property string $favorite_server
* @property int $favorite_at
* @property int|null $filesize
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property string $file_uuid
* @property string $state
* @property int $online_patcher
* @property int $secondary_online_patcher
* @property-read \App\Models\Entry|null $entry
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereEntryId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFavoriteAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFavoriteServer($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFileUuid($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFilename($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFilepath($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereFilesize($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereOnlinePatcher($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereSecondaryOnlinePatcher($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereState($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryFile whereUpdatedAt($value)
* @mixin \Eloquent
*/
class EntryFile extends Model
{
protected $fillable = [

View File

@@ -2,10 +2,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class EntryGallery extends Model
{
protected $fillable = ['entry_id','image'];
}
/**
* @deprecated Use Gallery instead.
*/
class EntryGallery extends Gallery {}

View File

@@ -5,6 +5,29 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $id
* @property int $entry_id
* @property string $filename
* @property string $hash_crc32
* @property string $hash_sha1
* @property string $verified
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \App\Models\Entry|null $entry
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereEntryId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereFilename($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereHashCrc32($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereHashSha1($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereUpdatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|EntryHash whereVerified($value)
* @mixin \Eloquent
*/
class EntryHash extends Model
{
protected $fillable = [

34
app/Models/Gallery.php Normal file
View File

@@ -0,0 +1,34 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
/**
* @property int $id
* @property int $entry_id
* @property string $image
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery whereEntryId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery whereImage($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Gallery whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Gallery extends Model
{
protected $table = 'galleries';
protected $fillable = ['image', 'galleryable_id', 'galleryable_type'];
public function galleryable(): MorphTo
{
return $this->morphTo();
}
}

View File

@@ -5,6 +5,30 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property int $platform_id
* @property int $genre_id
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Entry> $entries
* @property-read int|null $entries_count
* @property-read \App\Models\Genre $genre
* @property-read \App\Models\Platform $platform
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereGenreId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game wherePlatformId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Game whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Game extends Model
{
/**

View File

@@ -6,6 +6,24 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Game> $games
* @property-read int|null $games_count
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Genre whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Genre extends Model
{
protected $fillable = [ 'name', 'slug' ];

View File

@@ -6,6 +6,24 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Entry> $entries
* @property-read int|null $entries_count
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Language whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Language extends Model
{
protected $fillable = [ 'name', 'slug' ];

26
app/Models/Level.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Level whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Level extends Model
{
protected $fillable = ['name', 'slug'];
}

View File

@@ -4,6 +4,22 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Modification whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Modification extends Model
{
protected $fillable = [ 'name', 'slug' ];

View File

@@ -5,6 +5,28 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property string|null $short_name
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Entry> $entries
* @property-read int|null $entries_count
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Game> $games
* @property-read int|null $games_count
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereShortName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Platform whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Platform extends Model
{

View File

@@ -4,6 +4,22 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|Status whereUpdatedAt($value)
* @mixin \Eloquent
*/
class Status extends Model
{
protected $fillable = ['name', 'slug'];

26
app/Models/System.php Normal file
View File

@@ -0,0 +1,26 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
/**
* @property int $id
* @property string $name
* @property string $slug
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder<static>|System newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|System newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|System query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|System whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|System whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|System whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|System whereSlug($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|System whereUpdatedAt($value)
* @mixin \Eloquent
*/
class System extends Model
{
protected $fillable = ['name', 'slug'];
}

View File

@@ -10,6 +10,31 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
/**
* @property int $id
* @property string $name
* @property string $email
* @property \Illuminate\Support\Carbon|null $email_verified_at
* @property string $password
* @property string|null $remember_token
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @property-read int|null $notifications_count
* @method static \Database\Factories\UserFactory factory($count = null, $state = [])
* @method static \Illuminate\Database\Eloquent\Builder<static>|User newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|User newQuery()
* @method static \Illuminate\Database\Eloquent\Builder<static>|User query()
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereEmailVerifiedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereRememberToken($value)
* @method static \Illuminate\Database\Eloquent\Builder<static>|User whereUpdatedAt($value)
* @mixin \Eloquent
*/
#[Fillable(['name', 'email', 'password'])]
#[Hidden(['password', 'remember_token'])]
class User extends Authenticatable

View File

@@ -8,15 +8,17 @@ use App\Helpers\XenForoHelpers;
use App\Http\Requests\StoreEntryRequest;
use App\Jobs\CreateXenForoCommentsThread;
use App\Models\Author;
use App\Models\Category;
use App\Models\Entry;
use App\Models\EntryFile;
use App\Models\EntryGallery;
use App\Models\Gallery;
use App\Models\EntryHash;
use App\Models\Game;
use App\Models\Genre;
use App\Models\Language;
use App\Models\Modification;
use App\Models\Platform;
use App\Models\System;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
@@ -118,11 +120,7 @@ class SubmissionsService {
$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();
}
$gameId = $this->Step2_CreateAndReturnGameId();
// STEP 3 : Create Complete title.
$completeTitle = $this->Step3_BuildCompleteTitle( $gameId );
@@ -132,7 +130,7 @@ class SubmissionsService {
if( section_must_be( 'translations', $this->section ) &&
!$this->request->input('entry_title') ){
$entryTitle = Game::find($gameId)->name;
$entryTitle = Game::find($gameId)->name ?? "";
} else {
$entryTitle = $this->request->input('entry_title');
}
@@ -149,6 +147,7 @@ class SubmissionsService {
'main_image' => $this->request->input('main-image'),
'state' => $this->request->input('submit-state'),
'game_id' => $gameId,
'platform_id' => $this->request->input('platform_only_id'),
'status_id' => $this->request->input('status'),
'version' => $this->request->input('version'),
'release_date' => $this->request->input('release-date'),
@@ -157,6 +156,7 @@ class SubmissionsService {
'youtube_link' => $this->request->input('youtube_video'),
'user_id' => $user_id,
'complete_title' => $completeTitle,
'level_id' => $this->request->input('level')
];
$entry = Entry::create( $fields );
@@ -165,19 +165,28 @@ class SubmissionsService {
$this->Step7_SaveEntryFiles( $entry );
// STEP 8 : Save hashes.
$this->Step8_SaveHashes( $entry->id );
if( section_must_be( ['translations', 'romhacks' ], $this->section ) )
$this->Step8_SaveHashes( $entry->id );
// STEP 9 : Save Authors.
$this->Step9_SaveAuthors( $entry );
// STEP 10 : Save Modifications.
if( section_must_be( 'romhacks', $this->section ) ){
if( section_must_be( ['romhacks','lua-scripts'], $this->section ) ){
$this->Step10_SaveRomhacksModifications( $entry );
}
if( section_must_be( 'utilities', $this->section ) ){
$this->Step10_SaveUtilitiesSystems( $entry );
}
// STEP 11 : Save Languages
$this->Step11_SaveLanguages( $entry );
// STEP 11.5 : Save Categories
if( section_must_be( 'utilities', $this->section ) ) {
$this->Step11_5_SaveCategories($entry);
}
// STEP 12 : Prepare Gallery images.
$this->Step12a_PrepareGalleryImages( $entry );
@@ -207,6 +216,10 @@ class SubmissionsService {
*/
private function Step2_CreateAndReturnGameId(): ?int {
$mode = $this->request->input('game_selection_mode', 'game');
if( $mode !== 'game' )
return null;
// Already existing game.
if( $this->request->input('game_id') )
return $this->request->input('game_id');
@@ -261,9 +274,9 @@ class SubmissionsService {
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', 'translations', 'homebrew', 'lua-scripts', 'tutorials'], $this->section ) ) {
if( section_must_be(['romhacks', 'translations', 'homebrew', 'lua-scripts'], $this->section ) ) {
// TODO: Add single platform ID compatibility.
$fields['platform_name'] = $gameId ? Game::find( $gameId )->platform->name : null;
$fields['platform_name'] = $gameId ? Game::find( $gameId )->platform->name : Platform::find( $this->request->input('platform_only_id') )?->name ?? null;
}
return EntryHelpers::buildCompleteTitle( $this->section, $fields );
@@ -381,6 +394,24 @@ class SubmissionsService {
}
}
/**
* @param Entry $entry
*
* @return void
* @throws SubmissionException
*/
private function Step10_SaveUtilitiesSystems( Entry $entry ): void
{
// TODO: Replace by edit version
foreach ( $this->request->input('systems', [] ) ?? [] as $systemId ) {
$system = System::find( $systemId );
if( !$system )
throw new SubmissionException( "System {$systemId} does not exist." );
$entry->systems()->attach( $system->id );
}
}
/**
* @param Entry $entry
*
@@ -400,11 +431,29 @@ class SubmissionsService {
}
/**
* @param Entry $entry
*
* @return void
* @throws SubmissionException
*/
private function Step11_5_SaveCategories( Entry $entry ): void
{
// TODO: Replace by edit version.
foreach ( $this->request->input('categories', [] ) ?? [] as $categoryId ) {
$category = Category::find( $categoryId );
if( !$category )
throw new SubmissionException( "Category {$categoryId} does not exist." );
$entry->categories()->attach( $category->id );
}
}
private function Step12a_PrepareGalleryImages( Entry $entry ): void
{
foreach ( $this->request->input('gallery', [] ) ?? [] as $imagePath ) {
EntryGallery::create([
'entry_id' => $entry->id,
$entry->gallery()->create([
'image' => $imagePath,
]);
}
@@ -464,9 +513,7 @@ class SubmissionsService {
// STEP 2: Create game if different.
$gameId = null;
if( section_must_be( ['romhacks', 'translations' ], $this->section ) ){
$gameId = $this->eStep2_VerifyCreateAndEditGameId();
}
$gameId = $this->eStep2_VerifyCreateAndEditGameId();
// STEP 3: Recreate complete title and refresh slug if needed.
$completeTitle = $this->Step3_BuildCompleteTitle( $gameId );
@@ -494,6 +541,7 @@ class SubmissionsService {
'main_image' => $this->request->input('main-image'),
'state' => $this->request->input('submit-state'),
'game_id' => $gameId,
'platform_id' => $this->request->input('platform_only_id'),
'status_id' => $this->request->input('status'),
'version' => $this->request->input('version'),
'release_date' => $this->request->input('release-date'),
@@ -502,12 +550,13 @@ class SubmissionsService {
'youtube_link' => $this->request->input('youtube_video'),
'user_id' => $user_id,
'complete_title' => $completeTitle,
'comments_thread_id' => $this->request->input('comments_thread_id'),
'featured' => $this->request->input('featured') ?? false,
'level_id' => $this->request->input('level'),
];
if( \Auth::user()->can('moderate', $this->entry) ){
$fields['staff_comment'] = $this->request->input('staff_comment');
$fields['featured'] = $this->request->input('featured') ?? false;
$fields['comments_thread_id'] = $this->request->input('comments_thread_id');
}
$this->entry->update( $fields );
@@ -516,19 +565,27 @@ class SubmissionsService {
$this->eStep6_UpdateEntryFiles( $this->entry->id );
// STEP 7: Update hashes.
$this->eStep7_UpdateHashes( $this->entry->id );
if( section_must_be( ['translations', 'romhacks' ], $this->section ) )
$this->eStep7_UpdateHashes( $this->entry->id );
// STEP 8: Update Authors.
$this->eStep8_UpdateAuthors();
// STEP 9: Update romhacks modifications.
if( section_must_be( 'romhacks', $this->section ) ) {
if( section_must_be( ['romhacks', 'lua-scripts'], $this->section ) ) {
$this->eStep9_UpdateRomhacksModifications();
}
if( section_must_be( 'utilities', $this->section ) ) {
$this->eStep9_UpdateUtilitiesSystems();
}
// STEP 10: Update Languages.
$this->eStep10_UpdateLanguages();
// STEP 10.5 : Update categories
if( section_must_be( 'utilities', $this->section ) )
$this->eStep10_5_UpdateCategories();
// STEP 11: Prepare new gallery images and prepare deletion of others ones.
$galleryPaths = $this->eStep11a_UpdateGalleryImages();
@@ -558,8 +615,14 @@ class SubmissionsService {
/**
* @throws SubmissionException
*/
private function eStep2_VerifyCreateAndEditGameId(): int
private function eStep2_VerifyCreateAndEditGameId(): ?int
{
$mode = $this->request->input('game_selection_mode', 'game');
if ($mode !== 'game') {
return null;
}
// Already existing game.
if( $this->request->input('game_id') ){
@@ -721,6 +784,27 @@ class SubmissionsService {
}
/**
* @return void
* @throws SubmissionException
*/
private function eStep9_UpdateUtilitiesSystems(): void
{
$requestSystems = $this->request->input('systems', [] ) ?? [];
if( !empty( $requestSystems ) ){
$valid = System::whereIn( 'id', $requestSystems )->pluck('id')->toArray();
if( count( $valid ) !== count( $requestSystems ) ){
throw new SubmissionException( "One of the systems doesn't exist." );
}
}
$this->entry->systems()->sync( $requestSystems );
}
/**
* @return void
* @throws SubmissionException
@@ -739,6 +823,24 @@ class SubmissionsService {
$this->entry->languages()->sync( $requestLanguages );
}
/**
* @return void
* @throws SubmissionException
*/
private function eStep10_5_UpdateCategories(): void
{
$requestCategories = $this->request->input('categories', [] ) ?? [];
if( !empty( $requestCategories ) ){
$valid = Category::whereIn( 'id', $requestCategories )->pluck('id')->toArray();
if( count( $valid ) !== count( $requestCategories ) ){
throw new SubmissionException( "One of the categories doesn't exist." );
}
}
$this->entry->categories()->sync( $requestCategories );
}
private function eStep11a_UpdateGalleryImages(): array
{
$requestGallery = $this->request->input('gallery', [] ) ?? [];
@@ -747,14 +849,13 @@ class SubmissionsService {
$needDeletion = array_diff( $existingGalleryPaths, $requestGallery );
if( !empty( $needDeletion ) ){
EntryGallery::where('entry_id', $this->entry->id)->whereIn('image', $needDeletion )->delete();
$this->entry->gallery()->whereIn('image', $needDeletion )->delete();
}
$needAddition = array_diff( $requestGallery, $existingGalleryPaths );
$images = [];
foreach( $needAddition as $imagePath ){
$images[] = EntryGallery::create([
'entry_id' => $this->entry->id,
$images[] = $this->entry->gallery()->create([
'image' => $imagePath,
]);
}

14
app/Traits/HasGallery.php Normal file
View File

@@ -0,0 +1,14 @@
<?php
namespace App\Traits;
use App\Models\Gallery;
use Illuminate\Database\Eloquent\Relations\MorphMany;
trait HasGallery
{
public function gallery(): MorphMany
{
return $this->morphMany(Gallery::class, 'galleryable')->orderBy('id');
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\View\Components;
use App\Models\Category;
use App\Models\Language;
use Closure;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
class CategorySelector extends Component
{
public $categories;
/**f
* Create a new component instance.
*/
public function __construct(
public string $section,
public array $selected = [],
public bool $required = true
)
{
$this->categories = Category::query()
->where(function ($query) {
$query->whereJsonContains('restricted_to', $this->section)
->orWhereNull('restricted_to');
})
->orderBy('name')
->get();
}
/**
* Get the view / contents that represent the component.
*/
public function render(): View|Closure|string
{
return view('components.category-selector');
}
}