PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.6
Yatra – Travel Booking & Tour Operator Software v3.0.6
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 / templates / partials / single-trip / reviews.php

reviews.php in Yatra – Travel Booking & Tour Operator Software 3.0.6, at templates/partials/single-trip/reviews.php

318 lines 19.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if (!defined('ABSPATH')) {
3 exit;
4 }
5
6 // Reviews Section
7 // Expected variables: $trip
8 ?>
9 <!-- Reviews: full width within unified trip container (same max-width + padding as .yatra-trip-container) -->
10 <section class="yatra-reviews-section" id="reviews" itemscope itemtype="https://schema.org/Review">
11 <div class="yatra-reviews-section-container">
12 <div class="yatra-reviews-header">
13 <h2 class="yatra-reviews-section-title">
14 <?php echo yatra_svg_icon('star', 'yatra-reviews-section-icon'); ?>
15 <?php echo esc_html__('Reviews', 'yatra'); ?>
16 </h2>
17 <meta itemprop="about" content="<?php echo esc_attr($trip->getTitle()); ?>">
18 </div>
19
20 <?php
21 // Use dynamic reviews from database (via SingleTripController)
22 $display_reviews = !empty($trip->reviews) && is_array($trip->reviews) ? $trip->reviews : [];
23
24 // Total approved count and average come from SQL on the Trip model (list may be capped at N rows).
25 $total_reviews = (int) ($trip->review_count ?? 0);
26 if ($total_reviews < 1) {
27 $total_reviews = count($display_reviews);
28 }
29 $avg_rating = (isset($trip->average_rating) && (float) $trip->average_rating > 0)
30 ? (float) $trip->average_rating
31 : 0.0;
32
33 // Rating distribution: prefer full aggregate from Trip (accurate when review list is limited).
34 $rating_distribution = [5 => 0, 4 => 0, 3 => 0, 2 => 0, 1 => 0];
35 $dist = $trip->rating_distribution ?? null;
36 if (is_array($dist) && $dist !== [] && ($trip->review_count ?? 0) > 0) {
37 foreach ([5, 4, 3, 2, 1] as $star) {
38 $rating_distribution[$star] = (int) ($dist[$star] ?? $dist[(string) $star] ?? 0);
39 }
40 } else {
41 foreach ($display_reviews as $review) {
42 $review_rating = (int) (is_object($review) ? ($review->rating ?? 0) : ($review['rating'] ?? 0));
43 if ($review_rating >= 1 && $review_rating <= 5) {
44 $rating_distribution[$review_rating]++;
45 }
46 }
47 }
48
49 // If we have reviews, calculate average from them
50 if ($total_reviews > 0 && $avg_rating == 0) {
51 $total_rating = 0;
52 foreach ($display_reviews as $review) {
53 $total_rating += (int) (is_object($review) ? ($review->rating ?? 0) : ($review['rating'] ?? 0));
54 }
55 $avg_rating = round($total_rating / $total_reviews, 1);
56 }
57 ?>
58
59 <div class="yatra-reviews-container">
60 <!-- Left: Overall Rating Summary -->
61 <div class="yatra-reviews-summary">
62 <div class="yatra-overall-rating">
63 <div class="yatra-overall-rating-score">
64 <span class="yatra-rating-big"><?php echo esc_html(number_format($avg_rating, 1)); ?></span>
65 <span class="yatra-rating-max">/5</span>
66 </div>
67 <div class="yatra-overall-stars">
68 <?php
69 $full_stars = floor($avg_rating);
70 $has_half = ($avg_rating - $full_stars) >= 0.3;
71 for ($i = 1; $i <= 5; $i++):
72 if ($i <= $full_stars):
73 ?>
74 <span class="yatra-star-icon filled">�
75 </span>
76 <?php elseif ($i == $full_stars + 1 && $has_half): ?>
77 <span class="yatra-star-icon half">�
78 </span>
79 <?php else: ?>
80 <span class="yatra-star-icon">�
81 </span>
82 <?php endif; endfor; ?>
83 </div>
84 <p class="yatra-reviews-based-on">
85 <?php
86 /* translators: %s: formatted total number of reviews. */
87 echo esc_html(sprintf(_n('based on %s review', 'based on %s reviews', $total_reviews, 'yatra'), number_format($total_reviews)));
88 ?>
89 </p>
90 </div>
91
92 <div class="yatra-rating-distribution">
93 <h4 class="yatra-rating-distribution-title"><?php echo esc_html__('Rating breakdown', 'yatra'); ?></h4>
94 <?php for ($star = 5; $star >= 1; $star--):
95 $count = $rating_distribution[$star];
96 $percentage = $total_reviews > 0 ? ($count / $total_reviews) * 100 : 0;
97 ?>
98 <div class="yatra-rating-row">
99 <span class="yatra-rating-star-label">
100 <?php for ($s = 1; $s <= 5; $s++): ?>
101 <span class="yatra-breakdown-star <?php echo $s <= $star ? 'filled' : ''; ?>">�
102 </span>
103 <?php endfor; ?>
104 </span>
105 <div class="yatra-rating-bar">
106 <div class="yatra-rating-bar-fill" style="width: <?php echo esc_attr($percentage); ?>%"></div>
107 </div>
108 <span class="yatra-rating-count"><?php echo esc_html($count); ?></span>
109 </div>
110 <?php endfor; ?>
111 </div>
112 </div>
113
114 <!-- Right: Reviews List -->
115 <div class="yatra-reviews-list">
116 <?php if (!empty($display_reviews)): ?>
117 <!-- Sort & Filter Toolbar -->
118 <div class="yatra-reviews-toolbar">
119 <div class="yatra-reviews-sort">
120 <span class="yatra-sort-label"><?php echo esc_html__('Sort by:', 'yatra'); ?></span>
121 <select class="yatra-sort-select" id="review-sort">
122 <option value="newest"><?php echo esc_html__('Newest first', 'yatra'); ?></option>
123 <option value="highest"><?php echo esc_html__('Highest rated', 'yatra'); ?></option>
124 <option value="lowest"><?php echo esc_html__('Lowest rated', 'yatra'); ?></option>
125 </select>
126 </div>
127 </div>
128 <!-- Reviews -->
129 <div class="yatra-reviews-items">
130 <?php foreach ($display_reviews as $review):
131 $review_rating = is_object($review) ? ($review->rating ?? 5) : ($review['rating'] ?? 5);
132 $review_title = is_object($review) ? ($review->title ?? '') : ($review['title'] ?? '');
133 $review_content = is_object($review) ? ($review->content ?? '') : ($review['content'] ?? '');
134 $review_author = is_object($review) ? ($review->author_name ?? __('Anonymous', 'yatra')) : ($review['author_name'] ?? __('Anonymous', 'yatra'));
135 $review_location = is_object($review) ? ($review->author_location ?? '') : ($review['author_location'] ?? '');
136 $review_date = is_object($review) ? ($review->created_at ?? '') : ($review['created_at'] ?? '');
137 $review_user_id = is_object($review) ? ($review->user_id ?? 0) : ($review['user_id'] ?? 0);
138 $is_verified = $review_user_id > 0;
139 $author_initial = strtoupper(substr($review_author, 0, 1));
140 $avatar_colors = ['#ef4444', '#f97316', '#eab308', '#22c55e', '#3b82f6', '#8b5cf6', '#ec4899'];
141 $avatar_color = $avatar_colors[ord($author_initial) % count($avatar_colors)];
142 ?>
143 <div class="yatra-review-item">
144 <div class="yatra-review-header">
145 <div class="yatra-review-header-left">
146 <div class="yatra-review-avatar" style="background: linear-gradient(135deg, <?php echo esc_attr($avatar_color); ?> 0%, <?php echo esc_attr($avatar_color); ?>dd 100%);">
147 <?php echo esc_html($author_initial); ?>
148 </div>
149 <div class="yatra-review-author-info">
150 <div class="yatra-review-author-top">
151 <span class="yatra-review-author-name"><?php echo esc_html($review_author); ?></span>
152 <?php if ($is_verified): ?>
153 <span class="yatra-verified-badge">
154 <svg class="yatra-icon-xs" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5">
155 <path d="M20 6L9 17l-5-5"/>
156 </svg>
157 <?php echo esc_html__('Verified', 'yatra'); ?>
158 </span>
159 <?php endif; ?>
160 </div>
161 <div class="yatra-review-meta">
162 <?php if ($review_date): ?>
163 <span class="yatra-review-date"><?php echo esc_html(date_i18n('F j, Y', strtotime($review_date))); ?></span>
164 <?php endif; ?>
165 <?php if ($review_location): ?>
166 <span class="yatra-review-author-location">• <?php echo esc_html($review_location); ?></span>
167 <?php endif; ?>
168 </div>
169 </div>
170 </div>
171 <div class="yatra-review-stars">
172 <?php for ($i = 1; $i <= 5; $i++): ?>
173 <span class="yatra-star-sm <?php echo $i <= $review_rating ? 'filled' : ''; ?>">�
174 </span>
175 <?php endfor; ?>
176 </div>
177 </div>
178 <div class="yatra-review-body">
179 <?php if ($review_title): ?>
180 <h4 class="yatra-review-title"><?php echo esc_html($review_title); ?></h4>
181 <?php endif; ?>
182 <p class="yatra-review-content"><?php echo esc_html($review_content); ?></p>
183 </div>
184 </div>
185 <?php endforeach; ?>
186 </div>
187
188 <!-- Load More -->
189 <?php if ($total_reviews > 3): ?>
190 <div class="yatra-reviews-load-more">
191 <button class="yatra-load-more-btn" type="button">
192 <?php echo esc_html__('Show more reviews', 'yatra'); ?>
193 </button>
194 </div>
195 <?php endif; ?>
196 <?php else: ?>
197 <div class="yatra-no-reviews-message">
198 <div class="yatra-no-reviews-icon">
199 <?php echo yatra_svg_icon('message-circle', 'yatra-icon-lg'); ?>
200 </div>
201 <p><?php echo esc_html__('No reviews yet. Be the first to review this trip!', 'yatra'); ?></p>
202 </div>
203 <?php endif; ?>
204 </div>
205 </div>
206
207 <!-- Review Form -->
208 <?php
209 $can_review = yatra_can_review((int) $trip->id);
210 $require_booking = yatra_setting_enabled('require_booking_to_review');
211 $minimum_rating = (int) yatra_get_setting('minimum_rating', 1);
212
213 // Check for existing review that can be edited
214 $existing_review = null;
215 $can_edit_review = false;
216 $edit_time_remaining = '';
217
218 if (is_user_logged_in()) {
219 $existing_review = yatra_get_user_review((int) $trip->id);
220 if ($existing_review) {
221 $can_edit_review = yatra_can_edit_review($existing_review);
222 if ($can_edit_review) {
223 $edit_time_remaining = yatra_get_review_edit_time_remaining($existing_review);
224 }
225 }
226 }
227 ?>
228 <div class="yatra-review-form-section">
229 <?php if ($existing_review && $can_edit_review): ?>
230 <h3 class="yatra-review-form-title"><?php echo esc_html__('Edit Your Review', 'yatra'); ?></h3>
231 <div class="yatra-review-edit-notice">
232 <svg width="16" height="16" fill="none" stroke="currentColor" viewBox="0 0 24 24">
233 <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
234 </svg>
235 <p><?php
236 /* translators: %s: remaining edit time (e.g. "12 minutes"). */
237 echo esc_html(sprintf(__('You can edit your review for %s more.', 'yatra'), $edit_time_remaining));
238 ?></p>
239 </div>
240 <?php else: ?>
241 <h3 class="yatra-review-form-title"><?php echo esc_html__('Write a Review', 'yatra'); ?></h3>
242 <?php endif; ?>
243
244 <?php if (!is_user_logged_in()): ?>
245 <div class="yatra-review-login-notice">
246 <p><?php echo esc_html__('Please', 'yatra'); ?> <a href="<?php echo esc_url(wp_login_url(get_permalink())); ?>"><?php echo esc_html__('log in', 'yatra'); ?></a> <?php echo esc_html__('to write a review.', 'yatra'); ?></p>
247 </div>
248 <?php elseif (!$can_review && $require_booking): ?>
249 <div class="yatra-review-booking-notice">
250 <p><?php echo esc_html__('Only customers who have booked this trip can leave a review.', 'yatra'); ?></p>
251 </div>
252 <?php elseif ($existing_review && !$can_edit_review): ?>
253 <div class="yatra-review-already-notice">
254 <?php if (isset($existing_review->status) && $existing_review->status === 'approved'): ?>
255 <p><?php echo esc_html__('Thank you! Your review has been approved and published.', 'yatra'); ?></p>
256 <?php else: ?>
257 <p><?php echo esc_html__('You have already reviewed this trip.', 'yatra'); ?></p>
258 <?php endif; ?>
259 </div>
260 <?php elseif ($can_review || ($existing_review && $can_edit_review)): ?>
261 <form class="yatra-review-form" id="yatra-review-form" method="post">
262 <?php wp_nonce_field('yatra_submit_review', 'yatra_review_nonce'); ?>
263 <input type="hidden" name="trip_id" value="<?php echo esc_attr($trip->id); ?>">
264 <?php if ($existing_review && $can_edit_review): ?>
265 <input type="hidden" name="review_id" value="<?php echo esc_attr($existing_review->id); ?>">
266 <input type="hidden" name="action_type" value="edit">
267 <?php endif; ?>
268
269 <!-- Rating -->
270 <div class="yatra-form-field yatra-rating-field">
271 <label class="yatra-form-label"><?php echo esc_html__('Your Rating', 'yatra'); ?> <span class="yatra-required">*</span></label>
272 <div class="yatra-star-rating-input" data-min-rating="<?php echo esc_attr($minimum_rating); ?>">
273 <?php
274 $selected_rating = $existing_review ? (int) $existing_review->rating : 5;
275 for ($i = 1; $i <= 5; $i++):
276 ?>
277 <input type="radio" name="rating" id="rating-<?php echo $i; ?>" value="<?php echo $i; ?>" <?php echo $i === $selected_rating ? 'checked' : ''; ?> <?php echo $i < $minimum_rating ? 'disabled' : ''; ?>>
278 <label for="rating-<?php echo $i; ?>" class="yatra-star-label" title="<?php echo esc_attr(sprintf(__('%d star', 'yatra'), $i)); ?>">�
279 </label>
280 <?php endfor; ?>
281 </div>
282 <?php if ($minimum_rating > 1): ?>
283 <p class="yatra-field-hint"><?php
284 /* translators: %d: minimum allowed star rating. */
285 echo esc_html(sprintf(__('Minimum rating: %d star(s)', 'yatra'), $minimum_rating));
286 ?></p>
287 <?php endif; ?>
288 </div>
289
290 <!-- Title -->
291 <div class="yatra-form-field">
292 <label for="review-title" class="yatra-form-label"><?php echo esc_html__('Review Title', 'yatra'); ?></label>
293 <input type="text" id="review-title" name="title" class="yatra-form-input" placeholder="<?php echo esc_attr__('Summarize your experience', 'yatra'); ?>" maxlength="100" value="<?php echo $existing_review ? esc_attr($existing_review->title ?? '') : ''; ?>">
294 </div>
295
296 <!-- Review Content -->
297 <div class="yatra-form-field">
298 <label for="review-content" class="yatra-form-label"><?php echo esc_html__('Your Review', 'yatra'); ?> <span class="yatra-required">*</span></label>
299 <textarea id="review-content" name="content" class="yatra-form-textarea" rows="5" placeholder="<?php echo esc_attr__('Share your experience with this trip...', 'yatra'); ?>" required minlength="20"><?php echo $existing_review ? esc_textarea($existing_review->content ?? '') : ''; ?></textarea>
300 <p class="yatra-field-hint"><?php echo esc_html__('Minimum 20 characters', 'yatra'); ?></p>
301 </div>
302
303 <!-- Submit Button -->
304 <div class="yatra-form-field">
305 <button type="submit" class="yatra-review-submit-btn">
306 <?php echo yatra_svg_icon('check', 'yatra-icon-sm'); ?>
307 <?php echo $existing_review && $can_edit_review ? esc_html__('Update Review', 'yatra') : esc_html__('Submit Review', 'yatra'); ?>
308 </button>
309 <?php if (yatra_setting_enabled('enable_review_moderation')): ?>
310 <p class="yatra-review-moderation-notice"><?php echo esc_html__('Your review will be published after moderation.', 'yatra'); ?></p>
311 <?php endif; ?>
312 </div>
313 </form>
314 <?php endif; ?>
315 </div>
316 </div>
317 </section>
318