]> git.localhorst.tv Git - alttp.git/commitdiff
tournament names
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 10 Jul 2025 13:09:07 +0000 (15:09 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Thu, 10 Jul 2025 13:09:07 +0000 (15:09 +0200)
app/Http/Controllers/SitemapXmlController.php
app/Http/Controllers/TournamentController.php
app/Models/Tournament.php
database/migrations/2025_07_10_123521_tournament_names.php [new file with mode: 0644]
resources/js/pages/Tournament.jsx
routes/api.php
routes/web.php

index a99108bdd202ba519b9f6fa033b8de5f1fa69586..6d9f8d79dc99f0f241dfe3ee5d7ba6ee4b699961 100644 (file)
@@ -19,7 +19,11 @@ class SitemapXmlController extends Controller
 
                foreach (Tournament::all() as $tournament) {
                        $url = new SitemapUrl();
-                       $url->path = '/tournaments/'.$tournament->id;
+                       if ($tournament->name) {
+                               $url->path = '/tournaments/'.$tournament->name;
+                       } else {
+                               $url->path = '/tournaments/'.$tournament->id;
+                       }
                        $url->lastmod = $tournament->updated_at ? $tournament->updated_at : ($tournament->created_at ? $tournament->created_at : now());
                        $url->changefreq = $tournament->locked ? 'never' : 'daily';
                        $url->priority = $tournament->locked ? 0.5 : 1.0;
index 12289a27690aa58bcc6e7bf16ed2a5cfa1bd42a2..a8fa952d24851388207dce81690e2fb97de0b401 100644 (file)
@@ -25,15 +25,15 @@ class TournamentController extends Controller
                return $tournament->toJson();
        }
 
-       public function single(Request $request, $id) {
-               $tournament = Tournament::with(
+       public function single(Request $request, Tournament $tournament) {
+               $this->authorize('view', $tournament);
+               $tournament->load([
                        'applications',
                        'applications.user',
                        'description',
                        'participants',
                        'participants.user',
-               )->findOrFail($id);
-               $this->authorize('view', $tournament);
+               ]);
                $rounds = $tournament->rounds()->with(['results', 'results.user'])->limit(25)->get();
                foreach ($rounds as $round) {
                        if (!Gate::allows('seeResults', $round)) {
@@ -156,4 +156,11 @@ class TournamentController extends Controller
                return $tournament->toJson();
        }
 
+       public function web(Request $request, Tournament $tournament) {
+               $view = view('app')
+                       ->with('title', $tournament->getTranslatedTitle())
+                       ->with('description', $tournament->getTranslatedShort());
+               return $view;
+       }
+
 }
index 44bcaf08c1b460932912cfea6d7e3b03d4888bff..8080d2ac0a4b97be259dcec29282199d2117125e 100644 (file)
@@ -5,10 +5,17 @@ namespace App\Models;
 use Illuminate\Database\Eloquent\Factories\HasFactory;
 use Illuminate\Database\Eloquent\Model;
 
-class Tournament extends Model
-{
+class Tournament extends Model {
+
        use HasFactory;
 
+       public function resolveRouteBinding(mixed $value, $field = null): Tournament|null {
+               if (is_null($field) && !is_numeric($value)) {
+                       return $this->where('name', '=', $value)->firstOrFail();
+               }
+               return parent::resolveRouteBinding($value, $field);
+       }
+
 
        public function getRunners() {
                $runners = [];
@@ -83,6 +90,20 @@ class Tournament extends Model
                return $this->hasMany(Round::class)->orderBy('number', 'DESC');
        }
 
+       public function getTranslatedTitle(): string {
+               if ($this->description) {
+                       return $this->description->getTranslatedProperty('title');
+               }
+               return $this->title;
+       }
+
+       public function getTranslatedShort(): string {
+               if ($this->description) {
+                       return $this->description->getTranslatedProperty('short');
+               }
+               return '';
+       }
+
 
        protected $casts = [
                'accept_applications' => 'boolean',
diff --git a/database/migrations/2025_07_10_123521_tournament_names.php b/database/migrations/2025_07_10_123521_tournament_names.php
new file mode 100644 (file)
index 0000000..5f67338
--- /dev/null
@@ -0,0 +1,26 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+       /**
+        * Run the migrations.
+        */
+       public function up(): void {
+               Schema::table('tournaments', function (Blueprint $table) {
+                       $table->string('name')->nullable()->default(null)->after('id')->unique();
+               });
+       }
+
+       /**
+        * Reverse the migrations.
+        */
+       public function down(): void {
+               Schema::table('tournaments', function (Blueprint $table) {
+                       $table->dropColumn('name');
+               });
+       }
+};
index 661eaa7c687975d1d87baff6799875259dd58799..8f353c1bd2117bb9da2544f444b8b88b77fcf7fb 100644 (file)
@@ -205,7 +205,7 @@ export const Component = () => {
                                content={getTranslation(tournament.description, 'short', i18n.language)}
                        />
                </Helmet> : null}
-               <CanonicalLinks base={`/tournaments/${tournament.id}`} />
+               <CanonicalLinks base={`/tournaments/${tournament.name || tournament.id}`} />
                <Detail
                        actions={actions}
                        tournament={tournament}
index 53430dcdecd32b9cff756b8876b3282a0a56ef8c..7c4d0ea19006b674f1d56ab51aa9971e7e0ab2ea 100644 (file)
@@ -88,7 +88,7 @@ Route::post('rounds/{round}/unlock', 'App\Http\Controllers\RoundController@unloc
 Route::get('tech', 'App\Http\Controllers\TechniqueController@search');
 Route::get('tech/{tech:name}', 'App\Http\Controllers\TechniqueController@single');
 
-Route::get('tournaments/{id}', 'App\Http\Controllers\TournamentController@single');
+Route::get('tournaments/{tournament}', 'App\Http\Controllers\TournamentController@single');
 Route::get('tournaments/{tournament}/more-rounds', 'App\Http\Controllers\TournamentController@moreRounds');
 Route::post('tournaments/{tournament}/apply', 'App\Http\Controllers\TournamentController@apply');
 Route::post('tournaments/{tournament}/close', 'App\Http\Controllers\TournamentController@close');
index 57a0d1ab4ee382896abd5891469deb95e49600e1..075fa81cfcdae99074ae97ce37b3e64874695db1 100644 (file)
@@ -42,6 +42,8 @@ Route::get('/tech/{name}', function ($name) {
        return app()->call('App\Http\Controllers\TechniqueController@web', ['type' => 'tech', 'name' => $name]);
 });
 
+Route::get('/tournaments/{tournament}', 'App\Http\Controllers\TournamentController@web');
+
 Route::get('/twitch/guessing-game-leaderboard/{channel:twitch_id}/{type}', 'App\Http\Controllers\ChannelController@getGuessingGameLeaderboard');
 
 Route::view('/{path?}', 'app')->where('path', '.*');