PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.2.9
Yatra – Travel Booking & Tour Operator Software v3.0.2.9
3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 2.0.1 All 84 releases
yatra / app / Core / Handlers / TaxonomyPageHandler.php

TaxonomyPageHandler.php in Yatra – Travel Booking & Tour Operator Software 3.0.2.9, at app/Core/Handlers/TaxonomyPageHandler.php

222 lines 6.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Yatra\Core\Handlers;
6
7 use Yatra\Database\Tables\ClassificationsTable;
8 use Yatra\Repositories\TripRepository;
9
10 /**
11 * Taxonomy Page Handler
12 *
13 * Handles single taxonomy page requests (destination, activity, category)
14 */
15 class TaxonomyPageHandler extends BasePageHandler
16 {
17 /**
18 * Handle taxonomy page request
19 *
20 * @param array $route_data Route data from RouteMatcher
21 * @return bool True if handled successfully
22 */
23 public function handle(array $route_data): bool
24 {
25 $taxonomy_type = $route_data['taxonomy_type'];
26 $slug = $route_data['slug'];
27 $base = $route_data['base'];
28
29 $taxonomy_data = $this->getTaxonomyData($taxonomy_type, $slug);
30
31 if (!$taxonomy_data) {
32 $this->set404();
33 return false;
34 }
35
36 $tripRepository = new TripRepository();
37 $filter_key = $this->getFilterKey($taxonomy_type);
38
39 $pageNum = !empty($route_data['paged']) ? max(1, (int) $route_data['paged']) : \yatra_get_archive_listing_paged();
40 $perPage = \yatra_get_posts_per_page();
41
42 $filters = [$filter_key => $slug];
43 // AND with complementary slug filters from the query string (same semantics as /trip/?destination=&activity=).
44 if ($taxonomy_type === 'destination' && !empty($_GET['activity']) && is_string($_GET['activity'])) {
45 $a = sanitize_text_field(wp_unslash($_GET['activity']));
46 if ($a !== '') {
47 $filters['activity'] = $a;
48 }
49 }
50 if ($taxonomy_type === 'activity' && !empty($_GET['destination']) && is_string($_GET['destination'])) {
51 $d = sanitize_text_field(wp_unslash($_GET['destination']));
52 if ($d !== '') {
53 $filters['destination'] = $d;
54 }
55 }
56 $sort = isset($_GET['sort']) ? sanitize_text_field(wp_unslash((string) $_GET['sort'])) : '';
57 $allowedSorts = ['most_popular', 'price_low', 'price_high', 'rating_high', 'duration_short', 'duration_long'];
58 if ($sort !== '' && in_array($sort, $allowedSorts, true)) {
59 $filters['sort'] = $sort;
60 }
61
62 $trips_data = $tripRepository->findWithFilters($filters, $pageNum, $perPage);
63
64 $taxonomy_data->trips_total = (int) ($trips_data['total'] ?? 0);
65 $taxonomy_data->trips_pages = (int) ($trips_data['pages'] ?? 1);
66 $taxonomy_data->trips_per_page = (int) ($trips_data['per_page'] ?? $perPage);
67 $taxonomy_data->trips_current_page = (int) ($trips_data['page'] ?? $pageNum);
68 $taxonomy_data->trips = $trips_data['trips'] ?? [];
69
70 $tripsWithReviews = [];
71 foreach ($taxonomy_data->trips as $trip) {
72 $trip->reviews = $this->getReviewsForTrip((int) $trip->id);
73 $trip->average_rating = $this->calculateAverageRating($trip->reviews);
74 $trip->review_count = count($trip->reviews);
75
76 $tripsWithReviews[] = $trip;
77 }
78
79 $taxonomy_data->trips = $tripsWithReviews;
80
81 $this->prevent404();
82
83 $this->setGlobal('yatra_taxonomy_data', $taxonomy_data);
84
85 $this->setQueryVars([
86 'yatra_taxonomy_type' => $taxonomy_data->type,
87 'yatra_taxonomy_slug' => $taxonomy_data->slug,
88 'yatra_taxonomy' => $taxonomy_data,
89 'yatra_page' => $base,
90 ]);
91
92 $template_path = YATRA_PLUGIN_PATH . 'templates/single-taxonomy.php';
93
94 if (!file_exists($template_path)) {
95 $this->logError("Taxonomy template not found: {$template_path}");
96 return false;
97 }
98
99 include $template_path;
100 $this->exit();
101
102 return true;
103 }
104
105 /**
106 * Get taxonomy data by type and slug
107 *
108 * @param string $type Taxonomy type
109 * @param string $slug Taxonomy slug
110 * @return object|null Taxonomy data or null if not found
111 */
112 private function getTaxonomyData(string $type, string $slug): ?object
113 {
114 global $wpdb;
115
116 $table = ClassificationsTable::getTableName();
117
118 $sql = $wpdb->prepare(
119 "SELECT * FROM {$table} WHERE type = %s AND slug = %s AND status = 'publish' LIMIT 1",
120 $type,
121 $slug
122 );
123
124 $data = $wpdb->get_row($sql);
125
126 if ($data) {
127 if (isset($data->metadata) && is_string($data->metadata)) {
128 $data->metadata = maybe_unserialize($data->metadata);
129 }
130
131 if (isset($data->icon) && is_string($data->icon)) {
132 $data->icon = maybe_unserialize($data->icon);
133 }
134
135 if (isset($data->icon) && is_numeric($data->icon)) {
136 $data->icon = wp_get_attachment_url($data->icon);
137 }
138 }
139
140 return $data ?: null;
141 }
142
143 /**
144 * Get filter key for taxonomy type
145 *
146 * @param string $taxonomy_type Taxonomy type
147 * @return string Filter key for TripRepository
148 */
149 private function getFilterKey(string $taxonomy_type): string
150 {
151 switch ($taxonomy_type) {
152 case 'category':
153 return 'trip_category';
154 case 'activity':
155 return 'activity';
156 case 'destination':
157 return 'destination';
158 case 'difficulty':
159 return 'difficulty';
160 default:
161 return $taxonomy_type;
162 }
163 }
164
165 /**
166 * Get reviews for a specific trip (same as SingleTripController)
167 *
168 * @param int $trip_id Trip ID
169 * @return array Reviews
170 */
171 private function getReviewsForTrip(int $trip_id): array
172 {
173 global $wpdb;
174
175 $reviewsTable = \Yatra\Database\Tables\ReviewsTable::getTableName();
176
177 $table_exists = $wpdb->get_var(
178 $wpdb->prepare(
179 'SHOW TABLES LIKE %s',
180 $reviewsTable
181 )
182 );
183
184 if (!$table_exists) {
185 return [];
186 }
187
188 $sql = $wpdb->prepare(
189 "SELECT * FROM {$reviewsTable}
190 WHERE trip_id = %d
191 AND status = 'approved'
192 ORDER BY created_at DESC
193 LIMIT 10",
194 $trip_id
195 );
196
197 $reviews = $wpdb->get_results($sql);
198
199 return $reviews ?: [];
200 }
201
202 /**
203 * Calculate average rating from reviews (same as SingleTripController)
204 *
205 * @param array $reviews Reviews array
206 * @return float Average rating
207 */
208 private function calculateAverageRating(array $reviews): float
209 {
210 if (empty($reviews)) {
211 return 0.0;
212 }
213
214 $total = 0;
215 foreach ($reviews as $review) {
216 $total += (float) ($review->rating ?? 0);
217 }
218
219 return round($total / count($reviews), 1);
220 }
221 }
222