PluginProbe
VikBooking Hotel Booking Engine & PMS / trunk
VikBooking Hotel Booking Engine & PMS vtrunk
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 / geocoding.php

geocoding.php in VikBooking Hotel Booking Engine & PMS trunk, at admin/helpers/geocoding.php

742 lines 24.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 com_vikbooking
5 * @author Alessio Gaggii - e4j - Extensionsforjoomla.com
6 * @copyright Copyright (C) 2018 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 * Helper class for the geocoding functions.
15 *
16 * @since 1.4.0
17 */
18 class VikBookingHelperGeocoding
19 {
20 /**
21 * The singleton instance of the class.
22 *
23 * @var VikBookingHelperGeocoding
24 */
25 protected static $instance = null;
26
27 /**
28 * The Google Maps API Key.
29 *
30 * @var string
31 */
32 protected $gmaps_apikey = null;
33
34 /**
35 * The current room geo-params.
36 *
37 * @var mixed
38 */
39 protected $room_geoparams = null;
40
41 /**
42 * The current room params.
43 *
44 * @var mixed
45 */
46 protected $room_params = null;
47
48 /**
49 * Class constructor is protected.
50 *
51 * @see getInstance()
52 */
53 protected function __construct()
54 {
55 // load the Google Maps API Key from the configuration settings
56 $this->setGoogleMapsKey(VikBooking::getGoogleMapsKey());
57 }
58
59 /**
60 * Returns the global object, either
61 * a new instance or the existing instance
62 * if the class was already instantiated.
63 *
64 * @return self A new instance of the class.
65 */
66 public static function getInstance()
67 {
68 if (is_null(static::$instance)) {
69 static::$instance = new static();
70 }
71
72 return static::$instance;
73 }
74
75 /**
76 * Sets the Google Maps API Key.
77 *
78 * @param string the Google Maps API Key to set
79 *
80 * @return self
81 */
82 public function setGoogleMapsKey($apikey = null)
83 {
84 $this->gmaps_apikey = $apikey;
85
86 return $this;
87 }
88
89 /**
90 * Gets the current Google Maps API Key.
91 *
92 * @return mixed string or false if empty.
93 */
94 public function getGoogleMapsKey()
95 {
96 if (empty($this->gmaps_apikey)) {
97 return false;
98 }
99
100 return $this->gmaps_apikey;
101 }
102
103 /**
104 * Checks whether the Google Maps can be used.
105 *
106 * @return bool true or false
107 */
108 public function isSupported()
109 {
110 return (!empty($this->gmaps_apikey));
111 }
112
113 /**
114 * Loads the necessary assets to the document for Google Maps.
115 *
116 * @param mixed string or array values values to append to the URL.
117 *
118 * @return self
119 *
120 * @since 1.18.3 (J) - 1.8.3 (WP) loaded file gmaps-utils.js.
121 */
122 public function loadAssets($params = null)
123 {
124 static $loaded = null;
125
126 if (empty($this->gmaps_apikey) || $loaded) {
127 return $this;
128 }
129
130 // turn flag on
131 $loaded = true;
132
133 // values like &callback=initMap could be passed as argument
134 $qstring = '';
135
136 if (!empty($params)) {
137 if (is_string($params)) {
138 $qstring = (substr($params, 0, 1) != '&' ? '&' : '') . $params;
139 } elseif (!is_scalar($params)) {
140 $qstring = '&' . http_build_query($params);
141 }
142 }
143
144 $document = JFactory::getDocument();
145
146 // load the Google Maps Utils file within VikBooking
147 $document->addScript(VBO_SITE_URI . 'resources/gmaps-utils.js', ['version' => VIKBOOKING_SOFTWARE_VERSION]);
148
149 // load Google Maps API JS
150 $document->addScript('https://maps.googleapis.com/maps/api/js?key=' . $this->gmaps_apikey . $qstring);
151
152 return $this;
153 }
154
155 /**
156 * Gets the room parameters (one or all) related to the geocoding.
157 * Class variables are using to cache parameters into the buffer.
158 *
159 * @param mixed $rparams string to be decoded or array/object params.
160 * @param string $key the optional param key to get.
161 * @param mixed $def the default room param value to return.
162 *
163 * @return mixed object with all params or empty object, requested param otherwise.
164 */
165 public function getRoomGeoParams($rparams, $key = null, $def = null)
166 {
167 $geoparams = new stdClass;
168
169 if (empty($rparams)) {
170 return !empty($key) ? $def : $geoparams;
171 }
172
173 if ($this->room_geoparams === null || $this->room_params != $rparams || $key === null) {
174 if (is_string($rparams)) {
175 $rparams_obj = json_decode($rparams);
176 if (!is_object($rparams_obj) || !isset($rparams_obj->geo)) {
177 return !empty($key) ? $def : $geoparams;
178 }
179 $geoparams = $rparams_obj->geo;
180 } elseif (is_array($rparams)) {
181 // rooms parameters already decoded, convert it to object
182 $geoparams = json_decode(json_encode($rparams));
183 } elseif (is_object($rparams)) {
184 // rooms parameters already decoded
185 $geoparams = $rparams;
186 }
187
188 if (is_object($geoparams) && isset($geoparams->geo)) {
189 $geoparams = $geoparams->geo;
190 }
191
192 // update global vars
193 $this->room_params = $rparams;
194 $this->room_geoparams = $geoparams;
195 }
196
197 if (($key == 'units_pos' || $key === null) && is_object($this->room_geoparams) && isset($this->room_geoparams->units_pos)) {
198 $units_pos = $this->room_geoparams->units_pos;
199 // make sure to adjust some properties of type float (number) so that they are not strings
200 foreach ($units_pos as $k => $unit) {
201 if (isset($unit->lat)) {
202 $units_pos->{$k}->lat = (float)$unit->lat;
203 }
204 if (isset($unit->lng)) {
205 $units_pos->{$k}->lng = (float)$unit->lng;
206 }
207 if (isset($unit->icon)) {
208 foreach ($unit->icon as $icon_prop => $icon_val) {
209 if ($icon_prop == 'fillOpacity') {
210 $units_pos->{$k}->icon->{$icon_prop} = (float)$icon_val;
211 }
212 if ($icon_prop == 'scale') {
213 $units_pos->{$k}->icon->{$icon_prop} = (float)$icon_val;
214 }
215 if ($icon_prop == 'strokeWeight') {
216 $units_pos->{$k}->icon->{$icon_prop} = (float)$icon_val;
217 }
218 if ($icon_prop == 'anchor' && isset($icon_val->x) && isset($icon_val->y)) {
219 // anchor point object is composed of coordinates with numbers
220 $units_pos->{$k}->icon->{$icon_prop}->x = (float)$icon_val->x;
221 $units_pos->{$k}->icon->{$icon_prop}->y = (float)$icon_val->y;
222 }
223 if (($icon_prop == 'size' || $icon_prop == 'scaledSize') && isset($icon_val->width) && isset($icon_val->height)) {
224 // size and scaledSize object is composed of size width and height numbers
225 $units_pos->{$k}->icon->{$icon_prop}->width = (int)$icon_val->width;
226 $units_pos->{$k}->icon->{$icon_prop}->height = (int)$icon_val->height;
227 }
228 }
229 }
230 }
231 $this->room_geoparams->units_pos = $units_pos;
232 }
233
234 if (!empty($key)) {
235 return is_object($this->room_geoparams) && isset($this->room_geoparams->{$key}) ? $this->room_geoparams->{$key} : $def;
236 }
237
238 return $geoparams;
239 }
240
241 /**
242 * Gets the list of default marker symbols (SVG icons) for Google Maps.
243 *
244 * @return array list of default marker symbols.
245 */
246 public function getDefaultMarkerSymbols()
247 {
248 $symbols = array();
249 $group = 'default';
250 $color = '#000000';
251 $opacity = 1;
252
253 $symbol = new stdClass;
254 $symbol->id = 'hotel';
255 $symbol->name = 'Hotel';
256 $symbol->group = $group;
257 $symbol->fill = $color;
258 $symbol->opacity = $opacity;
259 $symbol->width = 48.4;
260 $symbol->height = 43;
261 $symbol->path = 'M47,5.4c0.7,0,1.3-0.6,1.3-1.3V1.3C48.4,0.6,47.8,0,47,0H1.3C0.6,0,0,0.6,0,1.3V4c0,0.7,0.6,1.3,1.3,1.3h1.3v32.2H1.3 C0.6,37.6,0,38.2,0,39v2.7C0,42.4,0.6,43,1.3,43h20.2v-6.7c0-0.7,0.6-1.3,1.3-1.3h2.7c0.7,0,1.3,0.6,1.3,1.3V43H47 c0.7,0,1.3-0.6,1.3-1.3V39c0-0.7-0.6-1.3-1.3-1.3h-1.3V5.4H47z M21.5,9.1c0-0.5,0.5-1.1,1.1-1.1h3.2c0.5,0,1.1,0.5,1.1,1.1v3.2 c0,0.5-0.5,1.1-1.1,1.1h-3.2c-0.5,0-1.1-0.5-1.1-1.1L21.5,9.1L21.5,9.1z M21.5,17.2c0-0.5,0.5-1.1,1.1-1.1h3.2 c0.5,0,1.1,0.5,1.1,1.1v3.2c0,0.5-0.5,1.1-1.1,1.1h-3.2c-0.5,0-1.1-0.5-1.1-1.1L21.5,17.2L21.5,17.2z M10.8,9.1 c0-0.5,0.5-1.1,1.1-1.1h3.2c0.5,0,1.1,0.5,1.1,1.1v3.2c0,0.5-0.5,1.1-1.1,1.1h-3.2c-0.5,0-1.1-0.5-1.1-1.1L10.8,9.1L10.8,9.1z M15.1,21.5h-3.2c-0.5,0-1.1-0.5-1.1-1.1v-3.2c0-0.5,0.5-1.1,1.1-1.1H15c0.5,0,1.1,0.5,1.1,1.1v3.2C16.1,21,15.6,21.5,15.1,21.5 L15.1,21.5z M16.1,32.2c0-4.5,3.6-8.1,8.1-8.1s8.1,3.6,8.1,8.1H16.1z M37.6,20.4c0,0.5-0.5,1.1-1.1,1.1h-3.2c-0.5,0-1.1-0.5-1.1-1.1 v-3.2c0-0.5,0.5-1.1,1.1-1.1h3.2c0.5,0,1.1,0.5,1.1,1.1V20.4L37.6,20.4z M37.6,12.4c0,0.5-0.5,1.1-1.1,1.1h-3.2 c-0.5,0-1.1-0.5-1.1-1.1V9.1c0-0.5,0.5-1.1,1.1-1.1h3.2c0.5,0,1.1,0.5,1.1,1.1V12.4z';
262 array_push($symbols, $symbol);
263
264 $symbol = new stdClass;
265 $symbol->id = 'home';
266 $symbol->name = 'Home';
267 $symbol->group = $group;
268 $symbol->fill = $color;
269 $symbol->opacity = $opacity;
270 $symbol->width = 56.8;
271 $symbol->height = 43;
272 $symbol->path = 'M27.7,11.2L10,25.8v15.7c0,0.8,0.7,1.5,1.5,1.5l10.8,0c0.8,0,1.5-0.7,1.5-1.5v-9.2c0-0.8,0.7-1.5,1.5-1.5h6.1 c0.8,0,1.5,0.7,1.5,1.5v9.2c0,0.8,0.7,1.5,1.5,1.5c0,0,0,0,0,0l10.8,0c0.8,0,1.5-0.7,1.5-1.5V25.7L29.1,11.2 C28.7,10.8,28.1,10.8,27.7,11.2L27.7,11.2z M55.6,21.1l-8-6.6V1.2c0-0.6-0.5-1.2-1.2-1.2h-5.4c-0.6,0-1.2,0.5-1.2,1.2v7l-8.6-7.1 c-1.7-1.4-4.2-1.4-5.9,0l-24.3,20c-0.5,0.4-0.6,1.1-0.2,1.6c0,0,0,0,0,0l2.4,3c0.4,0.5,1.1,0.6,1.6,0.2c0,0,0,0,0,0L27.7,7.2 c0.4-0.3,1-0.3,1.5,0l22.6,18.6c0.5,0.4,1.2,0.3,1.6-0.2c0,0,0,0,0,0l2.4-3C56.2,22.2,56.1,21.5,55.6,21.1 C55.6,21.1,55.6,21.1,55.6,21.1L55.6,21.1z';
273 array_push($symbols, $symbol);
274
275 $symbol = new stdClass;
276 $symbol->id = 'city';
277 $symbol->name = 'City';
278 $symbol->group = $group;
279 $symbol->fill = $color;
280 $symbol->opacity = $opacity;
281 $symbol->width = 53.8;
282 $symbol->height = 43;
283 $symbol->path = 'M51.7,16.1H40.3V2c0-1.1-0.9-2-2-2H26.2c-1.1,0-2,0.9-2,2v6h-5.4V1.3c0-0.7-0.6-1.3-1.3-1.3h-1.3c-0.7,0-1.3,0.6-1.3,1.3 v6.7H9.4V1.3C9.4,0.6,8.8,0,8.1,0H6.7C6,0,5.4,0.6,5.4,1.3v6.7H2c-1.1,0-2,0.9-2,2v30.2C0,41.8,1.2,43,2.7,43h48.4 c1.5,0,2.7-1.2,2.7-2.7V18.1C53.8,17,52.8,16.1,51.7,16.1z M10.8,33.9c0,0.6-0.5,1-1,1H6.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1 h3.4c0.6,0,1,0.5,1,1V33.9z M10.8,25.9c0,0.6-0.5,1-1,1H6.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V25.9z M10.8,17.8c0,0.6-0.5,1-1,1H6.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V17.8z M21.5,33.9c0,0.6-0.5,1-1,1h-3.4 c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V33.9z M21.5,25.9c0,0.6-0.5,1-1,1h-3.4c-0.6,0-1-0.5-1-1v-3.4 c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V25.9z M21.5,17.8c0,0.6-0.5,1-1,1h-3.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4 c0.6,0,1,0.5,1,1V17.8z M34.9,25.9c0,0.6-0.5,1-1,1h-3.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V25.9z M34.9,17.8c0,0.6-0.5,1-1,1h-3.4c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V17.8z M34.9,9.7c0,0.6-0.5,1-1,1h-3.4 c-0.6,0-1-0.5-1-1V6.4c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V9.7z M48.4,33.9c0,0.6-0.5,1-1,1H44c-0.6,0-1-0.5-1-1v-3.4 c0-0.6,0.5-1,1-1h3.4c0.6,0,1,0.5,1,1V33.9z M48.4,25.9c0,0.6-0.5,1-1,1H44c-0.6,0-1-0.5-1-1v-3.4c0-0.6,0.5-1,1-1h3.4 c0.6,0,1,0.5,1,1V25.9z';
284 array_push($symbols, $symbol);
285
286 $symbol = new stdClass;
287 $symbol->id = 'campground';
288 $symbol->name = 'Campground';
289 $symbol->group = $group;
290 $symbol->fill = $color;
291 $symbol->opacity = $opacity;
292 $symbol->width = 53.7;
293 $symbol->height = 43;
294 $symbol->path = 'M52.4,37.6h-2.1L30.2,9.9l4.5-6.2c0.4-0.6,0.3-1.4-0.3-1.9l-2.2-1.6c-0.6-0.4-1.4-0.3-1.9,0.3l-3.5,4.8l-3.5-4.8 C23,0,22.1-0.2,21.5,0.3l-2.2,1.6c-0.6,0.4-0.7,1.3-0.3,1.9l4.5,6.2L3.4,37.6H1.3C0.6,37.6,0,38.2,0,39v2.7C0,42.4,0.6,43,1.3,43 h51.1c0.7,0,1.3-0.6,1.3-1.3V39C53.7,38.2,53.1,37.6,52.4,37.6z M26.9,24.2l9.8,13.4H17.1L26.9,24.2z';
295 array_push($symbols, $symbol);
296
297 $symbol = new stdClass;
298 $symbol->id = 'trailer';
299 $symbol->name = 'Trailer';
300 $symbol->group = $group;
301 $symbol->fill = $color;
302 $symbol->opacity = $opacity;
303 $symbol->width = 66.2;
304 $symbol->height = 43;
305 $symbol->path = 'M64.5,26.5h-8.3V1.7c0-0.9-0.7-1.7-1.7-1.7H1.7C0.7,0,0,0.7,0,1.7v29.8c0,0.9,0.7,1.7,1.7,1.7h5.1c0.8-5.6,5.6-9.9,11.4-9.9 s10.6,4.3,11.4,9.9h34.9c0.9,0,1.7-0.7,1.7-1.7v-3.3C66.2,27.2,65.4,26.5,64.5,26.5z M9.9,18.6c-1.2,0.6-2.3,1.3-3.3,2.1V7.4 C6.6,7,7,6.6,7.4,6.6h1.7c0.5,0,0.8,0.4,0.8,0.8V18.6z M19.8,16.7c-0.5-0.1-1.1-0.1-1.7-0.1c-0.6,0-1.1,0.1-1.7,0.1V7.4 c0-0.5,0.4-0.8,0.8-0.8H19c0.5,0,0.8,0.4,0.8,0.8V16.7z M29.8,20.7c-1-0.8-2.1-1.5-3.3-2.1V7.4c0-0.5,0.4-0.8,0.8-0.8h1.7 c0.5,0,0.8,0.4,0.8,0.8V20.7z M39.7,26.5h-3.3v-19c0-0.5,0.4-0.8,0.8-0.8h1.7c0.5,0,0.8,0.4,0.8,0.8V26.5z M49.6,26.5h-3.3v-19 c0-0.5,0.4-0.8,0.8-0.8h1.7c0.5,0,0.8,0.4,0.8,0.8V26.5z M18.2,26.5c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3 S22.8,26.5,18.2,26.5z M18.2,38c-1.8,0-3.3-1.5-3.3-3.3s1.5-3.3,3.3-3.3s3.3,1.5,3.3,3.3S20,38,18.2,38z';
306 array_push($symbols, $symbol);
307
308 return $symbols;
309 }
310
311 /**
312 * Gets the list of marker symbols for Google Maps.
313 *
314 * @param string $group optionally filter the symbols by group
315 *
316 * @return array list of marker symbols.
317 */
318 public function getMarkerSymbols($group = null)
319 {
320 $dbo = JFactory::getDbo();
321 $symbols = array();
322
323 $q = "SELECT `param`, `setting` FROM `#__vikbooking_config` WHERE `param` LIKE 'marker_symbols_%' ORDER BY `param` ASC;";
324 $dbo->setQuery($q);
325 $dbo->execute();
326 if ($dbo->getNumRows()) {
327 $all_symbols = $dbo->loadAssocList();
328 foreach ($all_symbols as $symbols_data) {
329 $list = json_decode($symbols_data['setting']);
330 if (!is_array($list) || !count($list)) {
331 continue;
332 }
333 $symbols = array_merge($symbols, $list);
334 }
335 } else {
336 $default_symbols = $this->getDefaultMarkerSymbols();
337 $q = "INSERT INTO `#__vikbooking_config` (`param`,`setting`) VALUES ('marker_symbols_default', " . $dbo->quote(json_encode($default_symbols)) . ");";
338 $dbo->setQuery($q);
339 $dbo->execute();
340
341 return $default_symbols;
342 }
343
344 $symbols = count($symbols) ? $symbols : $this->getDefaultMarkerSymbols();
345
346 if (!empty($group)) {
347 // filter symbol objects by group
348 $group = strtolower($group);
349 foreach ($symbols as $k => $symbol) {
350 if (!isset($symbol->group)) {
351 // filtering is impossible
352 continue;
353 }
354 if ($symbol->group != $group) {
355 unset($symbols[$k]);
356 }
357 }
358 // reset keys
359 $symbols = array_values($symbols);
360 }
361
362 return $symbols;
363 }
364
365 /**
366 * Gets one marker symbol for Google Maps.
367 *
368 * @param string $id the symbol identifier
369 * @param string $group optionally filter the symbols by group
370 *
371 * @return mixed marker symbol object or null.
372 */
373 public function getMarkerSymbol($id, $group = null)
374 {
375 if (empty($id)) {
376 return null;
377 }
378
379 $symbols = $this->getMarkerSymbols($group);
380 foreach ($symbols as $symbol) {
381 if (isset($symbol->id) && $symbol->id == $id) {
382 // symbol found
383 return $symbol;
384 }
385 }
386
387 // symbol not found
388 return null;
389 }
390
391 /**
392 * AJAX method called by the main controller when adding
393 * or updating a new or existing SVG symbol icon.
394 *
395 * @return mixed
396 *
397 * @throws Exception
398 */
399 public function storeSvgSymbol()
400 {
401 $symbol = VikRequest::getVar('symbol', array(), 'request', 'array');
402 if (!is_array($symbol) || empty($symbol['id'])) {
403 throw new Exception("Symbol ID not found", 404);
404 }
405
406 if (empty($symbol['name'])) {
407 throw new Exception("Symbol name is empty", 500);
408 }
409
410 if (empty($symbol['path'])) {
411 throw new Exception("Symbol path is empty", 500);
412 }
413
414 // sanitize values
415 $symbol['group'] = !empty($symbol['group']) ? strtolower($symbol['group']) : 'default';
416 if (isset($symbol['opacity'])) {
417 // this must be a float, not a string
418 $symbol['opacity'] = floatval($symbol['opacity']);
419 }
420
421 $current_symbol = $this->getMarkerSymbol($symbol['id']);
422 $addnew = false;
423 if (is_object($current_symbol)) {
424 // force symbol group because ID exists
425 $symbol['group'] = $current_symbol->group;
426 // update existing marker symbol
427 foreach ($current_symbol as $prop => $val) {
428 if (isset($symbol[$prop])) {
429 // overwrite existing property taken from the new icon
430 $current_symbol->{$prop} = $symbol[$prop];
431 }
432 }
433 } else {
434 // create new marker symbol
435 $addnew = true;
436 $current_symbol = (object)$symbol;
437 }
438
439 $dbo = JFactory::getDbo();
440
441 $group_symbols = array();
442 $update = false;
443 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`=" . $dbo->quote('marker_symbols_' . $symbol['group']) . ";";
444 $dbo->setQuery($q);
445 $dbo->execute();
446 if ($dbo->getNumRows()) {
447 $update = true;
448 $group_symbols = json_decode($dbo->loadResult());
449 $group_symbols = !is_array($group_symbols) ? array() : $group_symbols;
450 }
451
452 if ($addnew) {
453 // push new symbol
454 array_push($group_symbols, $current_symbol);
455 } else {
456 // find current symbol
457 $found = false;
458 foreach ($group_symbols as $k => $s) {
459 if ($s->id == $symbol['id']) {
460 // replace existing symbol
461 $found = true;
462 $group_symbols[$k] = $current_symbol;
463 break;
464 }
465 }
466 if (!$found) {
467 // push new symbol as it was not found
468 array_push($group_symbols, $current_symbol);
469 }
470 }
471
472 // update values in db
473 if ($update) {
474 $q = "UPDATE `#__vikbooking_config` SET `setting`=" . $dbo->quote(json_encode($group_symbols)) . " WHERE `param`=" . $dbo->quote('marker_symbols_' . $symbol['group']) . ";";
475 } else {
476 $q = "INSERT INTO `#__vikbooking_config` (`param`,`setting`) VALUES (" . $dbo->quote('marker_symbols_' . $symbol['group']) . ", " . $dbo->quote(json_encode($group_symbols)) . ");";
477 }
478 $dbo->setQuery($q);
479 $dbo->execute();
480
481 // return the new symbol object just stored
482 return $current_symbol;
483 }
484
485 /**
486 * AJAX method called by the main controller when needing
487 * to delete an existing SVG symbol icon.
488 *
489 * @return mixed
490 *
491 * @throws Exception
492 */
493 public function deleteSvgSymbol()
494 {
495 $symbol_id = VikRequest::getString('symbol_id', '', 'request');
496 if (empty($symbol_id)) {
497 throw new Exception("Symbol ID is empty", 404);
498 }
499
500 $current_symbol = $this->getMarkerSymbol($symbol_id);
501 if (!is_object($current_symbol)) {
502 throw new Exception("Symbol ID not found", 404);
503 }
504
505 $dbo = JFactory::getDbo();
506 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`=" . $dbo->quote('marker_symbols_' . $current_symbol->group) . ";";
507 $dbo->setQuery($q);
508 $dbo->execute();
509 if (!$dbo->getNumRows()) {
510 throw new Exception("Symbol Group not found", 404);
511 }
512 $records = json_decode($dbo->loadResult());
513 if (!is_array($records) || !count($records)) {
514 throw new Exception("Symbol Group has got no symbols", 404);
515 }
516
517 $found = false;
518 foreach ($records as $k => $v) {
519 if ($v->id == $symbol_id) {
520 $found = true;
521 unset($records[$k]);
522 break;
523 }
524 }
525
526 if (!$found) {
527 throw new Exception("Symbol ID not found in all symbols of this group", 404);
528 }
529
530 // reset keys
531 $records = array_values($records);
532
533 // update db
534 $q = "UPDATE `#__vikbooking_config` SET `setting`=" . $dbo->quote(json_encode($records)) . " WHERE `param`=" . $dbo->quote('marker_symbols_' . $current_symbol->group) . ";";
535 $dbo->setQuery($q);
536 $dbo->execute();
537
538 return $symbol_id;
539 }
540
541 /**
542 * AJAX method called by the main controller when starting to work
543 * on the geo coding information for one specific room.
544 *
545 * @return int a simple result integer code identifier.
546 *
547 * @throws Exception
548 */
549 public function initRoomGeoTransient()
550 {
551 $dbo = JFactory::getDbo();
552 $room_id = VikRequest::getInt('room_id', 0, 'request');
553
554 $param = "geocoding_transient_room_" . $room_id;
555 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`=" . $dbo->quote($param) . ";";
556 $dbo->setQuery($q);
557 $dbo->execute();
558 if ($dbo->getNumRows()) {
559 // make the temporary record empty
560 $q = "UPDATE `#__vikbooking_config` SET `setting`='' WHERE `param`=" . $dbo->quote($param) . ";";
561 $dbo->setQuery($q);
562 $dbo->execute();
563
564 return 2;
565 }
566
567 return 1;
568 }
569
570 /**
571 * AJAX method called by the main controller when updating
572 * the geo coding information for one specific room.
573 *
574 * @return object the geo params stored.
575 *
576 * @throws Exception
577 */
578 public function updateRoomGeoTransient()
579 {
580 $dbo = JFactory::getDbo();
581
582 $room_id = VikRequest::getInt('room_id', 0, 'request');
583 $geo_enabled = VikRequest::getInt('geo_enabled', 0, 'request');
584 $geo_address = VikRequest::getString('geo_address', '', 'request');
585 $geo_latitude = VikRequest::getFloat('geo_latitude', 0, 'request');
586 $geo_longitude = VikRequest::getFloat('geo_longitude', 0, 'request');
587 $geo_zoom = VikRequest::getInt('geo_zoom', 1, 'request');
588 $geo_mtype = VikRequest::getString('geo_mtype', '', 'request');
589 $geo_height = VikRequest::getInt('geo_height', 100, 'request');
590 $geo_markers_multi = VikRequest::getInt('geo_markers_multi', 0, 'request');
591 $geo_marker_lat = VikRequest::getFloat('geo_marker_lat', 0, 'request');
592 $geo_marker_lng = VikRequest::getFloat('geo_marker_lng', 0, 'request');
593 $geo_marker_hide = VikRequest::getInt('geo_marker_hide', 0, 'request');
594 $geo_units_pos = VikRequest::getVar('geo_units_pos', array(), 'request', 'array');
595 $geo_goverlay = VikRequest::getInt('geo_goverlay', 0, 'request');
596 $geo_overlay_img = VikRequest::getString('geo_overlay_img', '', 'request');
597 $geo_overlay_south = VikRequest::getFloat('geo_overlay_south', 0, 'request');
598 $geo_overlay_west = VikRequest::getFloat('geo_overlay_west', 0, 'request');
599 $geo_overlay_north = VikRequest::getFloat('geo_overlay_north', 0, 'request');
600 $geo_overlay_east = VikRequest::getFloat('geo_overlay_east', 0, 'request');
601
602 // prepare geo params object
603 $geo_params = new stdClass;
604 /**
605 * Property "enabled" must ALWAYS be the first one
606 *
607 * @see getImportableConfigRooms()
608 */
609 $geo_params->enabled = $geo_enabled;
610 //
611 $geo_params->address = $geo_address;
612 $geo_params->latitude = $geo_latitude;
613 $geo_params->longitude = $geo_longitude;
614 $geo_params->zoom = $geo_zoom;
615 $geo_params->mtype = $geo_mtype;
616 $geo_params->height = $geo_height;
617 $geo_params->markers_multi = $geo_markers_multi;
618 $geo_params->marker_lat = $geo_marker_lat;
619 $geo_params->marker_lng = $geo_marker_lng;
620 $geo_params->marker_hide = $geo_marker_hide;
621 $geo_params->units_pos = $geo_units_pos;
622 $geo_params->goverlay = $geo_goverlay;
623 $geo_params->overlay_img = $geo_overlay_img;
624 $geo_params->overlay_south = $geo_overlay_south;
625 $geo_params->overlay_west = $geo_overlay_west;
626 $geo_params->overlay_north = $geo_overlay_north;
627 $geo_params->overlay_east = $geo_overlay_east;
628
629 // check transient record
630 $param = "geocoding_transient_room_" . $room_id;
631 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`=" . $dbo->quote($param) . ";";
632 $dbo->setQuery($q);
633 $dbo->execute();
634 if ($dbo->getNumRows()) {
635 $q = "UPDATE `#__vikbooking_config` SET `setting`=" . $dbo->quote(json_encode($geo_params)) . " WHERE `param`=" . $dbo->quote($param) . ";";
636 } else {
637 $q = "INSERT INTO `#__vikbooking_config` (`param`,`setting`) VALUES (" . $dbo->quote($param) . ", " . $dbo->quote(json_encode($geo_params)) . ");";
638 }
639 // update transient record with new geo params
640 $dbo->setQuery($q);
641 $dbo->execute();
642
643 return $geo_params;
644 }
645
646 /**
647 * Retrieves the last transient for the given room ID (or new room). This
648 * way the room geo params are ready to be stored by the main controller.
649 *
650 * @param int $room_id the room ID (0 for new).
651 *
652 * @return mixed geo params object or false.
653 */
654 public function getRoomGeoTransient($room_id)
655 {
656 $dbo = JFactory::getDbo();
657 $param = "geocoding_transient_room_" . (int)$room_id;
658
659 $q = "SELECT `setting` FROM `#__vikbooking_config` WHERE `param`=" . $dbo->quote($param) . ";";
660 $dbo->setQuery($q);
661 $dbo->execute();
662 if (!$dbo->getNumRows()) {
663 $geo_enabled = VikRequest::getInt('geo_enabled', 0, 'request');
664 if ($geo_enabled) {
665 VikError::raiseWarning('', 'no records found ' . $param);
666 }
667 return false;
668 }
669 $geo_params = json_decode($dbo->loadResult());
670
671 return is_object($geo_params) ? $geo_params : false;
672 }
673
674 /**
675 * Returns a list of room-types with a complete geocoding information that could be imported.
676 * This facilitates the setup of the geographic information for a new room-type.
677 *
678 * @param int $exclude_id the current room to exclude, 0 for new.
679 *
680 * @return array list of room-types with an importable geo configuration.
681 */
682 public function getImportableConfigRooms($exclude_id = 0)
683 {
684 $importable = array();
685
686 $dbo = JFactory::getDbo();
687 $clauses = array();
688
689 if ($exclude_id > 0) {
690 array_push($clauses, '`id` != ' . $exclude_id);
691 }
692
693 // fetch all rooms with the geo information enabled
694 array_push($clauses, '`params` LIKE ' . $dbo->quote('%"geo":{"enabled":1%'));
695
696 $q = "SELECT `id`, `name` FROM `#__vikbooking_rooms` WHERE " . implode(' AND ', $clauses) . " ORDER BY `name` ASC;";
697 $dbo->setQuery($q);
698 $dbo->execute();
699 if ($dbo->getNumRows()) {
700 $importable = $dbo->loadAssocList();
701 }
702
703 return $importable;
704 }
705
706 /**
707 * AJAX method called by the main controller when requesting
708 * to import the geo coding information for one specific room.
709 *
710 * @return object the geo params of the room requested.
711 *
712 * @throws Exception
713 */
714 public function importRoomGeoConfig()
715 {
716 $dbo = JFactory::getDbo();
717
718 $room_id = VikRequest::getInt('room_id', 0, 'request');
719
720 $q = "SELECT `id`, `name`, `params` FROM `#__vikbooking_rooms` WHERE id={$room_id};";
721 $dbo->setQuery($q);
722 $dbo->execute();
723 if (!$dbo->getNumRows()) {
724 throw new Exception("Room not found for importing geo config", 404);
725 }
726 $room = $dbo->loadAssoc();
727 $rparams = json_decode($room['params']);
728 if (!is_object($rparams)) {
729 throw new Exception("Unable to decode room params", 500);
730 }
731
732 // get all geo params
733 $geo_params = $this->getRoomGeoParams($rparams);
734
735 if (!is_object($geo_params)) {
736 throw new Exception("Unable to get room geo params", 500);
737 }
738
739 return $geo_params;
740 }
741 }
742