PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.15
VikBooking Hotel Booking Engine & PMS v1.8.15
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 1.7.3 All 36 releases
vikbooking / admin / helpers / src / booking / subunit / moveset.php

moveset.php in VikBooking Hotel Booking Engine & PMS 1.8.15, at admin/helpers/src/booking/subunit/moveset.php

344 lines 8.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 core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2026 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 * Room-Booking sub-unit moveset implementation.
16 *
17 * @since 1.18.7 (J) - 1.8.7 (WP)
18 */
19 final class VBOBookingSubunitMoveset
20 {
21 /**
22 * @var array
23 */
24 private array $moveset = [];
25
26 /**
27 * @var VBOBookingRegistry
28 */
29 private VBOBookingRegistry $registry;
30
31 /**
32 * @var int
33 */
34 private int $iterationNumber = 0;
35
36 /**
37 * @var int
38 */
39 private int $totalMoves = 0;
40
41 /**
42 * @var int
43 */
44 private int $solutionsCount = 0;
45
46 /**
47 * @var ?string
48 */
49 private ?string $verboseRelocation = null;
50
51 /**
52 * Class constructor will check and bind the moveset list and booking registry.
53 *
54 * @param VBOBookingSubunitRecord[] $moveset List of (fitting) sub-unit record objects.
55 */
56 public function __construct(array $moveset, VBOBookingRegistry $registry)
57 {
58 // accept only sub-unit record objects
59 $moveset = array_filter($moveset, function($move) {
60 return $move instanceof VBOBookingSubunitRecord;
61 });
62
63 if (!$moveset) {
64 throw new InvalidArgumentException('Moveset expects a list of sub-unit record objects.', 500);
65 }
66
67 // bind moveset list, expected to fit
68 $this->moveset = $moveset;
69
70 // bind booking registry
71 $this->registry = $registry;
72 }
73
74 /**
75 * Returns the raw moveset with which the object was constructed.
76 *
77 * @return array
78 */
79 public function getRawMoveset()
80 {
81 return $this->moveset;
82 }
83
84 /**
85 * Gets the matrix iteration number when the moveset was completed.
86 *
87 * @return int
88 */
89 public function getIterationNumber()
90 {
91 return $this->iterationNumber;
92 }
93
94 /**
95 * Sets the matrix iteration number when the moveset was completed.
96 *
97 * @param int $number Matrix iteration number when returning the moveset.
98 *
99 * @return static
100 */
101 public function setIterationNumber(int $number)
102 {
103 $this->iterationNumber = abs($number);
104
105 return $this;
106 }
107
108 /**
109 * Gets the matrix total possible moves number.
110 *
111 * @return int
112 */
113 public function getTotalMoves()
114 {
115 return $this->totalMoves;
116 }
117
118 /**
119 * Sets the matrix total possible moves number.
120 *
121 * @param int $moves Matrix total combinations count.
122 *
123 * @return static
124 */
125 public function setTotalMoves(int $moves)
126 {
127 $this->totalMoves = $moves;
128
129 return $this;
130 }
131
132 /**
133 * Returns the number of fitting solutions found so far.
134 *
135 * @return int
136 */
137 public function getSolutionsCount()
138 {
139 return $this->solutionsCount;
140 }
141
142 /**
143 * Sets the number of fitting solutions found so far.
144 *
145 * @param int $count Solutions found.
146 *
147 * @return static
148 */
149 public function setSolutionsCount(int $count)
150 {
151 $this->solutionsCount = $count;
152
153 return $this;
154 }
155
156 /**
157 * Gets the verbose explanation of how the relocation did fit.
158 *
159 * @return ?string
160 */
161 public function getVerboseRelocation()
162 {
163 return $this->verboseRelocation;
164 }
165
166 /**
167 * Sets the verbose explanation of how the relocation did fit.
168 *
169 * @param string $relocationText Verbose explanation string.
170 *
171 * @return static
172 */
173 public function setVerboseRelocation(string $relocationText)
174 {
175 $this->verboseRelocation = $relocationText;
176
177 return $this;
178 }
179
180 /**
181 * Returns the current booking registry.
182 *
183 * @return VBOBookingRegistry
184 */
185 public function getBooking()
186 {
187 return $this->registry;
188 }
189
190 /**
191 * Calculates and returns the moveset signature.
192 *
193 * @return string
194 */
195 public function getSignature()
196 {
197 $signatureSteps = [];
198
199 foreach ($this->moveset as $roomRecord) {
200 // access current and initial room unit index
201 $currentRoomUnitIndex = $roomRecord->getRoomUnitIndex();
202 $initialRoomUnitIndex = $roomRecord->getInitialRoomUnitIndex();
203
204 if (!$currentRoomUnitIndex || $currentRoomUnitIndex == $initialRoomUnitIndex) {
205 // no moves for this room record
206 continue;
207 }
208
209 // build move elements
210 $moveElements = [
211 $roomRecord->getBookingID(),
212 $roomRecord->getRoomBookingID(),
213 (int) $initialRoomUnitIndex,
214 (int) $currentRoomUnitIndex,
215 ];
216
217 // represent move elements
218 $signatureSteps[] = implode('.', $moveElements);
219 }
220
221 return implode('-', $signatureSteps);
222 }
223
224 /**
225 * Returns a list of booking IDs involved in the moveset.
226 *
227 * @param bool $unique Whether to make the list unique.
228 *
229 * @return array
230 */
231 public function getBookingIDs(bool $unique = true)
232 {
233 $bidsInvolved = [];
234
235 foreach ($this->moveset as $roomRecord) {
236 // access current and initial room unit index
237 $currentRoomUnitIndex = $roomRecord->getRoomUnitIndex();
238 $initialRoomUnitIndex = $roomRecord->getInitialRoomUnitIndex();
239
240 if (!$currentRoomUnitIndex || $currentRoomUnitIndex == $initialRoomUnitIndex) {
241 // no moves for this room record
242 continue;
243 }
244
245 // push involved booking ID
246 $bidsInvolved[] = (int) $roomRecord->getBookingID();
247 }
248
249 if ($unique) {
250 $bidsInvolved = array_values(array_unique($bidsInvolved));
251 }
252
253 return $bidsInvolved;
254 }
255
256 /**
257 * Returns the current room record being relocated.
258 *
259 * @return VBOBookingSubunitRecord
260 *
261 * @throws Exception
262 */
263 public function getRelocatingRecord()
264 {
265 foreach ($this->moveset as $roomRecord) {
266 if ($roomRecord->isRelocating()) {
267 return $roomRecord;
268 }
269 }
270
271 throw new Exception('Missing room relocating record in moveset.', 404);
272 }
273
274 /**
275 * Describes the moveset operations.
276 *
277 * @return string
278 */
279 public function describeMoveset()
280 {
281 // moveset title
282 $description = sprintf(
283 "Fitting moveset found after %s matrix iterations over %s possible combinations.\n\n",
284 number_format($this->getIterationNumber(), 0, ',', '.'),
285 number_format($this->getTotalMoves(), 0, ',', '.')
286 );
287
288 // describe the booking to relocate
289 foreach ($this->moveset as $roomRecord) {
290 if ($roomRecord->isRelocating()) {
291 // describe the record to relocate
292 $description .= sprintf(
293 "Allocating booking ID %d (room reservation record ID %d) to sub-unit index number: [%d].\n\n",
294 $roomRecord->getBookingID(),
295 $roomRecord->getRoomBookingID(),
296 (int) $roomRecord->getRoomUnitIndex()
297 );
298
299 // just one
300 break;
301 }
302 }
303
304 // describe all necessary moves
305 $stepCounter = 1;
306 foreach ($this->moveset as $roomRecord) {
307 if ($roomRecord->isRelocating()) {
308 // do not describe it here
309 continue;
310 }
311
312 // access current and initial room unit index
313 $currentRoomUnitIndex = $roomRecord->getRoomUnitIndex();
314 $initialRoomUnitIndex = $roomRecord->getInitialRoomUnitIndex();
315
316 if (!$currentRoomUnitIndex || $currentRoomUnitIndex == $initialRoomUnitIndex) {
317 // no moves for this room record
318 continue;
319 }
320
321 // describe move
322 $description .= sprintf(
323 "Move booking ID %d (room reservation record ID %d): from index number [%d] --> to [%d]\n",
324 $roomRecord->getBookingID(),
325 $roomRecord->getRoomBookingID(),
326 (int) $initialRoomUnitIndex,
327 (int) $currentRoomUnitIndex
328 );
329 }
330
331 return $description;
332 }
333
334 /**
335 * Describes the moveset.
336 *
337 * @return string
338 */
339 public function __toString()
340 {
341 return $this->describeMoveset();
342 }
343 }
344