PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
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 / controllers / bookings.php

bookings.php in VikBooking Hotel Booking Engine & PMS 1.6.4, at admin/controllers/bookings.php

358 lines 10.9 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 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 /**
15 * VikBooking bookings controller.
16 *
17 * @since 1.16.0 (J) - 1.6.0 (WP)
18 */
19 class VikBookingControllerBookings extends JControllerAdmin
20 {
21 /**
22 * AJAX endpoint to search for an extra service name.
23 *
24 * @return void
25 */
26 public function search_service()
27 {
28 $dbo = JFactory::getDbo();
29
30 $service_name = VikRequest::getString('service_name', '', 'request');
31 $max_results = VikRequest::getInt('max_results', 10, 'request');
32
33 $sql_term = $dbo->quote("%{$service_name}%");
34 $sql_clause = !empty($service_name) ? 'LIKE ' . $sql_term : 'IS NOT NULL';
35
36 $q = "SELECT `or`.`idorder`, `or`.`idroom`, `or`.`adults`, `or`.`children`, `or`.`extracosts`, `o`.`days` AS `nights`, `o`.`ts`, `r`.`name` AS `room_name`
37 FROM `#__vikbooking_ordersrooms` AS `or`
38 LEFT JOIN `#__vikbooking_orders` AS `o` ON `or`.`idorder`=`o`.`id`
39 LEFT JOIN `#__vikbooking_rooms` AS `r` ON `or`.`idroom`=`r`.`id`
40 WHERE `or`.`extracosts` {$sql_clause}
41 ORDER BY `or`.`idorder` DESC";
42 $dbo->setQuery($q, 0, $max_results);
43 $dbo->execute();
44 if (!$dbo->getNumRows()) {
45 // no results
46 VBOHttpDocument::getInstance()->json([]);
47 }
48
49 $results = $dbo->loadAssocList();
50
51 $matching_services = [];
52
53 foreach ($results as $k => $result) {
54 $extra_services = json_decode($result['extracosts'], true);
55 if (empty($extra_services)) {
56 continue;
57 }
58 foreach ($extra_services as $extra_service) {
59 if (empty($service_name) || stristr($extra_service['name'], $service_name) !== false || stristr($service_name, $extra_service['name']) !== false) {
60 // matching service found
61 $matching_service = $result;
62 unset($matching_service['extracosts']);
63 $matching_service['service'] = $extra_service;
64 $matching_service['service']['format_cost'] = VikBooking::getCurrencySymb() . ' ' . VikBooking::numberFormat($extra_service['cost']);
65 $matching_service['format_dt'] = VikBooking::formatDateTs($result['ts']);
66 // push result
67 $matching_services[] = $matching_service;
68 if (count($matching_services) >= $max_results) {
69 break 2;
70 }
71 }
72 }
73 }
74
75 // output the JSON encoded list of matching results found
76 VBOHttpDocument::getInstance()->json($matching_services);
77 }
78
79 /**
80 * AJAX endpoint to count the number of uses for various coupon codes.
81 *
82 * @return void
83 */
84 public function coupons_use_count()
85 {
86 $dbo = JFactory::getDbo();
87
88 $coupon_codes = VikRequest::getVar('coupon_codes', array());
89
90 $use_counts = [];
91
92 foreach ($coupon_codes as $coupon_code) {
93 $q = "SELECT COUNT(*) FROM `#__vikbooking_orders` WHERE `coupon` LIKE " . $dbo->quote("%;{$coupon_code}");
94 $dbo->setQuery($q);
95 $dbo->execute();
96 $use_counts[] = [
97 'code' => $coupon_code,
98 'count' => (int)$dbo->loadResult(),
99 ];
100 }
101
102 // output the JSON encoded list of coupon use counts
103 VBOHttpDocument::getInstance()->json($use_counts);
104 }
105
106 /**
107 * AJAX endpoint to dynamically search for customers. Compatible with select2.
108 *
109 * @return void
110 */
111 public function customers_search()
112 {
113 $dbo = JFactory::getDbo();
114
115 $term = VikRequest::getString('term', '', 'request');
116
117 $response = [
118 'results' => [],
119 'pagination' => [
120 'more' => false,
121 ],
122 ];
123
124 if (empty($term)) {
125 // output the JSON object with no results
126 VBOHttpDocument::getInstance()->json($response);
127 }
128
129 $sql_term = $dbo->quote("%{$term}%");
130
131 $q = "SELECT `c`.`id`, `c`.`first_name`, `c`.`last_name`, `c`.`country`,
132 (SELECT COUNT(*) FROM `#__vikbooking_customers_orders` AS `co` WHERE `co`.`idcustomer`=`c`.`id`) AS `tot_bookings`
133 FROM `#__vikbooking_customers` AS `c`
134 WHERE CONCAT_WS(' ', `c`.`first_name`, `c`.`last_name`) LIKE {$sql_term}
135 OR `email` LIKE {$sql_term}
136 ORDER BY `c`.`first_name` ASC, `c`.`last_name` ASC;";
137 $dbo->setQuery($q);
138 $dbo->execute();
139
140 if ($dbo->getNumRows()) {
141 $customers = $dbo->loadAssocList();
142 foreach ($customers as $k => $customer) {
143 $customers[$k]['text'] = trim($customer['first_name'] . ' ' . $customer['last_name']) . ' (' . $customer['tot_bookings'] . ')';
144 }
145 // push results found
146 $response['results'] = $customers;
147 }
148
149 // output the JSON encoded object with results found
150 VBOHttpDocument::getInstance()->json($response);
151 }
152
153 /**
154 * Regular task to update the status of a cancelled booking to pending (stand-by).
155 *
156 * @return void
157 */
158 public function set_to_pending()
159 {
160 $dbo = JFactory::getDbo();
161 $app = JFactory::getApplication();
162
163 $bid = $app->input->getInt('bid', 0);
164
165 $q = "SELECT * FROM `#__vikbooking_orders` WHERE `id`=" . $bid;
166 $dbo->setQuery($q, 0, 1);
167 $dbo->execute();
168 if (!$dbo->getNumRows()) {
169 $app->enqueueMessage('Booking not found', 'error');
170 $app->redirect('index.php?option=com_vikbooking&task=orders');
171 $app->close();
172 }
173
174 $booking = $dbo->loadAssoc();
175 if ($booking['status'] != 'cancelled') {
176 $app->enqueueMessage('Booking status must be -Cancelled-', 'error');
177 $app->redirect('index.php?option=com_vikbooking&task=editorder&cid[]=' . $booking['id']);
178 $app->close();
179 }
180
181 $q = "UPDATE `#__vikbooking_orders` SET `status`='standby' WHERE `id`=" . $booking['id'];
182 $dbo->setQuery($q);
183 $dbo->execute();
184
185 $app->enqueueMessage(JText::translate('JLIB_APPLICATION_SAVE_SUCCESS'));
186 $app->redirect('index.php?option=com_vikbooking&task=editorder&cid[]=' . $booking['id']);
187 $app->close();
188 }
189
190 /**
191 * AJAX endpoint to assign a room index to a room booking record.
192 *
193 * @return void
194 */
195 public function set_room_booking_subunit()
196 {
197 $dbo = JFactory::getDbo();
198 $app = JFactory::getApplication();
199
200 $bid = $app->input->getInt('bid', 0);
201 $rid = $app->input->getInt('rid', 0);
202 $orkey = $app->input->getInt('orkey', 0);
203 $rindex = $app->input->getInt('rindex', 0);
204
205 if (empty($bid) || empty($rid)) {
206 VBOHttpDocument::getInstance()->close(500, 'Missing request values');
207 }
208
209 $q = "SELECT * FROM `#__vikbooking_orders` WHERE `id`=" . $bid;
210 $dbo->setQuery($q, 0, 1);
211 $booking = $dbo->loadAssoc();
212 if (!$booking) {
213 VBOHttpDocument::getInstance()->close(404, 'Booking not found');
214 }
215
216 $booking_rooms = VikBooking::loadOrdersRoomsData($booking['id']);
217 if (!$booking_rooms) {
218 VBOHttpDocument::getInstance()->close(500, 'No rooms booking found');
219 }
220
221 if (!isset($booking_rooms[$orkey]) || $booking_rooms[$orkey]['idroom'] != $rid) {
222 VBOHttpDocument::getInstance()->close(500, 'Invalid room booking record');
223 }
224
225 // update room record
226 $room_record = new stdClass;
227 $room_record->id = $booking_rooms[$orkey]['id'];
228 $room_record->roomindex = $rindex;
229
230 $dbo->updateObject('#__vikbooking_ordersrooms', $room_record, 'id');
231
232 // build list of affected nights
233 $nights_list_ymd = [];
234 $from_checkin_info = getdate($booking['checkin']);
235 for ($n = 0; $n < $booking['days']; $n++) {
236 // push affected night
237 $nights_list_ymd[] = date('Y-m-d', mktime(0, 0, 0, $from_checkin_info['mon'], ($from_checkin_info['mday'] + $n), $from_checkin_info['year']));
238 }
239
240 // build return values
241 $response = [
242 'bid' => $booking['id'],
243 'rid' => $booking_rooms[$orkey]['idroom'],
244 'rindex' => $rindex,
245 'from' => date('Y-m-d', $booking['checkin']),
246 'to' => date('Y-m-d', $booking['checkout']),
247 'nights' => $nights_list_ymd,
248 ];
249
250 // output the JSON encoded object
251 VBOHttpDocument::getInstance()->json($response);
252 }
253
254 /**
255 * AJAX endpoint to swap one sub-unit index with another for the same room ID and dates.
256 *
257 * @return void
258 *
259 * @since 1.16.2 (J) - 1.6.2 (WP)
260 */
261 public function swap_room_subunits()
262 {
263 $dbo = JFactory::getDbo();
264 $app = JFactory::getApplication();
265
266 $bid_one = $app->input->getInt('bid_one', 0);
267 $bid_two = $app->input->getInt('bid_two', 0);
268 $rid = $app->input->getInt('rid', 0);
269 $index_one = $app->input->getInt('index_one', 0);
270 $index_two = $app->input->getInt('index_two', 0);
271 $checkin = $app->input->getString('checkin', '');
272
273 if (!$bid_one || !$bid_two || !$rid || !$index_one || !$index_two) {
274 VBOHttpDocument::getInstance()->close(500, 'Missing request values');
275 }
276
277 // collect the booking information
278 $booking_one = VikBooking::getBookingInfoFromID($bid_one);
279 $booking_two = VikBooking::getBookingInfoFromID($bid_two);
280 if (!$booking_one || !$booking_two) {
281 VBOHttpDocument::getInstance()->close(500, 'Could not find the involved reservations');
282 }
283
284 // get room reservation records
285 $rooms_one = VikBooking::loadOrdersRoomsData($bid_one);
286 $rooms_two = VikBooking::loadOrdersRoomsData($bid_two);
287 if (!$rooms_one || !$rooms_two) {
288 VBOHttpDocument::getInstance()->close(500, 'Could not find the involved room reservation records');
289 }
290
291 // find the record IDs involved and room name
292 $update_id_one = null;
293 $update_id_two = null;
294 $room_name = '';
295
296 foreach ($rooms_one as $room_one) {
297 if ($room_one['idroom'] == $rid && $room_one['roomindex'] == $index_one) {
298 $update_id_one = $room_one['id'];
299 $room_name = $room_one['room_name'];
300 break;
301 }
302 }
303
304 foreach ($rooms_two as $room_two) {
305 if ($room_two['idroom'] == $rid && $room_two['roomindex'] == $index_two) {
306 $update_id_two = $room_two['id'];
307 $room_name = $room_two['room_name'];
308 break;
309 }
310 }
311
312 if (!$update_id_one || !$update_id_two) {
313 VBOHttpDocument::getInstance()->close(500, 'Could not find the involved room reservation record IDs');
314 }
315
316 // swap first room record
317 $q = $dbo->getQuery(true);
318
319 $q->update($dbo->qn('#__vikbooking_ordersrooms'))
320 ->set($dbo->qn('roomindex') . ' = ' . $index_two)
321 ->where($dbo->qn('id') . ' = ' . (int)$update_id_one);
322
323 $dbo->setQuery($q);
324 $dbo->execute();
325
326 $result = (bool)$dbo->getAffectedRows();
327
328 // swap second room record
329 $q = $dbo->getQuery(true);
330
331 $q->update($dbo->qn('#__vikbooking_ordersrooms'))
332 ->set($dbo->qn('roomindex') . ' = ' . $index_one)
333 ->where($dbo->qn('id') . ' = ' . (int)$update_id_two);
334
335 $dbo->setQuery($q);
336 $dbo->execute();
337
338 $result = $result || (bool)$dbo->getAffectedRows();
339
340 if (!$result) {
341 VBOHttpDocument::getInstance()->close(500, 'No records were updated for the involved room reservation IDs');
342 }
343
344 // update history records
345 $user = JFactory::getUser();
346 VikBooking::getBookingHistoryInstance()->setBid($booking_one['id'])->store('MB', JText::sprintf('VBO_SWAP_ROOMS_LOG', $room_name, $index_one, $index_two) . " ({$user->name})");
347 if ($booking_one['id'] != $booking_two['id']) {
348 VikBooking::getBookingHistoryInstance()->setBid($booking_two['id'])->store('MB', JText::sprintf('VBO_SWAP_ROOMS_LOG', $room_name, $index_two, $index_one) . " ({$user->name})");
349 }
350
351 // output the JSON encoded response object
352 VBOHttpDocument::getInstance()->json([
353 'swap_from' => $index_one,
354 'swap_to' => $index_two,
355 ]);
356 }
357 }
358