PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / cart / item.php
vikappointments / site / helpers / libraries / cart Last commit date
cart.php 3 days ago discount.php 3 days ago index.html 3 days ago item.php 3 days ago option.php 3 days ago utils.php 3 days ago
item.php
1151 lines
1 <?php
2 /**
3 * @package VikAppointments
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 VAPLoader::import('libraries.cart.option');
15 VAPLoader::import('libraries.tax.factory');
16
17 /**
18 * Class used to handle the items that can be stored within a cart.
19 *
20 * @since 1.6
21 */
22 class VAPCartItem implements JsonSerializable
23 {
24 /**
25 * The service identifier.
26 *
27 * @var integer
28 */
29 private $idService;
30
31 /**
32 * The employee identifier (-1 if not specified).
33 *
34 * @var integer
35 */
36 private $idEmployee;
37
38 /**
39 * The service name.
40 *
41 * @var string
42 */
43 private $serviceName;
44
45 /**
46 * The employee name (empty if not specified).
47 *
48 * @var string
49 */
50 private $employeeName;
51
52 /**
53 * The service price.
54 *
55 * @var float
56 */
57 private $price;
58
59 /**
60 * The service duration (in minutes).
61 *
62 * @var integer
63 */
64 private $duration;
65
66 /**
67 * The appointment checkin date and time.
68 *
69 * @var string
70 */
71 private $checkin;
72
73 /**
74 * The number of people.
75 *
76 * @var integer
77 */
78 private $people;
79
80 /**
81 * A factor used to increase the duration by the given number.
82 * For example, if we have a factor equals to 3 and the service lasts 1 hour,
83 * the resulting duration will be equals to 3 hours (3 * 60 min).
84 *
85 * @var integer
86 */
87 private $factor = 1;
88
89 /**
90 * Flag used to check if the item is discounted by a specific deal.
91 * For example, when the service is redeemed by using a package.
92 *
93 * @var boolean
94 */
95 private $discounted = false;
96
97 /**
98 * A list of selected options.
99 *
100 * @var VAPCartOption[]
101 */
102 private $options = array();
103
104 /**
105 * An object holding the item totals.
106 *
107 * @var object
108 * @since 1.7
109 */
110 private $totals;
111
112 /**
113 * Class constructor.
114 *
115 * @param integer $id_ser The service ID.
116 * @param integer $id_emp The employee ID.
117 * @param string $ser_name The service name.
118 * @param string $emp_name The employee name.
119 * @param float $price The service price.
120 * @param integer $duration The service duration.
121 * @param string $checkin The appointment check-in datetime (UTC).
122 * @param integer $people The number of guests.
123 */
124 public function __construct($id_ser, $id_emp, $ser_name, $emp_name, $price, $duration, $checkin, $people = 1)
125 {
126 $this->idService = (int) $id_ser;
127 $this->idEmployee = (int) $id_emp;
128 $this->serviceName = $ser_name;
129 $this->employeeName = $emp_name;
130 $this->duration = (int) $duration;
131 $this->checkin = $checkin;
132 $this->people = (int) $people;
133
134 // calculate totals
135 $this->setPrice($price);
136 }
137
138 /**
139 * Returns the service identifier.
140 *
141 * @return integer
142 *
143 * @deprecated 1.8 Use getServiceID() instead.
144 */
145 public function getID()
146 {
147 return $this->getServiceID();
148 }
149
150 /**
151 * Returns the service identifier.
152 *
153 * @return integer
154 */
155 public function getServiceID()
156 {
157 return $this->idService;
158 }
159
160 /**
161 * Returns the employee identifier.
162 *
163 * @return integer
164 *
165 * @deprecated 1.8 Use getEmployeeID() instead.
166 */
167 public function getID2()
168 {
169 return $this->getEmployeeID();
170 }
171
172 /**
173 * Returns the employee identifier.
174 *
175 * @return integer
176 */
177 public function getEmployeeID()
178 {
179 return $this->idEmployee;
180 }
181
182 /**
183 * Returns the service name.
184 *
185 * @return string
186 *
187 * @deprecated 1.8 Use getServiceID() instead.
188 */
189 public function getName()
190 {
191 return $this->getServiceName();
192 }
193
194 /**
195 * Returns the service name.
196 *
197 * @return string
198 */
199 public function getServiceName()
200 {
201 /**
202 * Translate service name at runtime.
203 *
204 * @since 1.7
205 */
206 $translator = VAPFactory::getTranslator();
207 // translate the specified service
208 $tx = $translator->translate('service', $this->getServiceID());
209
210 if ($tx)
211 {
212 // use the specified translation
213 $name = $tx->name;
214 }
215 else
216 {
217 // use the default service name
218 $name = $this->serviceName;
219 }
220
221 return $name;
222 }
223
224 /**
225 * Returns the employee name.
226 *
227 * @return string
228 *
229 * @deprecated 1.8 Use getEmployeeName() instead.
230 */
231 public function getName2()
232 {
233 return $this->getEmployeeName();
234 }
235
236 /**
237 * Returns the employee name.
238 *
239 * @return string
240 */
241 public function getEmployeeName()
242 {
243 if ($this->getEmployeeID() <= 0)
244 {
245 // no selected employee
246 return '';
247 }
248
249 /**
250 * Translate employee name at runtime.
251 *
252 * @since 1.7
253 */
254 $translator = VAPFactory::getTranslator();
255 // translate the specified employee
256 $tx = $translator->translate('employee', $this->getEmployeeID());
257
258 if ($tx)
259 {
260 // use the specified translation
261 $name = $tx->nickname;
262 }
263 else
264 {
265 // use the default employee name
266 $name = $this->employeeName;
267 }
268
269 return $name;
270 }
271
272 /**
273 * Returns the service price.
274 * In case the service is discounted by a package, the value will be 0.
275 *
276 * @return float
277 */
278 public function getPrice()
279 {
280 if ($this->isDiscounted())
281 {
282 // service discounted by a package
283 return 0;
284 }
285
286 return max(array(0, $this->price));
287 }
288
289 /**
290 * Returns the resulting price after applying the discounts.
291 *
292 * @param mixed $cart When specified, the system will try to apply
293 * the discounts to the base price.
294 * @param array &$lookup A lookup used to track the applied discounts.
295 *
296 * @return float
297 *
298 * @since 1.7
299 */
300 public function getDiscountedPrice($cart = null, &$lookup = array())
301 {
302 $price = $this->getPrice();
303
304 if (!$price)
305 {
306 // the item has been discounted by a package or has no price
307 return 0;
308 }
309
310 // iterate all options in search of a discount
311 foreach ($this->options as $option)
312 {
313 // calculate option total
314 $total = $option->getTotalPrice();
315
316 if ($total < 0)
317 {
318 // in case we have a total lower than 0, treat the option as a discount
319 // and subtract it from the service price
320 $price += $total;
321 }
322 }
323
324 // in case the cart was specified, check whether there are some
325 // discounts to apply
326 if (!$cart || !$cart->getDiscounts())
327 {
328 // nope, use default price
329 return $price;
330 }
331
332 foreach ($cart->getDiscounts() as $discount)
333 {
334 $old = $price;
335
336 // apply discount on cascade
337 $price = $discount->apply($price, $price, $this);
338
339 if (!isset($lookup[$discount->getID()]))
340 {
341 // create discount repository
342 $lookup[$discount->getID()] = 0;
343 }
344
345 // increase repo by subtracting the price after the discount
346 // from the price before the discount
347 $lookup[$discount->getID()] += $old - $price;
348 }
349
350 // make sure the price is not lower than 0
351 return max(array(0, $price));
352 }
353
354 /**
355 * Returns the net price of the service.
356 *
357 * @param mixed $cart When specified, the system will try to apply
358 * the discounts to the base price.
359 *
360 * @return float
361 *
362 * @since 1.7
363 */
364 public function getPriceNet($cart = null)
365 {
366 $base = $this->getPrice();
367
368 if (!$base)
369 {
370 // the item has been discounted by a package or has no price
371 return 0.0;
372 }
373
374 // get discounted price
375 $price = $this->getDiscountedPrice($cart);
376
377 if ($price == $base)
378 {
379 // no discount, use default total net
380 return $this->totals->net;
381 }
382
383 $options = array();
384 $options['subject'] = 'service';
385 // $options['id_user'] = JFactory::getUser()->id;
386
387 // re-calculate net of discounted item
388 return VAPTaxFactory::calculate($this->getServiceID(), $price, $options)->net;
389 }
390
391 /**
392 * Returns the taxes of the service cost.
393 *
394 * @param mixed $cart When specified, the system will try to apply
395 * the discounts to the base price.
396 *
397 * @return float
398 *
399 * @since 1.7
400 */
401 public function getPriceTax($cart = null)
402 {
403 $base = $this->getPrice();
404
405 if (!$base)
406 {
407 // the item has been discounted by a package or has no price
408 return 0.0;
409 }
410
411 // get discounted price
412 $price = $this->getDiscountedPrice($cart);
413
414 if ($price == $base)
415 {
416 // no discount, use default total tax
417 return $this->totals->tax;
418 }
419
420 $options = array();
421 $options['subject'] = 'service';
422 // $options['id_user'] = JFactory::getUser()->id;
423
424 // re-calculate taxes of discounted item
425 return VAPTaxFactory::calculate($this->getServiceID(), $price, $options)->tax;
426 }
427
428 /**
429 * Returns the gross price of the service.
430 *
431 * @param mixed $cart When specified, the system will try to apply
432 * the discounts to the base price.
433 *
434 * @return float
435 *
436 * @since 1.7
437 */
438 public function getPriceGross($cart = null)
439 {
440 $base = $this->getPrice();
441
442 if (!$base)
443 {
444 // the item has been discounted by a package or has no price
445 return 0.0;
446 }
447
448 // get discounted price
449 $price = $this->getDiscountedPrice($cart);
450
451 if ($price == $base)
452 {
453 // no discount, use default total gross
454 return $this->totals->gross;
455 }
456
457 $options = array();
458 $options['subject'] = 'service';
459 // $options['id_user'] = JFactory::getUser()->id;
460
461 // re-calculate gross of discounted item
462 return VAPTaxFactory::calculate($this->getServiceID(), $price, $options)->gross;
463 }
464
465 /**
466 * Sets the service price.
467 *
468 * @param float $price The service cost.
469 *
470 * @return self This object to support chaining.
471 *
472 * @since 1.6.6
473 */
474 public function setPrice($price)
475 {
476 $this->price = (float) $price;
477
478 $options = array();
479 $options['subject'] = 'service';
480 // $options['id_user'] = JFactory::getUser()->id;
481
482 // calculate taxes
483 $this->totals = VAPTaxFactory::calculate($this->getServiceID(), $this->getPrice(), $options);
484
485 return $this;
486 }
487
488 /**
489 * Returns the total cost of the service.
490 *
491 * @return float
492 *
493 * @uses getPrice()
494 */
495 public function getTotalCost()
496 {
497 $total = $this->getPrice();
498
499 foreach ($this->options as $o)
500 {
501 $total += $o->getTotalPrice();
502 }
503
504 return $total;
505 }
506
507 /**
508 * Returns the total net.
509 *
510 * @param mixed $cart When specified, the system will try to apply
511 * the discounts to the base price.
512 *
513 * @return float
514 *
515 * @since 1.7
516 */
517 public function getTotalNet($cart = null)
518 {
519 $net = $this->getPriceNet($cart);
520
521 foreach ($this->options as $o)
522 {
523 $net += $o->getTotalNet($cart);
524 }
525
526 return $net;
527 }
528
529 /**
530 * Returns the total taxes.
531 *
532 * @param mixed $cart When specified, the system will try to apply
533 * the discounts to the base price.
534 *
535 * @return float
536 *
537 * @since 1.7
538 */
539 public function getTotalTax($cart = null)
540 {
541 $tax = $this->getPriceTax($cart);
542
543 foreach ($this->options as $o)
544 {
545 $tax += $o->getTotalTax($cart);
546 }
547
548 return $tax;
549 }
550
551 /**
552 * Returns the total gross.
553 *
554 * @param mixed $cart When specified, the system will try to apply
555 * the discounts to the base price.
556 *
557 * @return float
558 *
559 * @since 1.7
560 */
561 public function getTotalGross($cart = null)
562 {
563 $gross = $this->getPriceGross($cart);
564
565 foreach ($this->options as $o)
566 {
567 $gross += $o->getTotalGross($cart);
568 }
569
570 return $gross;
571 }
572
573 /**
574 * Returns the service base duration (in minutes).
575 *
576 * @param boolean $total True to include the extra duration that might be applied
577 * by the selected options (added @since 1.7.3).
578 *
579 * @return integer
580 */
581 public function getDuration($total = true)
582 {
583 $duration = $this->duration;
584
585 if ($total)
586 {
587 /**
588 * Apply the extra duration provided by the options.
589 *
590 * @since 1.7.3
591 */
592 foreach ($this->options as $o)
593 {
594 $duration += $o->getTotalDuration();
595 }
596 }
597
598 return $duration;
599 }
600
601 /**
602 * Sets the service duration.
603 *
604 * @param integer $duration The service duration (in minutes).
605 *
606 * @return self This object to support chaining.
607 *
608 * @since 1.6.6
609 */
610 public function setDuration($duration)
611 {
612 $this->duration = abs((int) $duration);
613
614 return $this;
615 }
616
617 /**
618 * Returns the check-in timestamp (UTC).
619 *
620 * @return integer
621 */
622 public function getCheckinTimestamp()
623 {
624 return JFactory::getDate($this->checkin)->getTimestamp();
625 }
626
627 /**
628 * Returns the formatted check-in.
629 *
630 * @param string $format The date format.
631 * @param mixed $local False to return the date in UTC,
632 * 'customer' to adjust the date into
633 * the user timezone, 'employee' to
634 * use the local timezone set by the
635 * operator, or a DateTimeZone object.
636 *
637 * @return string
638 */
639 public function getCheckinDate($format = null, $local = false)
640 {
641 return $this->formatDate($this->checkin, $format, $local);
642 }
643
644 /**
645 * Returns the check-out timestamp (UTC).
646 *
647 * @return integer
648 *
649 * @since 1.7
650 */
651 public function getCheckoutTimestamp()
652 {
653 $dt = JFactory::getDate($this->checkin);
654 $dt->modify('+' . $this->getDuration() . ' minutes');
655 return $dt->getTimestamp();
656 }
657
658 /**
659 * Returns the formatted check-out.
660 *
661 * @param string $format The date format.
662 * @param mixed $local False to return the date in UTC,
663 * 'customer' to adjust the date into
664 * the user timezone, 'employee' to
665 * use the local timezone set by the
666 * operator, or a DateTimeZone object.
667 *
668 * @return string
669 *
670 * @since 1.7
671 */
672 public function getCheckoutDate($format = null, $local = false)
673 {
674 $dt = JFactory::getDate($this->checkin);
675 $dt->modify('+' . $this->getDuration() . ' minutes');
676
677 return $this->formatDate($dt, $format, $local);
678 }
679
680 /**
681 * Helper method to format the given date.
682 *
683 * @param mixed $date The date to format.
684 * @param string $format The format to use.
685 * @param mixed $local False to return the date in UTC,
686 * 'customer' to adjust the date into
687 * the user timezone, 'employee' to
688 * use the local timezone set by the
689 * operator, or a DateTimeZone object.
690 *
691 * @return string
692 *
693 * @since 1.7
694 */
695 private function formatDate($date, $format = null, $local = false)
696 {
697 if ($local instanceof DateTimeZone)
698 {
699 // use given timezone
700 $tz = $local;
701 }
702 else if (preg_match("/^(user|customer)$/i", $local))
703 {
704 // get timezone of the current user
705 $tz = VikAppointments::getUserTimezone();
706 }
707 else if (preg_match("/^(emp|employee)$/i", $local))
708 {
709 // get timezone of the employee
710 $tz = JModelVAP::getInstance('employee')->getTimezone($this->idEmployee);
711 }
712 else
713 {
714 $tz = null;
715 }
716
717 if (is_string($date))
718 {
719 // create date instance
720 $date = JFactory::getDate($date);
721 }
722
723 if ($tz)
724 {
725 // adjust to fetched timezone
726 $date->setTimezone($tz);
727 }
728
729 if (!$format)
730 {
731 // use default military format if not specified
732 $format = 'Y-m-d H:i:s';
733 }
734
735 // format check-in date
736 return $date->format($format, (bool) $tz);
737 }
738
739 /**
740 * Returns the number of guests.
741 *
742 * @return integer
743 */
744 public function getPeople()
745 {
746 return $this->people;
747 }
748
749 /**
750 * Returns the appointment details.
751 *
752 * @return string
753 */
754 public function getDetails()
755 {
756 // include service name
757 $details = $this->getServiceName();
758
759 if ($this->getEmployeeID() > 0)
760 {
761 // include employee name
762 $details .= ' - ' . $this->getEmployeeName();
763 }
764
765 // wrap service in a tag
766 $details = '<span class="cart-item-summary-service">' . $details . '</span>';
767
768 // fetch details separator
769 $separator = trim(JText::translate('VAP_FOR_DATE_SEPARATOR'));
770
771 if ($separator)
772 {
773 // include the separator in a tag
774 $details .= '<span class="cart-item-summary-separator">&nbsp;' . $separator . '&nbsp;</span>';
775 }
776
777 // format check-in date time, adjusted to the user timezone
778 $checkin = $this->getCheckinDate(JText::translate('DATE_FORMAT_LC2'), 'customer');
779 // include check-in date time within the summary details
780 $details .= '<span class="cart-item-summary-checkin">' . $checkin . '</span>';
781
782 // get working days model
783 $worktime = JModelVAP::getInstance('worktime');
784 // fetch the location matching the specified appointment details
785 $id_loc = $worktime->getLocation($this->getCheckinDate(), $this->getServiceID(), $this->getEmployeeID());
786
787 if ($id_loc)
788 {
789 // get location model
790 $locModel = JModelVAP::getInstance('location');
791 // get location details
792 $location = $locModel->getInfo($id_loc);
793
794 if ($location)
795 {
796 // include location details
797 $details .= '<br /><span class="cart-item-summary-location">' . $location->text . '</span>';
798 }
799 }
800
801 /**
802 * Trigger hook to manipulate the description of the item that is displayed
803 * within the summary cart.
804 *
805 * @param string &$details The description to show.
806 * @param VAPCartItem $item The item instance.
807 *
808 * @return void
809 *
810 * @since 1.7
811 */
812 VAPFactory::getEventDispatcher()->trigger('onPrepareCartItemDetails', array(&$details, $this));
813
814 return $details;
815 }
816
817 /**
818 * Checks if the service is discounted.
819 * The "discounted" term here means that the item has been
820 * redeemed by a package and has no cost.
821 *
822 * @return boolean
823 */
824 public function isDiscounted()
825 {
826 return $this->discounted;
827 }
828
829 /**
830 * Marks the service as discounted or not.
831 *
832 * @param mixed $s True if discounted, false otherwise.
833 *
834 * @return self This object to support chaining.
835 */
836 public function setDiscounted($s)
837 {
838 $this->discounted = (bool) $s;
839
840 return $this;
841 }
842
843 /**
844 * Returns the duration factor of the service.
845 *
846 * @return integer
847 */
848 public function getFactor()
849 {
850 return $this->factor;
851 }
852
853 /**
854 * Sets the duration factor.
855 *
856 * @param integer $f The factor.
857 *
858 * @return self This object to support chaining.
859 */
860 public function setFactor($f)
861 {
862 // make sure the factor has changed
863 if ($f != $this->factor)
864 {
865 // recalculate base price and duration
866 $this->duration /= $this->factor;
867 $this->price /= $this->factor;
868
869 // update factor
870 $this->factor = max(array(1, (int) $f));
871
872 // multiply duration and prices by the new factor
873 $this->duration *= $this->factor;
874 $this->price *= $this->factor;
875
876 // refresh totals
877 $this->setPrice($this->price);
878 }
879
880 return $this;
881 }
882
883 /**
884 * Checks if this item is active or not.
885 *
886 * @return boolean
887 *
888 * @deprecated 1.8 Without replacement.
889 */
890 public function isActive()
891 {
892 return true;
893 }
894
895 /**
896 * Marks this item as active.
897 *
898 * @return self This object to support chaining.
899 *
900 * @deprecated 1.8 Without replacement.
901 */
902 public function active()
903 {
904 return $this;
905 }
906
907 /**
908 * Marks this item as unactive.
909 *
910 * @return self This object to support chaining.
911 *
912 * @deprecated 1.8 Without replacement.
913 */
914 public function remove()
915 {
916 return $this;
917 }
918
919 /**
920 * Adds a new option within the list.
921 *
922 * @param VAPCartOption $opt The option to add.
923 *
924 * @return self This object to support chaining.
925 *
926 * @uses indexOf()
927 */
928 public function addOption(VAPCartOption $opt)
929 {
930 // check whether the specified option already exists
931 $index = $this->indexOf($opt->getID());
932
933 if ($index != -1)
934 {
935 // update the existing one
936 $this->options[$index]->add($opt->getQuantity());
937 }
938 else
939 {
940 // add the option at the end of the list
941 $this->options[] = $opt;
942 }
943
944 return $this;
945 }
946
947 /**
948 * Removes the specified option.
949 *
950 * @param integer $id The option ID.
951 * @param integer $unit The number of units to remove.
952 *
953 * @return boolean True on success, false otherwise.
954 *
955 * @uses indexOf()
956 */
957 public function removeOption($id, $unit = 1)
958 {
959 $index = $this->indexOf($id);
960
961 if ($index != -1)
962 {
963 // remove by the specified units
964 $q = $this->options[$index]->remove($unit);
965
966 if ($q == 0)
967 {
968 // no more units, delete the option from the list
969 array_splice($this->options, $index, 1);
970 }
971
972 return true;
973 }
974
975 return false;
976 }
977
978 /**
979 * Returns the position within the list of the specified option.
980 *
981 * @param integer $id The option ID.
982 *
983 * @return integer The option index if exists, -1 otherwise.
984 *
985 * @uses getOptionsLength()
986 */
987 public function indexOf($id)
988 {
989 for ($i = 0; $i < $this->getOptionsLength(); $i++)
990 {
991 if ($this->options[$i]->getID() == $id)
992 {
993 return $i;
994 }
995 }
996
997 return -1;
998 }
999
1000 /**
1001 * Returns the option at the specified index.
1002 *
1003 * @param integer $index The option index.
1004 *
1005 * @return mixed The option if exists, false otherwise.
1006 *
1007 * @uses getoptionsLength()
1008 */
1009 public function getOptionAt($index)
1010 {
1011 if ($index >= 0 && $index < $this->getOptionsLength())
1012 {
1013 return $this->options[$index];
1014 }
1015
1016 return null;
1017 }
1018
1019 /**
1020 * Returns the number of options within the list.
1021 * The list may contain also options that are no more
1022 * active (quantity less than 1).
1023 *
1024 * @return integer
1025 */
1026 public function getOptionsLength()
1027 {
1028 return count($this->options);
1029 }
1030
1031 /**
1032 * Empties the options list.
1033 *
1034 * @return self This object to support chaining.
1035 */
1036 public function emptyOptions()
1037 {
1038 $this->options = array();
1039
1040 return $this;
1041 }
1042
1043 /**
1044 * Checks if there are no options within the list.
1045 *
1046 * @return boolean
1047 */
1048 public function isEmpty()
1049 {
1050 return count($this->options) == 0;
1051 }
1052
1053 /**
1054 * Balances the item in order to remove all the options
1055 * with quantity lower than 1.
1056 *
1057 * @return self This object to support chaining.
1058 *
1059 * @deprecated 1.8 Without replacement.
1060 */
1061 public function balance()
1062 {
1063 // do nothing, balance is automatically made every
1064 // time an option gets removed
1065
1066 return $this;
1067 }
1068
1069 /**
1070 * Returns a list containing all the active options.
1071 *
1072 * @return array
1073 */
1074 public function getOptionsList()
1075 {
1076 return $this->options;
1077 }
1078
1079 /**
1080 * Returns the first available index to push a new option.
1081 * Used to replace a unactive option with a new one.
1082 *
1083 * @return integer
1084 *
1085 * @deprecated 1.8 Without replacement.
1086 */
1087 protected function getFirstAvailableIndex()
1088 {
1089 return $this->getOptionsLength();
1090 }
1091
1092 /**
1093 * Magic method used to return a string representation of this instance.
1094 *
1095 * @return string
1096 */
1097 public function __tostring()
1098 {
1099 return '<pre>' . print_r($this, true) . '</pre>';
1100 }
1101
1102 /**
1103 * Returns an array containing the details of this instance.
1104 *
1105 * @return array
1106 */
1107 public function toArray()
1108 {
1109 $arr = array(
1110 'id_service' => $this->getServiceID(),
1111 'id_employee' => $this->getEmployeeID(),
1112 'service_name' => $this->getServiceName(),
1113 'employee_name' => $this->getEmployeeName(),
1114 'price' => $this->getPrice(),
1115 'totalcost' => $this->getTotalCost(),
1116 'duration' => $this->getDuration(),
1117 'checkin' => $this->getCheckinDate(),
1118 'people' => $this->getPeople(),
1119 'details' => $this->getDetails(),
1120 'totals' => $this->totals,
1121 'options' => array(),
1122 );
1123
1124 // replicate checkin date time by using a different attribute
1125 $arr['checkin_ts'] = $arr['checkin'];
1126
1127 foreach ($this->options as $o)
1128 {
1129 $arr['options'][] = $o->toArray();
1130 }
1131
1132 return $arr;
1133 }
1134
1135 /**
1136 * Creates a standard object, containing all the supported properties,
1137 * to be used when this class is passed to "json_encode()".
1138 *
1139 * @return object
1140 *
1141 * @since 1.7
1142 *
1143 * @see JsonSerializable
1144 */
1145 #[ReturnTypeWillChange]
1146 public function jsonSerialize()
1147 {
1148 return $this->toArray();
1149 }
1150 }
1151