| @@ -1,0 +1,255 @@ | ||
| 1 | +<?php | |
| 2 | +/** | |
| 3 | + * @package VikBooking | |
| 4 | + * @subpackage com_vikbooking | |
| 5 | + * @author Alessio Gaggii - e4j - Extensionsforjoomla.com | |
| 6 | + * @copyright Copyright (C) 2020 e4j - Extensionsforjoomla.com. All rights reserved. | |
| 7 | + * @license GNU General Public License version 2 or later; see LICENSE | |
| 8 | + * @link https://vikwp.com | |
| 9 | + */ | |
| 10 | + | |
| 11 | +defined('ABSPATH') or die('No script kiddies please!'); | |
| 12 | + | |
| 13 | +/** | |
| 14 | + * Critical Dates handler class for Vik Booking. | |
| 15 | + * | |
| 16 | + * @since 1.13.5 (J) - 1.3.5 (WP) | |
| 17 | + */ | |
| 18 | +class VikBookingCriticalDates | |
| 19 | +{ | |
| 20 | + /** | |
| 21 | + * The singleton instance of the class. | |
| 22 | + * | |
| 23 | + * @var VikBookingCriticalDates | |
| 24 | + */ | |
| 25 | + protected static $instance = null; | |
| 26 | + | |
| 27 | + /** | |
| 28 | + * Class constructor is protected. | |
| 29 | + * | |
| 30 | + * @see getInstance() | |
| 31 | + */ | |
| 32 | + protected function __construct() | |
| 33 | + {} | |
| 34 | + | |
| 35 | + /** | |
| 36 | + * Returns the global Critical Dates object, either | |
| 37 | + * a new instance or the existing instance | |
| 38 | + * if the class was already instantiated. | |
| 39 | + * | |
| 40 | + * @return self a new instance of the class. | |
| 41 | + */ | |
| 42 | + public static function getInstance() | |
| 43 | + { | |
| 44 | + if (is_null(static::$instance)) { | |
| 45 | + static::$instance = new static(); | |
| 46 | + } | |
| 47 | + | |
| 48 | + return static::$instance; | |
| 49 | + } | |
| 50 | + | |
| 51 | + /** | |
| 52 | + * Checks whether a precise note exists on the given date. | |
| 53 | + * | |
| 54 | + * @param string $ymd the date string in Y-m-d format. | |
| 55 | + * @param int $idroom the ID of the room involved. | |
| 56 | + * @param int $subunit the index of the sub-unit (0 by default). | |
| 57 | + * @param string $key the key name of the note. | |
| 58 | + * @param bool $get whether to get the found record. | |
| 59 | + * | |
| 60 | + * @return mixed True/array if festivity exists, false otherwise. | |
| 61 | + */ | |
| 62 | + public function dayNoteExists($ymd, $idroom, $subunit = 0, $key = '', $get = false) | |
| 63 | + { | |
| 64 | + // vars validation | |
| 65 | + $idroom = intval($idroom); | |
| 66 | + $subunit = intval($subunit); | |
| 67 | + | |
| 68 | + $dbo = JFactory::getDbo(); | |
| 69 | + | |
| 70 | + $q = "SELECT * FROM `#__vikbooking_critical_dates` WHERE `dt`=" . $dbo->q($ymd) . " AND `idroom`={$idroom} AND `subunit`={$subunit};"; | |
| 71 | + $dbo->setQuery($q); | |
| 72 | + $note = $dbo->loadAssoc(); | |
| 73 | + if (!$note) { | |
| 74 | + return false; | |
| 75 | + } | |
| 76 | + | |
| 77 | + $notes_info = json_decode($note['info']); | |
| 78 | + if (!$notes_info) { | |
| 79 | + return false; | |
| 80 | + } | |
| 81 | + | |
| 82 | + // update this information in the array in case it needs to be returned | |
| 83 | + $note['info'] = $notes_info; | |
| 84 | + | |
| 85 | + // seek for the requested note | |
| 86 | + foreach ($notes_info as $n) { | |
| 87 | + if (empty($key) || (!empty($n->type) && $n->type == $key)) { | |
| 88 | + return $get ? $note : true; | |
| 89 | + } | |
| 90 | + } | |
| 91 | + | |
| 92 | + return false; | |
| 93 | + } | |
| 94 | + | |
| 95 | + /** | |
| 96 | + * Stores/updates a note for the given date, idroom and subunit. If a record for the given data exists, then the | |
| 97 | + * note is added to or updated in the current record. Otherwise a new record is created. | |
| 98 | + * | |
| 99 | + * @param array $note the array note to store. | |
| 100 | + * @param string $ymd the date string in Y-m-d format. | |
| 101 | + * @param int $idroom the ID of the room involved. | |
| 102 | + * @param int $subunit the index of the sub-unit (0 by default). | |
| 103 | + * | |
| 104 | + * @return bool True if the new record is stored or updated, false otherwise. | |
| 105 | + */ | |
| 106 | + public function storeDayNote($note, $ymd, $idroom = 0, $subunit = 0) | |
| 107 | + { | |
| 108 | + // vars validation | |
| 109 | + $idroom = intval($idroom); | |
| 110 | + $subunit = intval($subunit); | |
| 111 | + if (!is_array($note) || (empty($note['name']) && empty($note['descr']))) { | |
| 112 | + return false; | |
| 113 | + } | |
| 114 | + | |
| 115 | + if (!isset($note['type'])) { | |
| 116 | + $note['type'] = 'custom'; | |
| 117 | + } | |
| 118 | + | |
| 119 | + if (!isset($note['ts'])) { | |
| 120 | + $note['ts'] = time(); | |
| 121 | + } | |
| 122 | + | |
| 123 | + if (!empty($note['name'])) { | |
| 124 | + // make sure the "name" does not contain commas, which may be used by JS as separator in the readable notes data attribute | |
| 125 | + $note['name'] = trim(str_replace(',', '', $note['name'])); | |
| 126 | + } | |
| 127 | + | |
| 128 | + $dbo = JFactory::getDbo(); | |
| 129 | + | |
| 130 | + $q = "SELECT * FROM `#__vikbooking_critical_dates` WHERE `dt`=" .$dbo->q($ymd) . " AND `idroom`={$idroom} AND `subunit`={$subunit}"; | |
| 131 | + $dbo->setQuery($q); | |
| 132 | + $prevNote = $dbo->loadAssoc(); | |
| 133 | + if (!$prevNote) { | |
| 134 | + // create a new record | |
| 135 | + $q = "INSERT INTO `#__vikbooking_critical_dates` (`dt`, `idroom`, `subunit`, `info`) VALUES (".$dbo->q($ymd).", ".$dbo->q($idroom).", ".$dbo->q($subunit).", ".$dbo->q(json_encode(array($note))).");"; | |
| 136 | + $dbo->setQuery($q); | |
| 137 | + $dbo->execute(); | |
| 138 | + | |
| 139 | + return (bool) ((int) $dbo->insertid()); | |
| 140 | + } | |
| 141 | + | |
| 142 | + // update current record by pushing the note into the existing info array of objects | |
| 143 | + $notes_arr = json_decode($prevNote['info']); | |
| 144 | + array_push($notes_arr, (object) $prevNote); | |
| 145 | + $q = "UPDATE `#__vikbooking_critical_dates` SET `info`=".$dbo->q(json_encode($notes_arr))." WHERE `id`={$prevNote['id']};"; | |
| 146 | + $dbo->setQuery($q); | |
| 147 | + $dbo->execute(); | |
| 148 | + | |
| 149 | + return (bool) ((int) $dbo->getAffectedRows()); | |
| 150 | + } | |
| 151 | + | |
| 152 | + /** | |
| 153 | + * Deletes a specific note for the given date, room ID and subunit. | |
| 154 | + * If the day will not contain anymore notes, then | |
| 155 | + * the whole record will be deleted. | |
| 156 | + * | |
| 157 | + * @param int $index the array index of the note. | |
| 158 | + * @param string $ymd the date string in Y-m-d format. | |
| 159 | + * @param int $idroom the room ID involved. | |
| 160 | + * @param int $subunit the subunit of the room ID. | |
| 161 | + * @param string $type the key name of the note ('custom' for manual entries). | |
| 162 | + * | |
| 163 | + * @return bool True if the fest is removed, false otherwise. | |
| 164 | + */ | |
| 165 | + public function deleteDayNote($index, $ymd, $idroom = 0, $subunit = 0, $type = 'custom') | |
| 166 | + { | |
| 167 | + $record = $this->dayNoteExists($ymd, $idroom, $subunit, $type, true); | |
| 168 | + if (!$record) { | |
| 169 | + return false; | |
| 170 | + } | |
| 171 | + | |
| 172 | + $drop_record = false; | |
| 173 | + if (isset($record['info'][$index])) { | |
| 174 | + // note was found by array-index | |
| 175 | + array_splice($record['info'], $index, 1); | |
| 176 | + if (!count($record['info'])) { | |
| 177 | + // this day has got no more notes | |
| 178 | + $drop_record = true; | |
| 179 | + } | |
| 180 | + } else { | |
| 181 | + // seek for the requested note by type | |
| 182 | + foreach ($record['info'] as $k => $note) { | |
| 183 | + if (empty($type) || (!empty($note->type) && $note->type == $type)) { | |
| 184 | + // note found | |
| 185 | + array_splice($record['info'], $k, 1); | |
| 186 | + if (!count($record['info'])) { | |
| 187 | + // this day has got no more notes | |
| 188 | + $drop_record = true; | |
| 189 | + } | |
| 190 | + break; | |
| 191 | + } | |
| 192 | + } | |
| 193 | + } | |
| 194 | + | |
| 195 | + $dbo = JFactory::getDbo(); | |
| 196 | + if ($drop_record) { | |
| 197 | + $q = "DELETE FROM `#__vikbooking_critical_dates` WHERE `dt`=" . $dbo->q($ymd) . " AND `idroom`={$idroom} AND `subunit`={$subunit}"; | |
| 198 | + } else { | |
| 199 | + $q = "UPDATE `#__vikbooking_critical_dates` SET `info`=".$dbo->q(json_encode($record['info']))." WHERE `dt`=" . $dbo->q($ymd) . " AND `idroom`={$idroom} AND `subunit`={$subunit}"; | |
| 200 | + } | |
| 201 | + $dbo->setQuery($q); | |
| 202 | + $dbo->execute(); | |
| 203 | + | |
| 204 | + return true; | |
| 205 | + } | |
| 206 | + | |
| 207 | + /** | |
| 208 | + * Loads the room day notes of any type and returns and associative | |
| 209 | + * array indexed by date with decoded notes information. | |
| 210 | + * | |
| 211 | + * @param string $from_ymd Optional minimum date in Y-m-d (defaults to today). | |
| 212 | + * @param string $to_ymd Optional maximum date in Y-m-d (defaults to none). | |
| 213 | + * @param int $idroom Optional room id filter. | |
| 214 | + * @param int $subunit Optional room index filter. | |
| 215 | + * | |
| 216 | + * @return array the list of festivities found in VikBooking. | |
| 217 | + */ | |
| 218 | + public function loadRoomDayNotes($from_ymd = null, $to_ymd = null, $idroom = null, $subunit = null) | |
| 219 | + { | |
| 220 | + $dbo = JFactory::getDbo(); | |
| 221 | + | |
| 222 | + $rdnotes = []; | |
| 223 | + | |
| 224 | + if (empty($from_ymd)) { | |
| 225 | + $from_ymd = date('Y-m-d'); | |
| 226 | + } | |
| 227 | + | |
| 228 | + $clauses = []; | |
| 229 | + array_push($clauses, "`dt` >= " . $dbo->q($from_ymd)); | |
| 230 | + | |
| 231 | + if (!empty($to_ymd)) { | |
| 232 | + array_push($clauses, "`dt` <= " . $dbo->q($to_ymd)); | |
| 233 | + } | |
| 234 | + if ($idroom !== null && is_int($idroom)) { | |
| 235 | + array_push($clauses, "`idroom`=" . (int) $idroom); | |
| 236 | + } | |
| 237 | + if ($subunit !== null && is_int($subunit)) { | |
| 238 | + array_push($clauses, "`subunit`=" . (int) $subunit); | |
| 239 | + } | |
| 240 | + | |
| 241 | + $q = "SELECT * FROM `#__vikbooking_critical_dates` WHERE " . implode(' AND ', $clauses) . " ORDER BY `dt` ASC;"; | |
| 242 | + $dbo->setQuery($q); | |
| 243 | + $all_notes = $dbo->loadAssocList(); | |
| 244 | + | |
| 245 | + // make sure to decode all notes infos | |
| 246 | + foreach ($all_notes as $k => $v) { | |
| 247 | + $v['info'] = json_decode($v['info']); | |
| 248 | + $keyid = $v['dt'] . '_' . ((int) $v['idroom']) . '_' . ((int) $v['subunit']); | |
| 249 | + // set room-day note | |
| 250 | + $rdnotes[$keyid] = $v; | |
| 251 | + } | |
| 252 | + | |
| 253 | + return $rdnotes; | |
| 254 | + } | |
| 255 | +} | |