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 / listing-activity.php

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

325 lines 17.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Activity Listing Template
4 *
5 * Lists all published activities from the Yatra activities table
6 * using the ActivityService. This replaces the previous static
7 * dummy-data implementation.
8 *
9 * @package Yatra
10 */
11
12 // Prevent direct access
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 // Load ActivityService from plugin namespace
18 if (!class_exists('Yatra\\Services\\ActivityService')) {
19 // If the service is not available for some reason, bail gracefully.
20 yatra_get_header();
21 echo '<p>' . esc_html__('Activity service is not available.', 'yatra') . '</p>';
22 yatra_get_footer();
23 return;
24 }
25
26 $activity_service = new \Yatra\Services\ActivityService();
27
28 // Fetch published activities with stats (including trips_count, avg_rating, starting_price)
29 $activities = $activity_service->getPublishedWithStats();
30
31 // Apply simple server-side sorting and pagination for UX.
32 $sort = isset($_GET['yatra_sort']) ? sanitize_text_field(wp_unslash($_GET['yatra_sort'])) : 'rating_desc';
33
34 if (!empty($activities) && is_array($activities)) {
35 yatra_sort_archive_listing_stats_rows($activities, $sort);
36 }
37
38 $per_page = yatra_get_posts_per_page();
39 $current_page = yatra_get_archive_listing_paged();
40 $total_items = is_array($activities) ? count($activities) : 0;
41 $total_pages = $total_items > 0 ? (int) ceil($total_items / $per_page) : 1;
42 $current_page = min($current_page, $total_pages);
43
44 $offset = ($current_page - 1) * $per_page;
45 $paged_activities = $total_items > 0 ? array_slice($activities, $offset, $per_page) : [];
46
47 $yatra_browse_start = $total_items > 0 ? $offset + 1 : 0;
48 $yatra_browse_end = $total_items > 0 ? min($offset + $per_page, $total_items) : 0;
49 $yatra_browse_line = function_exists('yatra_archive_browse_results_line')
50 ? yatra_archive_browse_results_line(
51 $yatra_browse_start,
52 $yatra_browse_end,
53 $total_items,
54 $current_page,
55 $total_pages,
56 __('activities', 'yatra')
57 )
58 : '';
59
60 $GLOBALS['yatra_archive_browse_pagination'] = [
61 'current_page' => (int) $current_page,
62 'total_pages' => (int) $total_pages,
63 ];
64
65 yatra_get_header();
66 ?>
67
68 <style>
69 .yatra-activity-icon-wrapper svg {
70 width: 100% !important;
71 height: 100% !important;
72 max-width: none !important;
73 max-height: none !important;
74 min-width: 100%;
75 min-height: 100%;
76 }
77 </style>
78
79 <div class="yatra-listing-page yatra-activity-listing">
80 <div class="yatra-listing-wrapper">
81 <main id="yatra-primary" class="yatra-listing-main">
82 <div class="yatra-listing-container">
83
84 <!-- Page Header -->
85 <div class="yatra-activity-header">
86 <div class="yatra-activity-header-content">
87 <h1><?php esc_html_e('All Activities', 'yatra'); ?></h1>
88 <p class="yatra-archive-listing-lede"><?php esc_html_e('Browse experiences (hiking, diving, sightseeing, and more). Open one to see trips built around that activity.', 'yatra'); ?></p>
89 <?php if ($yatra_browse_line !== '') : ?>
90 <p class="yatra-archive-listing-results" role="status"><?php echo esc_html($yatra_browse_line); ?></p>
91 <?php endif; ?>
92 </div>
93 <div class="yatra-results-controls">
94 <div class="yatra-sort-control">
95 <label><?php esc_html_e('Sort by:', 'yatra'); ?></label>
96 <select onchange="if (this.value) window.location.href=this.value;">
97 <?php
98 $options = [
99 'rating_desc' => __('Most Popular', 'yatra'),
100 'trips_desc' => __('Most Trips', 'yatra'),
101 'name_asc' => __('Name: A-Z', 'yatra'),
102 'name_desc' => __('Name: Z-A', 'yatra'),
103 ];
104 foreach ($options as $value => $label) {
105 $url = yatra_build_archive_listing_sort_url($value);
106 $selected = $sort === $value ? 'selected' : '';
107 echo '<option value="' . esc_attr($url) . '" ' . $selected . '>' . esc_html($label) . '</option>';
108 }
109 ?>
110 </select>
111 </div>
112 <div class="yatra-view-toggle">
113 <button class="yatra-view-btn active" data-view="grid" type="button" title="<?php esc_attr_e('Grid View', 'yatra'); ?>">
114 <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
115 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z"/>
116 </svg>
117 </button>
118 <button class="yatra-view-btn" data-view="list" type="button" title="<?php esc_attr_e('List View', 'yatra'); ?>">
119 <svg width="18" height="18" fill="none" stroke="currentColor" viewBox="0 0 24 24">
120 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
121 </svg>
122 </button>
123 </div>
124 </div>
125 </div>
126
127 <!-- Activity Grid -->
128 <div class="yatra-activity-grid" id="activity-grid">
129 <?php
130 if (!empty($paged_activities)) {
131 foreach ($paged_activities as $activity) {
132 // Activity is a stdClass from repository
133 $name = isset($activity->name) ? $activity->name : '';
134 $description = isset($activity->description) ? $activity->description : '';
135
136 // Resolve image/icon from the stored icon field when possible.
137 $image_url = '';
138 $icon_class = '';
139 if (!empty($activity->icon)) {
140 $icon = maybe_unserialize($activity->icon);
141
142 if (is_array($icon)) {
143 // Handle both newer format ['type' => 'icon', 'value' => 'footprint']
144 // and older format [0 => 'icon', 1 => 'footprint']
145 $type = $icon['type'] ?? $icon[0] ?? '';
146 $value = $icon['value'] ?? $icon[1] ?? '';
147
148 if ($type === 'image' && !empty($value)) {
149 if (is_numeric($value)) {
150 $maybe_url = wp_get_attachment_image_url((int) $value, 'large');
151 if (!empty($maybe_url)) {
152 $image_url = $maybe_url;
153 }
154 } elseif (is_string($value) && filter_var($value, FILTER_VALIDATE_URL)) {
155 $image_url = $value;
156 }
157 } elseif ($type === 'icon' && !empty($value) && is_string($value)) {
158 // Store icon name so yatra_svg_icon() can render the same SVG
159 // icon as used in the React admin (e.g. 'camera').
160 $icon_class = $value;
161 } elseif (!empty($icon['url']) && filter_var($icon['url'], FILTER_VALIDATE_URL)) {
162 // Legacy format: ['url' => 'https://...']
163 $image_url = $icon['url'];
164 } elseif (!empty($icon['id'])) {
165 // Legacy format: ['id' => attachment_id]
166 $maybe_url = wp_get_attachment_image_url((int) $icon['id'], 'large');
167 if (!empty($maybe_url)) {
168 $image_url = $maybe_url;
169 }
170 }
171 } elseif (is_numeric($icon)) {
172 $maybe_url = wp_get_attachment_image_url((int) $icon, 'large');
173 if (!empty($maybe_url)) {
174 $image_url = $maybe_url;
175 }
176 } elseif (is_string($icon) && filter_var($icon, FILTER_VALIDATE_URL)) {
177 $image_url = $icon;
178 }
179 }
180
181 // Basic stats: only use real DB fields when present; do not fake numbers.
182 $has_avg_rating = isset($activity->avg_rating) && (float) $activity->avg_rating > 0;
183 $avg_rating = $has_avg_rating ? (float) $activity->avg_rating : 0.0;
184
185 $has_trips_count = isset($activity->trips_count) && (int) $activity->trips_count > 0;
186 $trips_count = $has_trips_count ? (int) $activity->trips_count : 0;
187
188 $starting_price_raw = isset($activity->starting_price)
189 ? (float) $activity->starting_price
190 : 0.0;
191 $has_starting_price = $starting_price_raw > 0;
192
193 // Use core helper to format price with correct currency symbol & settings.
194 $starting_price = $has_starting_price
195 ? yatra_format_price($starting_price_raw)
196 : '';
197
198 // Build permalink
199 $permalink = function_exists('yatra_get_activity_permalink')
200 ? yatra_get_activity_permalink($activity->id ?? $activity)
201 : '';
202 ?>
203 <div class="yatra-activity-card">
204 <div class="yatra-activity-image">
205 <?php if (!empty($image_url)) : ?>
206 <img src="<?php echo esc_url($image_url); ?>" alt="<?php echo esc_attr($name); ?>">
207 <?php elseif (!empty($icon_class)) : ?>
208 <div class="yatra-activity-icon-wrapper" aria-hidden="true" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; background: linear-gradient(135deg, #f3f4f6 0%, #e5e7eb 100%); color: #4b5563;">
209 <?php echo yatra_svg_icon($icon_class, 'yatra-activity-icon'); ?>
210 </div>
211 <?php else : ?>
212 <?php
213 // Use the placeholder image from plugin assets
214 $placeholder_src = plugins_url('assets/images/placeholder.png', dirname(__FILE__));
215 ?>
216 <img src="<?php echo esc_url($placeholder_src); ?>" alt="<?php echo esc_attr__('Yatra placeholder', 'yatra'); ?>">
217 <?php endif; ?>
218 </div>
219 <div class="yatra-activity-content">
220 <h3><?php echo esc_html($name); ?></h3>
221 <?php if (!empty($description)) : ?>
222 <p class="yatra-archive-card-excerpt"><?php echo esc_html(wp_trim_words(wp_strip_all_tags((string) $description), 28)); ?></p>
223 <?php endif; ?>
224 <div class="yatra-activity-stats">
225 <?php if ($has_avg_rating) : ?>
226 <div class="yatra-activity-stat">
227 <svg width="16" height="16" fill="#fbbf24" viewBox="0 0 24 24">
228 <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"/>
229 </svg>
230 <span><?php echo esc_html(number_format($avg_rating, 1)); ?></span>
231 </div>
232 <?php endif; ?>
233 <?php if ($has_trips_count) : ?>
234 <div class="yatra-activity-stat">
235 <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
236 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"/>
237 </svg>
238 <span><?php echo esc_html($trips_count); ?> <?php esc_html_e('Trips', 'yatra'); ?></span>
239 </div>
240 <?php endif; ?>
241 <?php if ($has_starting_price) : ?>
242 <div class="yatra-activity-stat">
243 <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
244 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
245 </svg>
246 <span><?php esc_html_e('From', 'yatra'); ?> <?php echo esc_html($starting_price); ?></span>
247 </div>
248 <?php endif; ?>
249 </div>
250 <?php if (!empty($permalink)) : ?>
251 <a class="yatra-btn yatra-btn-primary yatra-archive-card-cta" href="<?php echo esc_url($permalink); ?>">
252 <?php echo yatra_archive_listing_cta_icon_markup($icon_class, 'activity'); ?>
253 <span><?php echo esc_html__('View Trips', 'yatra'); ?></span>
254 </a>
255 <?php endif; ?>
256 </div>
257 </div>
258 <?php
259 }
260 } else {
261 ?>
262 <div class="yatra-no-activities">
263 <p><?php esc_html_e('No activities found.', 'yatra'); ?></p>
264 </div>
265 <?php } ?>
266 </div>
267
268 <!-- Pagination -->
269 <?php if ($total_pages > 1) : ?>
270 <div class="yatra-listing-pagination">
271 <?php
272 $prev_page = max(1, $current_page - 1);
273 $next_page = min($total_pages, $current_page + 1);
274 ?>
275 <?php if ($current_page <= 1) : ?>
276 <span class="yatra-pagination-btn disabled" aria-disabled="true">
277 <?php echo yatra_svg_icon('chevron-left', 'yatra-btn-icon'); ?>
278 <span><?php esc_html_e('Previous', 'yatra'); ?></span>
279 </span>
280 <?php else : ?>
281 <a class="yatra-pagination-btn" href="<?php echo esc_url(yatra_build_archive_listing_url($prev_page)); ?>">
282 <?php echo yatra_svg_icon('chevron-left', 'yatra-btn-icon'); ?>
283 <span><?php esc_html_e('Previous', 'yatra'); ?></span>
284 </a>
285 <?php endif; ?>
286 <?php
287 $range = 2;
288 for ($i = 1; $i <= $total_pages; $i++) :
289 if ($i == 1 || $i == $total_pages || ($i >= $current_page - $range && $i <= $current_page + $range)) :
290 if ($i === $current_page) :
291 ?>
292 <span class="yatra-pagination-btn active"><?php echo esc_html((string) $i); ?></span>
293 <?php
294 else :
295 ?>
296 <a class="yatra-pagination-btn" href="<?php echo esc_url(yatra_build_archive_listing_url($i)); ?>"><?php echo esc_html((string) $i); ?></a>
297 <?php
298 endif;
299 elseif ($i == $current_page - $range - 1 || $i == $current_page + $range + 1) :
300 ?>
301 <span class="yatra-pagination-ellipsis">...</span>
302 <?php
303 endif;
304 endfor;
305 ?>
306 <?php if ($current_page >= $total_pages) : ?>
307 <span class="yatra-pagination-btn disabled" aria-disabled="true">
308 <span><?php esc_html_e('Next', 'yatra'); ?></span>
309 <?php echo yatra_svg_icon('chevron-right', 'yatra-btn-icon'); ?>
310 </span>
311 <?php else : ?>
312 <a class="yatra-pagination-btn" href="<?php echo esc_url(yatra_build_archive_listing_url($next_page)); ?>">
313 <span><?php esc_html_e('Next', 'yatra'); ?></span>
314 <?php echo yatra_svg_icon('chevron-right', 'yatra-btn-icon'); ?>
315 </a>
316 <?php endif; ?>
317 </div>
318 <?php endif; ?>
319 </div>
320 </main>
321 </div>
322 </div>
323
324 <?php yatra_get_footer(); ?>
325