@extends('layouts.app') @section('title', __('site.search_results.title')) @section('content') @php $locale = app()->getLocale(); $isRtl = $locale === 'ar'; // Fonction pour déterminer la route d'affichage function getRouteForModel($model) { if ($model instanceof \App\Models\News) { return route('news.show', $model->slug); } elseif ($model instanceof \App\Models\TropheeSportif) { return route('trophees.show', $model->slug); } elseif ($model instanceof \App\Models\Guide) { if($model->type_contenu === 'builder' && $model->builder_id) { return route('front.builder', ['id' => $model->builder_id]); } elseif($model->type_contenu === 'lien' && filter_var($model->lien, FILTER_VALIDATE_URL)) { return $model->lien; } elseif($model->type_contenu === 'lien') { return url($model->lien); } else { return route('guide.redirect', $model->id_G); } } elseif ($model instanceof \App\Models\Federation) { return route('federation.public.list', $model->id); } elseif ($model instanceof \App\Models\DescGouvr) { return route('detail_gouver', $model->id_desc); } elseif ($model instanceof \App\Models\Builder) { return route('front.builder', $model->id_builder); } elseif ($model instanceof \App\Models\BuilderContenu) { return route('front.builder', ['id' => $model->id_builder]); } elseif ($model instanceof \App\Models\Concours) { return route('concours.show', $model->id); } elseif ($model instanceof \App\Models\Auberge) { return route('auberge.show', $model->id); } return '#'; } // Fonction pour obtenir le titre localisé // Fonction pour obtenir le titre localisé function getLocalizedTitle($model) { $locale = app()->getLocale(); if (method_exists($model, 'getLocalizedTitle')) { return $model->getLocalizedTitle(); } // Logique par défaut pour chaque modèle if ($model instanceof \App\Models\News) { return $model->title; } elseif ($model instanceof \App\Models\TropheeSportif) { return trans_field($model, 'title'); } elseif ($model instanceof \App\Models\Guide) { return trans_field($model, 'titre'); } elseif ($model instanceof \App\Models\Federation) { $field = 'nom_' . $locale; return $model->$field ?? $model->nom_ar; } elseif ($model instanceof \App\Models\DescGouvr) { // Pour DescGouvr, on peut utiliser le nom du gouvernorat if ($model->gouvernorat) { $field = 'nom_' . $locale; return $model->gouvernorat->$field ?? $model->gouvernorat->nom_ar; } return __('site.result.desc_gouvr'); } elseif ($model instanceof \App\Models\Builder) { $field = 'titre_' . $locale; return $model->$field ?? $model->titre_ar; } elseif ($model instanceof \App\Models\BuilderContenu) { $locale = app()->getLocale(); // 1) Prefer the parent builder title if ($model->relationLoaded('builder') && $model->builder) { $field = 'titre_' . $locale; return $model->builder->$field ?? $model->builder->titre_ar ?? $model->builder->titre_fr ?? $model->builder->titre_en ?? __('site.result.builder'); } // 2) If relation is not loaded, try to fetch it if ($model->builder) { $field = 'titre_' . $locale; return $model->builder->$field ?? $model->builder->titre_ar ?? $model->builder->titre_fr ?? $model->builder->titre_en ?? __('site.result.builder'); } // 3) Final fallback return __('site.result.builder'); } elseif ($model instanceof \App\Models\Concours) { $field = 'titre_' . $locale; return $model->$field ?? $model->titre_ar; } elseif ($model instanceof \App\Models\Auberge) { $field = 'nom_' . $locale; return $model->$field ?? $model->nom_ar; } return $model->title ?? $model->name ?? __('site.result.no_title'); } // Fonction pour obtenir la description localisée // Utility: detect PDF anywhere in the raw content (links, iframe src, mime) function isPdfContent($raw) { if (empty($raw)) return false; // common signs: .pdf extension in href/src or application/pdf or iframe with pdf src if (preg_match('/\.pdf(\?[^"\']*)?/i', $raw)) return true; if (stripos($raw, 'application/pdf') !== false) return true; if (preg_match('/]+src=["\'][^"\']+\.pdf/i', $raw)) return true; return false; } // Utility: determine whether content contains plain text useful for preview function isPreviewableContent($raw) { if (empty($raw)) return false; $clean = cleanHtmlContent($raw); // If cleaned text remains, it's previewable return !empty($clean); } // detect presence of (table content usually not previewable in a short snippet) function isTableContent($raw) { if (empty($raw)) return false; return (bool) preg_match('/]*>/i', $raw); } // detect embedded objects (iframe/object/embed) which are not previewable function isEmbedContent($raw) { if (empty($raw)) return false; return (bool) preg_match('/<(iframe|object|embed)\b[^>]*>/i', $raw); } // Function for cleaning HTML content (unchanged logic but ensure available) function cleanHtmlContent($html) { if (empty($html)) { return ''; } $html = preg_replace('/]*>(.*?)<\/script>/is', '', $html); $html = preg_replace('/]*>(.*?)<\/style>/is', '', $html); $html = preg_replace('//s', '', $html); $html = preg_replace('/<[^>]+>/', ' ', $html); $html = html_entity_decode($html, ENT_QUOTES | ENT_HTML5, 'UTF-8'); $html = preg_replace('/\s+/', ' ', $html); return trim($html); } // Updated getLocalizedDescription: prefers plain text preview when possible, // otherwise returns an empty string (so template can display fallback) function getLocalizedDescription($model) { $locale = app()->getLocale(); // helper to test raw content quickly $check = function($raw) { if (empty($raw)) return ''; if (isPdfContent($raw) || isTableContent($raw) || isEmbedContent($raw)) { return ''; // force fallback for non-previewable content } $clean = cleanHtmlContent($raw); return !empty($clean) ? \Illuminate\Support\Str::limit($clean, 150) : ''; }; if ($model instanceof \App\Models\News) { return $check($model->content ?? ''); } elseif ($model instanceof \App\Models\TropheeSportif) { $field = 'content_' . $locale; return $check($model->$field ?? ''); } elseif ($model instanceof \App\Models\Guide) { return __('site.result.guide'); } elseif ($model instanceof \App\Models\Federation) { return $model->email ?? __('site.result.federation'); } elseif ($model instanceof \App\Models\DescGouvr) { $field = 'desc1_' . $locale; return $check($model->$field ?? $model->desc1 ?? ''); } elseif ($model instanceof \App\Models\Builder) { return __('site.result.builder'); } elseif ($model instanceof \App\Models\BuilderContenu) { $field = 'text_' . $locale; $raw = $model->$field ?? $model->text_ar ?? ''; $res = $check($raw); if (empty($res)) { // try title fallback when content not previewable $titleField = 'titre_' . $locale; $title = $model->$titleField ?? $model->titre_ar ?? ''; return !empty($title) ? \Illuminate\Support\Str::limit(strip_tags($title), 150) : ''; } return $res; } elseif ($model instanceof \App\Models\Concours) { return __('site.result.concours'); } elseif ($model instanceof \App\Models\Auberge) { $field = 'description_' . $locale; return $check($model->$field ?? $model->description_ar ?? ''); } return ''; } // Fonction pour obtenir le badge selon le type function getBadgeForModel($model) { if ($model instanceof \App\Models\News) { return ['text' => __('site.badge.news'), 'color' => 'danger']; } elseif ($model instanceof \App\Models\TropheeSportif) { return ['text' => __('site.badge.trophees'), 'color' => 'success']; } elseif ($model instanceof \App\Models\Guide) { return ['text' => __('site.badge.guides'), 'color' => 'info']; } elseif ($model instanceof \App\Models\Federation) { return ['text' => __('site.badge.federations'), 'color' => 'warning']; } elseif ($model instanceof \App\Models\DescGouvr) { return ['text' => __('site.badge.desc_gouvr'), 'color' => 'primary']; } elseif ($model instanceof \App\Models\Builder) { return ['text' => __('site.badge.builders'), 'color' => 'secondary']; } elseif ($model instanceof \App\Models\BuilderContenu) { return ['text' => __('site.badge.builder_contenus'), 'color' => 'dark']; } elseif ($model instanceof \App\Models\Concours) { return ['text' => __('site.badge.concours'), 'color' => 'danger']; } elseif ($model instanceof \App\Models\Auberge) { return ['text' => __('site.badge.auberges'), 'color' => 'success']; } return ['text' => __('site.badge.general'), 'color' => 'light']; } // Combinez tous les résultats dans un tableau UNIQUE $allResults = collect(); // Fonction pour ajouter des résultats avec leur type function addResults($collection, $type) { return $collection->map(function ($item) use ($type) { $item->result_type = $type; $item->result_id = $type . '_' . ($item->id ?? $item->id_desc ?? $item->id_G ?? uniqid()); return $item; }); } // Ajoutez tous les résultats UNIQUEMENT DANS allResults $allResults = $allResults->concat(addResults($news, 'news')); $allResults = $allResults->concat(addResults($trophees, 'trophees')); $allResults = $allResults->concat(addResults($guides, 'guides')); $allResults = $allResults->concat(addResults($federations, 'federations')); $allResults = $allResults->concat(addResults($descGouvr, 'descGouvr')); $allResults = $allResults->concat(addResults($builders, 'builders')); $allResults = $allResults->concat(addResults($builderContenus, 'builderContenus')); $allResults = $allResults->concat(addResults($concours, 'concours')); $allResults = $allResults->concat(addResults($auberges, 'auberges')); // Grouper les résultats par type pour les filtres $groupedResults = $allResults->groupBy('result_type'); @endphp

{{ __('site.hero.welcome_title') }}

{{ __('site.hero.subtitle') }}


{{ __('site.search.title') }}

{{ __('site.no_image_alt') }}

{{ __('site.results.header_query') }} {{ $query }}

{{ __('site.results.total_results') }} {{ $totalResults }}
@if($totalResults == 0)
{{ __('site.results.no_results') }}
@else {{-- Boutons de filtrage par catégorie --}}
@foreach($groupedResults as $type => $items) @php $typeNames = [ 'news' => ['name' => __('site.results.section_news'), 'color' => 'danger'], 'trophees' => ['name' => __('site.results.section_trophees'), 'color' => 'success'], 'guides' => ['name' => __('site.results.section_guides'), 'color' => 'info'], 'federations' => ['name' => __('site.results.section_federations'), 'color' => 'warning'], 'descGouvr' => ['name' => __('site.results.section_desc_gouvr'), 'color' => 'primary'], 'builders' => ['name' => __('site.results.section_builders'), 'color' => 'secondary'], 'builderContenus' => ['name' => __('site.results.section_builder_contenus'), 'color' => 'dark'], 'concours' => ['name' => __('site.results.section_concours'), 'color' => 'danger'], 'auberges' => ['name' => __('site.results.section_auberges'), 'color' => 'success'], ]; @endphp @if(isset($typeNames[$type])) @endif @endforeach
{{-- Tous les résultats combinés --}}
@if($allResults->count() > 0)
@foreach($allResults as $index => $item) @php $badge = getBadgeForModel($item); $title = getLocalizedTitle($item); $description = getLocalizedDescription($item); $route = getRouteForModel($item); $target = ($item instanceof \App\Models\Guide && $item->open_new_tab) ? ' target="_blank"' : ''; // Déterminer l'image à afficher $image = null; if (property_exists($item, 'image') && !empty($item->image)) { $image = $item->image; } elseif (property_exists($item, 'image_gouv') && !empty($item->image_gouv)) { $image = $item->image_gouv; } elseif (property_exists($item, 'logo') && !empty($item->logo)) { $image = $item->logo; } @endphp
{!! highlight($title, $query) !!}
@if(property_exists($item, 'created_at') || property_exists($item, 'date')) {{ ($item->created_at ?? $item->date)->format('Y-m-d') }} @elseif(property_exists($item, 'ville') && !empty($item->ville)) {{ $item->ville }} @endif @php // Try to get raw content to detect PDF/table/embed (for a few model types) $rawPreview = ''; if ($item instanceof \App\Models\BuilderContenu) { $rawPreview = $item->{'text_'.$locale} ?? $item->text_ar ?? ''; } elseif ($item instanceof \App\Models\News) { $rawPreview = $item->content ?? ''; } elseif ($item instanceof \App\Models\DescGouvr) { $rawPreview = $item->{'desc1_'.$locale} ?? $item->desc1 ?? ''; } elseif ($item instanceof \App\Models\Auberge) { $rawPreview = $item->{'description_'.$locale} ?? $item->description_ar ?? ''; } elseif ($item instanceof \App\Models\TropheeSportif) { $rawPreview = $item->{'content_'.$locale} ?? $item->content ?? ''; } $isPdf = isPdfContent($rawPreview); $isTable = isTableContent($rawPreview); $isEmbed = isEmbedContent($rawPreview); $hasPreview = !empty($description) && trim(strip_tags($description)) !== ''; @endphp @if($hasPreview && !$isPdf && !$isTable && !$isEmbed)

{!! highlight($description, $query) !!}

@else

{{ __('site.result.click_to_display') }}

@endif
{{ $badge['text'] }} {{ __('site.action.view') }}
@endforeach
@else
{{ __('site.results.no_results_found') }}
@endif
{{-- Statistiques par catégorie --}}
{{ __('site.results.results_by_category') }}
@foreach($groupedResults as $type => $items) @php $typeInfo = [ 'news' => ['name' => __('site.results.section_news'), 'color' => 'danger', 'icon' => 'newspaper'], 'trophees' => ['name' => __('site.results.section_trophees'), 'color' => 'success', 'icon' => 'trophy'], 'guides' => ['name' => __('site.results.section_guides'), 'color' => 'info', 'icon' => 'book'], 'federations' => ['name' => __('site.results.section_federations'), 'color' => 'warning', 'icon' => 'users'], 'descGouvr' => ['name' => __('site.results.section_desc_gouvr'), 'color' => 'primary', 'icon' => 'landmark'], 'builders' => ['name' => __('site.results.section_builders'), 'color' => 'secondary', 'icon' => 'cubes'], 'builderContenus' => ['name' => __('site.results.section_builder_contenus'), 'color' => 'dark', 'icon' => 'file-alt'], 'concours' => ['name' => __('site.results.section_concours'), 'color' => 'danger', 'icon' => 'medal'], 'auberges' => ['name' => __('site.results.section_auberges'), 'color' => 'success', 'icon' => 'hotel'], ]; @endphp @if(isset($typeInfo[$type]))
{{ $typeInfo[$type]['name'] }}

{{ $items->count() }} {{ __('site.results.results') }}

@endif @endforeach
@endif
@endsection