PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.9
VikBooking Hotel Booking Engine & PMS v1.6.9
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
vikbooking / libraries / system / install.php

install.php in VikBooking Hotel Booking Engine & PMS 1.6.9, at libraries/system/install.php

701 lines 18.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 set_time_limit(0);
431
432 // enter maintenance mode for the current version
433 JFile::write($maintenance_file_path, VIKBOOKING_SOFTWARE_VERSION);
434 update_option($maintenance_db_option, VIKBOOKING_SOFTWARE_VERSION);
435 }
436 else
437 {
438 // turn off maintenance mode
439 JFile::delete($maintenance_file_path);
440 delete_option($maintenance_db_option);
441 }
442 }
443
444 /**
445 * In case of an expired PRO version, prompts a message informing
446 * the user that it is going to lose the PRO features.
447 *
448 * @param array $data An array of plugin metadata.
449 * @param array $response An array of metadata about the available plugin update.
450 *
451 * @return void
452 *
453 * @since 1.3.12
454 */
455 public static function getUpdateMessage($data, $response)
456 {
457 // check whether the user is not running the PRO version
458 if (!VikBookingLicense::isPro())
459 {
460 // not a PRO version, check whether a license
461 // key was registered
462 if (VikBookingLicense::getKey())
463 {
464 // The plugin registered a key; the customer
465 // chose to let the license expires...
466 // We need to display an alert.
467 add_action('admin_footer', function() use ($data, $response)
468 {
469 // display layout
470 echo JLayoutHelper::render(
471 'html.license.update',
472 array($data, $response),
473 null,
474 array('component' => 'com_vikbooking')
475 );
476 });
477 }
478 }
479 }
480
481 /**
482 * Helper method used to obtain the list of breaking
483 * changes registered within the wordpress options.
484 *
485 * @return array
486 *
487 * @since 1.6.5
488 */
489 public static function getBreakingChanges()
490 {
491 // get existing breaking changes
492 $files = get_option('vikbooking_breaking_changes');
493 // decode from JSON
494 return (array) ($files ? json_decode($files, true) : null);
495 }
496
497 /**
498 * Helper method used to register a list of breaking
499 * changes within the wordpress options.
500 *
501 * @param array $files The files to register.
502 *
503 * @return void
504 *
505 * @since 1.6.5
506 */
507 public static function registerBreakingChanges(array $files)
508 {
509 if ($files)
510 {
511 // get existing files
512 $existing = static::getBreakingChanges();
513
514 foreach ($files as $client => $list)
515 {
516 if (!$list)
517 {
518 // ignore in case the list is empty
519 continue;
520 }
521
522 if (!isset($existing[$client]))
523 {
524 // no client set, register it right now
525 $existing[$client] = (array) $list;
526 }
527 else
528 {
529 // client already set, merge existing with new ones (get rid of duplicates)
530 $existing[$client] = array_values(array_unique(array_merge($existing[$client], (array) $list)));
531 }
532 }
533
534 // register within an option the breaking changes
535 update_option('vikbooking_breaking_changes', json_encode($existing));
536 }
537 }
538
539 /**
540 * Helper method used to unregister a list of breaking
541 * changes within the wordpress options.
542 *
543 * @param string|array|null $files The file(s) to unregister.
544 * Leave empty to clear all the files.
545 *
546 * @return void
547 *
548 * @since 1.6.5
549 */
550 public static function unregisterBreakingChanges($files = null)
551 {
552 if ($files)
553 {
554 $existing = static::getBreakingChanges();
555
556 // scan all the provided files
557 foreach ((array) $files as $file)
558 {
559 // search path under each client
560 foreach ($existing as $client => $list)
561 {
562 // get index of the specified file
563 $index = array_search($file, $list);
564
565 if ($index === false)
566 {
567 // path not found, ignore
568 continue;
569 }
570
571 // remove path at the specified index
572 array_splice($existing[$client], $index, 1);
573
574 if (!$existing[$client])
575 {
576 // remove client as there are no more pending overrides
577 unset($existing[$client]);
578 }
579 }
580 }
581
582 if ($existing)
583 {
584 // update breaking changes in case the list is not empty
585 update_option('vikbooking_breaking_changes', json_encode($existing));
586 }
587 else
588 {
589 // directly delete the breaking changes option otherwise
590 static::unregisterBreakingChanges();
591 }
592 }
593 else
594 {
595 // clear breaking changes
596 delete_option('vikbooking_breaking_changes');
597 }
598 }
599
600 /**
601 * Helper method used to show the breaking changes to
602 * the administrator. This method will have no effect
603 * in case the logged-in user is not an administrator.
604 *
605 * @return void
606 *
607 * @since 1.6.5
608 */
609 public static function showBreakingChanges()
610 {
611 // make sure the user is an administrator
612 if (JFactory::getUser()->authorise('core.admin', 'com_vikbooking'))
613 {
614 // retieve breaking changes list, if any
615 $bc = static::getBreakingChanges();
616
617 if ($bc)
618 {
619 // use layout to render the warning message
620 $warn = JLayoutHelper::render(
621 'html.overrides.bc',
622 ['files' => $bc],
623 null,
624 ['component' => 'com_vikbooking']
625 );
626
627 // enqueue warning to be displayed
628 JFactory::getApplication()->enqueueMessage($warn, 'warning');
629 }
630 }
631 }
632
633 /**
634 * Method used to check for any installation message to show.
635 *
636 * @return void
637 */
638 public static function handleMessage()
639 {
640 $app = JFactory::getApplication();
641
642 // if we are in the admin section and the plugin has been activated
643 if ($app->isAdmin() && get_option('vikbooking_onactivate') == 1)
644 {
645 // delete the activation flag to avoid displaying the message more than once
646 delete_option('vikbooking_onactivate');
647
648 ?>
649 <div class="notice is-dismissible notice-success">
650 <p>
651 <strong>Thanks for activating our plugin!</strong>
652 <a href="https://vikwp.com" target="_blank">https://vikwp.com</a>
653 </p>
654 </div>
655 <?php
656 }
657 }
658
659 /**
660 * Check if the Pro version has expired to alert the user that an
661 * update would actually mean downgrading to the free version.
662 *
663 * @since 1.2.8
664 */
665 public static function handleUpdateWarning()
666 {
667 global $pagenow;
668
669 if ($pagenow == 'plugins.php' && VikBookingLicense::isExpired() && !VikBookingLicense::hasVcm())
670 {
671 if (!JFactory::getApplication()->input->cookie->getInt('vbo_update_warning_hide', 0))
672 {
673 ?>
674 <div class="notice is-dismissible notice-warning" id="vbo-update-warning">
675 <p>
676 <strong><?php echo JText::translate('VBOPROVEXPWARNUPD'); ?></strong>
677 </p>
678 </div>
679
680 <script type="text/javascript">
681 jQuery(document).ready(function() {
682 jQuery('#vbo-update-warning').on('click', '.notice-dismiss', function(event, el) {
683 var numWeeks = 1;
684 if (typeof localStorage !== 'undefined') {
685 numWeeks = localStorage.getItem('vbo_update_warning_hide_count');
686 numWeeks = !numWeeks ? 0 : parseInt(numWeeks);
687 numWeeks++;
688 localStorage.setItem('vbo_update_warning_hide_count', numWeeks);
689 }
690 var nd = new Date();
691 nd.setDate(nd.getDate() + (7 * numWeeks));
692 document.cookie = 'vbo_update_warning_hide=1; expires=' + nd.toUTCString() + '; path=/; SameSite=Lax';
693 });
694 });
695 </script>
696 <?php
697 }
698 }
699 }
700 }
701