| @@ -71,8 +71,9 @@ | ||
| 71 | 71 | |
| 72 | 72 | // get date timestamps |
| 73 | 73 | $from_ts = VikBooking::getDateTimestamp($from_dt, 0, 0); |
| 74 | 74 | $to_ts = VikBooking::getDateTimestamp($to_dt, 23, 59, 59); |
| 75 | + $from_ts_end = VikBooking::getDateTimestamp($from_dt, 23, 59, 59); | |
| 75 | 76 | |
| 76 | 77 | // query the db |
| 77 | 78 | $dbo = JFactory::getDbo(); |
| 78 | 79 | |
| @@ -97,13 +98,10 @@ | ||
| 97 | 98 | $q->where($dbo->qn('o.ts') . ' >= ' . $from_ts); |
| 98 | 99 | $q->where($dbo->qn('o.ts') . ' <= ' . $to_ts); |
| 99 | 100 | } else { |
| 100 | 101 | // stayover |
| 101 | - $q->where('( | |
| 102 | - (' . $dbo->qn('o.checkin') . ' >= ' . $from_ts . ' AND ' . $dbo->qn('o.checkin') . ' <= ' . $to_ts . ') | |
| 103 | - OR | |
| 104 | - (' . $dbo->qn('o.checkout') . ' >= ' . $from_ts . ' AND ' . $dbo->qn('o.checkout') . ' <= ' . $to_ts . ') | |
| 105 | - )'); | |
| 102 | + $q->where($dbo->qn('o.checkin') . ' < ' . $from_ts_end); | |
| 103 | + $q->where($dbo->qn('o.checkout') . ' > ' . $to_ts); | |
| 106 | 104 | } |
| 107 | 105 | |
| 108 | 106 | $dbo->setQuery($q); |
| 109 | 107 | $bookings = $dbo->loadAssocList(); |
| @@ -297,9 +295,9 @@ | ||
| 297 | 295 | { |
| 298 | 296 | $wrapper = VikRequest::getString('wrapper', '', 'request'); |
| 299 | 297 | $bid = VikRequest::getInt('bid', 0, 'request'); |
| 300 | 298 | $index = VikRequest::getInt('index', 0, 'request'); |
| 301 | - $message = VikRequest::getString('message', '', 'request'); | |
| 299 | + $message = VikRequest::getString('message', '', 'request', VIKREQUEST_ALLOWHTML); | |
| 302 | 300 | $subject = VikRequest::getString('subject', '', 'request'); |
| 303 | 301 | |
| 304 | 302 | $booking = VikBooking::getBookingInfoFromID($bid); |
| 305 | 303 | |
| @@ -310,8 +308,12 @@ | ||
| 310 | 308 | if (empty($message)) { |
| 311 | 309 | VBOHttpDocument::getInstance()->close(500, JText::translate('VBO_PLEASE_FILL_FIELDS')); |
| 312 | 310 | } |
| 313 | 311 | |
| 312 | + // inject the customer information | |
| 313 | + $customer = VikBooking::getCPinInstance()->getCustomerFromBooking($booking['id']); | |
| 314 | + $booking['customer'] = $customer; | |
| 315 | + | |
| 314 | 316 | if ($index === 0) { |
| 315 | 317 | // update widget's settings with last message and subject |
| 316 | 318 | $this->widgetSettings->last_subject = $subject; |
| 317 | 319 | $this->widgetSettings->last_message = $message; |
| @@ -394,8 +396,11 @@ | ||
| 394 | 396 | |
| 395 | 397 | if (VBOPlatformDetection::isJoomla()) { |
| 396 | 398 | // load assets |
| 397 | 399 | $this->vbo_app->loadVisualEditorAssets(); |
| 400 | + } else { | |
| 401 | + // load lang defs | |
| 402 | + $this->vbo_app->loadVisualEditorDefinitions(); | |
| 398 | 403 | } |
| 399 | 404 | |
| 400 | 405 | // JS lang defs |
| 401 | 406 | JText::script('VBO_PLEASE_SELECT'); |
| @@ -408,13 +413,13 @@ | ||
| 408 | 413 | /** |
| 409 | 414 | * Main method to invoke the widget. Contents will be loaded |
| 410 | 415 | * through AJAX requests, not via PHP when the page loads. |
| 411 | 416 | * |
| 412 | - * @param VBOMultitaskData $data | |
| 417 | + * @param ?VBOMultitaskData $data | |
| 413 | 418 | * |
| 414 | 419 | * @return void |
| 415 | 420 | */ |
| 416 | - public function render(VBOMultitaskData $data = null) | |
| 421 | + public function render(?VBOMultitaskData $data = null) | |
| 417 | 422 | { |
| 418 | 423 | // increase widget's instance counter |
| 419 | 424 | static::$instance_counter++; |
| 420 | 425 | |
| @@ -1003,24 +1008,19 @@ | ||
| 1003 | 1008 | |
| 1004 | 1009 | // load all conditional text special tags |
| 1005 | 1010 | $condtext_tags = array_keys(VikBooking::getConditionalRulesInstance()->getSpecialTags()); |
| 1006 | 1011 | |
| 1007 | - // join special tags with conditional texts to construct a list of editor buttons, | |
| 1012 | + /** | |
| 1013 | + * Load Door Access Control special tags from the configured integration providers. | |
| 1014 | + * | |
| 1015 | + * @since 1.18.4 (J) - 1.8.4 (WP) | |
| 1016 | + */ | |
| 1017 | + $dac_tags = VBOFactory::getDoorAccessControl()->getInstalledSpecialTags(); | |
| 1018 | + | |
| 1019 | + // join special tags with conditional texts and DAC to construct a list of editor buttons, | |
| 1008 | 1020 | // displayed within the toolbar of Quill editor |
| 1009 | - $editor_btns = array_merge($special_tags_base, $condtext_tags); | |
| 1021 | + $editor_btns = array_merge($special_tags_base, $condtext_tags, $dac_tags); | |
| 1010 | 1022 | |
| 1011 | - // convert special tags into HTML buttons, displayed under the text editor | |
| 1012 | - $special_tags_base = array_map(function($tag) | |
| 1013 | - { | |
| 1014 | - return '<button type="button" class="btn" onclick="setCronTplTag(\'tpl_text\', \'' . $tag . '\');">' . $tag . '</button>'; | |
| 1015 | - }, $special_tags_base); | |
| 1016 | - | |
| 1017 | - // convert conditional texts into HTML buttons, displayed under the text editor | |
| 1018 | - $condtext_tags = array_map(function($tag) | |
| 1019 | - { | |
| 1020 | - return '<button type="button" class="btn vbo-condtext-specialtag-btn" onclick="setCronTplTag(\'tpl_text\', \'' . $tag . '\');">' . $tag . '</button>'; | |
| 1021 | - }, $condtext_tags); | |
| 1022 | - | |
| 1023 | 1023 | // build the default message value |
| 1024 | 1024 | $def_message = !empty($this->widgetSettings->last_message) ? $this->widgetSettings->last_message : $this->getDefaultMessage(); |
| 1025 | 1025 | |
| 1026 | 1026 | return $this->vbo_app->renderVisualEditor( |
| @@ -1031,10 +1031,10 @@ | ||
| 1031 | 1031 | 'style' => 'width: 96%; height: 150px;', |
| 1032 | 1032 | ], |
| 1033 | 1033 | [ |
| 1034 | 1034 | 'modes' => [ |
| 1035 | + 'visual', | |
| 1035 | 1036 | 'text', |
| 1036 | - 'visual', | |
| 1037 | 1037 | ], |
| 1038 | 1038 | ], |
| 1039 | 1039 | $editor_btns |
| 1040 | 1040 | ); |
| @@ -1169,13 +1169,25 @@ | ||
| 1169 | 1169 | */ |
| 1170 | 1170 | VikBooking::getConditionalRulesInstance() |
| 1171 | 1171 | ->set(array('booking', 'rooms'), array($booking, $booking_rooms)) |
| 1172 | 1172 | ->parseTokens($tpl); |
| 1173 | - // | |
| 1174 | 1173 | |
| 1174 | + /** | |
| 1175 | + * Parse all Door Access Control tags. | |
| 1176 | + * | |
| 1177 | + * @since 1.18.4 (J) - 1.8.4 (WP) | |
| 1178 | + */ | |
| 1179 | + VBOFactory::getDoorAccessControl() | |
| 1180 | + ->parseTokens((new VBOBookingRegistry($booking, $booking_rooms)), $tpl); | |
| 1181 | + | |
| 1182 | + // normalize customer details | |
| 1183 | + if (empty($booking['customer_name']) && !empty($booking['customer'])) { | |
| 1184 | + $booking['customer_name'] = trim($booking['first_name'] . ' ' . $booking['last_name']); | |
| 1185 | + } | |
| 1186 | + | |
| 1175 | 1187 | $vbo_df = VikBooking::getDateFormat(); |
| 1176 | 1188 | $df = $vbo_df == "%d/%m/%Y" ? 'd/m/Y' : ($vbo_df == "%m/%d/%Y" ? 'm/d/Y' : 'Y-m-d'); |
| 1177 | - $tpl = str_replace('{customer_name}', $booking['customer_name'], $tpl); | |
| 1189 | + $tpl = str_replace('{customer_name}', ($booking['customer_name'] ?: ''), $tpl); | |
| 1178 | 1190 | $tpl = str_replace('{booking_id}', $booking['id'], $tpl); |
| 1179 | 1191 | $tpl = str_replace('{checkin_date}', date($df, $booking['checkin']), $tpl); |
| 1180 | 1192 | $tpl = str_replace('{checkout_date}', date($df, $booking['checkout']), $tpl); |
| 1181 | 1193 | $tpl = str_replace('{num_nights}', $booking['days'], $tpl); |
| @@ -1204,9 +1216,9 @@ | ||
| 1204 | 1216 | $tpl = str_replace('{total}', VikBooking::numberFormat($booking['total']), $tpl); |
| 1205 | 1217 | $tpl = str_replace('{total_paid}', VikBooking::numberFormat($booking['totpaid']), $tpl); |
| 1206 | 1218 | $remaining_bal = $booking['total'] - $booking['totpaid']; |
| 1207 | 1219 | $tpl = str_replace('{remaining_balance}', VikBooking::numberFormat($remaining_bal), $tpl); |
| 1208 | - $tpl = str_replace('{customer_pin}', $booking['customer_pin'], $tpl); | |
| 1220 | + $tpl = str_replace('{customer_pin}', (($booking['customer_pin'] ?? '') ?: ($booking['customer']['pin'] ?? '')), $tpl); | |
| 1209 | 1221 | |
| 1210 | 1222 | $use_sid = empty($booking['sid']) && !empty($booking['idorderota']) ? $booking['idorderota'] : $booking['sid']; |
| 1211 | 1223 | |
| 1212 | 1224 | $bestitemid = VikBooking::findProperItemIdType(['booking'], (!empty($booking['lang']) ? $booking['lang'] : null)); |