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
← All changes | admin/helpers/src/checkin/adapter.php +277 -1 1.7.0 → 1.8.16 View file →
@@ -25,8 +25,38 @@
25 25 */
26 26 protected $collector_id = '';
27 27
28 28 /**
29 + * Default pax fields MRZ type map.
30 + *
31 + * @var VBOCheckinPaxfieldsMrzMap
32 + */
33 + protected $mrzFieldsMapper = null;
34 +
35 + /**
36 + * Class constructor will define internal properties.
37 + *
38 + * @since 1.18.6 (J) - 1.8.6 (WP)
39 + */
40 + public function __construct()
41 + {
42 + // get pax data collector base class name
43 + $collector_base_class = preg_replace('/^VBOCheckinPaxfields/i', '', strtolower(get_class($this))) ?: 'basic';
44 +
45 + // build expected pax fields MRZ type map class name
46 + $pax_mrz_class = 'VBOCheckinPaxfieldsMrzMap' . ucfirst($collector_base_class);
47 +
48 + // define current pax fields MRZ type map
49 + if (class_exists($pax_mrz_class)) {
50 + // pax data collector provides a dedicated MRZ type map
51 + $this->mrzFieldsMapper = new $pax_mrz_class($this->collector_id, $this->listFields());
52 + } else {
53 + // use the default (basic) MRZ type map
54 + $this->mrzFieldsMapper = new VBOCheckinPaxfieldsMrzMapBasic($this->collector_id, $this->listFields());
55 + }
56 + }
57 +
58 + /**
29 59 * Tells whether children should be registered.
30 60 * Children registration is disabled by default.
31 61 *
32 62 * @param bool $precheckin true if requested for front-end pre check-in.
@@ -41,8 +71,46 @@
41 71 return false;
42 72 }
43 73
44 74 /**
75 + * Tells whether the check-in driver supports MRZ detection
76 + * for the uploaded guest documents (Machine Readable Zone).
77 + *
78 + * @return bool True if MRZ is supported, or false.
79 + *
80 + * @since 1.18.6 (J) - 1.8.6 (WP)
81 + */
82 + public function supportsMRZDetection()
83 + {
84 + static $mrzSupportChecked = null;
85 +
86 + if ($mrzSupportChecked !== null) {
87 + // use the cached support check
88 + return (bool) $mrzSupportChecked;
89 + }
90 +
91 + // enabled by default, only if the Channel Manager is installed with active AI support
92 + $mrzSupportChecked = class_exists('VikChannelManager') &&
93 + defined('VikChannelManagerConfig::AI') &&
94 + VikChannelManager::getChannel(VikChannelManagerConfig::AI);
95 +
96 + // return the support value
97 + return $mrzSupportChecked;
98 + }
99 +
100 + /**
101 + * Returns the current pax fields MRZ mapper.
102 + *
103 + * @return VBOCheckinPaxfieldsMrzMap
104 + *
105 + * @since 1.18.6 (J) - 1.8.6 (WP)
106 + */
107 + public function getMRZMapper()
108 + {
109 + return $this->mrzFieldsMapper;
110 + }
111 +
112 + /**
45 113 * Returns the instance of the given pax field key.
46 114 *
47 115 * @param string $key the field key identifier.
48 116 *
@@ -65,8 +133,38 @@
65 133 return $pax_field;
66 134 }
67 135
68 136 /**
137 + * Attempts to find the first field attribute key from the given type.
138 + *
139 + * @param string $type The type of pax field.
140 + *
141 + * @return string Empty string or first field attribute key found for this type.
142 + *
143 + * @since 1.18.0 (J) - 1.8.0 (WP)
144 + */
145 + public function getFieldTypeKey(string $type)
146 + {
147 + // get all the existing field attributes
148 + $attributes = $this->getAttributes();
149 +
150 + if (!in_array($type, $attributes)) {
151 + // unknown pax field type
152 + return '';
153 + }
154 +
155 + // search for the pax field key from the given type
156 + $key = array_search($type, $attributes);
157 +
158 + if ($key === false) {
159 + // pax field type not found
160 + return '';
161 + }
162 +
163 + return (string) $key;
164 + }
165 +
166 + /**
69 167 * Renders a specific pax field type.
70 168 *
71 169 * @param VBOCheckinPaxfield $field the pax field object to render.
72 170 *
@@ -114,9 +212,9 @@
114 212
115 213 // compose dinamically the implementor class name
116 214 $field_class = $this->getFieldTypeClass($field_type);
117 215
118 - if (!class_exists($field_class)) {
216 + if (!$field_class || !class_exists($field_class)) {
119 217 // no implementor handler found for this type of field
120 218 return null;
121 219 }
122 220
@@ -131,8 +229,186 @@
131 229 */
132 230 public function listFields()
133 231 {
134 232 return [$this->getLabels(), $this->getAttributes()];
233 + }
234 +
235 + /**
236 + * Builds the list of front-end (pre-checkin) pax fields for the extended collection type.
237 + * Check-in pax fields data collector implementations may override this method, if needed.
238 + *
239 + * @param array $def_fields list of default pre-checkin field labels and attributes.
240 + *
241 + * @return array the list of pax fields to collect in the front-end during pre-checkin.
242 + *
243 + * @since 1.17.2 (J) - 1.7.2 (WP)
244 + */
245 + public function listPrecheckinFields(array $def_fields)
246 + {
247 + // return no labels, nor attributes by default
248 + return [
249 + [],
250 + [],
251 + ];
252 + }
253 +
254 + /**
255 + * Invokes a callback for the extended collection type after the pre-checkin
256 + * information have been stored or updated to perform certain actions.
257 + *
258 + * @param array $data the guest registration data stored.
259 + * @param array $booking the booking record involved with the guests registration.
260 + * @param array $customer optional customer record associated with the booking.
261 + *
262 + * @return void
263 + *
264 + * @since 1.17.5 (J) - 1.7.5 (WP)
265 + */
266 + public function onPrecheckinDataStored(array $data, array $booking, array $customer)
267 + {
268 + // no actions to be performed by default
269 + return;
270 + }
271 +
272 + /**
273 + * Performs a validation over the guest registration field types for a given reservation.
274 + * Those responsible for storing the pre-check-in information should call this method first,
275 + * which will invoke the validation method over every registration field type, and then the
276 + * driver validation will be automatically called to verify the data submitted.
277 + *
278 + * @param array $booking The booking record involved with the guests registration.
279 + * @param array $booking_rooms The booking room records involved with the guests registration.
280 + * @param array $data The guests registration data to validate.
281 + * @param bool $precheckin True if validating pre-checkin fields.
282 + *
283 + * @return void
284 + *
285 + * @throws Exception
286 + *
287 + * @uses validateRegistrationFields()
288 + *
289 + * @since 1.18.0 (J) - 1.8.0 (WP)
290 + */
291 + public function validateRegistrationFieldTypes(array $booking, array $booking_rooms, array $data, bool $precheckin = true)
292 + {
293 + // first off, let the driver perform the validation over the field contents submitted to ensure mandatory values are set
294 + $this->validateRegistrationFields($booking, $booking_rooms, $data, $precheckin);
295 +
296 + // get the current driver's attributes
297 + $supported_attributes = $this->getAttributes();
298 +
299 + // iterate over all rooms booked to identify the custom registration field types
300 + foreach ($booking_rooms as $index => $booking_room) {
301 + // count expected room registration guests data
302 + $room_adults = $booking_room['adults'] ?? 1;
303 + $room_children = $booking_room['children'] ?? 0;
304 + $room_guests = $this->registerChildren($precheckin) ? ($room_adults + $room_children) : $room_adults;
305 +
306 + // scan room guests for the expected room guest registration data
307 + for ($g = 1; $g <= $room_guests; $g++) {
308 + if (!is_array(($data[$index][$g] ?? null))) {
309 + // no registration data available for this room and guest
310 + continue;
311 + }
312 +
313 + // iterate over the registration fields
314 + foreach ($supported_attributes as $field_type) {
315 + if (!is_string($field_type) || !$this->isCustomFieldType($field_type)) {
316 + // known field types will not be invoked for triggering a custom validation
317 + continue;
318 + }
319 +
320 + // find the first pax field key from the given type
321 + $pax_field_key = $this->getFieldTypeKey($field_type);
322 +
323 + if (!$pax_field_key) {
324 + // unknown pax field type
325 + continue;
326 + }
327 +
328 + // get an instance of the VBOCheckinPaxfield object
329 + $pax_field_obj = $this->getField($pax_field_key);
330 +
331 + // detect the current type of guest
332 + $guest_type = $g > $room_adults ? 'child' : 'adult';
333 +
334 + // set object data
335 + $pax_field_obj->setGuestType($guest_type)
336 + ->setGuestNumber($g)
337 + ->setGuestData($data[$index][$g])
338 + ->setRoomIndex($index)
339 + ->setBooking($booking)
340 + ->setBookingRooms($booking_rooms)
341 + ->setRoomGuests($room_adults, $room_children)
342 + ->setTotalRooms(count($booking_rooms));
343 +
344 + // get the field implementor
345 + if ($implementor = $this->getFieldTypeImplementor($pax_field_obj)) {
346 + // invoke the registration data validation on the field implementor
347 + $implementor->validateGuestRegistrationData();
348 + }
349 + }
350 + }
351 + }
352 +
353 + // all good
354 + return;
355 + }
356 +
357 + /**
358 + * Performs a validation over the guest registration fields data for a given reservation.
359 + * Custom drivers can override this method to implement their own validation method.
360 + *
361 + * @param array $booking The booking record involved with the guests registration.
362 + * @param array $booking_rooms The booking room records involved with the guests registration.
363 + * @param array $data The guests registration data to validate.
364 + * @param bool $precheckin True if validating pre-checkin fields.
365 + *
366 + * @return void
367 + *
368 + * @throws Exception
369 + *
370 + * @see validateRegistrationFieldTypes()
371 + *
372 + * @since 1.17.7 (J) - 1.7.7 (WP)
373 + */
374 + public function validateRegistrationFields(array $booking, array $booking_rooms, array $data, bool $precheckin = true)
375 + {
376 + // no guest fields data validation performed by default
377 + return;
378 + }
379 +
380 + /**
381 + * Tells whether the given field attribute typr correspond to a custom paxfield type.
382 + *
383 + * @param string $type The field attribute type.
384 + *
385 + * @return bool True if this is a custom field type.
386 + *
387 + * @since 1.18.0 (J) - 1.8.0 (WP)
388 + */
389 + protected function isCustomFieldType(string $type)
390 + {
391 + // get the current driver's attributes
392 + $supported_attributes = $this->getAttributes();
393 +
394 + if (!in_array($type, $supported_attributes)) {
395 + // unknown attribute type for this driver
396 + return false;
397 + }
398 +
399 + // declare the known field types that will not require a validation at field-object level
400 + $known_types = [
401 + 'calendar',
402 + 'country',
403 + 'file',
404 + 'number',
405 + 'select',
406 + 'text',
407 + 'textarea',
408 + ];
409 +
410 + return !in_array($type, $known_types);
135 411 }
136 412
137 413 /**
138 414 * Composes the field type class name given its type-string.