From 96f3499da945f8e653999240655ade6105e4dd2d Mon Sep 17 00:00:00 2001 From: ScuffedNewt Date: Mon, 14 Oct 2024 20:00:34 +0100 Subject: [PATCH] feat: extension --- .../Admin/Data/FeatureController.php | 3 ++ app/Http/Controllers/WorldController.php | 2 +- app/Models/Feature/Feature.php | 15 ++++++++ app/Services/FeatureService.php | 3 ++ ...0_14_184542_add_feature_variant_column.php | 32 ++++++++++++++++ .../features/create_edit_feature.blade.php | 18 +++++++-- .../views/world/_feature_entry.blade.php | 20 ++++++++++ .../world/_feature_variants_entry.blade.php | 37 +++++++++++++++++++ 8 files changed, 125 insertions(+), 5 deletions(-) create mode 100644 database/migrations/2024_10_14_184542_add_feature_variant_column.php create mode 100644 resources/views/world/_feature_variants_entry.blade.php diff --git a/app/Http/Controllers/Admin/Data/FeatureController.php b/app/Http/Controllers/Admin/Data/FeatureController.php index 8d05e5797d..8fe2d60f25 100644 --- a/app/Http/Controllers/Admin/Data/FeatureController.php +++ b/app/Http/Controllers/Admin/Data/FeatureController.php @@ -251,6 +251,7 @@ public function getFeatureIndex(Request $request) { public function getCreateFeature() { return view('admin.features.create_edit_feature', [ 'feature' => new Feature, + 'features' => Feature::orderBy('name', 'ASC')->pluck('name', 'id')->toArray(), 'rarities' => ['none' => 'Select a Rarity'] + Rarity::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), 'specieses' => ['none' => 'No restriction'] + Species::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), 'subtypes' => ['none' => 'No subtype'] + Subtype::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), @@ -273,6 +274,7 @@ public function getEditFeature($id) { return view('admin.features.create_edit_feature', [ 'feature' => $feature, + 'features' => Feature::where('id', '!=', $id)->orderBy('name', 'ASC')->pluck('name', 'id')->toArray(), 'rarities' => ['none' => 'Select a Rarity'] + Rarity::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), 'specieses' => ['none' => 'No restriction'] + Species::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), 'subtypes' => ['none' => 'No subtype'] + Subtype::orderBy('sort', 'DESC')->pluck('name', 'id')->toArray(), @@ -292,6 +294,7 @@ public function postCreateEditFeature(Request $request, FeatureService $service, $id ? $request->validate(Feature::$updateRules) : $request->validate(Feature::$createRules); $data = $request->only([ 'name', 'species_id', 'subtype_id', 'rarity_id', 'feature_category_id', 'description', 'image', 'remove_image', 'is_visible', + 'parent_id', ]); if ($id && $service->updateFeature(Feature::find($id), $data, Auth::user())) { flash('Trait updated successfully.')->success(); diff --git a/app/Http/Controllers/WorldController.php b/app/Http/Controllers/WorldController.php index 18b3e408a9..11c713be75 100644 --- a/app/Http/Controllers/WorldController.php +++ b/app/Http/Controllers/WorldController.php @@ -147,7 +147,7 @@ public function getFeatureCategories(Request $request) { * @return \Illuminate\Contracts\Support\Renderable */ public function getFeatures(Request $request) { - $query = Feature::visible(Auth::user() ?? null)->with('category')->with('rarity')->with('species'); + $query = Feature::visible(Auth::user() ?? null)->whereNull('parent_id')->with('category')->with('rarity')->with('species'); $data = $request->only(['rarity_id', 'feature_category_id', 'species_id', 'subtype_id', 'name', 'sort']); if (isset($data['rarity_id']) && $data['rarity_id'] != 'none') { $query->where('rarity_id', $data['rarity_id']); diff --git a/app/Models/Feature/Feature.php b/app/Models/Feature/Feature.php index b13dfc8729..62b513ff0b 100644 --- a/app/Models/Feature/Feature.php +++ b/app/Models/Feature/Feature.php @@ -16,6 +16,7 @@ class Feature extends Model { */ protected $fillable = [ 'feature_category_id', 'species_id', 'subtype_id', 'rarity_id', 'name', 'has_image', 'description', 'parsed_description', 'is_visible', 'hash', + 'parent_id', ]; /** @@ -88,6 +89,20 @@ public function category() { return $this->belongsTo(FeatureCategory::class, 'feature_category_id'); } + /** + * Get the parent feature. + */ + public function parent() { + return $this->belongsTo(Feature::class, 'parent_id'); + } + + /** + * Get the child features. + */ + public function children() { + return $this->hasMany(Feature::class, 'parent_id'); + } + /********************************************************************************************** SCOPES diff --git a/app/Services/FeatureService.php b/app/Services/FeatureService.php index a7ede66b7c..8795887392 100644 --- a/app/Services/FeatureService.php +++ b/app/Services/FeatureService.php @@ -272,6 +272,9 @@ public function updateFeature($feature, $data, $user) { if (isset($data['subtype_id']) && $data['subtype_id'] == 'none') { $data['subtype_id'] = null; } + if (isset($data['parent_id']) && $feature->children->count() > 0) { + throw new \Exception('This feature has children. Please remove them before changing the parent feature.'); + } // More specific validation if (Feature::where('name', $data['name'])->where('id', '!=', $feature->id)->exists()) { diff --git a/database/migrations/2024_10_14_184542_add_feature_variant_column.php b/database/migrations/2024_10_14_184542_add_feature_variant_column.php new file mode 100644 index 0000000000..b2da5ea22c --- /dev/null +++ b/database/migrations/2024_10_14_184542_add_feature_variant_column.php @@ -0,0 +1,32 @@ +unsignedInteger('parent_id')->nullable()->default(null); + $table->foreign('parent_id')->references('id')->on('features')->onDelete('set null'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + // + Schema::table('features', function (Blueprint $table) { + $table->dropForeign(['parent_id']); + $table->dropColumn('parent_id'); + }); + } +}; diff --git a/resources/views/admin/features/create_edit_feature.blade.php b/resources/views/admin/features/create_edit_feature.blade.php index c6aec2f2d7..5a319ecfab 100644 --- a/resources/views/admin/features/create_edit_feature.blade.php +++ b/resources/views/admin/features/create_edit_feature.blade.php @@ -41,15 +41,20 @@
-
+
{!! Form::label('Trait Category (Optional)') !!} {!! Form::select('feature_category_id', $categories, $feature->feature_category_id, ['class' => 'form-control']) !!}
-
+
+
Traits that are variants of other traits don't appear individually on the encyclopedia.
+ {!! Form::label('Parent Trait (Optional)') !!} {!! add_help('If this trait is a variant of another trait, select the parent trait here.') !!} + {!! Form::select('parent_id', $features, $feature->parent_id, ['class' => 'form-control', 'placeholder' => 'Select a Parent Trait']) !!} +
+
{!! Form::label('Species Restriction (Optional)') !!} {!! Form::select('species_id', $specieses, $feature->species_id, ['class' => 'form-control', 'id' => 'species']) !!}
-
+
{!! Form::label('Subtype (Optional)') !!} {!! add_help('This is cosmetic and does not limit choice of traits in selections.') !!} {!! Form::select('subtype_id', $subtypes, $feature->subtype_id, ['class' => 'form-control', 'id' => 'subtype']) !!}
@@ -74,7 +79,12 @@

Preview

- @include('world._feature_entry', ['feature' => $feature]) + @if ($feature->parent_id) +
This item is a variant of another item. It will not appear on the encyclopedia.
+ @include('world._feature_entry', ['feature' => $feature->parent]) + @else + @include('world._feature_entry', ['feature' => $feature]) + @endif
@endif diff --git a/resources/views/world/_feature_entry.blade.php b/resources/views/world/_feature_entry.blade.php index 71eee4909a..46f68aac6c 100644 --- a/resources/views/world/_feature_entry.blade.php +++ b/resources/views/world/_feature_entry.blade.php @@ -33,5 +33,25 @@
{!! $feature->parsed_description !!}
+ @if ($feature->children->count()) +

Trait Variants

+
+ @php + // Sort children collection in PHP based on the rarity's sort attribute + $sortedChildren = $feature->children()->with('rarity')->get()->sortBy(function ($child, $key) { + return $child->rarity ? $child->rarity->sort : null; + }); + @endphp + @foreach($sortedChildren as $i) +
+
+
+ @include('world._feature_variants_entry', ['variant' => $i]) +
+
+
+ @endforeach +
+ @endif
diff --git a/resources/views/world/_feature_variants_entry.blade.php b/resources/views/world/_feature_variants_entry.blade.php new file mode 100644 index 0000000000..83230c6dd9 --- /dev/null +++ b/resources/views/world/_feature_variants_entry.blade.php @@ -0,0 +1,37 @@ +
+ @if ($variant->has_image) +
+ + {{ $variant->name }} + +
+ @endif +
+ +

+ @if (!$variant->is_visible) + + @endif + {!! $variant->displayName !!} + + + +

+ @if ($variant->feature_category_id) +
+ Category: {!! $variant->category->displayName !!} +
+ @endif + @if ($variant->species_id) +
+ Species: {!! $variant->species->displayName !!} + @if ($variant->subtype_id) + ({!! $variant->subtype->displayName !!} subtype) + @endif +
+ @endif +
+ {!! $variant->parsed_description !!} +
+
+