PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.16
Yatra – Travel Booking & Tour Operator Software v3.0.16
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
← All changes | app/Shortcodes/DestinationShortcode.php +58 -72 3.0.2.8 → 3.0.16 View file →
@@ -3,8 +3,11 @@
3 3 declare(strict_types=1);
4 4
5 5 namespace Yatra\Shortcodes;
6 6
7 +use Yatra\Helpers\TripListingFilterBuilder;
8 +use Yatra\Services\SettingsService;
9 +
7 10 /**
8 11 * Destination Shortcode
9 12 *
10 13 * Displays destination showcase with associated trips using trip-listing-card.php template
@@ -20,10 +23,14 @@
20 23 'show_trip_count' => 'yes',
21 24 'show_description' => 'yes',
22 25 'show_image' => 'yes',
23 26 'show_pagination' => 'yes', // Default to show pagination like trip shortcode
24 - 'destination' => '', // Specific destination slug(s), comma separated
25 - 'hide_empty' => 'yes',
27 + 'destination' => '', // Classification IDs, comma-separated
28 + // hide_empty defaults to 'no' to preserve the historical
29 + // behavior (show every destination, even ones with zero
30 + // trips). Operators that prefer the empty-archive defense
31 + // opt in with hide_empty="yes".
32 + 'hide_empty' => 'no',
26 33 'featured_only' => 'no',
27 34 'title' => 'Destination Showcase'
28 35 ]);
29 36 }
@@ -54,14 +61,15 @@
54 61 'total_found' => $destinations_data['total_found'] ?? 0,
55 62 'per_page' => $per_page
56 63 ];
57 64
58 - // Enqueue shortcode-specific CSS
65 + $destinationCssPath = YATRA_PLUGIN_PATH . 'assets/css/shortcodes/destination-shortcode.css';
66 + $destinationCssVer = is_readable($destinationCssPath) ? YATRA_VERSION . '.' . filemtime($destinationCssPath) : YATRA_VERSION;
59 67 wp_enqueue_style(
60 68 'yatra-destination-shortcode',
61 69 YATRA_PLUGIN_URL . 'assets/css/shortcodes/destination-shortcode.css',
62 - [],
63 - YATRA_VERSION
70 + \Yatra\Providers\FrontendAssetsProvider::shortcodeStyleDependencies(),
71 + $destinationCssVer
64 72 );
65 73
66 74 // Enqueue shortcode-specific JavaScript
67 75 wp_enqueue_script(
@@ -94,15 +102,11 @@
94 102 // Use per_page parameter only
95 103 $per_page = 10; // Default fallback
96 104 if (!empty($atts['per_page'])) {
97 105 $per_page = (int) $atts['per_page'];
98 - if (defined('WP_DEBUG') && WP_DEBUG) {
99 - error_log('Yatra DestinationShortcode: Using per_page = ' . $per_page);
100 - }
106 +
101 107 } else {
102 - if (defined('WP_DEBUG') && WP_DEBUG) {
103 - error_log('Yatra DestinationShortcode: Using default per_page = ' . $per_page);
104 - }
108 +
105 109 }
106 110
107 111 // Validate per_page to prevent issues
108 112 $per_page = max(1, min($per_page, 100)); // Between 1 and 100 items
@@ -115,12 +119,16 @@
115 119 'order_by' => 'name',
116 120 'order' => $atts['order'] === 'asc' ? 'ASC' : 'DESC'
117 121 ];
118 122
119 - // Filter by specific destinations if provided
120 - if (!empty($atts['destination'])) {
121 - $args['where']['slug'] = explode(',', $atts['destination']);
122 - }
123 + $args['where'] = $args['where'] ?? [];
124 + TripListingFilterBuilder::applyTaxonomyWhere(
125 + $args['where'],
126 + $atts,
127 + 'destinationIds',
128 + 'destination_ids',
129 + 'destination'
130 + );
123 131
124 132 // Get total count for pagination
125 133 $count_args = $args;
126 134 unset($count_args['limit']);
@@ -129,32 +137,9 @@
129 137
130 138 // Try using the base repository method to bypass status filtering
131 139 $result = $destinationService->getAll($args);
132 140
133 - // Debug: Log the results with enhanced pagination info
134 - if (defined('WP_DEBUG') && WP_DEBUG) {
135 - error_log('=== YATRA DESTINATION PAGINATION DEBUG ===');
136 - error_log('Yatra DestinationShortcode Args: ' . print_r($args, true));
137 - error_log('Yatra DestinationShortcode Results count: ' . count($result));
138 - error_log('Yatra DestinationShortcode Total destinations: ' . $total_destinations);
139 - error_log('Yatra DestinationShortcode Pagination Info:');
140 - error_log(' - Current Page: ' . $current_page);
141 - error_log(' - Per Page: ' . $per_page);
142 - error_log(' - Offset: ' . $offset);
143 - error_log(' - Max Pages: ' . ($per_page > 0 ? ceil($total_destinations / $per_page) : 1));
144 - error_log(' - Expected items on this page: ' . min($per_page, max(0, $total_destinations - $offset)));
145 - error_log(' - SQL LIMIT clause should be: LIMIT ' . $offset . ', ' . $per_page);
146 -
147 - // Log each destination being returned
148 - if (!empty($result)) {
149 - error_log('Destinations returned on page ' . $current_page . ':');
150 - foreach ($result as $index => $destination) {
151 - error_log(' ' . ($index + 1) . '. ' . ($destination->name ?? 'NO NAME') . ' (ID: ' . $destination->id . ')');
152 - }
153 - }
154 - error_log('=== END PAGINATION DEBUG ===');
155 - }
156 -
141 +
157 142 $destinations = [];
158 143
159 144 foreach ($result as $destinationData) {
160 145 // Get real trip data for this destination using classification tables
@@ -212,19 +197,15 @@
212 197 AND status = 'approved'",
213 198 ...$trip_ids
214 199 ));
215 200
216 - if (defined('WP_DEBUG') && WP_DEBUG) {
217 - error_log('DESTINATION REVIEWS QUERY: ' . print_r($reviews, true));
218 - }
201 +
219 202
220 203 foreach ($reviews as $review) {
221 204 $total_rating_sum += $review->rating * $review->review_count;
222 205 $total_review_count += $review->review_count;
223 206
224 - if (defined('WP_DEBUG') && WP_DEBUG) {
225 - error_log('DESTINATION RATING CALCULATION: Added ' . $review->rating . ' * ' . $review->review_count . ' = ' . ($review->rating * $review->review_count));
226 - }
207 +
227 208 }
228 209 }
229 210
230 211 // Calculate average rating only for trips that actually have reviews
@@ -232,21 +213,9 @@
232 213 $avg_rating = $total_review_count > 0 ? $total_rating_sum / $total_review_count : 0;
233 214
234 215 foreach ($trips as $trip) {
235 216 // Debug: Log all trip data to see what fields exist
236 - if (defined('WP_DEBUG') && WP_DEBUG) {
237 - error_log('DESTINATION TRIP DATA: ' . print_r([
238 - 'trip_id' => $trip->id ?? 'NO ID',
239 - 'trip_title' => $trip->title ?? 'NO TITLE',
240 - 'original_price' => $trip->original_price ?? 'NO ORIGINAL_PRICE',
241 - 'discounted_price' => $trip->discounted_price ?? 'NO DISCOUNTED_PRICE',
242 - 'sale_price' => $trip->sale_price ?? 'NO SALE_PRICE',
243 - 'base_price' => $trip->base_price ?? 'NO BASE_PRICE',
244 - 'price' => $trip->price ?? 'NO PRICE',
245 - 'all_fields' => array_keys(get_object_vars($trip))
246 - ], true));
247 - }
248 -
217 +
249 218 // Get pricing via centralized TripPricingService
250 219 $effective = \Yatra\Services\TripPricingService::getEffectivePrice($trip);
251 220 if ($effective > 0) {
252 221 if ($min_price === null || $effective < $min_price) {
@@ -279,15 +248,15 @@
279 248 $avg_group_size = !empty($group_sizes) ? round(array_sum($group_sizes) / count($group_sizes)) : 0;
280 249 $best_season = !empty($best_seasons) ? $this->getMostCommonSeason($best_seasons) : 'Summer';
281 250
282 251 if (defined('WP_DEBUG') && WP_DEBUG) {
283 - error_log('FINAL DESTINATION RATING CALCULATION:');
284 - error_log('Destination: ' . ($destinationData->name ?? 'NO NAME'));
285 - error_log('Total rating sum: ' . $total_rating_sum);
286 - error_log('Total review count: ' . $total_review_count);
287 - error_log('Number of trips: ' . $trip_count);
288 - error_log('Logic: Only trips with reviews are included in average');
289 - error_log('Final avg_rating: ' . $final_avg_rating);
252 +
253 +
254 +
255 +
256 +
257 +
258 +
290 259 }
291 260
292 261 $destinations[] = [
293 262 'term' => $destinationData,
@@ -307,12 +276,24 @@
307 276 'best_season' => $best_season
308 277 ];
309 278 }
310 279
311 - // Filter out empty destinations if requested
280 + // Filter out destinations that have no published trips.
281 + //
282 + // See ActivityShortcode for the full rationale — the
283 + // prior implementation only filtered on term-metadata
284 + // emptiness (which never actually fires), so destinations
285 + // with zero trips were rendered with empty trip counts
286 + // and broken archive links. We now drop any destination
287 + // whose trip_count (computed above from
288 + // TripClassificationsTable JOIN TripsTable WHERE
289 + // status=publish) is zero, plus the original sanity
290 + // check on name/slug.
312 291 if ($atts['hide_empty'] === 'yes') {
313 - $destinations = array_filter($destinations, function($destination) {
314 - return !empty($destination['term']->name) && !empty($destination['term']->slug);
292 + $destinations = array_filter($destinations, static function ($destination) {
293 + return (int) ($destination['trip_count'] ?? 0) > 0
294 + && !empty($destination['term']->name)
295 + && !empty($destination['term']->slug);
315 296 });
316 297 }
317 298
318 299 // Filter to show only featured destinations if requested
@@ -335,9 +316,9 @@
335 316 ];
336 317
337 318 } catch (\Exception $e) {
338 319 if (defined('WP_DEBUG') && WP_DEBUG) {
339 - error_log('Yatra DestinationShortcode Error: ' . $e->getMessage());
320 +
340 321 }
341 322 return [];
342 323 }
343 324 }
@@ -493,9 +474,9 @@
493 474 // Fallback to placeholder
494 475 $fallback_url = YATRA_PLUGIN_URL . 'assets/images/placeholder.png';
495 476
496 477 if (defined('WP_DEBUG') && WP_DEBUG) {
497 - error_log('Yatra DestinationShortcode Using fallback image: ' . $fallback_url);
478 +
498 479 }
499 480
500 481 return $fallback_url;
501 482 }
@@ -504,11 +485,16 @@
504 485 * Get destination link
505 486 */
506 487 private function getDestinationLink($destination): string
507 488 {
508 - // Try to get permalink from destination service or construct it
509 489 if (isset($destination->slug)) {
510 - return home_url("/destination/{$destination->slug}/");
490 + // Use permalink helper so global base + plain permalinks are respected
491 + if (function_exists('yatra_get_destination_permalink')) {
492 + return yatra_get_destination_permalink($destination);
493 + }
494 +
495 + $base = SettingsService::getDestinationBase();
496 + return home_url('/' . $base . '/' . $destination->slug . '/');
511 497 }
512 498
513 499 return '#'; // Fallback
514 500 }