PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.8
VikBooking Hotel Booking Engine & PMS v1.6.8
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 / builder.php

builder.php in VikBooking Hotel Booking Engine & PMS 1.6.8, at libraries/system/builder.php

706 lines 18.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 - 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 /**
15 * Helper class to setup the plugin.
16 *
17 * @since 1.0
18 */
19 class VikBookingBuilder
20 {
21 /**
22 * Loads the .mo language related to the current locale.
23 *
24 * @return void
25 */
26 public static function loadLanguage()
27 {
28 $app = JFactory::getApplication();
29
30 /**
31 * @since 1.0.2 All the language files have been merged
32 * within a single file to be compliant with
33 * the Worpdress Translation Standards.
34 * The language file is located in /languages folder.
35 */
36 $path = VIKBOOKING_LANG;
37
38 $handler = VIKBOOKING_LIBRARIES . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
39 $domain = 'vikbooking';
40
41 // init language
42 $lang = JFactory::getLanguage();
43
44 $lang->attachHandler($handler . 'system.php', $domain);
45
46 if ($app->isAdmin())
47 {
48 $lang->attachHandler($handler . 'adminsys.php', $domain);
49 $lang->attachHandler($handler . 'admin.php', $domain);
50 }
51 else
52 {
53 $lang->attachHandler($handler . 'site.php', $domain);
54 }
55
56 $lang->load($domain, $path);
57 }
58
59 /**
60 * Setup the pagination layout to use.
61 *
62 * @return void
63 */
64 public static function setupPaginationLayout()
65 {
66 $layout = new JLayoutFile('html.system.pagination', null, array('component' => 'com_vikbooking'));
67
68 JLoader::import('adapter.pagination.pagination');
69 JPagination::setLayout($layout);
70 }
71
72 /**
73 * Pushes the plugin pages into the WP admin menu.
74 *
75 * @return void
76 *
77 * @link https://developer.wordpress.org/resource/dashicons/#star-filled
78 */
79 public static function setupAdminMenu()
80 {
81 JLoader::import('adapter.acl.access');
82 $capability = JAccess::adjustCapability('core.manage', 'com_vikbooking');
83
84 add_menu_page(
85 JText::translate('COM_VIKBOOKING'), // page title
86 JText::translate('COM_VIKBOOKING_MENU'), // menu title
87 $capability, // capability
88 'vikbooking', // slug
89 array('VikBookingBody', 'getHtml'), // callback
90 'dashicons-building', // icon
91 71 // ordering
92 );
93 }
94
95 /**
96 * Setup HTML helper classes.
97 * This method should be used to register custom function
98 * for example to render own layouts.
99 *
100 * @return void
101 */
102 public static function setupHtmlHelpers()
103 {
104 // helper method to render calendars layout
105 JHtml::register('renderCalendar', function($data)
106 {
107 JHtml::fetch('script', VBO_SITE_URI . 'resources/jquery-ui.min.js');
108 JHtml::fetch('stylesheet', VBO_SITE_URI . 'resources/jquery-ui.min.css');
109
110 $layout = new JLayoutFile('html.plugins.calendar', null, array('component' => 'com_vikbooking'));
111
112 return $layout->render($data);
113 });
114
115 // helper method to get the plugin layout file handler
116 JHtml::register('layoutfile', function($layoutId, $basePath = null, $options = array())
117 {
118 $input = JFactory::getApplication()->input;
119
120 if (!isset($options['component']) && !$input->getBool('option'))
121 {
122 // force layout file in case there is no active plugin
123 $options['component'] = 'com_vikbooking';
124 }
125
126 return new JLayoutFile($layoutId, $basePath, $options);
127 });
128
129 // helper method to include the system JS file
130 JHtml::register('system.js', function()
131 {
132 static $loaded = 0;
133
134 if (!$loaded)
135 {
136 // include only once
137 $loaded = 1;
138
139 $internalFilesOptions = array('version' => VIKBOOKING_SOFTWARE_VERSION);
140
141 JHtml::fetch('script', VBO_ADMIN_URI . 'resources/js/system.js', $internalFilesOptions, array('id' => 'vbo-sys-script'));
142 JHtml::fetch('stylesheet', VBO_ADMIN_URI . 'resources/css/system.css', $internalFilesOptions, array('id' => 'vbo-sys-style'));
143
144 /**
145 * The CSS/JS files of Bootstrap may disturb the styles of the Theme, and so
146 * we load it only within the back-end, or if the configuration setting is on.
147 *
148 * @since 1.3.0
149 */
150 if (JFactory::getApplication()->isAdmin() || (class_exists('VikBooking') && VikBooking::loadBootstrap()))
151 {
152 /**
153 * Prior the version 1.3.5 the file bootstrap.min.js was always loaded above and outside
154 * this IF statement. We now wrap all Bootstrap assets within the admin or setting enabled.
155 *
156 * @since 1.3.5
157 */
158 JHtml::fetch('script', VBO_ADMIN_URI . 'resources/js/bootstrap.min.js', $internalFilesOptions, array('id' => 'bootstrap-script'));
159
160 JHtml::fetch('stylesheet', VBO_ADMIN_URI . 'resources/css/bootstrap.lite.css', $internalFilesOptions, array('id' => 'bootstrap-lite-style'));
161 }
162 }
163 });
164
165 // helper method to include the select2 JS file
166 JHtml::register('select2', function()
167 {
168 /**
169 * Select2 is now loaded only when requested.
170 *
171 * @since 1.2.5
172 */
173 JHtml::fetch('script', VBO_ADMIN_URI . 'resources/select2.min.js');
174 JHtml::fetch('stylesheet', VBO_ADMIN_URI . 'resources/select2.min.css');
175 });
176
177 /**
178 * Register helper methods to sanitize attributes, html, JS and other elements.
179 */
180 JHtml::register('esc_attr', function($str)
181 {
182 return esc_attr($str);
183 });
184
185 JHtml::register('esc_html', function($str)
186 {
187 return esc_html($str);
188 });
189
190 JHtml::register('esc_js', function($str)
191 {
192 return esc_js($str);
193 });
194
195 JHtml::register('esc_textarea', function($str)
196 {
197 return esc_textarea($str);
198 });
199
200 /**
201 * Attempt to turn on the SQL_BIG_SELECTS setting at runtime, to avoid
202 * SQL errors like "The SELECT would examine more than MAX_JOIN_SIZE rows;".
203 * This has affected several clients with the Channel Manager for the Guest Messages
204 * downloaded by OTAs like Booking.com or Airbnb. Since we do this operation at runtime,
205 * we attempt to suppress the DB errors in case the user does not have enough permissions
206 * to run queries of type "SET". Once executed, we restore the original value for DB errors.
207 *
208 * @since 1.16.0 (J) - 1.6.0 (WP)
209 */
210 add_action('plugins_loaded', function()
211 {
212 $dbo = JFactory::getDbo();
213
214 // suppress temporarily any database error
215 $dbo->suppress_errors(true);
216
217 // turn on the required SQL setting
218 $dbo->setQuery('SET SQL_BIG_SELECTS=1');
219 $dbo->execute();
220
221 // restore the default SQL display errors setting
222 $dbo->suppress_errors(false);
223 });
224 }
225
226 /**
227 * This method is used to configure teh payments framework.
228 * Here should be registered all the default gateways supported
229 * by the plugin.
230 *
231 * @return void
232 *
233 * @since 1.0.5
234 */
235 public static function configurePaymentFramework()
236 {
237 // push the pre-installed gateways within the payment drivers list
238 add_filter('get_supported_payments_vikbooking', function($drivers)
239 {
240 $list = glob(VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'payments' . DIRECTORY_SEPARATOR . '*.php');
241
242 return array_merge($drivers, $list);
243 });
244
245 // load payment handlers when dispatched
246 add_action('load_payment_gateway_vikbooking', function(&$drivers, $payment)
247 {
248 $classname = null;
249
250 VikBookingLoader::import('admin.payments.' . $payment, VIKBOOKING_BASE);
251
252 switch ($payment)
253 {
254 case 'paypal':
255 $classname = 'VikBookingPayPalPayment';
256 break;
257
258 case 'paypal_checkout':
259 $classname = 'VikBookingPayPalCheckoutPayment';
260 break;
261
262 case 'offline_credit_card':
263 $classname = 'VikBookingOfflineCreditCardPayment';
264 break;
265
266 case 'bank_transfer':
267 $classname = 'VikBookingBankTransferPayment';
268 break;
269 }
270
271 if ($classname)
272 {
273 $drivers[] = $classname;
274 }
275 }, 10, 2);
276
277 // manipulate response to be compliant with notifypayment task
278 add_action('payment_after_validate_transaction_vikbooking', function(&$payment, &$status, &$response)
279 {
280 /**
281 * Transaction property can be used to perform refunds, and it's collected
282 * and returned during charge/capture transactions only.
283 *
284 * @since 1.4.0
285 */
286
287 // manipulate the response to be compliant with the old payment system
288 $response = array(
289 'verified' => (int) $status->isVerified(),
290 'tot_paid' => $status->amount,
291 'log' => $status->log,
292 'transaction' => $status->transaction,
293 );
294
295 if ($status->skip_email)
296 {
297 $response['skip_email'] = $status->skip_email;
298 }
299 }, 10, 3);
300
301 // manipulate response to be compliant with dorefund task
302 add_action('payment_after_refund_transaction_vikbooking', function(&$payment, &$status, &$response)
303 {
304 /**
305 * Transactions of type refund need to unify the response
306 * to be compliant with all platforms.
307 *
308 * @since 1.4.0
309 */
310
311 // manipulate the response to be compliant with the old payment system
312 $response = array(
313 'verified' => (int) $status->isVerified(),
314 'tot_refunded' => $status->amount,
315 'log' => $status->log,
316 );
317 }, 10, 3);
318
319 // manipulate response to be compliant with direct charge transaction
320 add_action('payment_after_direct_charge_vikbooking', function($payment, $status, &$response)
321 {
322 /**
323 * Transactions of type direct charge need to unify the response
324 * to be compliant with all platforms.
325 *
326 * @since 1.6.4
327 */
328
329 // manipulate the response to be compliant with any platform
330 $response = array(
331 'verified' => (int) $status->isVerified(),
332 'tot_paid' => $status->amount,
333 'log' => $status->log,
334 'transaction' => $status->transaction,
335 );
336 }, 10, 3);
337 }
338
339 /**
340 * Registers all the widget contained within the modules folder.
341 *
342 * @return void
343 */
344 public static function setupWidgets()
345 {
346 JLoader::import('adapter.module.factory');
347
348 // load all the modules
349 JModuleFactory::load(VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'modules');
350
351 /**
352 * Loads also the widgets to display within the
353 * admin dashboard of WordPress.
354 *
355 * @since 1.3.9
356 */
357 add_action('wp_dashboard_setup', function()
358 {
359 JLoader::import('adapter.dashboard.admin');
360
361 // set up folder containing the widget to load
362 $path = VIKBOOKING_LIBRARIES . DIRECTORY_SEPARATOR . 'dashboard';
363 // define the classname prefix
364 $prefix = 'JDashboardWidgetVikBooking';
365
366 try
367 {
368 // load and register widgets
369 JDashboardAdmin::load($path, $prefix);
370 }
371 catch (Exception $e)
372 {
373 // silently suppress exception to avoid breaking the website
374
375 if (VIKBOOKING_DEBUG)
376 {
377 // propagate error in case of debug enabled
378 throw $e;
379 }
380 }
381 });
382 }
383
384 /**
385 * Configures the RSS feeds reader.
386 *
387 * @return JRssReader
388 *
389 * @since 1.3.9
390 */
391 public static function setupRssReader()
392 {
393 // autoload RSS handler class
394 JLoader::import('adapter.rss.reader');
395
396 /**
397 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
398 *
399 * @param array $channels A list of RSS permalinks.
400 * @param boolean $status True to return only the published channels.
401 *
402 * @return array A list of supported channels.
403 *
404 * @since 1.3.9
405 */
406 $channels = apply_filters('vikbooking_fetch_rss_channels', array(), true);
407
408 if (VIKBOOKING_DEBUG)
409 {
410 /**
411 * Filters the transient lifetime of the feed cache.
412 *
413 * @since 2.8.0
414 *
415 * @param integer $lifetime Cache duration in seconds. Default is 43200 seconds (12 hours).
416 * @param string $filename Unique identifier for the cache object.
417 */
418 add_filter('wp_feed_cache_transient_lifetime', function($time, $url) use ($channels)
419 {
420 // in case of debug enabled, cache the feeds only for 60 seconds
421 if ($url == $channels || in_array($url, $channels))
422 {
423 $time = 60;
424 }
425
426 return $time;
427 }, 10, 2);
428 }
429
430 // instantiate RSS reader
431 $rss = JRssReader::getInstance($channels, 'vikbooking');
432
433 /**
434 * Hook used to apply some stuff before returning the RSS reader.
435 *
436 * @param JRssReader &$rss The RSS reader handler.
437 *
438 * @return void
439 *
440 * @since 1.3.9
441 */
442 do_action_ref_array('vikbooking_before_use_rss', array(&$rss));
443
444 return $rss;
445 }
446
447 /**
448 * Extends the backup framework.
449 *
450 * @return void
451 *
452 * @since 1.5
453 */
454 public static function setupBackupSystem()
455 {
456 /**
457 * Anonymous function used to check whether the manifest includes the shortcodes import.
458 *
459 * @param object $manifest The backup manifest.
460 *
461 * @return boolean
462 */
463 $hasShortcodes = function($manifest)
464 {
465 // look for the uninstall directive inside the manifest, which is mainly
466 // used during the sample data installation
467 if (isset($manifest->uninstall))
468 {
469 // iterate all uninstall queries
470 foreach ((array) $manifest->uninstall as $query)
471 {
472 // look for a table that uninstall the shortcodes
473 if (preg_match("/#__vikbooking_wpshortcodes\b/", $query))
474 {
475 return true;
476 }
477 }
478 }
479
480 // look for the directive containing the installation rules
481 if (isset($manifest->installers))
482 {
483 // iterate all install rules
484 foreach ((array) $manifest->installers as $rule)
485 {
486 // detect SQL File role
487 if ($rule->role === 'sqlfile')
488 {
489 // check shortcodes into the file path
490 $target = [$rule->data->path];
491 }
492 else if ($rule->role === 'sql')
493 {
494 // search into all the provided queries
495 $target = (array) $rule->data;
496 }
497 else
498 {
499 // nothing to check
500 $target = [];
501 }
502
503 foreach ($target as $tmp)
504 {
505 // check whether the current target mentions the shortcodes database table
506 if (preg_match("/#__vikbooking_wpshortcodes\b/", $tmp))
507 {
508 return true;
509 }
510 }
511 }
512 }
513
514 return false;
515 };
516
517 /**
518 * Trigger event to allow third party plugins to extend the backup import.
519 * This hook triggers before processing the import of an existing backup.
520 *
521 * It is possible to throw an exception to prevent the import process.
522 *
523 * Uninstalls all the pages that have been assigned to the existing shortcodes.
524 *
525 * @param object $manifest The backup manifest.
526 * @param string $path The path of the backup archive (uncompressed).
527 *
528 * @since 1.5
529 *
530 * @throws Exception
531 */
532 add_action('vikbooking_before_import_backup', function($manifest, $path) use ($hasShortcodes)
533 {
534 // check whether the manifest includes the shortcodes installation
535 $manifest->shortcodes = $hasShortcodes($manifest);
536
537 if (empty($manifest->shortcodes))
538 {
539 // shortcodes not included within the backup, do not uninstall
540 return;
541 }
542
543 // get shortcode admin model
544 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
545
546 // get all existing shortcodes
547 $shortcodes = $model->all(array('createdon', 'post_id'));
548
549 // iterate all shortcodes found
550 foreach ($shortcodes as $shortcode)
551 {
552 // make sure the shortcode has been assigned to a post
553 if ($shortcode->post_id)
554 {
555 // get post details
556 $post = get_post((int) $shortcode->post_id);
557
558 if (!$post)
559 {
560 continue;
561 }
562
563 // convert shortcode creation date
564 $shortcode->createdon = new JDate($shortcode->createdon);
565 // convert post creation date
566 $post->post_date_gmt = new JDate($post->post_date_gmt);
567
568 // compare ephocs and make sure the post was not created before the shortcode
569 if ((int) $shortcode->createdon->format('U') <= (int) $post->post_date_gmt->format('U'))
570 {
571 // permanently delete post
572 wp_delete_post($post->ID, $force_delete = true);
573 }
574 }
575 }
576 }, 10, 2);
577
578 /**
579 * Trigger event to allow third party plugins to extend the backup import.
580 * This hook triggers after processing the import of an existing backup.
581 *
582 * It is possible to throw an exception to prevent the import process.
583 *
584 * Assigns all the newly created shortcodes to new pages.
585 *
586 * @param object $manifest The backup manifest.
587 * @param string $path The path of the backup archive (uncompressed).
588 *
589 * @since 1.5
590 *
591 * @throws Exception
592 */
593 add_action('vikbooking_after_import_backup', function($manifest, $path)
594 {
595 if (empty($manifest->shortcodes))
596 {
597 // shortcodes not included within the backup, do not install
598 return;
599 }
600
601 // get shortcodes admin model
602 $listModel = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
603
604 // get all existing shortcodes
605 $shortcodes = $listModel->all('id');
606
607 // get shortcode admin model
608 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
609
610 // iterate all shortcodes found
611 foreach ($shortcodes as $shortcode)
612 {
613 // assign the shortcode to a new page
614 $model->addPage($shortcode->id);
615 }
616
617 // trigger full files mirroring
618 VikBookingUpdateManager::triggerUploadFullMirroring();
619 }, 10, 2);
620
621 /**
622 * Trigger event to allow third party plugins to choose what are the columns to dump
623 * and whether the table should be skipped or not.
624 *
625 * Fires while attaching a rule to dump some SQL statements.
626 *
627 * Used to avoid dumping the post ID to which the shortcodes are attached
628 *
629 * @param boolean $include False to avoid including the table into the backup.
630 * @param array &$columns An associative array of supported database table columns,
631 * where the key is the column name and the value is a nested
632 * array holding the column information.
633 * @param string $table The name of the database table.
634 *
635 * @since 1.5
636 */
637 add_filter('vikbooking_before_backup_dump_sql', function($include, &$columns, $table)
638 {
639 if (is_null($include))
640 {
641 $include = true;
642 }
643
644 // check if we are exporting the shortcodes
645 if ($table === '#__vikbooking_wpshortcodes')
646 {
647 // avoid dumping the post ID column
648 unset($columns['post_id'], $columns['tmp_post_id']);
649 }
650
651 return $include;
652 }, 10, 3);
653 }
654
655 /**
656 * Implements the tools needed to manage the overrides
657 * without having to use a FTP client.
658 *
659 * @return void
660 *
661 * @since 1.6.5
662 */
663 public static function setupOverridesManager()
664 {
665 /**
666 * Trigger event to allow the plugins to include custom HTML within the view.
667 * It is possible to return an associative array to group the HTML strings
668 * under different fieldsets. Plain/html string will be always pushed within
669 * the "custom" fieldset instead.
670 *
671 * Displays the overrides configuration.
672 *
673 * @param mixed $forms The HTML to display.
674 * @param mixed $view The current view instance.
675 *
676 * @since 1.6.5
677 */
678 add_filter('vikbooking_display_view_config_global', function($forms, $view)
679 {
680 if (!$forms)
681 {
682 // init forms array
683 $forms = [];
684 }
685
686 // render configuration layout
687 $html = JLayoutHelper::render('html.overrides.config', [
688 'view' => $view,
689 ]);
690
691 // add fieldset to forms
692 $forms[__('Page Overrides', 'vikbooking')] = $html;
693
694 return $forms;
695 }, 8, 2);
696
697 /**
698 * Hook used to display a list of breaking changes after completing an update of the plugin.
699 * The message will be displayed only once within the dashboard of VikBooking.
700 *
701 * @since 1.6.5
702 */
703 add_action('vikbooking_before_display_dashboard', array('VikBookingInstaller', 'showBreakingChanges'));
704 }
705 }
706