From f93190f029e7a6a4c9aa03616d425d7c056547e7 Mon Sep 17 00:00:00 2001 From: HolgerHatGarKeineNode <123783602+HolgerHatGarKeineNode@users.noreply.github.com> Date: Sun, 14 Jun 2026 01:32:03 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Add=20`whereLike`=20and=20`orWhereL?= =?UTF-8?q?ike`=20macros=20for=20driver-agnostic=20case-insensitive=20sear?= =?UTF-8?q?ches?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 🔄 Replace `ilike`/`like` conditions with `whereLike` in API controllers and search tools for consistency. - 🚀 Enhance query usability by ensuring cross-database compatibility (PostgreSQL and SQLite). --- app/Http/Controllers/Api/CityController.php | 2 +- .../Controllers/Api/CountryController.php | 4 ++-- app/Http/Controllers/Api/CourseController.php | 2 +- .../Controllers/Api/LanguageController.php | 23 ++++++++----------- .../Controllers/Api/LecturerController.php | 2 +- app/Http/Controllers/Api/MeetupController.php | 4 ++-- app/Http/Controllers/Api/VenueController.php | 2 +- app/Mcp/Tools/Search/ListCountriesTool.php | 4 ++-- app/Mcp/Tools/Search/SearchCitiesTool.php | 2 +- app/Mcp/Tools/Search/SearchCoursesTool.php | 2 +- app/Mcp/Tools/Search/SearchLecturersTool.php | 2 +- app/Mcp/Tools/Search/SearchVenuesTool.php | 2 +- app/Models/LibraryItem.php | 2 +- app/Providers/AppServiceProvider.php | 17 ++++++++++++++ 14 files changed, 42 insertions(+), 28 deletions(-) diff --git a/app/Http/Controllers/Api/CityController.php b/app/Http/Controllers/Api/CityController.php index 15c37d9..dece84d 100644 --- a/app/Http/Controllers/Api/CityController.php +++ b/app/Http/Controllers/Api/CityController.php @@ -42,7 +42,7 @@ class CityController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$request->search}%") + ->whereLike('name', "%{$request->search}%") ) ->when( $request->exists('selected'), diff --git a/app/Http/Controllers/Api/CountryController.php b/app/Http/Controllers/Api/CountryController.php index b65e8fc..9cc24a1 100644 --- a/app/Http/Controllers/Api/CountryController.php +++ b/app/Http/Controllers/Api/CountryController.php @@ -28,8 +28,8 @@ class CountryController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$request->search}%") - ->orWhere('code', 'ilike', "%{$request->search}%"), + ->whereLike('name', "%{$request->search}%") + ->orWhereLike('code', "%{$request->search}%"), ) ->when( $request->exists('selected'), diff --git a/app/Http/Controllers/Api/CourseController.php b/app/Http/Controllers/Api/CourseController.php index 2edaa4b..cd9272b 100644 --- a/app/Http/Controllers/Api/CourseController.php +++ b/app/Http/Controllers/Api/CourseController.php @@ -50,7 +50,7 @@ class CourseController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$request->search}%") + ->whereLike('name', "%{$request->search}%") ) ->when( $request->exists('selected'), diff --git a/app/Http/Controllers/Api/LanguageController.php b/app/Http/Controllers/Api/LanguageController.php index f71ecaa..e1f40e0 100644 --- a/app/Http/Controllers/Api/LanguageController.php +++ b/app/Http/Controllers/Api/LanguageController.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Controller; use Illuminate\Database\Eloquent\Builder; use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; +use Illuminate\Http\Response; use JoeDixon\Translation\Language; use JoeDixon\Translation\Translation; @@ -21,15 +22,14 @@ class LanguageController extends Controller ->orderBy('name') ->when( $request->search, - fn(Builder $query) - => $query - ->where('name', 'ilike', "%{$request->search}%") - ->orWhere('language', 'ilike', "%{$request->search}%"), + fn (Builder $query) => $query + ->whereLike('name', "%{$request->search}%") + ->orWhereLike('language', "%{$request->search}%"), ) ->when( $request->exists('selected'), - fn(Builder $query) => $query->whereIn('language', $request->input('selected', [])), - fn(Builder $query) => $query->limit(10), + fn (Builder $query) => $query->whereIn('language', $request->input('selected', [])), + fn (Builder $query) => $query->limit(10), ) ->get() ->map(function ($language) { @@ -61,7 +61,7 @@ class LanguageController extends Controller /** * Store a newly created resource in storage. * - * @return \Illuminate\Http\Response + * @return Response */ public function store(Request $request) { @@ -71,8 +71,7 @@ class LanguageController extends Controller /** * Display the specified resource. * - * @param $language - * @return \Illuminate\Http\Response + * @return Response */ public function show(Language $language) { @@ -82,8 +81,7 @@ class LanguageController extends Controller /** * Update the specified resource in storage. * - * @param $language - * @return \Illuminate\Http\Response + * @return Response */ public function update(Request $request, Language $language) { @@ -93,8 +91,7 @@ class LanguageController extends Controller /** * Remove the specified resource from storage. * - * @param $language - * @return \Illuminate\Http\Response + * @return Response */ public function destroy(Language $language) { diff --git a/app/Http/Controllers/Api/LecturerController.php b/app/Http/Controllers/Api/LecturerController.php index 34ebe01..e49ca97 100644 --- a/app/Http/Controllers/Api/LecturerController.php +++ b/app/Http/Controllers/Api/LecturerController.php @@ -45,7 +45,7 @@ class LecturerController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$request->search}%") + ->whereLike('name', "%{$request->search}%") ) ->when( $request->exists('selected'), diff --git a/app/Http/Controllers/Api/MeetupController.php b/app/Http/Controllers/Api/MeetupController.php index 4d07b47..17cada5 100644 --- a/app/Http/Controllers/Api/MeetupController.php +++ b/app/Http/Controllers/Api/MeetupController.php @@ -55,9 +55,9 @@ class MeetupController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'like', "%{$request->search}%") + ->whereLike('name', "%{$request->search}%") ->orWhereHas('city', - fn (Builder $query) => $query->where('cities.name', 'ilike', "%{$request->search}%")), + fn (Builder $query) => $query->whereLike('cities.name', "%{$request->search}%")), ) ->when( $request->exists('selected'), diff --git a/app/Http/Controllers/Api/VenueController.php b/app/Http/Controllers/Api/VenueController.php index f978296..e78ce4d 100644 --- a/app/Http/Controllers/Api/VenueController.php +++ b/app/Http/Controllers/Api/VenueController.php @@ -42,7 +42,7 @@ class VenueController extends Controller ->when( $request->search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$request->search}%") + ->whereLike('name', "%{$request->search}%") ) ->when( $request->exists('selected'), diff --git a/app/Mcp/Tools/Search/ListCountriesTool.php b/app/Mcp/Tools/Search/ListCountriesTool.php index 5e1c8b7..31ec0f5 100644 --- a/app/Mcp/Tools/Search/ListCountriesTool.php +++ b/app/Mcp/Tools/Search/ListCountriesTool.php @@ -26,8 +26,8 @@ class ListCountriesTool extends Tool ->when( $search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$search}%") - ->orWhere('code', 'ilike', "%{$search}%"), + ->whereLike('name', "%{$search}%") + ->orWhereLike('code', "%{$search}%"), ) ->limit(10) ->get() diff --git a/app/Mcp/Tools/Search/SearchCitiesTool.php b/app/Mcp/Tools/Search/SearchCitiesTool.php index 4bfac3d..793fda0 100644 --- a/app/Mcp/Tools/Search/SearchCitiesTool.php +++ b/app/Mcp/Tools/Search/SearchCitiesTool.php @@ -27,7 +27,7 @@ class SearchCitiesTool extends Tool ->when( $search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$search}%") + ->whereLike('name', "%{$search}%") ) ->limit(10) ->get(); diff --git a/app/Mcp/Tools/Search/SearchCoursesTool.php b/app/Mcp/Tools/Search/SearchCoursesTool.php index 4769171..fba7dc3 100644 --- a/app/Mcp/Tools/Search/SearchCoursesTool.php +++ b/app/Mcp/Tools/Search/SearchCoursesTool.php @@ -29,7 +29,7 @@ class SearchCoursesTool extends Tool ->when( $search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$search}%") + ->whereLike('name', "%{$search}%") ) ->limit(10) ->get() diff --git a/app/Mcp/Tools/Search/SearchLecturersTool.php b/app/Mcp/Tools/Search/SearchLecturersTool.php index 8a2369d..3bf9ebd 100644 --- a/app/Mcp/Tools/Search/SearchLecturersTool.php +++ b/app/Mcp/Tools/Search/SearchLecturersTool.php @@ -26,7 +26,7 @@ class SearchLecturersTool extends Tool ->when( $search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$search}%") + ->whereLike('name', "%{$search}%") ) ->limit(10) ->get() diff --git a/app/Mcp/Tools/Search/SearchVenuesTool.php b/app/Mcp/Tools/Search/SearchVenuesTool.php index aa69477..d289197 100644 --- a/app/Mcp/Tools/Search/SearchVenuesTool.php +++ b/app/Mcp/Tools/Search/SearchVenuesTool.php @@ -27,7 +27,7 @@ class SearchVenuesTool extends Tool ->when( $search, fn (Builder $query) => $query - ->where('name', 'ilike', "%{$search}%") + ->whereLike('name', "%{$search}%") ) ->limit(10) ->get() diff --git a/app/Models/LibraryItem.php b/app/Models/LibraryItem.php index 977a6cf..17a6cf3 100644 --- a/app/Models/LibraryItem.php +++ b/app/Models/LibraryItem.php @@ -157,7 +157,7 @@ class LibraryItem extends Model implements Feedable, HasMedia, Sortable ->latest('id'); if ($value) { - $query->where('name', 'ilike', "%{$value}%"); + $query->whereLike('name', "%{$value}%"); } return $query->get(); diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index d7a1a25..f6c91ca 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -5,6 +5,7 @@ namespace App\Providers; use App\Support\Carbon; use Illuminate\Cache\RateLimiting\Limit; use Illuminate\Contracts\Auth\Authenticatable; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Events\DiagnosingHealth; use Illuminate\Http\Request; @@ -39,6 +40,22 @@ class AppServiceProvider extends ServiceProvider { $this->configureRateLimiting(); + // Case-insensitive Teilstring-Suche DB-portabel halten: PostgreSQL + // kennt `ilike`, SQLite (lokales Dev / Tests) nicht — dort liefert ein + // hartkodiertes `ilike` einen Syntaxfehler. Auf SQLite ist `like` + // ohnehin case-insensitiv (ASCII), sodass das Produktionsverhalten + // (PostgreSQL/ilike) unverändert bleibt. Verwendung in den API- + // Controllern: ->whereLike('name', "%{$search}%"). + Builder::macro('whereLike', function (string $column, string $value, string $boolean = 'and') { + $operator = $this->getConnection()->getDriverName() === 'pgsql' ? 'ilike' : 'like'; + + return $this->where($column, $operator, $value, $boolean); + }); + + Builder::macro('orWhereLike', function (string $column, string $value) { + return $this->whereLike($column, $value, 'or'); + }); + Gate::define('viewApiDocs', fn (?Authenticatable $user = null): bool => true); // OAuth-2.1-Flow des MCP-Servers (Claude.ai Web-Connector).