PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.6
VikBooking Hotel Booking Engine & PMS v1.8.6
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 / multitask / parser.php

parser.php in VikBooking Hotel Booking Engine & PMS 1.8.6, at admin/helpers/src/multitask/parser.php

338 lines 7.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 Alessio Gaggii - E4J s.r.l.
6 * @copyright Copyright (C) 2022 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 * Multitask data extraction for admin widgets.
16 *
17 * @since 1.15.0 (J) - 1.5.0 (WP)
18 */
19 final class VBOMultitaskParser
20 {
21 /**
22 * The singleton instance of the class.
23 *
24 * @var VBOMultitaskFactory
25 */
26 private static $instance = null;
27
28 /**
29 * The view/task where multitask is being used.
30 *
31 * @var string
32 */
33 private $page_name = '';
34
35 /**
36 * The page URI where multitask is being used.
37 *
38 * @var string
39 */
40 private $page_uri = '';
41
42 /**
43 * The page query values.
44 *
45 * @var array
46 */
47 private $page_query = [];
48
49 /**
50 * Returns the global object to immediately support chaining.
51 * Either a new instance or the existing instance.
52 *
53 * @param string $page the name of the view/task.
54 * @param string $uri the page URI to parse.
55 *
56 * @return self
57 */
58 public static function getInstance($page = '', $uri = '')
59 {
60 if (is_null(static::$instance)) {
61 static::$instance = new static($page, $uri);
62 }
63
64 return static::$instance;
65 }
66
67 /**
68 * Those pages capable of receiving data for a clicked Push notification through
69 * query string can use this method to quickly validate and parse the admin widget
70 * to load and the multitask data + options to set for rendering the information.
71 *
72 * @param array $data associative list of multitask data.
73 * @param mixed $payload JSON-encoded string or decoded object payload.
74 *
75 * @return array numeric list of widget ID, data and options.
76 *
77 * @since 1.16.5 (J) - 1.6.5 (WP)
78 */
79 public static function queryPushData(array $data, $payload)
80 {
81 $parsed = [
82 'widget_id' => '',
83 'multitask_data' => $data,
84 'multitask_options' => [],
85 ];
86
87 if (empty($payload)) {
88 // do not proceed
89 return array_values($parsed);
90 }
91
92 if (is_string($payload)) {
93 // attempt to JSON-decode the payload encoded string
94 $decoded_payload = json_decode($payload);
95
96 /**
97 * Payloads may have been previously encoded in base64, which expects binary data as its input.
98 * In case of titles or messages in the Push notification payload with multi-byte characters,
99 * JSON-decoding the string that was base64-decoded, may result into malformed UTF-8 characters.
100 * In this case, we will try to convert any character to ASCII by ignoring what's not UTF-8.
101 */
102 if (json_last_error() && json_last_error() === JSON_ERROR_UTF8) {
103 // try to convert the encoding from UTF-8 to any ASCII
104 $payload = json_decode(@iconv("UTF-8", "ASCII//TRANSLIT//IGNORE", $payload));
105 } else {
106 // assign the properly decoded value
107 $payload = $decoded_payload;
108 }
109 }
110
111 if (is_object($payload) && isset($payload->type) && (isset($payload->title) || isset($payload->message))) {
112 // determine the type of widget that should handle the notification data
113 $parsed['widget_id'] = $payload->type == 'Chat' ? 'guest_messages' : 'booking_details';
114
115 // extract and remove raw content from payload
116 $raw_content = isset($payload->content) ? (array)$payload->content : [];
117 unset($payload->content);
118
119 // build multitask options
120 $parsed['multitask_options'] = array_merge(['_push' => 1], (array)$payload, $raw_content);
121 }
122
123 return array_values($parsed);
124 }
125
126 /**
127 * Class constructor.
128 *
129 * @param string $page the name of the view/task.
130 * @param string $uri the page URI to parse.
131 */
132 public function __construct($page = '', $uri = '')
133 {
134 // set name for view/task to consider
135 $this->setPageName($page);
136
137 // set URI to parse
138 $this->setPageURI($uri);
139 }
140
141 /**
142 * Builds a multitask data object with the page information
143 * ready to be passed to the admin widget being rendered.
144 *
145 * @return VBOMultitaskData
146 */
147 public function getData()
148 {
149 /**
150 * Rendering an admin widget does support injected request values.
151 *
152 * @since 1.16.0 (J) - 1.6.0 (WP)
153 */
154 $injected_data = JFactory::getApplication()->input->get('multitask_data', [], 'array');
155
156 // extra the options for multitask data, if any
157 $data_options = [];
158 if (isset($injected_data['_options'])) {
159 // access the options received
160 $data_options = (array)$injected_data['_options'];
161
162 // separate options layer from regular data
163 unset($injected_data['_options']);
164 }
165
166 // get a new multitask data object instance
167 $multitask_data = new VBOMultitaskData($injected_data);
168
169 // inject current page values
170 $multitask_data->setPage($this->getPageName());
171 $multitask_data->setURI($this->getPageURI());
172 $multitask_data->setQuery($this->getPageQueryValues());
173
174 // check if the page has a booking
175 $page_booking_id = $this->getPageBookingId();
176 if ($page_booking_id) {
177 $multitask_data->setBookingId($page_booking_id);
178 }
179
180 /**
181 * Register a separate layer of data that will serve as multitask options.
182 *
183 * @since 1.16.5 (J) - 1.6.5 (WP)
184 */
185 $multitask_data->registerDataOptions($data_options);
186
187 // return the data object for the admin widget
188 return $multitask_data;
189 }
190
191 /**
192 * Binds data to the multitask options object and returns it.
193 *
194 * @return VBOMultitaskOptions
195 *
196 * @since 1.16.5 (J) - 1.6.5 (WP)
197 */
198 public function getOptions()
199 {
200 return VBOMultitaskOptions::getInstance(JFactory::getApplication()->input->get('_options', [], 'array'));
201 }
202
203 /**
204 * Gets the current name of the view/task.
205 *
206 * @return string
207 */
208 public function getPageName()
209 {
210 return $this->page_name;
211 }
212
213 /**
214 * Sets the current name of the view/task.
215 *
216 * @param string $page the name of the view/task.
217 *
218 * @return self
219 */
220 public function setPageName($page = '')
221 {
222 $this->page_name = $page;
223
224 return $this;
225 }
226
227 /**
228 * Gets the current page URI.
229 *
230 * @return string
231 */
232 public function getPageURI()
233 {
234 return $this->page_uri;
235 }
236
237 /**
238 * Sets the current page URI.
239 *
240 * @param string $uri the page URI to parse
241 *
242 * @return self
243 */
244 public function setPageURI($uri = '')
245 {
246 $this->page_uri = $uri;
247
248 // parse current URI
249 $this->parseCurrentURI();
250
251 return $this;
252 }
253
254 /**
255 * Gets the current values for the page query.
256 *
257 * @return array
258 */
259 public function getPageQueryValues()
260 {
261 return $this->page_query;
262 }
263
264 /**
265 * Parses the current URI to detect values to extract.
266 *
267 * @return void
268 */
269 private function parseCurrentURI()
270 {
271 // reset query values
272 $this->page_query = [];
273
274 if (empty($this->page_uri)) {
275 // nothing to parse
276 return;
277 }
278
279 // parse URL data
280 $uri_data = parse_url($this->page_uri);
281
282 if (!isset($uri_data['query'])) {
283 // no query values to parse
284 return;
285 }
286
287 // parse query variables
288 $uri_data['query'] = str_replace('&amp;', '&', $uri_data['query']);
289
290 // inject parsed string values in page_query
291 parse_str($uri_data['query'], $this->page_query);
292
293 // adjust values, if needed
294 if (empty($this->page_name)) {
295 // try guessing the page from the query values
296 if (!empty($this->page_query['view'])) {
297 $this->page_name = $this->page_query['view'];
298 } elseif (!empty($this->page_query['task'])) {
299 $this->page_name = $this->page_query['task'];
300 }
301 }
302 }
303
304 /**
305 * Checks whether the page contains a booking.
306 *
307 * @return bool|int false on failure or reservation ID.
308 */
309 private function getPageBookingId()
310 {
311 if (!is_array($this->page_query) || !count($this->page_query)) {
312 return false;
313 }
314
315 // list of pages that can contain a reservation
316 $pages_with_booking = [
317 'editorder',
318 'editbusy',
319 'bookingcheckin',
320 ];
321
322 if (!in_array($this->page_name, $pages_with_booking)) {
323 return false;
324 }
325
326 if (!isset($this->page_query['cid']) || !is_array($this->page_query['cid'])) {
327 return false;
328 }
329
330 if (empty($this->page_query['cid'][0])) {
331 return false;
332 }
333
334 // booking ID found
335 return (int)$this->page_query['cid'][0];
336 }
337 }
338