PluginProbe
Yatra – Travel Booking & Tour Operator Software / trunk
Yatra – Travel Booking & Tour Operator Software vtrunk
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 2.0.10 2.0.11 All 82 releases
yatra / templates / single-activity.php

single-activity.php in Yatra – Travel Booking & Tour Operator Software trunk, at templates/single-activity.php

320 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Single Activity Template
4 *
5 * Displays individual activity page with associated trips
6 * Uses global $activity object (similar to WordPress $post)
7 *
8 * @package Yatra
9 * @global object $activity Activity data object
10 */
11
12 // Prevent direct access
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 // Access global $activity object
18 global $activity;
19
20 // Debug: Check what data we have
21 if (defined('WP_DEBUG') && WP_DEBUG) {
22 }
23
24 // Bail if no activity data - return proper 404
25 if (!$activity) {
26 global $wp_query;
27 $wp_query->set_404();
28 status_header(404);
29 get_template_part(404);
30 exit;
31 }
32
33 // Set up page title
34 add_filter('wp_title', function($title) {
35 global $activity;
36 return esc_html($activity->name) . ' - ' . get_bloginfo('name');
37 }, 10, 1);
38
39 yatra_get_header();
40 ?>
41
42 <div class="yatra-single-activity" style="max-width: 1200px; margin: 0 auto; padding: 40px 20px;">
43 <!-- Activity Header -->
44 <div class="activity-header" style="margin-bottom: 40px;">
45 <h1 style="font-size: 2.5rem; margin-bottom: 16px; color: #1f2937;">
46 <?php echo esc_html($activity->name); ?>
47 </h1>
48
49 <?php if (!empty($activity->description)): ?>
50 <div class="activity-description" style="font-size: 1.125rem; color: #6b7280; line-height: 1.6;">
51 <?php echo wp_kses_post($activity->description); ?>
52 </div>
53 <?php endif; ?>
54 </div>
55
56 <!-- Activity Icon/Image -->
57 <?php if (!empty($activity->icon)): ?>
58 <div class="activity-media" style="margin-bottom: 40px;">
59 <?php
60 $icon = maybe_unserialize($activity->icon);
61 $image_url = '';
62 $icon_class = '';
63
64 if (is_array($icon)) {
65 $type = $icon['type'] ?? $icon[0] ?? '';
66 $value = $icon['value'] ?? $icon[1] ?? '';
67
68 if ($type === 'image' && !empty($value)) {
69 if (is_numeric($value)) {
70 $maybe_url = wp_get_attachment_image_url((int) $value, 'large');
71 if (!empty($maybe_url)) {
72 $image_url = $maybe_url;
73 }
74 } elseif (is_string($value) && filter_var($value, FILTER_VALIDATE_URL)) {
75 $image_url = $value;
76 }
77 } elseif ($type === 'icon' && !empty($value) && is_string($value)) {
78 $icon_class = $value;
79 }
80 }
81 ?>
82
83 <?php if (!empty($image_url)): ?>
84 <div class="activity-image" style="width: 100%; max-width: 600px; margin: 0 auto;">
85 <img src="<?php echo esc_url($image_url); ?>"
86 alt="<?php echo esc_attr($activity->name); ?>"
87 style="width: 100%; height: auto; border-radius: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.1);">
88 </div>
89 <?php elseif (!empty($icon_class)): ?>
90 <div class="activity-icon" style="text-align: center; padding: 60px; background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); border-radius: 12px; margin: 0 auto; max-width: 400px;">
91 <div style="font-size: 4rem; color: #4b5563;">
92 <?php echo yatra_svg_icon($icon_class, 'activity-large-icon'); ?>
93 </div>
94 </div>
95 <?php endif; ?>
96 </div>
97 <?php endif; ?>
98
99 <!-- Activity Stats -->
100 <?php if (!empty($activity->trips_count) || !empty($activity->avg_rating)): ?>
101 <div class="activity-stats" style="display: flex; gap: 24px; margin-bottom: 40px; justify-content: center; flex-wrap: wrap;">
102 <?php if (!empty($activity->trips_count)): ?>
103 <div class="stat-item" style="text-align: center; padding: 20px; background: #f8fafc; border-radius: 8px; min-width: 120px;">
104 <div style="font-size: 2rem; font-weight: bold; color: #059669; margin-bottom: 4px;">
105 <?php echo esc_html($activity->trips_count); ?>
106 </div>
107 <div style="color: #6b7280; font-size: 0.875rem;">
108 <?php echo esc_html(_n('Trip', 'Trips', (int)$activity->trips_count, 'yatra')); ?>
109 </div>
110 </div>
111 <?php endif; ?>
112
113 <?php if (!empty($activity->avg_rating)): ?>
114 <div class="stat-item" style="text-align: center; padding: 20px; background: #f8fafc; border-radius: 8px; min-width: 120px;">
115 <div style="font-size: 2rem; font-weight: bold; color: #f59e0b; margin-bottom: 4px;">
116 <?php echo esc_html(number_format($activity->avg_rating, 1)); ?>
117 </div>
118 <div style="color: #6b7280; font-size: 0.875rem;">
119 <?php esc_html_e('Rating', 'yatra'); ?>
120 </div>
121 </div>
122 <?php endif; ?>
123
124 <?php if (!empty($activity->starting_price)): ?>
125 <div class="stat-item" style="text-align: center; padding: 20px; background: #f8fafc; border-radius: 8px; min-width: 120px;">
126 <div style="font-size: 1.5rem; font-weight: bold; color: #2563eb; margin-bottom: 4px;">
127 <?php echo esc_html($activity->starting_price); ?>
128 </div>
129 <div style="color: #6b7280; font-size: 0.875rem;">
130 <?php esc_html_e('From', 'yatra'); ?>
131 </div>
132 </div>
133 <?php endif; ?>
134 </div>
135 <?php endif; ?>
136
137 <!-- Available Trips -->
138 <div class="activity-trips" style="margin-top: 60px;">
139 <h2 style="font-size: 2rem; margin-bottom: 24px; color: #1f2937; text-align: center;">
140 <?php esc_html_e('Available Trips', 'yatra'); ?>
141 </h2>
142
143 <?php if (!empty($activity->trips) && is_array($activity->trips)): ?>
144 <?php
145 $yatra_dp_flags_activity = function_exists('yatra_get_dynamic_pricing_display_flags') ? yatra_get_dynamic_pricing_display_flags() : [
146 'show_original_price' => true,
147 'show_savings_badge' => true,
148 'show_urgency_messages' => false,
149 ];
150 ?>
151 <div class="yatra-trip-grid">
152 <?php foreach ($activity->trips as $trip): ?>
153 <div class="yatra-trip-card">
154 <div class="yatra-trip-image">
155 <?php if (!empty($trip->featured_image_url)): ?>
156 <img src="<?php echo esc_url($trip->featured_image_url); ?>" alt="<?php echo esc_attr($trip->title ?? $trip->name ?? __('Trip', 'yatra')); ?>">
157 <?php else: ?>
158 <img src="<?php echo esc_url(plugins_url('assets/images/trip-placeholder.svg', YATRA_PLUGIN_FILE)); ?>" alt="<?php echo esc_attr($trip->title ?? $trip->name ?? __('Trip', 'yatra')); ?>">
159 <?php endif; ?>
160
161 <?php if (!empty($trip->discount_percentage) && $trip->discount_percentage > 0 && !empty($yatra_dp_flags_activity['show_savings_badge'])): ?>
162 <div class="yatra-discount-badge">
163 <?php
164 printf(
165 /* translators: %s: discount percentage */
166 esc_html__('%s%% OFF', 'yatra'),
167 esc_html($trip->discount_percentage)
168 );
169 ?>
170 </div>
171 <?php endif; ?>
172
173 <?php if (function_exists('yatra_wishlist_enabled') && yatra_wishlist_enabled() && !empty($trip->id)) : ?>
174 <button type="button" class="yatra-favorite-btn yatra-similar-favorite-btn" data-trip-id="<?php echo esc_attr((string) $trip->id); ?>" title="<?php esc_attr_e('Save to wishlist', 'yatra'); ?>">
175 <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
176 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4.318 6.318a4.5 4.5 0 000 6.364L12 20.364l7.682-7.682a4.5 4.5 0 00-6.364-6.364L12 7.636l-1.318-1.318a4.5 4.5 0 00-6.364 0z"/>
177 </svg>
178 </button>
179 <?php endif; ?>
180 </div>
181
182 <div class="yatra-trip-content">
183 <div class="yatra-trip-meta">
184 <span class="yatra-trip-location"><?php echo esc_html($trip->location ?? $activity->name); ?></span>
185 <?php if (!empty($trip->duration)): ?>
186 <span class="yatra-trip-separator"></span>
187 <span class="yatra-trip-duration"><?php echo esc_html($trip->duration); ?> <?php esc_html_e('Days', 'yatra'); ?></span>
188 <?php endif; ?>
189 <?php if (!empty($trip->difficulty)): ?>
190 <span class="yatra-trip-separator"></span>
191 <span class="yatra-trip-difficulty"><?php echo esc_html($trip->difficulty); ?></span>
192 <?php endif; ?>
193 </div>
194
195 <h3 class="yatra-trip-title">
196 <a href="<?php echo esc_url($trip->permalink ?? ''); ?>">
197 <?php echo esc_html($trip->title ?? $trip->name ?? __('Untitled Trip', 'yatra')); ?>
198 </a>
199 </h3>
200
201 <?php if (!empty($trip->destinations) && is_array($trip->destinations)): ?>
202 <div class="yatra-trip-highlights">
203 <?php foreach (array_slice($trip->destinations, 0, 3) as $destination): ?>
204 <span class="yatra-highlight-badge"><?php echo esc_html($destination->name ?? ''); ?></span>
205 <?php endforeach; ?>
206 </div>
207 <?php endif; ?>
208
209 <div class="yatra-trip-rating">
210 <div class="yatra-rating-stars">
211 <svg width="16" height="16" fill="#fbbf24" viewBox="0 0 24 24">
212 <path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"/>
213 </svg>
214 <span class="yatra-rating-value"><?php echo esc_html(number_format($trip->average_rating ?? 0, 1)); ?></span>
215 </div>
216 <span class="yatra-reviews-count">(<?php echo esc_html($trip->review_count ?? 0); ?> <?php esc_html_e('reviews', 'yatra'); ?>)</span>
217 </div>
218
219 <div class="yatra-trip-footer">
220 <div class="yatra-trip-price">
221 <?php
222 $raw_orig_act = (float) ($trip->original_price ?? 0);
223 $raw_eff_act = (float) ($trip->effective_price_min ?? $trip->original_price ?? 0);
224 $disp_orig_act = $raw_orig_act;
225 $disp_eff_act = $raw_eff_act;
226 if (apply_filters('yatra_dynamic_pricing_enabled', false)) {
227 if ($disp_eff_act > 0) {
228 $disp_eff_act = apply_filters('yatra_trip_display_price', $disp_eff_act, (int) ($trip->id ?? 0), [
229 'departure_date' => null,
230 'spots_remaining' => null,
231 'original_price' => $raw_orig_act > 0 ? $raw_orig_act : (float) $disp_eff_act,
232 'discounted_price' => $raw_eff_act > 0 ? $raw_eff_act : (float) $disp_eff_act,
233 ]);
234 }
235 }
236 $yatra_act_urgency = function_exists('yatra_trip_card_dynamic_pricing_urgency_lines')
237 ? yatra_trip_card_dynamic_pricing_urgency_lines((int) ($trip->id ?? 0), [
238 'base_sale_price' => $raw_eff_act,
239 'base_original_price' => $raw_orig_act,
240 'sale_price' => (float) $disp_eff_act,
241 'original_price' => (float) $disp_orig_act,
242 'departure_date' => null,
243 'spots_remaining' => null,
244 'availability_id' => null,
245 'surface' => 'activity_card',
246 ])
247 : [];
248 ?>
249 <?php if (!empty($yatra_dp_flags_activity['show_original_price']) && $disp_orig_act > 0 && $disp_eff_act > 0 && $disp_orig_act > $disp_eff_act): ?>
250 <div class="yatra-original-price"><?php echo esc_html(yatra_format_price($disp_orig_act)); ?></div>
251 <?php endif; ?>
252 <div class="yatra-current-price">
253 <?php
254 if ($disp_eff_act > 0) {
255 echo esc_html(yatra_format_price($disp_eff_act));
256 } elseif ($disp_orig_act > 0) {
257 echo esc_html(yatra_format_price($disp_orig_act));
258 } else {
259 echo esc_html__('Price on request', 'yatra');
260 }
261 ?>
262 </div>
263 <div class="yatra-price-note"><?php esc_html_e('per person', 'yatra'); ?></div>
264 <?php if (!empty($yatra_act_urgency)) : ?>
265 <?php foreach ($yatra_act_urgency as $yatra_a_urg) : ?>
266 <div style="margin-top:6px;font-size:11px;line-height:1.35;color:#92400e;background:#fef3c7;padding:4px 6px;border-radius:4px;">
267 <?php echo esc_html((string) $yatra_a_urg); ?>
268 </div>
269 <?php endforeach; ?>
270 <?php endif; ?>
271 </div>
272 <a href="<?php echo esc_url($trip->permalink ?? ''); ?>" class="yatra-btn yatra-btn-primary yatra-archive-card-cta yatra-card-view-btn">
273 <?php echo yatra_svg_icon('file-text', 'yatra-btn-icon'); ?>
274 <span><?php esc_html_e('View Details', 'yatra'); ?></span>
275 </a>
276 </div>
277 </div>
278 </div>
279 <?php endforeach; ?>
280 </div>
281 <?php else: ?>
282 <div style="text-align: center; padding: 40px; background: #f9fafb; border-radius: 12px; margin-bottom: 40px;">
283 <p style="color: #6b7280; margin: 0 0 16px 0;">
284 <?php esc_html_e('No trips are currently available with this activity.', 'yatra'); ?>
285 </p>
286 <a href="<?php echo esc_url(function_exists('yatra_get_trip_listing_url') ? yatra_get_trip_listing_url() : home_url('/' . \Yatra\Services\SettingsService::getTripBase() . '/')); ?>"
287 style="color: #2563eb; text-decoration: none; font-weight: 500;">
288 <?php esc_html_e('Browse all trips', 'yatra'); ?>
289 </a>
290 </div>
291 <?php endif; ?>
292
293 <div style="text-align: center;">
294 <a href="<?php echo esc_url(add_query_arg(['activity' => urlencode($activity->slug)], function_exists('yatra_get_trip_listing_url') ? yatra_get_trip_listing_url() : home_url('/' . \Yatra\Services\SettingsService::getTripBase() . '/'))); ?>"
295 class="yatra-btn"
296 style="display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; background: #059669; color: white; text-decoration: none; border-radius: 6px; font-weight: 600; transition: background-color 0.2s;">
297 <svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
298 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
299 </svg>
300 <?php esc_html_e('View All Trips with', 'yatra'); ?> <?php echo esc_html($activity->name); ?>
301 </a>
302 </div>
303 </div>
304
305 <!-- Back to Activities -->
306 <div style="text-align: center; margin-top: 60px; padding-top: 40px; border-top: 1px solid #e5e7eb;">
307 <a href="<?php echo esc_url(function_exists('yatra_get_taxonomy_listing_url') ? yatra_get_taxonomy_listing_url('activity') : home_url('/' . \Yatra\Services\SettingsService::getActivityBase() . '/')); ?>"
308 style="color: #6b7280; text-decoration: none; display: inline-flex; align-items: center; gap: 8px;">
309 <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
310 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
311 </svg>
312 <?php esc_html_e('Back to All Activities', 'yatra'); ?>
313 </a>
314 </div>
315 </div>
316
317 <?php
318 yatra_get_footer();
319 ?>
320