PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.20
VikAppointments Services Booking Calendar v1.2.20
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / layouts / blocks / reviews.php
vikappointments / site / layouts / blocks Last commit date
calendar 1 month ago login 1 month ago payment 1 month ago alert.php 1 month ago carttotals.php 1 month ago checkout.php 1 month ago couponform.php 1 month ago index.html 1 month ago login.php 1 month ago options.php 1 month ago paymentmethods.php 1 month ago quickcontact.php 1 month ago reviews.php 1 month ago timeline.php 1 month ago waitlist.php 1 month ago
reviews.php
476 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 $reviews = isset($displayData['reviews']) ? $displayData['reviews'] : array();
15 $can_leave = isset($displayData['canLeave']) ? $displayData['canLeave'] : false;
16 $ordering_links = isset($displayData['orderingLinks']) ? $displayData['orderingLinks'] : false;
17 $id_service = isset($displayData['id_service']) ? $displayData['id_service'] : 0;
18 $id_employee = isset($displayData['id_employee']) ? $displayData['id_employee'] : 0;
19 $rev_sub_title = isset($displayData['subtitle']) ? $displayData['subtitle'] : '';
20 $dt_format = isset($displayData['datetime_format']) ? $displayData['datetime_format'] : '';
21 $itemid = isset($displayData['itemid']) ? $displayData['itemid'] : null;
22
23 if ($id_service)
24 {
25 // reviews for a service
26 $col_name = 'id_service';
27 $col_value = $id_service;
28 $controller = 'servicesearch';
29 }
30 else
31 {
32 // reviews for an employee
33 $col_name = 'id_employee';
34 $col_value = $id_employee;
35 $controller = 'employeesearch';
36 }
37
38 if (is_null($itemid))
39 {
40 // item id not provided, get the current one (if set)
41 $itemid = JFactory::getApplication()->input->getInt('Itemid');
42 }
43
44 $config = VAPFactory::getConfig();
45
46 /**
47 * Returns the mode used to load the reviews:
48 * - [1] on scroll down
49 * - [2] button click
50 */
51 $reviews_load_mode = $config->getUint('revloadmode');
52
53 $MIN_COMMENT_LENGTH = $config->getUint('revminlength');
54 $MAX_COMMENT_LENGTH = $config->getUint('revmaxlength');
55 $REVIEW_COMMENT_REQUIRED = $config->getBool('revcommentreq');
56
57 $vik = VAPApplication::getInstance();
58
59 $reviews->rows = isset($reviews->rows) ? $reviews->rows : array();
60 $reviews->size = isset($reviews->size) ? $reviews->size : 0;
61
62 ?>
63
64 <div class="vap-allreviews-intro">
65
66 <div class="vap-allreviews-title">
67 <h2><?php echo JText::translate('VAPREVIEWSTITLE'); ?></h2>
68 <span><?php echo $rev_sub_title; ?></span>
69 </div>
70
71 <div class="vap-allreviews-actions">
72 <?php
73 foreach ($ordering_links as $link)
74 {
75 ?>
76 <a href="<?php echo JRoute::rewrite($link['uri']); ?>" class="vap-btn dark-gray vap-revord-link <?php echo ($link['active'] ? 'active' : ''); ?>">
77 <i class="fas fa-<?php echo $link['mode'] == 'ASC' ? 'sort-amount-up-alt' : 'sort-amount-down'; ?>"></i>
78 <span><?php echo $link['name']; ?></span>
79 </a>
80 <?php
81 }
82 ?>
83 </div>
84 </div>
85
86 <?php if ($can_leave) { ?>
87
88 <div class="vap-postreview-block">
89
90 <div class="vap-postreview-form" style="display: none;">
91 <form action="<?php echo JRoute::rewrite('index.php?option=com_vikappointments&task=' . $controller . '.leavereview' . ($itemid ? '&Itemid=' . $itemid : '')); ?>" method="post" id="vaprevformpost">
92
93 <div class="vap-postreview-top">
94
95 <!-- Rating -->
96 <div class="vap-postreview-ratingwrap">
97 <div class="vap-postreview-label review-rating"><?php echo JText::translate('VAPPOSTREVIEWLBLRATING'); ?>*</div>
98 <div class="vap-postreview-field">
99 <div class="vap-rating-field">
100 <?php for ($i = 1; $i <= 5; $i++) { ?>
101 <div class="vap-rating-box rating-nostar" id="vaprating<?php echo $i; ?>"></div>
102 <?php } ?>
103 </div>
104 <input type="hidden" name="rating" value="" class="required" id="vapreviewrating" />
105 </div>
106 </div>
107
108 <!-- Title -->
109 <div class="vap-postreview-titlewrap">
110 <div class="vap-postreview-label review-title"><?php echo JText::translate('VAPPOSTREVIEWLBLTITLE'); ?>*</div>
111 <div class="vap-postreview-field">
112 <input type="text" name="title" value="" maxlength="64" size="32" class="required" id="vapreviewtitle" />
113 </div>
114 </div>
115
116 </div>
117
118 <!-- Comment -->
119 <div class="vap-postreview-label review-comment">
120 <?php echo JText::translate('VAPPOSTREVIEWLBLCOMMENT'); ?>
121 <?php echo ($REVIEW_COMMENT_REQUIRED ? '*' : ''); ?>
122 </div>
123
124 <div class="vap-postreview-field">
125 <div class="vap-postreview-commentarea">
126
127 <textarea maxlength="<?php echo $MAX_COMMENT_LENGTH; ?>" name="comment" class="<?php echo $REVIEW_COMMENT_REQUIRED ? 'required' : ''; ?>" id="vapreviewcomment"></textarea>
128
129 <div class="vap-postreview-charsleft">
130 <span><?php echo JText::translate('VAPPOSTREVIEWCHARSLEFT'); ?>&nbsp;</span>
131 <span id="vapcommentchars"><?php echo $MAX_COMMENT_LENGTH; ?></span>
132 </div>
133
134 <?php if ($MIN_COMMENT_LENGTH > 0) { ?>
135 <div class="vap-postreview-minchars">
136 <span><?php echo JText::translate('VAPPOSTREVIEWMINCHARS'); ?>&nbsp;</span>
137 <span id="vapcommentminchars"><?php echo $MIN_COMMENT_LENGTH; ?></span>
138 </div>
139 <?php } ?>
140 </div>
141 </div>
142
143 <input type="hidden" name="option" value="com_vikappointments" />
144 <input type="hidden" name="task" value="<?php echo $controller; ?>.leavereview" />
145 <input type="hidden" name="<?php echo $col_name; ?>" value="<?php echo $col_value; ?>" />
146 </form>
147 </div>
148
149 <div class="vap-postreview-bottom">
150 <button type="button" class="vap-btn blue" onClick="vapLeaveReview(this);"><?php echo JText::translate('VAPLEAVEREVIEWLINK'); ?></button>
151 </div>
152
153 </div>
154
155 <?php } ?>
156
157 <div class="vap-reviews-cont">
158 <div class="vap-reviews-list">
159
160 <?php
161 foreach ($reviews->rows as $review)
162 {
163 $data = array(
164 /**
165 * An object containing the review details.
166 *
167 * @var object
168 */
169 'review' => $review,
170
171 /**
172 * The date time format used to display when the review was created.
173 * If not provided, it will be used the default one (military format).
174 *
175 * @var string
176 */
177 'datetime_format' => $dt_format,
178 );
179
180 /**
181 * The review block is displayed from the layout below:
182 * /components/com_vikappointments/layouts/review/default.php
183 *
184 * If you need to change something from this layout, just create
185 * an override of this layout by following the instructions below:
186 * - open the back-end of your Joomla
187 * - visit the Extensions > Templates > Templates page
188 * - edit the active template
189 * - access the "Create Overrides" tab
190 * - select Layouts > com_vikappointments > review
191 * - start editing the default.php file on your template to create your own layout
192 *
193 * @since 1.6
194 */
195 echo JLayoutHelper::render('review.default', $data);
196 }
197 ?>
198
199 </div>
200 </div>
201
202 <?php
203 if ($reviews_load_mode == 2 && $reviews->size > count($reviews->rows))
204 {
205 // AJAX disabled, load reviews with the apposite buttons
206 ?>
207 <div class="vap-reviews-load-wrap">
208 <button class="vap-btn blue" onClick="loadMoreReviews();">
209 <?php echo JText::translate('VAPREVIEWLOADMOREBTN'); ?>
210 </button>
211 </div>
212 <?php
213 }
214 ?>
215
216 <div id="vap-reviews-limit"></div>
217
218 <?php
219 JText::script('VAPREVIEWCOMMENTSHOWLESS');
220 JText::script('VAPREVIEWCOMMENTSHOWMORE');
221 JText::script('VAPSUBMITREVIEWLINK');
222 ?>
223
224 <script>
225
226 var LOAD_REVIEWS = true;
227 var REVIEWS_START_LIM = <?php echo count($reviews->rows); ?>;
228 var ALL_LOADED = <?php echo ($reviews->size > count($reviews->rows) ? 0 : 1); ?>;
229
230 var reviewsValidator = null;
231
232 jQuery(function($) {
233 if (document.location.search.indexOf('revordby') != -1) {
234 $('html,body').animate({
235 scrollTop: $('.vap-allreviews-title').first().offset().top - 5,
236 }, {
237 duration: 'normal',
238 });
239 }
240
241 // create reviews form validator
242 reviewsValidator = new VikFormValidator('#vaprevformpost', 'vap-reviewfield-required');
243 reviewsValidator.setLabel($('#vapreviewrating'), $('.vap-postreview-label.review-rating'));
244 reviewsValidator.setLabel($('#vapreviewtitle'), $('.vap-postreview-label.review-title'));
245 reviewsValidator.setLabel($('#vapreviewcomment'), $('.vap-postreview-label.review-comment'));
246 // validate comment length
247 reviewsValidator.addCallback(() => {
248 const comment = $('#vapreviewcomment');
249
250 if (REVIEW_COMMENT_REQUIRED && comment.hasClass('vap-reviewfield-required')) {
251 // do not neet to validate comment again
252 return false;
253 }
254
255 let val = comment.val();
256
257 // make sure the user specified at least the minimum number of characters
258 if (val.length > 0 && val.length < MIN_COMMENT_LENGTH) {
259 reviewsValidator.setInvalid(comment);
260 return false;
261 }
262
263 reviewsValidator.unsetInvalid(comment);
264 return true;
265 });
266
267 <?php
268 if ($reviews_load_mode == 1)
269 {
270 ?>
271 // load the reviews via AJAX when the scrollbar touches the limit
272 $(window).scrollStopped(function() {
273 if (LOAD_REVIEWS && isReviewsLimitReached()) {
274 loadMoreReviews();
275 }
276 });
277 <?php
278 }
279 ?>
280 });
281
282 function showMoreLessDescription(action, id) {
283 var app = jQuery('#vaprevcomment' + id).text();
284 jQuery('#vaprevcomment' + id).text(jQuery('#vaprevcomfull'+id).val());
285 jQuery('#vaprevcomfull' + id).val(app);
286
287 if (jQuery('#vaprevcomtype' + id).val() == 'more') {
288 jQuery(action).text(Joomla.JText._('VAPREVIEWCOMMENTSHOWLESS'));
289 jQuery('#vaprevcomtype' + id).val('less');
290 } else {
291 jQuery(action).text(Joomla.JText._('VAPREVIEWCOMMENTSHOWMORE'));
292 jQuery('#vaprevcomtype' + id).val('more');
293 }
294 }
295
296 function loadMoreReviews(attempt) {
297 if (ALL_LOADED) {
298 return;
299 }
300
301 if (!attempt) {
302 attempt = 1;
303 }
304
305 LOAD_REVIEWS = false;
306
307 UIAjax.do(
308 '<?php echo $vik->ajaxUrl('index.php?option=com_vikappointments&task=' . $controller . '.loadreviews' . ($itemid ? '&Itemid=' . $itemid : '')); ?>',
309 {
310 <?php echo $col_name; ?>: <?php echo $col_value; ?>,
311 start: REVIEWS_START_LIM,
312 },
313 (resp) => {
314 resp.reviews.forEach((rev) => {
315 jQuery('.vap-reviews-list').append(rev);
316 });
317
318 REVIEWS_START_LIM += resp.reviews.length
319 ALL_LOADED = (REVIEWS_START_LIM >= resp.size);
320
321 if (ALL_LOADED) {
322 jQuery('.vap-reviews-load-wrap').hide();
323 }
324
325 LOAD_REVIEWS = true;
326 },
327 (err) => {
328 // enable reviews again
329 LOAD_REVIEWS = true;
330 }
331 );
332 }
333
334 function isReviewsLimitReached() {
335 var rev_limit_y = jQuery('#vap-reviews-limit').offset().top;
336 var scroll = jQuery(window).scrollTop();
337 var screen_height = jQuery(window).height();
338
339 if (rev_limit_y - scroll - 150 > screen_height) {
340 return false;
341 }
342
343 return true;
344 }
345
346 jQuery.fn.scrollStopped = function(callback) {
347 var elem = jQuery(this), self = this;
348 elem.scroll(function() {
349 if (elem.data('scrollTimeout')) {
350 clearTimeout(elem.data('scrollTimeout'));
351 }
352 elem.data('scrollTimeout', setTimeout(callback, 250, self));
353 });
354 };
355
356 // SUBMIT REVIEW
357
358 function vapLeaveReview(action) {
359 var form = jQuery('.vap-postreview-form');
360 if (!form.is(':visible')) {
361 form.slideDown();
362 jQuery(action).text(Joomla.JText._('VAPSUBMITREVIEWLINK'));
363 return;
364 }
365
366 if (reviewsValidator.validate()) {
367 jQuery('#vaprevformpost').submit();
368 }
369 }
370
371 function vapValidatesReviewFields() {
372 var input = ['title', 'rating'];
373
374 var resp = true;
375 jQuery.each(input, function(i,v){
376 var elem = jQuery('#vapreview'+v);
377 if (elem.val().length > 0) {
378 elem.parent().prev().removeClass('vap-reviewfield-required');
379 } else {
380 elem.parent().prev().addClass('vap-reviewfield-required');
381 resp = false;
382 }
383 });
384
385 if (resp && REVIEW_COMMENT_REQUIRED) {
386 var elem = jQuery('#vapreviewcomment');
387 if (elem.val().length > 0) {
388 elem.parent().parent().prev().removeClass('vap-reviewfield-required');
389 } else {
390 elem.parent().parent().prev().addClass('vap-reviewfield-required');
391 resp = false;
392 }
393 }
394
395 if (resp) {
396 var comment = jQuery('#vapreviewcomment');
397 if (comment.val().length > 0 && comment.val().length < MIN_COMMENT_LENGTH) {
398 comment.parent().parent().prev().addClass('vap-reviewfield-required');
399 jQuery('.vap-postreview-minchars').addClass('vap-reviewfield-required');
400 resp = false;
401 } else {
402 comment.parent().prev().removeClass('vap-reviewfield-required');
403 jQuery('.vap-postreview-minchars').removeClass('vap-reviewfield-required');
404 }
405 }
406
407 return resp;
408 }
409
410 var TO_RATE = true;
411 var MAX_COMMENT_LENGTH = <?php echo $MAX_COMMENT_LENGTH; ?>;
412 var MIN_COMMENT_LENGTH = <?php echo $MIN_COMMENT_LENGTH; ?>;
413 var REVIEW_COMMENT_REQUIRED = <?php echo $REVIEW_COMMENT_REQUIRED ? 1 : 0; ?>;
414
415 jQuery(function() {
416
417 jQuery('.vap-rating-box').on('click', function() {
418 var id = jQuery(this).attr('id').split('vaprating')[1];
419
420 jQuery('.vap-rating-box').removeClass('rating-nostar rating-hoverstar rating-yesstar');
421
422 if (TO_RATE) {
423 jQuery(this).addClass('rating-yesstar');
424 jQuery(this).siblings().each(function() {
425 if (jQuery(this).attr('id').split('vaprating')[1] < id) {
426 jQuery(this).addClass('rating-yesstar');
427 } else {
428 jQuery(this).addClass('rating-nostar');
429 }
430 });
431
432 jQuery('#vapreviewrating').val(id);
433 } else {
434 jQuery(this).addClass('rating-hoverstar');
435 jQuery(this).siblings().each(function(){
436 if (jQuery(this).attr('id').split('vaprating')[1] < id) {
437 jQuery(this).addClass('rating-hoverstar');
438 } else {
439 jQuery(this).addClass('rating-nostar');
440 }
441 });
442
443 jQuery('#vapreviewrating').val('');
444 }
445
446 TO_RATE = !TO_RATE
447 });
448
449 jQuery('.vap-rating-box').hover(function() {
450 var id = jQuery(this).attr('id').split('vaprating')[1];
451
452 if (TO_RATE) {
453 jQuery('.vap-rating-box').removeClass('rating-nostar rating-hoverstar rating-yesstar');
454
455 jQuery(this).addClass('rating-hoverstar');
456 jQuery(this).siblings().each(function(){
457 if (jQuery(this).attr('id').split('vaprating')[1] < id) {
458 jQuery(this).addClass('rating-hoverstar');
459 } else {
460 jQuery(this).addClass('rating-nostar');
461 }
462 });
463 }
464
465 }, function() {
466
467 });
468
469 jQuery('#vapreviewcomment').on('keyup', function(e) {
470 jQuery('#vapcommentchars').text((MAX_COMMENT_LENGTH - jQuery(this).val().length));
471 });
472
473 });
474
475 </script>
476