| 11 | | 2. Корисникот има можност да ги филтрира резултатите според горенаведените преференци. |
| | 11 | 2. Системот потоа: |
| | 12 | * Ја користи табелата destination како главен извор на податоци. |
| | 13 | * Преку LEFT JOIN се приклучуваат destination_tag и tag за филтрирање и прикажување на категории/ознаки. |
| | 14 | * Преку LEFT JOIN кон review и destination_user се добиваат информации за просечен рејтинг и коментари. |
| | 15 | * Условите се применуваат само ако корисникот внел вредности (инаку се игнорираат). |
| | 16 | * ILIKE за case-insensitive пребарување. |
| | 17 | * Популарноста се проверува врз основа на полето popularity од табелата destination. |
| | 18 | Резултатот е листа на дестинации со основни информации, просечен рејтинг и поврзани ознаки. |
| 13 | | SELECT DISTINCT d.* |
| 14 | | FROM DESTINACII d |
| 15 | | LEFT JOIN RECENZII r ON d.idDest = r.idDest |
| | 20 | SELECT d.id_destination, |
| | 21 | d.location_name, |
| | 22 | d.location_desc, |
| | 23 | d.types_of_places, |
| | 24 | d.recommended_season, |
| | 25 | d.country, |
| | 26 | d.popularity, |
| | 27 | ARRAY_AGG(DISTINCT t.tag_name) AS tags, |
| | 28 | COALESCE(ROUND(AVG(r.quality), 2), 0) AS avg_review |
| | 29 | FROM travel_sage.destination d |
| | 30 | LEFT JOIN travel_sage.destination_tag dt ON d.id_destination = dt.id_destination |
| | 31 | LEFT JOIN travel_sage.tag t ON dt.id_tag = t.id_tag |
| | 32 | LEFT JOIN travel_sage.review r ON d.id_destination = r.id_destination |
| 28 | | DESTINACII е главната табела од која се земаат податоци. Преку LEFT JOIN се приклучува табелата RECENZII, со што се овозможува филтрирање и по податоци од рецензии (ако има потреба во иднина). ILIKE овозможува case-insensitive пребарување (на пр. ќе најде и "море" и "Море"). Ако не е внесен некој параметар (NULL), тој услов се игнорира и не се филтрира според него. За популарност, бараме idTag од TAGOVI каде што tagOznaka се наоѓа во дадениот опсег. |
| 29 | | |
| 30 | | |
| 31 | | Ги зема сите дестинации (DESTINACII d). Им се приклучува табелата со рецензии (RECENZII r). Се филтрира според внесените параметри: |
| 32 | | * тип на место |
| 33 | | |
| 34 | | * сезона |
| 35 | | |
| 36 | | * популарност |
| 37 | | |
| 38 | | |
| 39 | | {{{ |
| 40 | | public function index(Request $request) |
| 41 | | { |
| 42 | | $tip = $request->input('tipovimesta'); |
| 43 | | $sezona = $request->input('preporachanasezona'); |
| 44 | | $popularnost = $request->input('popularnost'); |
| 45 | | |
| 46 | | $prioritet_min = null; |
| 47 | | $prioritet_max = null; |
| 48 | | |
| 49 | | if ($popularnost && str_contains($popularnost, '-')) { |
| 50 | | [$prioritet_min, $prioritet_max] = explode('-', $popularnost); |
| 51 | | } |
| 52 | | |
| 53 | | $sql = " |
| 54 | | SELECT DISTINCT d.* |
| 55 | | FROM DESTINACII d |
| 56 | | LEFT JOIN RECENZII r ON d.idDest = r.idDest |
| 57 | | WHERE |
| 58 | | (:tip IS NULL OR d.tipoviMesta ILIKE CONCAT('%', :tip, '%')) |
| 59 | | AND (:sezona IS NULL OR d.preporachanaSezona ILIKE CONCAT('%', :sezona, '%')) |
| 60 | | AND ( |
| 61 | | :prioritet_min IS NULL OR :prioritet_max IS NULL OR |
| 62 | | d.idTag IN ( |
| 63 | | SELECT idTag |
| 64 | | FROM TAGOVI |
| 65 | | WHERE tagOznaka::int BETWEEN :prioritet_min AND :prioritet_max |
| 66 | | ) |
| 67 | | ) |
| 68 | | "; |
| 69 | | |
| 70 | | $destinacii = DB::select($sql, [ |
| 71 | | 'tip' => $tip !== 'any' ? $tip : null, |
| 72 | | 'sezona' => $sezona !== 'any' ? $sezona : null, |
| 73 | | 'prioritet_min' => $prioritet_min, |
| 74 | | 'prioritet_max' => $prioritet_max, |
| 75 | | ]); |
| 76 | | |
| 77 | | return view('destinations.index', compact('destinacii')); |
| 78 | | } |
| 79 | | |
| 80 | | }}} |