diff --git a/app/Models/Company.php b/app/Models/Company.php index be06b5c7..28bd2fde 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -7,12 +7,14 @@ use App\Enums\Portal; use App\Models\Concerns\HasUniqueSlug; use App\Scopes\PortalScope; use Database\Factories\CompanyFactory; +use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; use Illuminate\Support\Str; @@ -72,6 +74,35 @@ class Company extends Model ]; } + /** + * Firmensuche für die Admin-Combobox: Volltext (name/email/slug) bei + * unterstützenden Treibern und Suchbegriffen ab 3 Zeichen, sonst LIKE. + * Bei leerem Begriff bleibt die Query unverändert. Single Source of Truth + * für die zuvor in mehreren Editoren duplizierte Such- und Treiberlogik. + */ + public function scopeSearchByTerm(Builder $query, string $term): Builder + { + $term = Portal::stripTrailingAbbreviation($term); + + if (! filled($term)) { + return $query; + } + + $supportsFullText = mb_strlen($term) >= 3 + && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'], true); + + return $query->where(function (Builder $query) use ($term, $supportsFullText): void { + if ($supportsFullText) { + $query->whereFullText(['name', 'email', 'slug'], $term); + + return; + } + + $query->where('name', 'like', '%'.$term.'%') + ->orWhere('slug', 'like', '%'.$term.'%'); + }); + } + public function owner(): BelongsTo { return $this->belongsTo(User::class, 'owner_user_id'); diff --git a/resources/views/livewire/admin/press-releases/create.blade.php b/resources/views/livewire/admin/press-releases/create.blade.php index 307edec6..d3b88fe0 100644 --- a/resources/views/livewire/admin/press-releases/create.blade.php +++ b/resources/views/livewire/admin/press-releases/create.blade.php @@ -10,7 +10,6 @@ use App\Services\Admin\AdminPerformanceCache; use App\Services\PressRelease\PressReleaseHtmlSanitizer; use Flux\Flux; use Illuminate\Database\Eloquent\Collection; -use Illuminate\Support\Facades\DB; use Illuminate\Support\Str; use Illuminate\Validation\Rule; use Livewire\Attributes\Computed; @@ -170,15 +169,7 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex $term = Portal::stripTrailingAbbreviation($this->companySearch); $companies = Company::withoutGlobalScopes() - ->when(filled($term), function ($q) use ($term): void { - if ($this->supportsFullTextSearch($term)) { - $q->whereFullText(['name', 'email', 'slug'], $term); - - return; - } - - $q->where('name', 'like', '%' . $term . '%')->orWhere('slug', 'like', '%' . $term . '%'); - }) + ->searchByTerm($term) ->when(blank($term) && $this->companyId, fn($q) => $q->whereIn('id', [(int) $this->companyId])) ->when(blank($term) && !$this->companyId, fn($q) => $q->whereRaw('0 = 1')) ->orderBy('name') @@ -215,10 +206,6 @@ new #[Layout('components.layouts.app'), Title('Neue Pressemitteilung')] class ex return app(AdminPerformanceCache::class)->remember(AdminPerformanceCache::ActiveCategoryOptions, AdminPerformanceCache::OptionsTtl, fn() => Category::query()->with('translations')->where('is_active', true)->orderBy('id')->get()); } - private function supportsFullTextSearch(string $term): bool - { - return mb_strlen($term) >= 3 && in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'], true); - } }; ?>