PluginProbe ʕ •ᴥ•ʔ
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More / 2.10.0
Reviews Feed – Add Testimonials and Customer Reviews From Google Reviews, Yelp, TripAdvisor, and More v2.10.0
2.11.0 2.10.0 2.9.0 2.8.0 2.7.0 2.6.7 2.6.8 2.6.5 2.6.4 2.6.3 2.6.2 2.6.0 2.5.5 2.5.4 2.5.3 2.5.2 trunk 1.0 1.0.1 1.0.2 1.0.3 1.1 1.1.1 1.1.2 1.2.0 2.0 2.1.0 2.1.1 2.4.0 2.4.1 2.4.2 2.4.3 2.4.4 2.4.5 2.4.6 2.5.0 2.5.1
reviews-feed / templates / frontend / post-elements / text-booking.php
reviews-feed / templates / frontend / post-elements Last commit date
extras 3 weeks ago rating-extras 3 weeks ago rating.php 3 weeks ago text-aliexpress.php 3 weeks ago text-booking.php 3 weeks ago text.php 3 weeks ago
text-booking.php
118 lines
1 <?php
2
3 /**
4 * Smash Balloon Reviews Feed Text Template - Booking.com
5 * Custom template for Booking.com reviews with title, pros/cons, and photos
6 *
7 * @package SmashBalloon\Reviews
8 * @version 1.0 Reviews Feed by Smash Balloon
9 */
10
11 if (! defined('ABSPATH')) {
12 exit; // Exit if accessed directly
13 }
14
15 // Check if review has title, pros, cons (review photos render in the media element).
16 $has_title = !empty($post['title']);
17 $has_pros = !empty($post['metadata']['pros']);
18 $has_cons = !empty($post['metadata']['cons']);
19
20 // Per-section read-more. The shared sbr-feed.js truncation only handles a
21 // single `.sb-item-text` per card, which Booking doesn't have (its body is
22 // the two pros/cons sections). So each section truncates server-side and
23 // reveals the rest with a pure-CSS toggle.
24 //
25 // The limit follows the feed's "Content Length" setting so Booking honors the
26 // same trim the customizer preview applies — PostText.js runs
27 // SbUtils.printText(pros/cons, feedSettings), trimming each section to
28 // feedSettings.contentLength. Previously this was hard-coded to 140, so the
29 // setting had no effect on Booking frontend cards. contentLength <= 0 means
30 // "no limit" (mirrors sbr-feed.js `if (text_limit < 1) text_limit = 99999`).
31 $sbr_feed_settings = $this->feed->get_settings();
32 $prosncons_limit = isset($sbr_feed_settings['contentLength'])
33 ? intval($sbr_feed_settings['contentLength'])
34 : 280;
35 if ($prosncons_limit < 1) {
36 $prosncons_limit = PHP_INT_MAX;
37 }
38 // Stable, page-unique base id for the toggle inputs (mirrors the lightbox id scheme).
39 $prosncons_uid = ! empty($post['post_id'])
40 ? 'sbr-rm-' . $post['post_id']
41 : 'sbr-rm-' . substr(md5(($post['title'] ?? '') . ($post['metadata']['pros'] ?? '') . ($post['metadata']['cons'] ?? '')), 0, 10);
42
43 /**
44 * Render a pros/cons body with per-section read-more. Short (cut on a word
45 * boundary) + a pure-CSS expand label when over the limit; plain text otherwise.
46 *
47 * @param string $text Section text (pros or cons).
48 * @param string $uid Unique id for the toggle input/label pair.
49 */
50 $render_prosncons = function (string $text, string $uid) use ($prosncons_limit): void {
51 $len = function_exists('mb_strlen') ? mb_strlen($text) : strlen($text);
52 if ($len <= $prosncons_limit) {
53 echo sbr_neutralize_shortcodes(sbr_kses_review_text(nl2br($text)));
54 return;
55 }
56 $short = function_exists('mb_substr') ? mb_substr($text, 0, $prosncons_limit) : substr($text, 0, $prosncons_limit);
57 // Trim back to a word boundary so we don't cut mid-word (matches the JS behaviour).
58 $last_space = function_exists('mb_strrpos') ? mb_strrpos($short, ' ') : strrpos($short, ' ');
59 if ($last_space !== false && $last_space > 0) {
60 $short = function_exists('mb_substr') ? mb_substr($short, 0, $last_space) : substr($short, 0, $last_space);
61 }
62 $id = esc_attr($uid);
63 // All dynamic parts escaped via esc_attr() / sbr_kses_review_text(); static markup is safe.
64 // a11y (SMASH-1383): the checkbox is the keyboard-operable control — never
65 // `hidden` (display:none is unfocusable); CSS visually hides it while the
66 // label stays the pointer affordance. Name lives on the input; the label's
67 // ellipsis glyph is decorative for AT.
68 echo '<input type="checkbox" id="' . $id . '" class="sbr-readmore-toggle" aria-label="' . esc_attr__('Show the full text', 'reviews-feed') . '" />'
69 . '<span class="sbr-readmore-short">' . sbr_neutralize_shortcodes(sbr_kses_review_text(nl2br($short)))
70 . '<label for="' . $id . '" class="sb-expand sb-readmore-label" aria-hidden="true"><span class="sb-more">&hellip;</span></label></span>'
71 . '<span class="sbr-readmore-full">' . sbr_neutralize_shortcodes(sbr_kses_review_text(nl2br($text))) . '</span>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
72 };
73
74 // Smiley face SVG icons
75 $pros_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16px" height="16px" style="flex-shrink: 0; margin-right: 8px;"><path fill="#008234" d="M22.5 12c0 5.799-4.701 10.5-10.5 10.5S1.5 17.799 1.5 12 6.201 1.5 12 1.5 22.5 6.201 22.5 12m1.5 0c0-6.627-5.373-12-12-12S0 5.373 0 12s5.373 12 12 12 12-5.373 12-12M5.634 13.5a1.5 1.5 0 0 0-1.414 2 8.25 8.25 0 0 0 15.56 0 1.5 1.5 0 0 0-1.414-2zm0 1.5h12.732a6.75 6.75 0 0 1-12.732 0M16.5 8.625a.375.375 0 1 1 0-.75.375.375 0 0 1 0 .75.75.75 0 0 0 0-1.5 1.125 1.125 0 1 0 0 2.25 1.125 1.125 0 0 0 0-2.25.75.75 0 0 0 0 1.5m-9 0a.375.375 0 1 1 0-.75.375.375 0 0 1 0 .75.75.75 0 0 0 0-1.5 1.125 1.125 0 1 0 0 2.25 1.125 1.125 0 0 0 0-2.25.75.75 0 0 0 0 1.5"/></svg>';
76
77 $cons_icon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16px" height="16px" style="flex-shrink: 0; margin-right: 8px;"><path fill="#1a1a1a" d="M22.5 12c0 5.799-4.701 10.5-10.5 10.5S1.5 17.799 1.5 12 6.201 1.5 12 1.5 22.5 6.201 22.5 12m1.5 0c0-6.627-5.373-12-12-12S0 5.373 0 12s5.373 12 12 12 12-5.373 12-12m-5.28 5.667a7.502 7.502 0 0 0-13.444 0 .75.75 0 1 0 1.344.666 6.002 6.002 0 0 1 10.756 0 .75.75 0 0 0 1.344-.666M8.25 9.375a.375.375 0 1 1 0-.75.375.375 0 0 1 0 .75.75.75 0 0 0 0-1.5 1.125 1.125 0 1 0 0 2.25 1.125 1.125 0 0 0 0-2.25.75.75 0 0 0 0 1.5m7.5 0a.375.375 0 1 1 0-.75.375.375 0 0 1 0 .75.75.75 0 0 0 0-1.5 1.125 1.125 0 1 0 0 2.25 1.125 1.125 0 0 0 0-2.25.75.75 0 0 0 0 1.5"/></svg>';
78 ?>
79
80 <?php if ($has_title) : ?>
81 <div class="sb-item-title sb-fs sbr-review-horizontal-element">
82 <?php echo sbr_neutralize_shortcodes(esc_html($post['title'])); ?>
83 </div>
84 <?php endif; ?>
85
86 <?php
87 if ($has_pros || $has_cons) :
88 $allowed_svg = array(
89 'svg' => array(
90 'xmlns' => array(),
91 'viewbox' => array(),
92 'width' => array(),
93 'height' => array(),
94 'style' => array(),
95 ),
96 'path' => array(
97 'fill' => array(),
98 'd' => array(),
99 ),
100 );
101 ?>
102 <div class="sb-item-pros-cons sbr-review-horizontal-element">
103 <?php if ($has_pros) : ?>
104 <div class="sb-item-pros" style="display: flex; align-items: flex-start; margin-bottom: 8px; clear: both;">
105 <span class="sb-item-pros-icon" style="display: inline-flex; align-items: center; height: 1lh; flex-shrink: 0;"><?php echo wp_kses($pros_icon, $allowed_svg); ?></span>
106 <span class="sb-pros-text"><?php $render_prosncons((string) $post['metadata']['pros'], $prosncons_uid . '-pros'); ?></span>
107 </div>
108 <?php endif; ?>
109
110 <?php if ($has_cons) : ?>
111 <div class="sb-item-cons" style="display: flex; align-items: flex-start;">
112 <span class="sb-item-cons-icon" style="display: inline-flex; align-items: center; height: 1lh; flex-shrink: 0;"><?php echo wp_kses($cons_icon, $allowed_svg); ?></span>
113 <span class="sb-cons-text"><?php $render_prosncons((string) $post['metadata']['cons'], $prosncons_uid . '-cons'); ?></span>
114 </div>
115 <?php endif; ?>
116 </div>
117 <?php endif; ?>
118