PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
vikbooking / admin / views / manageroom / tmpl / default.php

default.php in VikBooking Hotel Booking Engine & PMS 1.8.16, at admin/views/manageroom/tmpl/default.php

1,556 lines 70.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * @package VikBooking
4 * @subpackage com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 e4j - Extensionsforjoomla.com. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 * @link https://vikwp.com
9 */
10
11 defined('ABSPATH') or die('No script kiddies please!');
12
13 $row = $this->row;
14 $cats = $this->cats;
15 $carats = $this->carats;
16 $optionals = $this->optionals;
17 $adultsdiff = $this->adultsdiff;
18
19 JHtml::fetch('jquery.framework', true, true);
20 JHtml::fetch('script', VBO_SITE_URI.'resources/jquery-ui.sortable.min.js');
21
22 $has_vcm = class_exists('VikChannelManager');
23
24 JText::script('VBO_AI_LABEL_DEF');
25 JText::script('VBO_GEN_CONTENT');
26 JText::script('VBNEWROOMSMALLDESC');
27 JText::script('VBNEWROOMSEVEN');
28 JText::script('VBPVIEWROOMTHREE');
29 JText::script('VBANNULLA');
30
31 $vbo_app = VikBooking::getVboApplication();
32 $vbo_app->loadSelect2();
33 $currencysymb = VikBooking::getCurrencySymb();
34 $arrcats = array();
35 $arrcarats = array();
36 $arropts = array();
37 $oldcats = $row ? explode(";", (string)$row['idcat']) : array();
38 foreach ($oldcats as $oc) {
39 if (!empty($oc)) {
40 $arrcats[$oc] = $oc;
41 }
42 }
43 $oldcarats = $row ? explode(";", (string)$row['idcarat']) : array();
44 foreach ($oldcarats as $ocr) {
45 if (!empty($ocr)) {
46 $arrcarats[$ocr] = $ocr;
47 }
48 }
49 $oldopts = $row ? explode(";", (string)$row['idopt']) : array();
50 foreach ($oldopts as $oopt) {
51 if (!empty($oopt)) {
52 $arropts[$oopt] = $oopt;
53 }
54 }
55 $wcats = "";
56 $wcarats = "";
57 $woptionals = "";
58 if (is_array($cats)) {
59 $wcats = "<select name=\"ccat[]\" multiple=\"multiple\" id=\"categories_sel\" size=\"".(count($cats) + 1)."\">";
60 foreach ($cats as $cat) {
61 $wcats .= "<option value=\"".$cat['id']."\"".(array_key_exists($cat['id'], $arrcats) ? " selected=\"selected\"" : "").">".$cat['name']."</option>\n";
62 }
63 $wcats .= "</select>\n";
64 }
65 if (is_array($carats)) {
66 $wcarats = "<div class=\"vbo-roomentries-cont\">";
67 $nn = 0;
68 foreach ($carats as $kcarat => $carat) {
69 $wcarats .= "<div class=\"vbo-roomentry-cont\"><input type=\"checkbox\" name=\"ccarat[]\" id=\"carat".$kcarat."\" value=\"".$carat['id']."\"".(array_key_exists($carat['id'], $arrcarats) ? " checked=\"checked\"" : "")."/> <label for=\"carat".$kcarat."\">".$carat['name']."</label></div>\n";
70 $nn++;
71 if (($nn % 3) == 0) {
72 $wcarats .= "</div>\n<div class=\"vbo-roomentries-cont\">";
73 }
74 }
75 $wcarats .= "</div>\n";
76 }
77 if (is_array($optionals)) {
78 $woptionals = "<div class=\"vbo-roomentries-cont\">";
79 $nn = 0;
80 foreach ($optionals as $kopt => $optional) {
81 $woptionals .= "<div class=\"vbo-roomentry-cont\"><input type=\"checkbox\" name=\"coptional[]\" id=\"opt".$kopt."\" value=\"".$optional['id']."\"".(array_key_exists($optional['id'], $arropts) ? " checked=\"checked\"" : "")."/> <label for=\"opt".$kopt."\">".$optional['name']." ".(empty($optional['ageintervals']) ? ((int)$optional['pcentroom'] ? $optional['cost'].'%' : $currencysymb." ".$optional['cost']) : "")."</label></div>\n";
82 $nn++;
83 if (($nn % 3) == 0) {
84 $woptionals .= "</div>\n<div class=\"vbo-roomentries-cont\">";
85 }
86 }
87 $woptionals .= "</div>\n";
88 }
89 //more images
90 $morei = $row ? explode(';;', (string)$row['moreimgs']) : array();
91 $totmorei = count($morei);
92 $actmoreimgs = "";
93 if ($totmorei > 0) {
94 $notemptymoreim = false;
95 $imgcaptions = json_decode((string)$row['imgcaptions'], true);
96 $usecaptions = empty($imgcaptions) || !is_array($imgcaptions) || !(count($imgcaptions) > 0) ? false : true;
97 foreach ($morei as $ki => $mi) {
98 if (!empty($mi)) {
99 $notemptymoreim = true;
100 $actmoreimgs .= '<li class="vbo-editroom-currentphoto">';
101 $actmoreimgs .= '<a href="'.VBO_SITE_URI.'resources/uploads/big_'.$mi.'" target="_blank" class="vbomodal"><img src="'.VBO_SITE_URI.'resources/uploads/thumb_'.$mi.'" class="maxfifty"/></a>';
102 $actmoreimgs .= '<a class="vbo-toggle-imgcaption" href="javascript: void(0);" onclick="vbOpenImgDetails(\''.$ki.'\', this)"><i class="'.VikBookingIcons::i('cog').'"></i></a>';
103 $actmoreimgs .= '<div id="vbimgdetbox'.$ki.'" class="vbimagedetbox" style="display: none;"><div class="captionlabel"><span>'.JText::translate('VBIMGCAPTION').'</span><input type="text" name="caption'.$ki.'" value="'.($usecaptions === true && isset($imgcaptions[$ki]) ? htmlspecialchars($imgcaptions[$ki]) : "").'" size="40"/></div><input type="hidden" name="imgsorting[]" value="'.$mi.'"/><input class="captionsubmit" type="button" name="updcatpion" value="'.JText::translate('VBIMGUPDATE').'" onclick="javascript: updateCaptions();"/><div class="captionremoveimg"><a class="vbimgrm btn btn-danger" href="index.php?option=com_vikbooking&task=removemoreimgs&roomid='.$row['id'].'&imgind='.$ki.'" title="'.JText::translate('VBREMOVEIMG').'"><i class="icon-remove"></i>'.JText::translate('VBREMOVEIMG').'</a></div></div>';
104 $actmoreimgs .= '</li>';
105 }
106 }
107 }
108 //end more images
109 //num adults charges/discounts only if the max numb of adults allowed is > than 1 and the minimum is less than the maximum
110 $writeadultsdiff = false;
111 if (count($row) && $row['toadult'] > 1 && $row['fromadult'] < $row['toadult']) {
112 $writeadultsdiff = true;
113 $stradultsdiff = "";
114 $startadind = $row['fromadult'] > 0 ? $row['fromadult'] : 1;
115 $parseadultsdiff = array();
116 if (@is_array($adultsdiff)) {
117 foreach ($adultsdiff as $adiff) {
118 $parseadultsdiff[$adiff['adults']] = $adiff;
119 }
120 }
121 for ($adi = $startadind; $adi <= $row['toadult']; $adi++) {
122 $stradultsdiff .= "<p>";
123 $stradultsdiff .= '<span class="vbo-adults-usage">' . JText::sprintf('VBADULTSDIFFNUM', $adi) . "</span><select name=\"adultsdiffchdisc[]\"><option value=\"1\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['chdisc'] == 1 ? " selected=\"selected\"" : "").">".JText::translate('VBADULTSDIFFCHDISCONE')."</option><option value=\"2\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['chdisc'] == 2 ? " selected=\"selected\"" : "").">".JText::translate('VBADULTSDIFFCHDISCTWO')."</option></select>\n";
124 $stradultsdiff .= "<input type=\"number\" step=\"any\" name=\"adultsdiffval[]\" value=\"".(array_key_exists($adi, $parseadultsdiff) ? $parseadultsdiff[$adi]['value'] : "")."\" size=\"3\" style=\"width: 40px;\"/><input type=\"hidden\" name=\"adultsdiffnum[]\" value=\"".$adi."\"/>\n";
125 $stradultsdiff .= "<select name=\"adultsdiffvalpcent[]\"><option value=\"1\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['valpcent'] == 1 ? " selected=\"selected\"" : "").">".$currencysymb."</option><option value=\"2\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['valpcent'] == 2 ? " selected=\"selected\"" : "").">%</option></select>\n";
126 $stradultsdiff .= "<select name=\"adultsdiffpernight[]\"><option value=\"1\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['pernight'] == 1 ? " selected=\"selected\"" : "").">".JText::translate('VBADULTSDIFFONPERNIGHT')."</option><option value=\"0\"".(array_key_exists($adi, $parseadultsdiff) && $parseadultsdiff[$adi]['pernight'] == 0 ? " selected=\"selected\"" : "").">".JText::translate('VBADULTSDIFFONTOTAL')."</option></select>\n";
127 $stradultsdiff .= "</p>\n";
128 }
129 }
130 //
131 $editor = JEditor::getInstance(JFactory::getApplication()->get('editor'));
132 ?>
133 <script type="text/javascript">
134 //Code to debug the size of the form to be submitted in case it will exceed the PHP post_max_size
135 /*
136 Joomla.submitbutton = function(task) {
137 console.log(jQuery("#adminForm").not("[type='file']").serialize().length);
138 Joomla.submitform(task, document.adminForm);
139 }
140 */
141 //
142 function showResizeSel() {
143 if (document.adminForm.autoresize.checked == true) {
144 document.getElementById('resizesel').style.display='inline-block';
145 } else {
146 document.getElementById('resizesel').style.display='none';
147 }
148 return true;
149 }
150 function showResizeSelMore() {
151 if (document.adminForm.autoresizemore.checked == true) {
152 document.getElementById('resizeselmore').style.display='inline-block';
153 } else {
154 document.getElementById('resizeselmore').style.display='none';
155 }
156 return true;
157 }
158 function addMoreImages() {
159 var ni = document.getElementById('myDiv');
160 var numi = document.getElementById('moreimagescounter');
161 var num = (document.getElementById('moreimagescounter').value -1)+ 2;
162 numi.value = num;
163 var newdiv = document.createElement('div');
164 var divIdName = 'my'+num+'Div';
165 newdiv.setAttribute('id', divIdName);
166 newdiv.setAttribute('class', 'vbo-first-imgup');
167 newdiv.innerHTML = '<input type=\'file\' name=\'cimgmore[]\' size=\'35\'/><div class=\'vbo-imgup-caption\'><span><?php echo addslashes(JText::translate('VBIMGCAPTION')); ?></span> <input type=\'text\' name=\'cimgcaption[]\' size=\'30\' value=\'\'/></div>';
168 ni.appendChild(newdiv);
169 }
170 function vbPlusMinus(what, how) {
171 var inp = document.getElementById(what);
172 var actval = inp.value;
173 var newval = 0;
174 if (how == 'plus') {
175 newval = parseInt(actval) + 1;
176 } else {
177 if (parseInt(actval) >= 1) {
178 newval = parseInt(actval) - 1;
179 }
180 }
181 inp.value = newval;
182 <?php
183 if ($writeadultsdiff == true) {
184 ?>
185 var origfrom = <?php echo $row['fromadult']; ?>;
186 var origto = <?php echo $row['toadult']; ?>;
187 if (what == 'fromadult') {
188 if (newval == origfrom) {
189 document.getElementById('vbadultsdiffsavemess').style.display = 'none';
190 document.getElementById('vbadultsdiffbox').style.display = 'block';
191 } else {
192 document.getElementById('vbadultsdiffbox').style.display = 'none';
193 document.getElementById('vbadultsdiffsavemess').style.display = 'block';
194 }
195 }
196 if (what == 'toadult') {
197 if (newval == origto) {
198 document.getElementById('vbadultsdiffsavemess').style.display = 'none';
199 document.getElementById('vbadultsdiffbox').style.display = 'block';
200 } else {
201 document.getElementById('vbadultsdiffbox').style.display = 'none';
202 document.getElementById('vbadultsdiffsavemess').style.display = 'block';
203 }
204 }
205 <?php
206 }
207 ?>
208 if (what == 'toadult' || what == 'tochild') {
209 vbMaxTotPeople();
210 }
211 if (what == 'fromadult' || what == 'fromchild') {
212 vbMinTotPeople();
213 }
214 return true;
215 }
216 function vbMaxTotPeople() {
217 var toadu = document.getElementById('toadult').value;
218 var tochi = document.getElementById('tochild').value;
219 document.getElementById('totpeople').value = parseInt(toadu) + parseInt(tochi);
220 var suggocc = document.getElementById('suggocc').value;
221 if (!suggocc.length || (parseInt(suggocc) < 2 && parseInt(toadu) > 1)) {
222 document.getElementById('suggocc').value = toadu;
223 }
224 return true;
225 }
226 function vbMinTotPeople() {
227 var fadu = document.getElementById('fromadult').value;
228 var fchi = document.getElementById('fromchild').value;
229 document.getElementById('mintotpeople').value = parseInt(fadu) + parseInt(fchi);
230 return true;
231 }
232 function togglePriceCalendarParam() {
233 if (parseInt(document.getElementById('pricecal').value) == 1) {
234 document.getElementById('defcalcostp').style.display = 'flex';
235 } else {
236 document.getElementById('defcalcostp').style.display = 'none';
237 }
238 }
239 function toggleSeasonalCalendarParam() {
240 if (parseInt(document.getElementById('seasoncal').value) > 0) {
241 jQuery('.param-seasoncal').show();
242 } else {
243 jQuery('.param-seasoncal').each(function(k, v) {
244 if (k > 0) {
245 jQuery(this).hide();
246 }
247 });
248 }
249 }
250 var vbo_details_on = false;
251 function vbOpenImgDetails(key, el) {
252 if (vbo_details_on === true) {
253 jQuery('.vbimagedetbox').not('#vbimgdetbox'+key).hide();
254 jQuery('.vbo-toggle-imgcaption.vbo-toggle-imgcaption-on').removeClass('vbo-toggle-imgcaption-on');
255 }
256 if (document.getElementById('vbimgdetbox'+key).style.display == 'none') {
257 document.getElementById('vbimgdetbox'+key).style.display = 'block';
258 jQuery(el).addClass('vbo-toggle-imgcaption-on');
259 vbo_details_on = true;
260 } else {
261 document.getElementById('vbimgdetbox'+key).style.display = 'none';
262 jQuery(el).removeClass('vbo-toggle-imgcaption-on');
263 vbo_details_on = false;
264 }
265 }
266 function updateCaptions() {
267 var ni = document.adminForm;
268 var newdiv = document.createElement('div');
269 newdiv.innerHTML = '<input type=\'hidden\' name=\'updatecaption\' value=\'1\'/>';
270 ni.appendChild(newdiv);
271 document.adminForm.task.value='updateroom';
272 document.adminForm.submit();
273 }
274 function vboToggleRoomUpgrade() {
275 if (jQuery('input[name="room_upgrade"]').is(':checked')) {
276 jQuery('.vbo-roomupgrade-param').show();
277 } else {
278 jQuery('.vbo-roomupgrade-param').hide();
279 }
280 }
281 function vboToggleMinAdvNotice(is_checked) {
282 if (!is_checked) {
283 jQuery('.vbo-room-level-min_adv-notice').hide();
284 } else {
285 jQuery('.vbo-room-level-min_adv-notice').show();
286 }
287 }
288 function vboToggleMaxAdvNotice(is_checked) {
289 if (!is_checked) {
290 jQuery('.vbo-room-level-max_adv-notice').hide();
291 } else {
292 jQuery('.vbo-room-level-max_adv-notice').show();
293 }
294 }
295 /* Start - Room Disctinctive Features */
296 var cur_units = <?php echo $row ? $row['units'] : '1'; ?>;
297
298 jQuery(function() {
299 jQuery('#share_with_sel, #categories_sel, #upgrade-rooms').select2();
300 jQuery(".vbo-sortable").sortable({
301 helper: 'clone'
302 });
303 jQuery(".vbo-sortable").disableSelection();
304 jQuery('#vbo-distfeatures-toggle').click(function() {
305 jQuery(this).toggleClass('btn-primary');
306 jQuery('.vbo-distfeatures-cont').fadeToggle();
307 });
308 jQuery('#room_units').change(function() {
309 var to_units = parseInt(jQuery(this).val());
310 if (to_units > 1) {
311 jQuery('.param-multiunits').show();
312 jQuery('.vbo-distfeature-row').css('display', 'flex');
313 <?php
314 if (!count($row)) {
315 // suggest last available param to 1
316 ?>
317 if (!jQuery('#lastavail').val().length || parseInt(jQuery('#lastavail').val()) < 1) {
318 jQuery('#lastavail').val('1');
319 }
320 <?php
321 }
322 ?>
323 } else {
324 jQuery('.param-multiunits').hide();
325 jQuery('.vbo-distfeature-row').css('display', 'none');
326 }
327 if (to_units > cur_units) {
328 var diff_units = (to_units - cur_units);
329 for (var i = 1; i <= diff_units; i++) {
330 var unit_html = "<div class=\"vbo-runit-features-cont\" id=\"runit-features-"+(i + cur_units)+"\">"+
331 " <span class=\"vbo-runit-num\"><?php echo addslashes(JText::translate('VBODISTFEATURERUNIT')); ?>"+(i + cur_units)+"</span>"+
332 " <div class=\"vbo-runit-features\">"+
333 " <div class=\"vbo-runit-feature\">"+
334 " <input type=\"text\" name=\"feature-name"+(i + cur_units)+"[]\" value=\"\" size=\"20\" placeholder=\"<?php echo JText::translate('VBODISTFEATURETXT'); ?>\"/>"+
335 " <input type=\"hidden\" name=\"feature-lang"+(i + cur_units)+"[]\" value=\"\"/>"+
336 " <input type=\"text\" name=\"feature-value"+(i + cur_units)+"[]\" value=\"\" size=\"20\" placeholder=\"<?php echo JText::translate('VBODISTFEATUREVAL'); ?>\"/>"+
337 " <span class=\"vbo-feature-remove\"><i class=\"<?php echo VikBookingIcons::i('far fa-minus-square'); ?>\"></i></span>"+
338 " </div>"+
339 " <span class=\"vbo-feature-add btn vbo-config-btn\"><i class=\"icon-new\"></i><?php echo addslashes(JText::translate('VBODISTFEATUREADD')); ?></span>"+
340 " </div>"+
341 "</div>";
342 jQuery('.vbo-distfeatures-cont').append(unit_html);
343 }
344 cur_units = to_units;
345 } else if (to_units < cur_units) {
346 for (var i = cur_units; i > to_units; i--) {
347 jQuery('#runit-features-'+i).remove();
348 }
349 cur_units = to_units;
350 }
351 });
352
353 jQuery(document.body).on('click', '.vbo-feature-add', function() {
354 var cfeature_id = jQuery(this).parent('div').parent('div').attr('id').split('runit-features-');
355 if (cfeature_id[1].length) {
356 jQuery(this).before("<div class=\"vbo-runit-feature\">"+
357 " <input type=\"text\" name=\"feature-name"+cfeature_id[1]+"[]\" value=\"\" size=\"20\" placeholder=\"<?php echo JText::translate('VBODISTFEATURETXT'); ?>\"/>"+
358 " <input type=\"hidden\" name=\"feature-lang"+cfeature_id[1]+"[]\" value=\"\"/>"+
359 " <input type=\"text\" name=\"feature-value"+cfeature_id[1]+"[]\" value=\"\" size=\"20\" placeholder=\"<?php echo JText::translate('VBODISTFEATUREVAL'); ?>\"/>"+
360 " <span class=\"vbo-feature-remove\"><i class=\"<?php echo VikBookingIcons::i('far fa-minus-square'); ?>\"></i></span>"+
361 "</div>"
362 );
363 }
364 });
365
366 jQuery(document.body).on('click', '.vbo-feature-remove', function() {
367 jQuery(this).parent('div').remove();
368 });
369 });
370 /* End - Room Disctinctive Features */
371 </script>
372 <?php
373 $vbo_app->prepareModalBox('.vbomodal', '', true);
374 ?>
375 <input type="hidden" value="0" id="moreimagescounter" />
376
377 <form name="adminForm" id="adminForm" action="index.php" method="post" enctype="multipart/form-data">
378 <?php
379 if (count($row)) {
380 ?>
381 <div class="vbo-mngroom-rtitle">
382 <h3><?php echo $row['name']; ?></h3>
383 </div>
384 <?php
385 }
386 ?>
387 <div class="vbo-admin-container">
388 <div class="vbo-config-maintab-left">
389 <fieldset class="adminform">
390 <div class="vbo-params-wrap">
391 <legend class="adminlegend"><?php echo JText::translate('VBOROOMLEGUNITOCC'); ?></legend>
392 <div class="vbo-params-container">
393 <div class="vbo-param-container">
394 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMFIVE'); ?></div>
395 <div class="vbo-param-setting"><input type="text" name="cname" value="<?php echo $row ? htmlspecialchars($row['name']) : ''; ?>" size="40"/></div>
396 </div>
397 <div class="vbo-param-container">
398 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMEIGHT'); ?></div>
399 <div class="vbo-param-setting"><?php echo $vbo_app->printYesNoButtons('cavail', JText::translate('VBYES'), JText::translate('VBNO'), ((count($row) && intval($row['avail']) == 1) || !$row ? 'yes' : 0), 'yes', 0); ?></div>
400 </div>
401 <div class="vbo-param-container">
402 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMNINE'); ?></div>
403 <div class="vbo-param-setting"><input type="number" min="1" name="units" id="room_units" value="<?php echo $row ? $row['units'] : '1'; ?>" size="3" onfocus="this.select();" /></div>
404 </div>
405 <?php
406 $room_features = $row ? VikBooking::getRoomParam('features', $row['params']) : array(1 => VikBooking::getDefaultDistinctiveFeatures());
407 if (!is_array($room_features)) {
408 $room_features = array();
409 }
410 if (!(count($room_features) > 0)) {
411 $default_features = VikBooking::getDefaultDistinctiveFeatures();
412 for ($i = 1; $i <= $row['units']; $i++) {
413 $room_features[$i] = $default_features;
414 }
415 }
416 ?>
417 <div class="vbo-param-container vbo-distfeature-row" style="display: <?php echo count($row) && $row['units'] > 1 ? 'flex' : 'none'; ?>;">
418 <div class="vbo-param-label"><?php echo JText::translate('VBOROOMUNITSDISTFEAT'); ?></div>
419 <div class="vbo-param-setting">
420 <div class="vbo-distfeatures-toggle-cont">
421 <span id="vbo-distfeatures-toggle" class="btn vbo-config-btn"><?php VikBookingIcons::e('binoculars'); ?><?php echo JText::translate('VBOROOMUNITSDISTFEATTOGGLE'); ?></span>
422 </div>
423 <div class="vbo-distfeatures-cont">
424 <?php
425 $unitslim = $row ? $row['units'] : 1;
426 for ($i=1; $i <= $unitslim; $i++) {
427 ?>
428 <div class="vbo-runit-features-cont" id="runit-features-<?php echo $i; ?>">
429 <span class="vbo-runit-num"><?php echo JText::translate('VBODISTFEATURERUNIT'); ?><?php echo $i; ?></span>
430 <div class="vbo-runit-features">
431 <?php
432 if (array_key_exists($i, $room_features)) {
433 foreach ($room_features[$i] as $fkey => $fval) {
434 ?>
435 <div class="vbo-runit-feature">
436 <input type="text" name="feature-name<?php echo $i; ?>[]" value="<?php echo htmlspecialchars(JText::translate($fkey)); ?>" size="20"/>
437 <input type="hidden" name="feature-lang<?php echo $i; ?>[]" value="<?php echo $fkey; ?>"/>
438 <input type="text" name="feature-value<?php echo $i; ?>[]" value="<?php echo htmlspecialchars($fval); ?>" size="20"/>
439 <span class="vbo-feature-remove"><?php VikBookingIcons::e('far fa-minus-square'); ?></span>
440 </div>
441 <?php
442 }
443 }
444 ?>
445 <span class="vbo-feature-add btn vbo-config-btn"><?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBODISTFEATUREADD'); ?></span>
446 </div>
447 </div>
448 <?php
449 }
450 ?>
451 </div>
452 </div>
453 </div>
454 <div class="vbo-param-container">
455 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMADULTS'); ?></div>
456 <div class="vbo-param-setting">
457 <div class="vbo-param-setting-group">
458 <div class="vbplusminuscont">
459 <span><?php echo JText::translate('VBNEWROOMMIN'); ?></span>
460 <input type="number" min="0" id="fromadult" name="fromadult" value="<?php echo $row ? $row['fromadult'] : '1'; ?>" size="4" onchange="vbMinTotPeople();" style="width: 40px;"/>
461 </div>
462 <div class="vbplusminus-btns">
463 <span class="vbplusminus" onclick="vbPlusMinus('fromadult', 'plus');"><?php VikBookingIcons::e('far fa-plus-square'); ?></span>
464 <span class="vbminus vbplusminus" onclick="vbPlusMinus('fromadult', 'minus');"><?php VikBookingIcons::e('far fa-minus-square'); ?></span>
465 </div>
466 </div>
467 <div class="vbo-param-setting-group">
468 <div class="vbplusminuscont">
469 <span><?php echo JText::translate('VBNEWROOMMAX'); ?></span>
470 <input type="number" min="0" id="toadult" name="toadult" value="<?php echo $row ? $row['toadult'] : '1'; ?>" size="3" onchange="vbMaxTotPeople();" style="width: 40px;"/>
471 </div>
472 <div class="vbplusminus-btns">
473 <span class="vbplusminus" onclick="vbPlusMinus('toadult', 'plus');"><?php VikBookingIcons::e('far fa-plus-square'); ?></span>
474 <span class="vbminus vbplusminus" onclick="vbPlusMinus('toadult', 'minus');"><?php VikBookingIcons::e('far fa-minus-square'); ?></span>
475 </div>
476 </div>
477 </div>
478 </div>
479 <?php
480 if ($writeadultsdiff == true) {
481 ?>
482 <div class="vbo-param-container">
483 <div class="vbo-param-label"><?php echo $vbo_app->createPopover(array('title' => JText::translate('VBNEWROOMADULTSDIFF'), 'content' => JText::translate('VBNEWROOMADULTSDIFFHELP'))); ?> <?php echo JText::translate('VBNEWROOMADULTSDIFF'); ?></div>
484 <div class="vbo-param-setting">
485 <div id="vbadultsdiffsavemess" style="display: none;">
486 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBNEWROOMNOTCHANGENUMMESS'); ?></span>
487 </div>
488 <div id="vbadultsdiffbox" style="display: block;"><?php echo $stradultsdiff; ?></div>
489 </div>
490 </div>
491 <?php
492 } else {
493 ?>
494 <div class="vbo-param-container">
495 <div class="vbo-param-label"><?php echo $vbo_app->createPopover(array('title' => JText::translate('VBNEWROOMADULTSDIFF'), 'content' => JText::translate('VBNEWROOMADULTSDIFFHELP'))); ?> <?php echo JText::translate('VBNEWROOMADULTSDIFF'); ?></div>
496 <div class="vbo-param-setting">
497 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBNEWROOMADULTSDIFFBEFSAVE'); ?></span>
498 </div>
499 </div>
500 <?php
501 }
502 ?>
503 <div class="vbo-param-container">
504 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMCHILDREN'); ?></div>
505 <div class="vbo-param-setting">
506 <div class="vbo-param-setting-group">
507 <div class="vbplusminuscont">
508 <span><?php echo JText::translate('VBNEWROOMMIN'); ?></span>
509 <input type="number" min="0" id="fromchild" name="fromchild" value="<?php echo $row ? $row['fromchild'] : '0'; ?>" size="3" onchange="vbMinTotPeople();" style="width: 40px;"/>
510 </div>
511 <div class="vbplusminus-btns">
512 <span class="vbplusminus" onclick="vbPlusMinus('fromchild', 'plus');"><?php VikBookingIcons::e('far fa-plus-square'); ?></span>
513 <span class="vbminus vbplusminus" onclick="vbPlusMinus('fromchild', 'minus');"><?php VikBookingIcons::e('far fa-minus-square'); ?></span>
514 </div>
515 </div>
516 <div class="vbo-param-setting-group">
517 <div class="vbplusminuscont">
518 <span><?php echo JText::translate('VBNEWROOMMAX'); ?></span>
519 <input type="number" min="0" id="tochild" name="tochild" value="<?php echo $row ? $row['tochild'] : '0'; ?>" size="3" onchange="vbMaxTotPeople();" style="width: 40px;"/>
520 </div>
521 <div class="vbplusminus-btns">
522 <span class="vbplusminus" onclick="vbPlusMinus('tochild', 'plus');"><?php VikBookingIcons::e('far fa-plus-square'); ?></span>
523 <span class="vbminus vbplusminus" onclick="vbPlusMinus('tochild', 'minus');"><?php VikBookingIcons::e('far fa-minus-square'); ?></span>
524 </div>
525 </div>
526 </div>
527 </div>
528 <div class="vbo-param-container">
529 <div class="vbo-param-label"><?php echo JText::translate('VBMAXTOTPEOPLE'); ?></div>
530 <div class="vbo-param-setting">
531 <input type="number" min="1" name="totpeople" id="totpeople" value="<?php echo $row ? $row['totpeople'] : '1'; ?>" size="3" style="width: 40px;"/>
532 <span class="vbo-param-setting-comment-inline"><?php echo JText::translate('VBMAXTOTPEOPLEDESC'); ?></span>
533 </div>
534 </div>
535 <div class="vbo-param-container">
536 <div class="vbo-param-label"><?php echo JText::translate('VBMINTOTPEOPLE'); ?></div>
537 <div class="vbo-param-setting">
538 <input type="number" min="1" name="mintotpeople" id="mintotpeople" value="<?php echo $row ? $row['mintotpeople'] : '1'; ?>" size="3" style="width: 40px;"/>
539 <span class="vbo-param-setting-comment-inline"><?php echo JText::translate('VBMINTOTPEOPLEDESC'); ?></span>
540 </div>
541 </div>
542 </div>
543 </div>
544 </fieldset>
545
546 <fieldset class="adminform">
547 <div class="vbo-params-wrap">
548 <legend class="adminlegend"><?php echo JText::translate('VBOROOMLEGCARATCATOPT'); ?></legend>
549 <div class="vbo-params-container">
550 <?php
551 if (!empty($wcats)) {
552 ?>
553 <div class="vbo-param-container">
554 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMONE'); ?></div>
555 <div class="vbo-param-setting"><?php echo $wcats; ?></div>
556 </div>
557 <?php
558 }
559 if (!empty($wcarats)) {
560 ?>
561 <div class="vbo-param-container">
562 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMTHREE'); ?></div>
563 <div class="vbo-param-setting"><?php echo $wcarats; ?></div>
564 </div>
565 <?php
566 }
567 if (!empty($woptionals)) {
568 ?>
569 <div class="vbo-param-container">
570 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMFOUR'); ?></div>
571 <div class="vbo-param-setting"><?php echo $woptionals; ?></div>
572 </div>
573 <?php
574 }
575 ?>
576 </div>
577 </div>
578 </fieldset>
579
580 <fieldset class="adminform">
581 <div class="vbo-params-wrap">
582 <legend class="adminlegend"><?php echo JText::translate('VBPAYMENTPARAMETERS'); ?></legend>
583 <div class="vbo-params-container">
584 <?php
585 /**
586 * Room details page layout stile.
587 *
588 * @since 1.17.3 (J) - 1.7.3 (WP)
589 */
590 $layout_style = $row ? VikBooking::getRoomParam('layout_style', $row['params'], 'classic') : 'listing';
591 ?>
592 <div class="vbo-param-container">
593 <div class="vbo-param-label"><label for="layout_style"><?php echo JText::translate('COM_VIKBOOKING_LAYOUT_STYLE'); ?></label></div>
594 <div class="vbo-param-setting">
595 <select name="layout_style" id="layout_style">
596 <option value="classic"><?php echo JText::translate('VBOCONFIGSEARCHRESTPLCL'); ?></option>
597 <option value="listing"<?php echo $layout_style == 'listing' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBO_LISTING'); ?></option>
598 </select>
599 </div>
600 </div>
601 <?php
602 $multi_units = $row ? VikBooking::getRoomParam('multi_units', $row['params']) : 0;
603 ?>
604 <div class="vbo-param-container param-multiunits" style="display: <?php echo (count($row) && $row['units'] > 0 ? 'flex' : 'none'); ?>;">
605 <div class="vbo-param-label"><label for="multi_units"><?php echo JText::translate('VBPARAMROOMMULTIUNITS'); ?></label></div>
606 <div class="vbo-param-setting">
607 <select name="multi_units" id="multi_units">
608 <option value="0"><?php echo JText::translate('VBPARAMROOMMULTIUNITSDISABLE'); ?></option>
609 <option value="1"<?php echo intval($multi_units) == 1 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMROOMMULTIUNITSENABLE'); ?></option>
610 </select>
611 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMROOMMULTIUNITSHELP'); ?></span>
612 </div>
613 </div>
614 <div class="vbo-param-container">
615 <div class="vbo-param-label"><label for="lastavail"><?php echo JText::translate('VBPARAMLASTAVAIL'); ?></label></div>
616 <div class="vbo-param-setting">
617 <input type="number" min="0" name="lastavail" id="lastavail" value="<?php echo $row ? (int)VikBooking::getRoomParam('lastavail', $row['params']) : '0'; ?>"/>
618 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMLASTAVAILHELP'); ?></span>
619 </div>
620 </div>
621 <div class="vbo-param-container">
622 <div class="vbo-param-label"><label for="suggocc"><?php echo JText::translate('VBOPARAMSUGGOCC'); ?></label></div>
623 <div class="vbo-param-setting">
624 <input type="number" min="0" name="suggocc" id="suggocc" value="<?php echo $row ? (int)VikBooking::getRoomParam('suggocc', $row['params']) : '1'; ?>"/>
625 </div>
626 </div>
627 <div class="vbo-param-container">
628 <div class="vbo-param-label"><label for="custprice"><?php echo JText::translate('VBPARAMCUSTPRICE'); ?></label></div>
629 <div class="vbo-param-setting">
630 <input type="text" name="custprice" id="custprice" value="<?php echo $row ? JHtml::fetch('esc_attr', VikBooking::getRoomParam('custprice', $row['params'])) : ''; ?>" size="5"/>
631 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMCUSTPRICEHELP'); ?></span>
632 </div>
633 </div>
634 <div class="vbo-param-container">
635 <div class="vbo-param-label"><label for="custpricetxt"><?php echo JText::translate('VBPARAMCUSTPRICETEXT'); ?></label></div>
636 <div class="vbo-param-setting">
637 <input type="text" name="custpricetxt" id="custpricetxt" value="<?php echo $row ? JHtml::fetch('esc_attr', VikBooking::getRoomParam('custpricetxt', $row['params'])) : ''; ?>" size="9"/>
638 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMCUSTPRICETEXTHELP'); ?></span>
639 </div>
640 </div>
641 <div class="vbo-param-container">
642 <div class="vbo-param-label"><label for="custpricesubtxt"><?php echo JText::translate('VBPARAMCUSTPRICESUBTEXT'); ?></label></div>
643 <div class="vbo-param-setting">
644 <input type="text" name="custpricesubtxt" id="custpricesubtxt" value="<?php echo $row ? htmlentities(VikBooking::getRoomParam('custpricesubtxt', $row['params'])) : ''; ?>" size="31"/>
645 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMCUSTPRICESUBTEXTHELP'); ?></span>
646 </div>
647 </div>
648 <div class="vbo-param-container">
649 <div class="vbo-param-label"><label for="reqinfo"><?php echo JText::translate('VBORPARAMREQINFO'); ?></label></div>
650 <div class="vbo-param-setting"><?php echo $vbo_app->printYesNoButtons('reqinfo', JText::translate('VBYES'), JText::translate('VBNO'), (count($row) && intval(VikBooking::getRoomParam('reqinfo', $row['params'])) == 1 ? 1 : 0), 1, 0); ?></div>
651 </div>
652 <?php
653 $paramshowpeople = $row ? VikBooking::getRoomParam('maxminpeople', $row['params']) : '';
654 ?>
655 <div class="vbo-param-container">
656 <div class="vbo-param-label"><label for="maxminpeople"><?php echo JText::translate('VBPARAMSHOWPEOPLE'); ?></label></div>
657 <div class="vbo-param-setting">
658 <select name="maxminpeople" id="maxminpeople">
659 <option value="0"><?php echo JText::translate('VBPARAMSHOWPEOPLENO'); ?></option>
660 <option value="1"<?php echo ($paramshowpeople == "1" ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMSHOWPEOPLEADU'); ?></option>
661 <option value="2"<?php echo ($paramshowpeople == "2" ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMSHOWPEOPLECHI'); ?></option>
662 <option value="3"<?php echo ($paramshowpeople == "3" ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMSHOWPEOPLEADUTOT'); ?></option>
663 <option value="4"<?php echo ($paramshowpeople == "4" ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMSHOWPEOPLECHITOT'); ?></option>
664 <option value="5"<?php echo ($paramshowpeople == "5" ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMSHOWPEOPLEALLTOT'); ?></option>
665 </select>
666 </div>
667 </div>
668 <div class="vbo-param-container">
669 <div class="vbo-param-label"><label for="pricecal"><?php echo JText::translate('VBPARAMPRICECALENDAR'); ?></label></div>
670 <div class="vbo-param-setting">
671 <select name="pricecal" id="pricecal" onchange="togglePriceCalendarParam();">
672 <option value="0"><?php echo JText::translate('VBPARAMPRICECALENDARDISABLED'); ?></option>
673 <option value="1"<?php echo (count($row) && intval(VikBooking::getRoomParam('pricecal', $row['params'])) == 1 ? ' selected="selected"' : ''); ?>><?php echo JText::translate('VBPARAMPRICECALENDARENABLED'); ?></option>
674 </select>
675 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMPRICECALENDARHELP'); ?></span>
676 </div>
677 </div>
678 <div class="vbo-param-container vbo-param-nested" id="defcalcostp" style="display: <?php echo (count($row) && intval(VikBooking::getRoomParam('pricecal', $row['params'])) == 1 ? 'flex' : 'none'); ?>;">
679 <?php
680 /**
681 * The pricing calendar now relies on a default rate plan ID rather than on
682 * a default cost per night in order to have a better accuracy on the result.
683 *
684 * @since 1.16.3 (J) - 1.6.3 (WP)
685 */
686 $room_rate_plans = $row ? VBORoomHelper::getInstance($row)->getRatePlans() : [];
687 if ($row && $room_rate_plans) {
688 $def_rplan_id = VikBooking::getRoomParam('defrplan', $row['params']);
689 ?>
690 <div class="vbo-param-label"><label for="defrplan"><?php echo JText::translate('VBOROVWSELRPLAN'); ?></label></div>
691 <div class="vbo-param-setting">
692 <select name="defrplan" id="defrplan">
693 <?php
694 foreach ($room_rate_plans as $rplan) {
695 ?>
696 <option value="<?php echo $rplan['id']; ?>"<?php echo $def_rplan_id == $rplan['id'] ? ' selected="selected"' : ''; ?>><?php echo $rplan['name']; ?></option>
697 <?php
698 }
699 ?>
700 </select>
701 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMDEFCALCOSTHELP'); ?></span>
702 </div>
703 <?php
704 } else {
705 // default to the old calendar default (custom) cost
706 ?>
707 <div class="vbo-param-label"><label for="defcalcost"><?php echo JText::translate('VBPARAMDEFCALCOST'); ?></label></div>
708 <div class="vbo-param-setting">
709 <input type="number" min="0" step="any" name="defcalcost" id="defcalcost" value="<?php echo $row ? VikBooking::getRoomParam('defcalcost', $row['params']) : ''; ?>" placeholder="50.00"/>
710 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMDEFCALCOSTHELP'); ?></span>
711 </div>
712 <?php
713 }
714 ?>
715 </div>
716 <?php
717 $season_cal = $row ? VikBooking::getRoomParam('seasoncal', $row['params']) : 0;
718 $season_cal_prices = $row ? VikBooking::getRoomParam('seasoncal_prices', $row['params']) : 0;
719 $season_cal_restr = $row ? VikBooking::getRoomParam('seasoncal_restr', $row['params']) : 0;
720 ?>
721 <div class="vbo-param-container param-seasoncal">
722 <div class="vbo-param-label"><label for="seasoncal"><?php echo JText::translate('VBPARAMSEASONCALENDAR'); ?></label></div>
723 <div class="vbo-param-setting">
724 <select name="seasoncal" id="seasoncal" onchange="toggleSeasonalCalendarParam();">
725 <option value="0"><?php echo JText::translate('VBPARAMSEASONCALENDARDISABLED'); ?></option>
726 <optgroup label="<?php echo JText::translate('VBPARAMSEASONCALENDARENABLED'); ?>">
727 <option value="1"<?php echo intval($season_cal) == 1 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMSEASONCALENDARENABLEDALL'); ?></option>
728 <option value="2"<?php echo intval($season_cal) == 2 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMSEASONCALENDARENABLEDCHARGEDISC'); ?></option>
729 <option value="3"<?php echo intval($season_cal) == 3 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMSEASONCALENDARENABLEDCHARGE'); ?></option>
730 </optgroup>
731 </select>
732 </div>
733 </div>
734 <div class="vbo-param-container vbo-param-nested param-seasoncal" style="display: <?php echo (intval($season_cal) > 0 ? 'flex' : 'none'); ?>;">
735 <div class="vbo-param-label"><label for="seasoncal_nights"><?php echo JText::translate('VBPARAMSEASONCALNIGHTS'); ?></label></div>
736 <div class="vbo-param-setting">
737 <input type="text" name="seasoncal_nights" id="seasoncal_nights" size="10" value="<?php echo $row ? JHtml::fetch('esc_attr', VikBooking::getRoomParam('seasoncal_nights', $row['params'])) : ''; ?>" placeholder="1, 3, 7, 14"/>
738 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBPARAMSEASONCALNIGHTSHELP'); ?></span>
739 </div>
740 </div>
741 <div class="vbo-param-container vbo-param-nested param-seasoncal" style="display: <?php echo (intval($season_cal) > 0 ? 'flex' : 'none'); ?>;">
742 <div class="vbo-param-label"><label for="seasoncal_prices"><?php echo JText::translate('VBPARAMSEASONCALENDARPRICES'); ?></label></div>
743 <div class="vbo-param-setting">
744 <select name="seasoncal_prices" id="seasoncal_prices">
745 <option value="0"><?php echo JText::translate('VBPARAMSEASONCALENDARPRICESANY'); ?></option>
746 <option value="1"<?php echo intval($season_cal_prices) == 1 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMSEASONCALENDARPRICESLOW'); ?></option>
747 </select>
748 </div>
749 </div>
750 <div class="vbo-param-container vbo-param-nested param-seasoncal" style="display: <?php echo (intval($season_cal) > 0 ? 'flex' : 'none'); ?>;">
751 <div class="vbo-param-label"><label for="seasoncal_restr"><?php echo JText::translate('VBPARAMSEASONCALENDARLOS'); ?></label></div>
752 <div class="vbo-param-setting">
753 <select name="seasoncal_restr" id="seasoncal_restr">
754 <option value="0"><?php echo JText::translate('VBPARAMSEASONCALENDARLOSHIDE'); ?></option>
755 <option value="1"<?php echo intval($season_cal_restr) == 1 ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMSEASONCALENDARLOSSHOW'); ?></option>
756 </select>
757 </div>
758 </div>
759
760 <?php
761 /**
762 * Minimum advance booking offset (hours) can be defined at room-level.
763 *
764 * @since 1.18.3 (J) - 1.8.3 (WP)
765 */
766 if ($row) {
767 // only in edit mode, not when creating a new room
768 $room_level_min_adv_notice = VBOFactory::getConfig()->get("room_{$row['id']}_min_adv_notice", null);
769 $room_level_min_adv_notice = $room_level_min_adv_notice === '' ? null : $room_level_min_adv_notice;
770 // build default or current value (always an integer expressed in hours, or null)
771 $mindate_val = is_null($room_level_min_adv_notice) ? null : (int) $room_level_min_adv_notice;
772 ?>
773 <div class="vbo-param-container">
774 <div class="vbo-param-label"><?php echo JText::translate('VBO_MIN_ADV_BOOK_NOTICE'); ?></div>
775 <div class="vbo-param-setting">
776 <div class="vbo-toggle-small">
777 <?php
778 echo $vbo_app->printYesNoButtons('min_adv_notice_room', JText::translate('VBYES'), JText::translate('VBNO'), (is_null($mindate_val) ? 0 : 1), 1, 0, 'vboToggleMinAdvNotice(this.checked);');
779 ?>
780 </div>
781 <div class="vbo-room-level-min_adv-notice" style="<?php echo is_null($mindate_val) ? 'display: none;' : ''; ?>">
782 <input type="number" name="mindate" value="<?php echo $mindate_val; ?>" min="0"/>
783 <select name="mindateinterval">
784 <option value="h"><?php echo ucfirst(JText::translate('VBCONFIGONETENEIGHT')); ?></option>
785 </select>
786 </div>
787 </div>
788 </div>
789 <?php
790 }
791
792 /**
793 * Maximum advance booking offset can be defined at room-level.
794 *
795 * @since 1.16.3 (J) - 1.6.3 (WP)
796 */
797 if ($row) {
798 // only in edit mode, not when creating a new room
799 $room_level_max_adv_notice = VBOFactory::getConfig()->get("room_{$row['id']}_max_adv_notice");
800 // build default or current values
801 $maxdate_val = 0;
802 $maxdate_interval = 'y';
803 if (!empty($room_level_max_adv_notice)) {
804 $maxdatefuture = $room_level_max_adv_notice;
805 $maxdate_val = intval(substr($maxdatefuture, 1, (strlen($maxdatefuture) - 1)));
806 $maxdate_interval = substr($maxdatefuture, -1, 1);
807 }
808 ?>
809 <div class="vbo-param-container">
810 <div class="vbo-param-label"><?php echo JText::translate('VBO_MAX_ADV_BOOK_NOTICE'); ?></div>
811 <div class="vbo-param-setting">
812 <div class="vbo-toggle-small">
813 <?php
814 echo $vbo_app->printYesNoButtons('max_adv_notice_room', JText::translate('VBYES'), JText::translate('VBNO'), (empty($room_level_max_adv_notice) || empty($maxdate_val) ? 0 : 1), 1, 0, 'vboToggleMaxAdvNotice(this.checked);');
815 ?>
816 </div>
817 <div class="vbo-room-level-max_adv-notice" style="<?php echo empty($room_level_max_adv_notice) || empty($maxdate_val) ? 'display: none;' : ''; ?>">
818 <input type="number" name="maxdate" value="<?php echo $maxdate_val; ?>" min="0"/>
819 <select name="maxdateinterval">
820 <option value="d"<?php echo $maxdate_interval == 'd' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBCONFIGSEARCHPMAXDATEDAYS'); ?></option>
821 <option value="w"<?php echo $maxdate_interval == 'w' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBCONFIGSEARCHPMAXDATEWEEKS'); ?></option>
822 <option value="m"<?php echo $maxdate_interval == 'm' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBCONFIGSEARCHPMAXDATEMONTHS'); ?></option>
823 <option value="y"<?php echo $maxdate_interval == 'y' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBCONFIGSEARCHPMAXDATEYEARS'); ?></option>
824 </select>
825 </div>
826 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBO_MAX_ADV_BOOK_NOTICE_HELP'); ?></span>
827 </div>
828 </div>
829 <?php
830 }
831
832 /**
833 * Custom check-in and check-out times defined at listing-level.
834 *
835 * @since 1.18.3 (J) - 1.8.3 (WP)
836 */
837 $listing_checkin = $row ? VikBooking::getRoomParam('checkin', $row['params']) : '';
838 $listing_checkout = $row ? VikBooking::getRoomParam('checkout', $row['params']) : '';
839 ?>
840 <div class="vbo-param-container">
841 <div class="vbo-param-label"><label for="listing_checkin"><?php echo JText::translate('VBCONFIGONESEVEN'); ?></label></div>
842 <div class="vbo-param-setting">
843 <select name="listing_checkin" id="listing_checkin">
844 <option value=""><?php echo JText::translate('VBO_USE_DEFAULT'); ?></option>
845 <optgroup label="<?php echo JText::translate('VBO_CUSTOM'); ?>">
846 <?php
847 for ($h = 0; $h < 24; $h++) {
848 for ($m = 0; $m < 60; $m += 15) {
849 $display_h = ($h < 10 ? '0' : '') . $h;
850 $display_m = ($m < 10 ? '0' : '') . $m;
851 $display_time = $display_h . ':' . $display_m;
852 ?>
853 <option value="<?php echo $display_time; ?>"<?php echo $display_time == $listing_checkin ? ' selected="selected"' : ''; ?>><?php echo $display_time; ?></option>
854 <?php
855 }
856 }
857 ?>
858 </optgroup>
859 </select>
860 </div>
861 </div>
862 <div class="vbo-param-container">
863 <div class="vbo-param-label"><label for="listing_checkout"><?php echo JText::translate('VBCONFIGONETHREE'); ?></label></div>
864 <div class="vbo-param-setting">
865 <select name="listing_checkout" id="listing_checkout">
866 <option value=""><?php echo JText::translate('VBO_USE_DEFAULT'); ?></option>
867 <optgroup label="<?php echo JText::translate('VBO_CUSTOM'); ?>">
868 <?php
869 for ($h = 0; $h < 24; $h++) {
870 for ($m = 0; $m < 60; $m += 15) {
871 $display_h = ($h < 10 ? '0' : '') . $h;
872 $display_m = ($m < 10 ? '0' : '') . $m;
873 $display_time = $display_h . ':' . $display_m;
874 ?>
875 <option value="<?php echo $display_time; ?>"<?php echo $display_time == $listing_checkout ? ' selected="selected"' : ''; ?>><?php echo $display_time; ?></option>
876 <?php
877 }
878 }
879 ?>
880 </optgroup>
881 </select>
882 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBO_TURNOVER_TIME_WARNING'); ?></span>
883 </div>
884 </div>
885
886 <?php
887 /**
888 * Room-level check-in instructions.
889 *
890 * @since 1.18.12 (J) - 1.8.12 (WP)
891 */
892 $instructions = $row ? VikBooking::getRoomParam('instructions', $row['params']) : '';
893 ?>
894 <div class="vbo-param-container">
895 <div class="vbo-param-label"><label for="listing_instructions"><?php echo JText::translate('VBO_CHECKIN_INSTRUCTIONS'); ?></label></div>
896 <div class="vbo-param-setting">
897 <textarea id="listing_instructions" name="listing_instructions" rows="5"><?php echo JHtml::fetch('esc_textarea', $instructions); ?></textarea>
898 <span class="vbo-param-setting-comment"><?php echo JText::translate('VBO_CHECKIN_INSTRUCTIONS_HELP'); ?></span>
899 </div>
900 </div>
901 </div>
902 </div>
903 </fieldset>
904
905 </div>
906
907 <div class="vbo-config-maintab-right">
908 <fieldset class="adminform">
909 <div class="vbo-params-wrap">
910 <legend class="adminlegend"><?php echo JText::translate('VBOROOMLEGPHOTODESC'); ?></legend>
911 <div class="vbo-params-container">
912 <div class="vbo-param-container">
913 <div class="vbo-param-label"><?php echo JText::translate('VBNEWROOMSIX'); ?></div>
914 <div class="vbo-param-setting">
915 <div class="vbo-param-setting-block">
916 <?php echo (count($row) && !empty($row['img']) && file_exists(VBO_SITE_PATH.DIRECTORY_SEPARATOR.'resources'.DIRECTORY_SEPARATOR.'uploads'.DIRECTORY_SEPARATOR.$row['img']) ? '<a href="'.VBO_SITE_URI.'resources/uploads/'.$row['img'].'" class="vbomodal vbo-room-img-modal" target="_blank"><i class="' . VikBookingIcons::i('image') . '"></i> ' . $row['img'] . '</a>' : ""); ?>
917 <input type="file" name="cimg" size="35"/>
918 </div>
919 <div class="vbo-param-setting-block">
920 <span class="vbo-resize-lb-cont">
921 <label style="display: inline;" for="autoresize"><?php echo JText::translate('VBNEWOPTNINE'); ?></label>
922 <input type="checkbox" id="autoresize" name="autoresize" value="1" onclick="showResizeSel();"/>
923 </span>
924 <span id="resizesel" style="display: none;"><span><?php echo JText::translate('VBNEWOPTTEN'); ?></span><input type="number" name="resizeto" value="250" min="0" class="vbo-medium-input"/> px</span>
925 </div>
926 </div>
927 </div>
928 <?php
929 if (count($row)) {
930 ?>
931 <div class="vbo-param-container">
932 <div class="vbo-param-label">
933 <div class="vbo-param-label-top">
934 <span><?php echo JText::translate('VBMOREIMAGES'); ?></span>
935 <a href="javascript: void(0);" onclick="addMoreImages();" class="btn vbo-config-btn">
936 <?php VikBookingIcons::e('plus-circle'); ?>
937 <?php echo JText::translate('VBADDIMAGES'); ?>
938 </a>
939 </div>
940 <div class="vbo-bulkupload-cont">
941 <div class="vbo-bulkupload-inner">
942 <a href="javascript: void(0);" onclick="showBulkUpload();" class="btn vbo-config-btn">
943 <i class="icon-image" style="float: none;"></i><?php echo JText::translate('VBOBULKUPLOAD'); ?>
944 </a>
945 </div>
946 </div>
947 </div>
948 <div class="vbo-param-setting">
949 <div class="vbo-editroom-currentphotos">
950 <ul class="vbo-sortable"><?php echo $actmoreimgs; ?></ul>
951 </div>
952 <div class="vbo-rmphotos-cont">
953 <a class="btn btn-danger" href="index.php?option=com_vikbooking&amp;task=removemoreimgs&amp;roomid=<?php echo $row['id']; ?>&amp;imgind=-1" onclick="return confirm('<?php echo addslashes(JText::translate('VBORMALLPHOTOS')); ?>?');">
954 <i class="icon-cancel"></i><?php echo JText::translate('VBORMALLPHOTOS'); ?>
955 </a>
956 </div>
957 <div class="vbo-first-imgup">
958 <input type="file" name="cimgmore[]" size="35"/>
959 <div class="vbo-imgup-caption">
960 <span><?php echo JText::translate('VBIMGCAPTION'); ?></span>
961 <input type="text" name="cimgcaption[]" size="30" value=""/>
962 </div>
963 </div>
964 <div id="myDiv" style="display: block;"></div>
965 <div class="vbo-param-setting-block">
966 <span class="vbo-resize-lb-cont">
967 <label style="display: inline;" for="autoresizemore"><?php echo JText::translate('VBRESIZEIMAGES'); ?></label>
968 <input type="checkbox" id="autoresizemore" name="autoresizemore" value="1" onclick="showResizeSelMore();"/>
969 </span>
970 <span id="resizeselmore" style="display: none;"><span><?php echo JText::translate('VBNEWOPTTEN'); ?></span><input type="number" name="resizetomore" value="600" min="0" class="vbo-medium-input"/> px</span>
971 </div>
972 </div>
973 </div>
974 <?php
975 } else {
976 ?>
977 <div class="vbo-param-container">
978 <div class="vbo-param-label">
979 <div class="vbo-param-label-top">
980 <span><?php echo JText::translate('VBMOREIMAGES'); ?></span>
981 <a class="btn vbo-config-btn" href="javascript: void(0);" onclick="addMoreImages();">
982 <?php VikBookingIcons::e('plus-circle'); ?> <?php echo JText::translate('VBADDIMAGES'); ?>
983 </a>
984 </div>
985 <p class="vbo-small-p-info"><?php echo JText::translate('VBOBULKUPLOADAFTERSAVE'); ?></p>
986 </div>
987 <div class="vbo-param-setting">
988 <div class="vbo-first-imgup">
989 <input type="file" name="cimgmore[]" size="35"/>
990 <div class="vbo-imgup-caption">
991 <span><?php echo JText::translate('VBIMGCAPTION'); ?></span>
992 <input type="text" name="cimgcaption[]" size="30" value=""/>
993 </div>
994 </div>
995 <div id="myDiv" style="display: block;"></div>
996 <div class="vbo-param-setting-block">
997 <label style="display: inline;" for="autoresizemore"><?php echo JText::translate('VBRESIZEIMAGES'); ?></label>
998 <input type="checkbox" id="autoresizemore" name="autoresizemore" value="1" onclick="showResizeSelMore();"/>
999 <span id="resizeselmore" style="display: none;"><span><?php echo JText::translate('VBNEWOPTTEN'); ?></span><input type="text" name="resizetomore" value="600" size="3"/> px</span>
1000 </div>
1001 </div>
1002 </div>
1003 <?php
1004 }
1005 ?>
1006 <div class="vbo-param-container">
1007 <div class="vbo-param-label with-buttons">
1008 <span class="vbo-param-label-main"><?php echo JText::translate('VBNEWROOMSMALLDESC'); ?></span>
1009 <?php
1010 if ($has_vcm) {
1011 // Gen-AI small description
1012 ?>
1013 <div class="vbo-room-genai-btn-wrap">
1014 <button type="button" class="btn btn-small vbo-content-genai vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', JText::translate('VBO_GEN_CONTENT')); ?>" data-type="short"><?php echo JText::translate('VBO_AI_LABEL_DEF'); ?></button>
1015 </div>
1016 <?php
1017 }
1018 ?>
1019 </div>
1020 <div class="vbo-param-setting"><textarea name="smalldesc" rows="6" cols="50"><?php echo $row ? $row['smalldesc'] : ''; ?></textarea></div>
1021 </div>
1022 <div class="vbo-param-container vbo-param-container-full">
1023 <div class="vbo-param-label with-buttons">
1024 <span class="vbo-param-label-main"><?php echo JText::translate('VBNEWROOMSEVEN'); ?></span>
1025 <?php
1026 if ($has_vcm) {
1027 // Gen-AI small description
1028 ?>
1029 <span class="vbo-room-genai-btn-wrap inline">
1030 <button type="button" class="btn btn-small vbo-content-genai vbo-tooltip vbo-tooltip-top" data-tooltiptext="<?php echo JHtml::fetch('esc_attr', JText::translate('VBO_GEN_CONTENT')); ?>" data-type="long"><?php echo JText::translate('VBO_AI_LABEL_DEF'); ?></button>
1031 </span>
1032 <?php
1033 }
1034 ?>
1035 </div>
1036 <div class="vbo-param-setting">
1037 <?php
1038 if (interface_exists('Throwable')) {
1039 /**
1040 * With PHP >= 7 supporting throwable exceptions for Fatal Errors
1041 * we try to avoid issues with third party plugins that make use
1042 * of the WP native function get_current_screen().
1043 *
1044 * @wponly
1045 */
1046 try {
1047 echo $editor->display( "cdescr", ($row ? $row['info'] : ""), '100%', 300, 70, 20 );
1048 } catch (Throwable $t) {
1049 echo $t->getMessage() . ' in ' . $t->getFile() . ':' . $t->getLine() . '<br/>';
1050 }
1051 } else {
1052 // we cannot catch Fatal Errors in PHP 5.x
1053 echo $editor->display( "cdescr", ($row ? $row['info'] : ""), '100%', 300, 70, 20 );
1054 }
1055 ?>
1056 </div>
1057 </div>
1058 </div>
1059 </div>
1060 </fieldset>
1061
1062 <?php
1063 if (count($this->rooms_map)) {
1064 ?>
1065 <fieldset class="adminform">
1066 <div class="vbo-params-wrap">
1067 <legend class="adminlegend"><?php VikBookingIcons::e('calendar'); ?> <?php echo JText::translate('VBOROOMCALXREFSETTINGS'); ?></legend>
1068 <div class="vbo-params-container">
1069 <div class="vbo-param-container">
1070 <div class="vbo-param-label"><?php echo $vbo_app->createPopover(array('title' => JText::translate('VBOROOMSHARECALENDAR') . '...', 'content' => JText::translate('VBOROOMSHARECALENDARHELP'))); ?> <?php echo JText::translate('VBOROOMSHARECALENDAR'); ?></div>
1071 <div class="vbo-param-setting">
1072 <select name="share_with[]" multiple="multiple" size="7" id="share_with_sel">
1073 <?php
1074 foreach ($this->rooms_map as $k => $v) {
1075 ?>
1076 <option value="<?php echo $k; ?>"<?php echo in_array($k, $this->cal_xref['shared_with']) ? ' selected="selected"' : ''; ?>><?php echo $v; ?></option>
1077 <?php
1078 }
1079 ?>
1080 </select>
1081 </div>
1082 </div>
1083 <?php
1084 if (count($this->cal_xref['shared_by'])) {
1085 ?>
1086 <div class="vbo-param-container">
1087 <div class="vbo-param-label"><?php echo JText::translate('VBOROOMCALENDARSHAREDBY'); ?></div>
1088 <div class="vbo-param-setting">
1089 <div class="vbo-room-calxref-sharedby">
1090 <?php
1091 foreach ($this->cal_xref['shared_by'] as $v) {
1092 if (!isset($this->rooms_map[$v])) {
1093 continue;
1094 }
1095 ?>
1096 <a href="index.php?option=com_vikbooking&task=editroom&cid[]=<?php echo $v; ?>" target="_blank"><?php VikBookingIcons::e('calendar'); ?> <?php echo $this->rooms_map[$v]; ?></a>
1097 <?php
1098 }
1099 ?>
1100 </div>
1101 </div>
1102 </div>
1103 <?php
1104 }
1105 ?>
1106 </div>
1107 </div>
1108 </fieldset>
1109 <?php
1110 }
1111
1112 /**
1113 * Room's Geocoding information.
1114 *
1115 * @since 1.14 (J) - 1.4.0 (WP)
1116 */
1117 echo $this->loadTemplate('geocoding_info');
1118
1119 /**
1120 * Room upgrade relations.
1121 *
1122 * @since 1.16.0 (J) - 1.6.0 (WP)
1123 */
1124 if (count($this->rooms_map)) {
1125 $room_upgrade_options = $row ? VBOFactory::getConfig()->getArray('room_upgrade_options_' . $row['id'], []) : [];
1126 $room_upgrade_options['rooms'] = !empty($room_upgrade_options['rooms']) ? $room_upgrade_options['rooms'] : [];
1127 $room_upgrade_enabled = count($room_upgrade_options['rooms']) ? 1 : 0;
1128 ?>
1129 <fieldset class="adminform">
1130 <div class="vbo-params-wrap">
1131 <legend class="adminlegend"><?php VikBookingIcons::e('gem'); ?> <?php echo JText::translate('VBO_ROOM_UPGRADE'); ?></legend>
1132 <div class="vbo-params-container">
1133 <div class="vbo-param-container">
1134 <div class="vbo-param-label"><?php echo $vbo_app->createPopover(array('title' => JText::translate('VBO_ROOM_UPGRADE'), 'content' => JText::translate('VBO_ROOM_UPGRADE_HELP'))); ?> <?php echo JText::translate('VBPARAMPRICECALENDARENABLED'); ?></div>
1135 <div class="vbo-param-setting">
1136 <?php
1137 echo $vbo_app->printYesNoButtons('room_upgrade', JText::translate('VBYES'), JText::translate('VBNO'), $room_upgrade_enabled, 1, 0, 'vboToggleRoomUpgrade();');
1138 ?>
1139 </div>
1140 </div>
1141 </div>
1142 <div class="vbo-params-container vbo-roomupgrade-param" style="<?php echo !$room_upgrade_enabled ? 'display: none;' : ''; ?>">
1143 <div class="vbo-param-container">
1144 <div class="vbo-param-label"><?php echo JText::translate('VBO_ELIGIBLE_ROOMS'); ?></div>
1145 <div class="vbo-param-setting">
1146 <select name="upgrade_rooms[]" id="upgrade-rooms" multiple="multiple">
1147 <?php
1148 foreach ($this->rooms_map as $rid => $rname) {
1149 ?>
1150 <option value="<?php echo $rid; ?>"<?php echo in_array($rid, $room_upgrade_options['rooms']) ? ' selected="selected"' : ''; ?>><?php echo $rname; ?></option>
1151 <?php
1152 }
1153 ?>
1154 </select>
1155 </div>
1156 </div>
1157 </div>
1158 <div class="vbo-params-container vbo-roomupgrade-param" style="<?php echo !$room_upgrade_enabled ? 'display: none;' : ''; ?>">
1159 <div class="vbo-param-container">
1160 <div class="vbo-param-label"><?php echo JText::translate('VBAPPLYDISCOUNT'); ?></div>
1161 <div class="vbo-param-setting">
1162 <div class="input-append">
1163 <input type="number" name="upgrade_discount" value="<?php echo isset($room_upgrade_options['discount']) ? (float)$room_upgrade_options['discount'] : 0; ?>" min="0" max="100" step="any" />
1164 <button type="button" class="btn" disabled>%</button>
1165 </div>
1166 </div>
1167 </div>
1168 </div>
1169 </div>
1170 </fieldset>
1171 <?php
1172 }
1173 ?>
1174
1175 <fieldset class="adminform">
1176 <div class="vbo-params-wrap">
1177 <legend class="adminlegend"><?php echo JText::translate('VBOADMINLEGENDSETTINGS'); ?></legend>
1178 <div class="vbo-params-container">
1179 <?php
1180 $custptitle = $row ? VikBooking::getRoomParam('custptitle', $row['params']) : '';
1181 $custptitlew = $row ? VikBooking::getRoomParam('custptitlew', $row['params']) : '';
1182 $metakeywords = $row ? VikBooking::getRoomParam('metakeywords', $row['params']) : '';
1183 $metadescription = $row ? VikBooking::getRoomParam('metadescription', $row['params']) : '';
1184 if (VBOPlatformDetection::isJoomla()) {
1185 /**
1186 * @joomlaonly room SEF alias
1187 */
1188 ?>
1189 <div class="vbo-param-container">
1190 <div class="vbo-param-label"><label for="sefalias"><?php echo JText::translate('VBROOMSEFALIAS'); ?></label></div>
1191 <div class="vbo-param-setting">
1192 <input type="text" id="sefalias" name="sefalias" value="<?php echo $row ? JHtml::fetch('esc_attr', $row['alias']) : ''; ?>" placeholder="double-room-superior"/>
1193 </div>
1194 </div>
1195 <?php
1196 }
1197 ?>
1198 <div class="vbo-param-container">
1199 <div class="vbo-param-label"><label for="custptitle"><?php echo JText::translate('VBPARAMPAGETITLE'); ?></label></div>
1200 <div class="vbo-param-setting">
1201 <input type="text" id="custptitle" name="custptitle" value="<?php echo JHtml::fetch('esc_attr', $custptitle); ?>"/>
1202 </div>
1203 </div>
1204 <div class="vbo-param-container vbo-param-child">
1205 <div class="vbo-param-label"></div>
1206 <div class="vbo-param-setting">
1207 <select name="custptitlew">
1208 <option value="before"<?php echo $custptitlew == 'before' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMPAGETITLEBEFORECUR'); ?></option>
1209 <option value="after"<?php echo $custptitlew == 'after' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMPAGETITLEAFTERCUR'); ?></option>
1210 <option value="replace"<?php echo $custptitlew == 'replace' ? ' selected="selected"' : ''; ?>><?php echo JText::translate('VBPARAMPAGETITLEREPLACECUR'); ?></option>
1211 </select>
1212 </div>
1213 </div>
1214 <div class="vbo-param-container">
1215 <div class="vbo-param-label"><label for="metakeywords"><?php echo JText::translate('VBPARAMKEYWORDSMETATAG'); ?></label></div>
1216 <div class="vbo-param-setting">
1217 <textarea name="metakeywords" id="metakeywords" rows="3" cols="40"><?php echo $metakeywords; ?></textarea>
1218 </div>
1219 </div>
1220 <div class="vbo-param-container">
1221 <div class="vbo-param-label"><label for="metadescription"><?php echo JText::translate('VBPARAMDESCRIPTIONMETATAG'); ?></label></div>
1222 <div class="vbo-param-setting">
1223 <textarea name="metadescription" id="metadescription" rows="4" cols="40"><?php echo $metadescription; ?></textarea>
1224 </div>
1225 </div>
1226 </div>
1227 </div>
1228 </fieldset>
1229
1230 </div>
1231 </div>
1232
1233 <input type="hidden" name="task" value="">
1234 <?php
1235 if (count($row)) {
1236 ?>
1237 <input type="hidden" name="whereup" value="<?php echo $row['id']; ?>">
1238 <input type="hidden" name="actmoreimgs" id="actmoreimgs" value="<?php echo $row['moreimgs']; ?>">
1239 <?php
1240 }
1241 ?>
1242 <input type="hidden" name="option" value="com_vikbooking">
1243 <?php echo JHtml::fetch('form.token'); ?>
1244 </form>
1245
1246 <?php
1247 /**
1248 * Room's Geocoding information - modal.
1249 *
1250 * @since 1.14 (J) - 1.4.0 (WP)
1251 */
1252 echo $this->loadTemplate('geocoding_modal');
1253 ?>
1254
1255 <div class="vbo-info-overlay-block">
1256 <a class="vbo-info-overlay-close" href="javascript: void(0);"></a>
1257 <div class="vbo-info-overlay-content">
1258 <!-- The fileinput-button span is used to style the file input field as button -->
1259 <span class="btn vbo-config-btn fileinput-button">
1260 <?php VikBookingIcons::e('plus-circle'); ?>
1261 <span><?php echo JText::translate('VBOSELORDRAGFILES'); ?></span>
1262 <!-- The file input field used as target for the file upload widget -->
1263 <input id="fileupload" type="file" name="bulkphotos[]" multiple>
1264 </span>
1265 <!-- The global progress bar -->
1266 <div id="progress" class="progress">
1267 <div class="progress-bar"></div>
1268 </div>
1269 <!-- The container for the uploaded files -->
1270 <div id="files" class="files"></div>
1271 <div class="vbo-upload-done">
1272 <button type="button" class="btn btn-success" onclick="vboCloseModal();"><i class="icon-save"></i><?php echo JText::translate('VBOUPLOADFILEDONE'); ?></button>
1273 </div>
1274 </div>
1275 </div>
1276
1277 <?php
1278 /**
1279 * Render the Gen-AI content layout.
1280 *
1281 * @since 1.17.3 (J) - 1.7.3 (WP)
1282 */
1283 $layout_data = [
1284 'type' => 'room_content',
1285 'prefix' => 'vbo-content-genai',
1286 'room' => $this->row,
1287 ];
1288 echo JLayoutHelper::render('ai.gencontent', $layout_data);
1289
1290 // the Load Image plugin is included for the preview images and image resizing functionality
1291 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/load-image.all.min.js');
1292 // the Iframe Transport is required for browsers without support for XHR file uploads
1293 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/jquery.iframe-transport.js');
1294 // the basic File Upload plugin
1295 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/jquery.fileupload.js');
1296 // the File Upload processing plugin
1297 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/jquery.fileupload-process.js');
1298 // the File Upload image preview & resize plugin
1299 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/jquery.fileupload-image.js');
1300 // the File Upload validation plugin
1301 $vbo_app->addScript(VBO_ADMIN_URI . 'resources/js_upload/jquery.fileupload-validate.js');
1302 ?>
1303
1304 <script type="text/javascript">
1305 var vbo_overlay_on = false;
1306 function showBulkUpload() {
1307 jQuery(".vbo-info-overlay-block").fadeIn();
1308 vbo_overlay_on = true;
1309 }
1310 function vboCloseModal() {
1311 jQuery(".vbo-info-overlay-block").fadeOut(400, function() {
1312 jQuery(this).attr("class", "vbo-info-overlay-block");
1313 });
1314 vbo_overlay_on = false;
1315 }
1316 jQuery(function() {
1317 togglePriceCalendarParam();
1318 toggleSeasonalCalendarParam();
1319
1320 jQuery(document).mouseup(function(e) {
1321 if (!vbo_overlay_on) {
1322 return;
1323 }
1324 var vbo_overlay_cont = jQuery(".vbo-info-overlay-content");
1325 if (!vbo_overlay_cont.is(e.target) && vbo_overlay_cont.has(e.target).length === 0) {
1326 vboCloseModal();
1327 }
1328 });
1329
1330 jQuery(document).keyup(function(e) {
1331 if (e.keyCode == 27) {
1332 if (vbo_overlay_on) {
1333 vboCloseModal();
1334 }
1335 if (vbo_details_on) {
1336 vbo_details_on = false;
1337 jQuery('.vbimagedetbox').hide();
1338 }
1339 }
1340 });
1341
1342 var url = 'index.php?option=com_vikbooking&task=multiphotosupload&roomid=<?php echo $row ? $row['id'] : '0'; ?>',
1343 uploadButton = jQuery('<button/>')
1344 .addClass('btn btn-primary')
1345 .prop('disabled', true)
1346 .text('Processing...')
1347 .on('click', function () {
1348 var $this = jQuery(this),
1349 data = $this.data();
1350 $this
1351 .off('click')
1352 .text('Abort')
1353 .on('click', function () {
1354 $this.remove();
1355 data.abort();
1356 });
1357 data.submit().always(function () {
1358 $this.remove();
1359 });
1360 });
1361
1362 jQuery('#fileupload').fileupload({
1363 url: url,
1364 dataType: 'json',
1365 autoUpload: true,
1366 acceptFileTypes: /(\.|\/)(gif|jpe?g|png|webp)$/i,
1367 maxFileSize: 999000,
1368 disableImageResize: true,
1369 previewMaxWidth: 100,
1370 previewMaxHeight: 100,
1371 previewCrop: true
1372 }).on('fileuploadadd', function (e, data) {
1373 data.context = jQuery('<div/>').addClass('vbo-upload-photo').appendTo('#files');
1374 jQuery.each(data.files, function (index, file) {
1375 var node = jQuery('<p/>')
1376 .append(jQuery('<span/>').text(file.name));
1377 if (!index) {
1378 node.append(uploadButton.clone(true).data(data));
1379 }
1380 node.appendTo(data.context);
1381 });
1382 }).on('fileuploadprocessalways', function (e, data) {
1383 var index = data.index,
1384 file = data.files[index],
1385 node = jQuery(data.context.children()[index]);
1386 if (file.preview) {
1387 node.prepend(file.preview);
1388 }
1389 if (file.error) {
1390 node.append(jQuery('<span class="text-danger"/>').text(file.error));
1391 }
1392 if (index + 1 === data.files.length) {
1393 data.context.find('button')
1394 .text('Upload')
1395 .prop('disabled', !!data.files.error);
1396 }
1397 }).on('fileuploadprogressall', function (e, data) {
1398 var progress = parseInt(data.loaded / data.total * 100, 10);
1399 jQuery('#progress .progress-bar').css(
1400 'width',
1401 progress + '%'
1402 );
1403 if (progress > 99) {
1404 jQuery('#progress .progress-bar').addClass("progress-bar-success");
1405 } else {
1406 if (jQuery('#progress .progress-bar').hasClass("progress-bar-success")){
1407 jQuery('#progress .progress-bar').removeClass("progress-bar-success");
1408 }
1409 }
1410 }).on('fileuploaddone', function (e, data) {
1411 jQuery.each(data.result.files, function (index, file) {
1412 if (file.url) {
1413 var link = jQuery('<a>')
1414 .attr('target', '_blank')
1415 .attr('class', 'vbomodal')
1416 .prop('href', file.url);
1417 jQuery(data.context.children()[index])
1418 .wrap(link);
1419 data.context.find('button')
1420 .hide();
1421 jQuery('.vbo-upload-done')
1422 .fadeIn();
1423 } else if (file.error) {
1424 var error = jQuery('<span class="text-danger"/>').text(file.error);
1425 jQuery(data.context.children()[index])
1426 .append('<br>')
1427 .append(error);
1428 } else {
1429 jQuery(data.context.children()[index])
1430 .append('<br>')
1431 .append('Generic Error.');
1432 }
1433 });
1434 if (data.result.hasOwnProperty('actmoreimgs')) {
1435 jQuery('#actmoreimgs').val(data.result.actmoreimgs);
1436 }
1437 if (data.result.hasOwnProperty('currentthumbs')) {
1438 jQuery('.vbo-editroom-currentphotos').html(data.result.currentthumbs);
1439 }
1440 if (typeof reloadFancybox === 'function') {
1441 reloadFancybox();
1442 }
1443 }).on('fileuploadfail', function (e, data) {
1444 jQuery.each(data.files, function (index) {
1445 var error = jQuery('<span class="text-danger"/>').text('File upload failed.');
1446 jQuery(data.context.children()[index])
1447 .append('<br>')
1448 .append(error);
1449 });
1450 }).prop('disabled', !jQuery.support.fileInput)
1451 .parent().addClass(jQuery.support.fileInput ? undefined : 'disabled');
1452
1453 // generate content through AI
1454 jQuery('.vbo-content-genai').click(function() {
1455 // get the type of room description to generate
1456 let content_type = jQuery(this).attr('data-type');
1457
1458 // define the modal cancel button
1459 let cancel_btn = jQuery('<button></button>')
1460 .attr('type', 'button')
1461 .addClass('btn')
1462 .text(Joomla.JText._('VBANNULLA'))
1463 .on('click', function() {
1464 VBOCore.emitEvent('vbo-content-genai-dismiss');
1465 });
1466
1467 // define the submit button
1468 let submit_btn = jQuery('<button></button>')
1469 .attr('type', 'button')
1470 .addClass('btn btn-success')
1471 .text(Joomla.JText._('VBO_GEN_CONTENT'))
1472 .on('click', function() {
1473 // start loading
1474 VBOCore.emitEvent('vbo-content-genai-loading');
1475
1476 // perform the request
1477 VBOCore.doAjax(
1478 "<?php echo VikBooking::ajaxUrl('index.php?option=com_vikbooking&task=ai.roomContent'); ?>",
1479 {
1480 type: content_type,
1481 information: document.querySelector('.vbo-content-genai-field[data-field="information"]').value,
1482 language: document.querySelector('.vbo-content-genai-field[data-field="language"]').value.replace('__', ' - '),
1483 },
1484 (resp) => {
1485 // stop loading
1486 VBOCore.emitEvent('vbo-content-genai-loading');
1487
1488 // set description content
1489 resp = typeof resp === 'string' ? JSON.parse(resp) : resp;
1490
1491 if (content_type == 'short') {
1492 // short description
1493 jQuery('textarea[name="smalldesc"]').val(resp['content']);
1494 } else {
1495 // long HTML description
1496 try {
1497 // attempt to inject value inside wysiwyg editor
1498 Joomla.editors.instances['cdescr'].setValue(resp['content']);
1499 } catch(e) {
1500 // fallback to standard textarea
1501 jQuery('textarea[name="cdescr"]').val(resp['content']).trigger('change');
1502 }
1503 }
1504
1505 // dismiss the modal on success
1506 VBOCore.emitEvent('vbo-content-genai-dismiss');
1507 },
1508 (error) => {
1509 // stop loading
1510 VBOCore.emitEvent('vbo-content-genai-loading');
1511
1512 // display the error
1513 alert(error.responseText);
1514 }
1515 );
1516 });
1517
1518 // dynamically add the selected amenities
1519 let active_amenities = jQuery('input[type="checkbox"][name="ccarat[]"]:checked');
1520 if (active_amenities.length) {
1521 let amenity_texts = [];
1522 active_amenities.each(function(index, elem) {
1523 amenity_texts.push(jQuery(elem).parent().find('label').text());
1524 });
1525 amenity_texts = amenity_texts.filter(v => v);
1526 if (amenity_texts.length) {
1527 // replace any previously added string related to the amenities
1528 let current_info_txt = document.querySelector('.vbo-content-genai-field[data-field="information"]').value.trim();
1529 let amenities_lbl = Joomla.JText._('VBPVIEWROOMTHREE');
1530 let amenities_rgx = new RegExp("(" + amenities_lbl + ":\\s.+)", 'i');
1531 current_info_txt = current_info_txt.replace(amenities_rgx, '').trim();
1532 current_info_txt += "\n" + amenities_lbl + ': ' + amenity_texts.join(', ') + "\n";
1533 // set new information text
1534 document.querySelector('.vbo-content-genai-field[data-field="information"]').value = current_info_txt;
1535 }
1536 }
1537
1538 // display modal
1539 let modal_body = VBOCore.displayModal({
1540 suffix: 'content-genai',
1541 extra_class: 'vbo-modal-rounded',
1542 title: Joomla.JText._((content_type == 'short' ? 'VBNEWROOMSMALLDESC' : 'VBNEWROOMSEVEN')) + ' - ' + Joomla.JText._('VBO_AI_LABEL_DEF'),
1543 footer_left: cancel_btn,
1544 footer_right: submit_btn,
1545 loading_event: 'vbo-content-genai-loading',
1546 dismiss_event: 'vbo-content-genai-dismiss',
1547 onDismiss: () => {
1548 jQuery('.vbo-content-genai-wrap').appendTo('.vbo-content-genai-helper');
1549 },
1550 });
1551
1552 jQuery('.vbo-content-genai-wrap').appendTo(modal_body);
1553 });
1554 });
1555 </script>
1556