PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 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 All 37 releases
← All changes | libraries/system/install.php +701 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,701 @@
1 +<?php
2 +/**
3 + * @package VikBooking - Libraries
4 + * @subpackage system
5 + * @author E4J s.r.l.
6 + * @copyright Copyright (C) 2018 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 +VikBookingLoader::import('update.manager');
15 +VikBookingLoader::import('update.license');
16 +
17 +/**
18 + * Class used to handle the activation, deactivation and
19 + * uninstallation of VikBooking plugin.
20 + *
21 + * @since 1.0
22 + */
23 +class VikBookingInstaller
24 +{
25 + /**
26 + * Flag used to init the class only once.
27 + *
28 + * @var boolean
29 + */
30 + protected static $init = false;
31 +
32 + /**
33 + * Initialize the class attaching wp actions.
34 + *
35 + * @return void
36 + */
37 + public static function onInit()
38 + {
39 + // init only if not done yet
40 + if (static::$init === false)
41 + {
42 + // handle installation message
43 + add_action('admin_notices', array('VikBookingInstaller', 'handleMessage'));
44 +
45 + /**
46 + * Register hooks and actions here
47 + */
48 +
49 + // mark flag as true to avoid init it again
50 + static::$init = true;
51 + }
52 +
53 + /**
54 + * Check whether the Pro license has expired.
55 + *
56 + * @since 1.2.8
57 + */
58 + add_action('admin_notices', array('VikBookingInstaller', 'handleUpdateWarning'));
59 + }
60 +
61 + /**
62 + * Handles the activation of the plugin.
63 + *
64 + * @param boolean $message True to display the activation message,
65 + * false to ignore it.
66 + *
67 + * @return void
68 + */
69 + public static function activate($message = true)
70 + {
71 + // get installed software version
72 + $version = get_option('vikbooking_software_version', null);
73 +
74 + // check if the plugin has been already installed
75 + if (is_null($version))
76 + {
77 + // dispatch UPDATER to launch installation queries
78 + VikBookingUpdateManager::install();
79 +
80 + // mark the plugin has installed to avoid duplicated installation queries
81 + update_option('vikbooking_software_version', VIKBOOKING_SOFTWARE_VERSION);
82 + }
83 +
84 + if ($message)
85 + {
86 + // set activation flag to display a message
87 + add_option('vikbooking_onactivate', 1);
88 + }
89 + }
90 +
91 + /**
92 + * Handles the deactivation of the plugin.
93 + *
94 + * @return void
95 + */
96 + public static function deactivate()
97 + {
98 + // do nothing for the moment
99 + }
100 +
101 + /**
102 + * Handles the uninstallation of the plugin.
103 + *
104 + * @param boolean $drop True to drop the tables of VikBooking from the database.
105 + *
106 + * @return void
107 + */
108 + public static function uninstall($drop = true)
109 + {
110 + // dispatch UPDATER to drop database tables
111 + VikBookingUpdateManager::uninstall($drop);
112 +
113 + // delete installation flag
114 + delete_option('vikbooking_software_version');
115 + }
116 +
117 + /**
118 + * Handles the uninstallation of the plugin.
119 + * Proxy for uninstall method which always force database drop.
120 + *
121 + * @return void
122 + *
123 + * @uses uninstall()
124 + *
125 + * @since 1.2.6
126 + */
127 + public static function delete()
128 + {
129 + // complete uninstallation by dropping the database
130 + static::uninstall(true);
131 + }
132 +
133 + /**
134 + * Checks if the current version should be updated
135 + * and, eventually, processes it.
136 + *
137 + * @return void
138 + */
139 + public static function update()
140 + {
141 + // get installed software version
142 + $version = get_option('vikbooking_software_version', null);
143 +
144 + $app = JFactory::getApplication();
145 +
146 + // check if we are running an older version
147 + if (VikBookingUpdateManager::shouldUpdate($version))
148 + {
149 + /**
150 + * Avoid useless redirections if doing ajax.
151 + *
152 + * @since 1.1.6
153 + */
154 + if (!wp_doing_ajax() && $app->isAdmin())
155 + {
156 + // Turn on maintenance mode before running the update.
157 + // In case the maintenance mode was already active, then
158 + // an error message will be thrown.
159 + static::setMaintenance(true);
160 +
161 + // process the update (we don't need to raise an error)
162 + VikBookingUpdateManager::update($version);
163 +
164 + // update cached plugin version
165 + update_option('vikbooking_software_version', VIKBOOKING_SOFTWARE_VERSION);
166 +
167 + // deactivate the maintenance mode on update completion
168 + static::setMaintenance(false);
169 +
170 + /**
171 + * Check if pro version, but attempt to re-download the Pro settings
172 + * within the current loading flow rather than redirecting. In case
173 + * something goes wrong, fallback to the old "get pro" redirect method.
174 + *
175 + * @since 1.5.11
176 + */
177 + if (VikBookingLicense::isPro())
178 + {
179 + // load license model
180 + $model = JModel::getInstance('vikbooking', 'license', 'admin');
181 +
182 + // download PRO version hoping that all will go fine
183 + $result = $model->download(VikBookingLicense::getKey());
184 +
185 + if ($result === false)
186 + {
187 + // an error occurred, retrieve it as exception
188 + $error = $model->getError(null, $toString = true);
189 +
190 + // display exception error
191 + $app->enqueueMessage($error, 'error');
192 +
193 + // fallback to the pro-package download page (old method)
194 + $app->redirect('index.php?option=com_vikbooking&view=getpro&version=' . $version);
195 + $app->close();
196 + }
197 + }
198 + }
199 + }
200 + // check if the current instance is a new blog of a network
201 + else if (is_null($version))
202 + {
203 + /**
204 + * The version is NULL, vikbooking_software_version doesn't
205 + * exist as an option of this blog.
206 + * We need to launch the installation manually.
207 + *
208 + * @see activate()
209 + *
210 + * @since 1.0.6
211 + */
212 +
213 + // Use FALSE to ignore the activation message
214 + static::activate(false);
215 + }
216 + }
217 +
218 + /**
219 + * Callback used to complete the update of the plugin
220 + * made after a scheduled event.
221 + *
222 + * @param array $results The results of all attempted updates.
223 + *
224 + * @return void
225 + *
226 + * @since 1.3.12
227 + */
228 + public static function automaticUpdate($results)
229 + {
230 + // create log trace
231 + $trace = '### VikBooking Automatic Update | ' . JHtml::fetch('date', new JDate(), 'Y-m-d H:i:s') . "\n\n";
232 + $trace .= "```json\n" . json_encode($results, JSON_PRETTY_PRINT) . "\n```\n\n";
233 +
234 + if (empty($results['plugin']))
235 + {
236 + $results['plugin'] = [];
237 + }
238 +
239 + // iterate all plugins
240 + foreach ($results['plugin'] as $plugin)
241 + {
242 + if (!empty($plugin->item->slug))
243 + {
244 + // register check trace
245 + $trace .= "Does `{$plugin->item->slug}` match `vikbooking`?\n\n";
246 +
247 + // make sure the plugin slug matches this one
248 + if ($plugin->item->slug == 'vikbooking')
249 + {
250 + // register status trace
251 + $trace .= "Did WP complete the update without errors? [" . ($plugin->result ? 'Y' : 'N') . "]\n\n";
252 +
253 + // plugin found, make sure the update was successful
254 + if ($plugin->result)
255 + {
256 + try
257 + {
258 + // register version trace
259 + $trace .= sprintf("Updating from [%s] to [%s]...\n\n", VIKBOOKING_SOFTWARE_VERSION, $plugin->item->new_version);
260 +
261 + // complete the update in background
262 + static::backgroundUpdate($plugin->item->new_version);
263 +
264 + // update completed without errors
265 + $trace .= "Background update completed\n\n";
266 + }
267 + catch (Exception $e)
268 + {
269 + // something went wrong, register error within the trace
270 + $trace .= sprintf(
271 + "An error occurred while trying to finalize the update (%d):\n> %s\n\n",
272 + $e->getCode(),
273 + $e->getMessage()
274 + );
275 +
276 + /**
277 + * @todo An error occurred while trying to download the PRO version,
278 + * evaluate to send an e-mail to the administrator.
279 + */
280 + }
281 + }
282 + }
283 + }
284 + }
285 +
286 + // register debug trace within a log file
287 + JLoader::import('adapter.filesystem.file');
288 + JFile::write(VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'au-log.md', $trace . "---\n\n");
289 + }
290 +
291 + /**
292 + * Same as update task, but all made in background.
293 + *
294 + * @param string $new_version The new version of the plugin.
295 + *
296 + * @return void
297 + *
298 + * @since 1.3.12
299 + */
300 + protected static function backgroundUpdate($new_version)
301 + {
302 + // get installed software version
303 + $version = get_option('vikbooking_software_version', null);
304 +
305 + // DO NOT use shouldUpdate method because, since we are always within
306 + // the same flow, the version constant is still referring to the previous
307 + // version. So, always assume to proceed with the update of the plugin.
308 +
309 + // Turn on maintenance mode before running the update.
310 + // In case the maintenance mode was already active, then
311 + // an error message will be thrown.
312 + static::setMaintenance(true);
313 +
314 + // process the update (we don't need to raise an error)
315 + VikBookingUpdateManager::update($version);
316 +
317 + // update cached plugin version
318 + update_option('vikbooking_software_version', $new_version);
319 +
320 + // deactivate the maintenance mode on update completion
321 + static::setMaintenance(false);
322 +
323 + // check if pro version
324 + if (VikBookingLicense::isPro())
325 + {
326 + // load license model
327 + $model = JModel::getInstance('vikbooking', 'license', 'admin');
328 +
329 + // download PRO version hoping that all will go fine
330 + $result = $model->download(VikBookingLicense::getKey());
331 +
332 + if ($result === false)
333 + {
334 + // an error occurred, retrieve it as exception
335 + $error = $model->getError(null, $toString = false);
336 +
337 + // propagate exception
338 + throw $error;
339 + }
340 + }
341 + }
342 +
343 + /**
344 + * Checks whether the automatic updates should be turned off.
345 + * This is useful to prevent auto-updates for those customers
346 + * that are running an expired PRO version. This will avoid
347 + * losing the files after an unexpected update.
348 + *
349 + * @param boolean $update The current auto-update choice.
350 + * @param object $item The plugin offer.
351 + *
352 + * @return mixed Null to let WP decides, false to always deny it.
353 + *
354 + * @since 1.3.12
355 + */
356 + public static function useAutoUpdate($update, $item)
357 + {
358 + // make sure we are fetching VikBooking
359 + if (!empty($item->slug) && $item->slug == 'vikbooking')
360 + {
361 + // plugin found, lets check whether the user is
362 + // not running the PRO version
363 + if (!VikBookingLicense::isPro())
364 + {
365 + // not a PRO version, check whether a license
366 + // key was registered
367 + if (VikBookingLicense::getKey())
368 + {
369 + // The plugin registered a key; the customer
370 + // chose to let the license expires...
371 + // We need to prevent auto-updates.
372 + $update = false;
373 + }
374 + }
375 + }
376 +
377 + return $update;
378 + }
379 +
380 + /**
381 + * Toggle maintenance mode for the site.
382 + * Creates/deletes the maintenance file to enable/disable maintenance mode.
383 + *
384 + * @param boolean $enable True to enable maintenance mode, false to disable.
385 + *
386 + * @return void
387 + *
388 + * @since 1.4.4
389 + * @since 1.4.7 the maintenance mode also relies on database options, not only on a file.
390 + * we also allow to turn off/skip maintenance mode by passing a value in query string.
391 + */
392 + protected static function setMaintenance($enable)
393 + {
394 + $maintenance_file_path = VIKBOOKING_BASE . '/maintenance.txt';
395 + $maintenance_db_option = 'vikbooking_maintenance';
396 +
397 + if ($enable)
398 + {
399 + // check if we are in maintenance mode
400 + if (JFile::exists($maintenance_file_path) && get_option($maintenance_db_option, null) !== null)
401 + {
402 + // allow to skip maintenance mode via query string
403 + if (JFactory::getApplication()->input->getInt('skip_maintenance', 0))
404 + {
405 + // turn off maintenance mode
406 + return static::setMaintenance(false);
407 + }
408 +
409 + // raise error message in case the update process is currently running
410 + $skip_maintenance_url = JUri::current();
411 + $skip_maintenance_url .= (strpos($skip_maintenance_url, '?') === false ? '?' : '&') . 'skip_maintenance=1';
412 + wp_die(
413 + // message to be displayed
414 + '<h1>Maintenance</h1>' .
415 + '<p>VikBooking is in maintenance mode. Please wait a minute for the update to complete.</p>',
416 + // page title to set
417 + 'Maintenance',
418 + // arguments to control behavior
419 + array(
420 + // set link for the message to be displayed
421 + 'link_url' => $skip_maintenance_url,
422 + 'link_text' => 'Skip Maintenance',
423 + // HTTP error code "locked"
424 + 'code' => 423,
425 + )
426 + );
427 + }
428 +
429 + // make sure no time limits will impact the process to restore the necessary files
430 + ignore_user_abort(true);
431 + set_time_limit(0);
432 +
433 + // enter maintenance mode for the current version
434 + JFile::write($maintenance_file_path, VIKBOOKING_SOFTWARE_VERSION);
435 + update_option($maintenance_db_option, VIKBOOKING_SOFTWARE_VERSION);
436 + }
437 + else
438 + {
439 + // turn off maintenance mode
440 + JFile::delete($maintenance_file_path);
441 + delete_option($maintenance_db_option);
442 + }
443 + }
444 +
445 + /**
446 + * In case of an expired PRO version, prompts a message informing
447 + * the user that it is going to lose the PRO features.
448 + *
449 + * @param array $data An array of plugin metadata.
450 + * @param array $response An array of metadata about the available plugin update.
451 + *
452 + * @return void
453 + *
454 + * @since 1.3.12
455 + */
456 + public static function getUpdateMessage($data, $response)
457 + {
458 + // check whether the user is not running the PRO version
459 + if (!VikBookingLicense::isPro())
460 + {
461 + // not a PRO version, check whether a license
462 + // key was registered
463 + if (VikBookingLicense::getKey())
464 + {
465 + // The plugin registered a key; the customer
466 + // chose to let the license expires...
467 + // We need to display an alert.
468 + add_action('admin_footer', function() use ($data, $response)
469 + {
470 + // display layout
471 + echo JLayoutHelper::render(
472 + 'html.license.update',
473 + array($data, $response),
474 + null,
475 + array('component' => 'com_vikbooking')
476 + );
477 + });
478 + }
479 + }
480 + }
481 +
482 + /**
483 + * Helper method used to obtain the list of breaking
484 + * changes registered within the wordpress options.
485 + *
486 + * @return array
487 + *
488 + * @since 1.6.5
489 + */
490 + public static function getBreakingChanges()
491 + {
492 + // get existing breaking changes
493 + $files = get_option('vikbooking_breaking_changes');
494 + // decode from JSON
495 + return (array) ($files ? json_decode($files, true) : null);
496 + }
497 +
498 + /**
499 + * Helper method used to register a list of breaking
500 + * changes within the wordpress options.
501 + *
502 + * @param array $files The files to register.
503 + *
504 + * @return void
505 + *
506 + * @since 1.6.5
507 + */
508 + public static function registerBreakingChanges(array $files)
509 + {
510 + if ($files)
511 + {
512 + // get existing files
513 + $existing = static::getBreakingChanges();
514 +
515 + foreach ($files as $client => $list)
516 + {
517 + if (!$list)
518 + {
519 + // ignore in case the list is empty
520 + continue;
521 + }
522 +
523 + if (!isset($existing[$client]))
524 + {
525 + // no client set, register it right now
526 + $existing[$client] = (array) $list;
527 + }
528 + else
529 + {
530 + // client already set, merge existing with new ones (get rid of duplicates)
531 + $existing[$client] = array_values(array_unique(array_merge($existing[$client], (array) $list)));
532 + }
533 + }
534 +
535 + // register within an option the breaking changes
536 + update_option('vikbooking_breaking_changes', json_encode($existing));
537 + }
538 + }
539 +
540 + /**
541 + * Helper method used to unregister a list of breaking
542 + * changes within the wordpress options.
543 + *
544 + * @param string|array|null $files The file(s) to unregister.
545 + * Leave empty to clear all the files.
546 + *
547 + * @return void
548 + *
549 + * @since 1.6.5
550 + */
551 + public static function unregisterBreakingChanges($files = null)
552 + {
553 + if ($files)
554 + {
555 + $existing = static::getBreakingChanges();
556 +
557 + // scan all the provided files
558 + foreach ((array) $files as $file)
559 + {
560 + // search path under each client
561 + foreach ($existing as $client => $list)
562 + {
563 + // get index of the specified file
564 + $index = array_search($file, $list);
565 +
566 + if ($index === false)
567 + {
568 + // path not found, ignore
569 + continue;
570 + }
571 +
572 + // remove path at the specified index
573 + array_splice($existing[$client], $index, 1);
574 +
575 + if (!$existing[$client])
576 + {
577 + // remove client as there are no more pending overrides
578 + unset($existing[$client]);
579 + }
580 + }
581 + }
582 +
583 + if ($existing)
584 + {
585 + // update breaking changes in case the list is not empty
586 + update_option('vikbooking_breaking_changes', json_encode($existing));
587 + }
588 + else
589 + {
590 + // directly delete the breaking changes option otherwise
591 + static::unregisterBreakingChanges();
592 + }
593 + }
594 + else
595 + {
596 + // clear breaking changes
597 + delete_option('vikbooking_breaking_changes');
598 + }
599 + }
600 +
601 + /**
602 + * Helper method used to show the breaking changes to
603 + * the administrator. This method will have no effect
604 + * in case the logged-in user is not an administrator.
605 + *
606 + * @return void
607 + *
608 + * @since 1.6.5
609 + */
610 + public static function showBreakingChanges()
611 + {
612 + // make sure the user is an administrator
613 + if (JFactory::getUser()->authorise('core.admin', 'com_vikbooking'))
614 + {
615 + // retieve breaking changes list, if any
616 + $bc = static::getBreakingChanges();
617 +
618 + if ($bc)
619 + {
620 + // use layout to render the warning message
621 + $warn = JLayoutHelper::render(
622 + 'html.overrides.bc',
623 + ['files' => $bc],
624 + null,
625 + ['component' => 'com_vikbooking']
626 + );
627 +
628 + // enqueue warning to be displayed
629 + JFactory::getApplication()->enqueueMessage($warn, 'warning');
630 + }
631 + }
632 + }
633 +
634 + /**
635 + * Method used to check for any installation message to show.
636 + *
637 + * @return void
638 + */
639 + public static function handleMessage()
640 + {
641 + $app = JFactory::getApplication();
642 +
643 + // if we are in the admin section and the plugin has been activated
644 + if ($app->isAdmin() && get_option('vikbooking_onactivate') == 1)
645 + {
646 + // delete the activation flag to avoid displaying the message more than once
647 + delete_option('vikbooking_onactivate');
648 +
649 + ?>
650 + <div class="notice is-dismissible notice-success">
651 + <p>
652 + <strong>Thanks for activating our plugin!</strong>
653 + <a href="https://vikwp.com" target="_blank">https://vikwp.com</a>
654 + </p>
655 + </div>
656 + <?php
657 + }
658 + }
659 +
660 + /**
661 + * Check if the Pro version has expired to alert the user that an
662 + * update would actually mean downgrading to the free version.
663 + *
664 + * @since 1.2.8
665 + */
666 + public static function handleUpdateWarning()
667 + {
668 + global $pagenow;
669 +
670 + if ($pagenow == 'plugins.php' && VikBookingLicense::isExpired() && !VikBookingLicense::hasVcm())
671 + {
672 + if (!JFactory::getApplication()->input->cookie->getInt('vbo_update_warning_hide', 0))
673 + {
674 + ?>
675 + <div class="notice is-dismissible notice-warning" id="vbo-update-warning">
676 + <p>
677 + <strong><?php echo JText::translate('VBOPROVEXPWARNUPD'); ?></strong>
678 + </p>
679 + </div>
680 +
681 + <script type="text/javascript">
682 + jQuery(function() {
683 + jQuery('#vbo-update-warning').on('click', '.notice-dismiss', function(event, el) {
684 + var numWeeks = 1;
685 + if (typeof localStorage !== 'undefined') {
686 + numWeeks = localStorage.getItem('vbo_update_warning_hide_count');
687 + numWeeks = !numWeeks ? 0 : parseInt(numWeeks);
688 + numWeeks++;
689 + localStorage.setItem('vbo_update_warning_hide_count', numWeeks);
690 + }
691 + var nd = new Date();
692 + nd.setDate(nd.getDate() + (7 * numWeeks));
693 + document.cookie = 'vbo_update_warning_hide=1; expires=' + nd.toUTCString() + '; path=/; SameSite=Lax';
694 + });
695 + });
696 + </script>
697 + <?php
698 + }
699 + }
700 + }
701 +}