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 / builder.php

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

705 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 * @since 1.6.9 added support for "tot_fees".
286 */
287
288 // manipulate the response to be compliant with the old payment system
289 $response = array(
290 'verified' => (int) $status->isVerified(),
291 'tot_paid' => $status->amount,
292 'tot_fees' => $status->fees,
293 'log' => $status->log,
294 'transaction' => $status->transaction,
295 );
296
297 if ($status->skip_email)
298 {
299 $response['skip_email'] = $status->skip_email;
300 }
301 }, 10, 3);
302
303 // manipulate response to be compliant with dorefund task
304 add_action('payment_after_refund_transaction_vikbooking', function(&$payment, &$status, &$response)
305 {
306 /**
307 * Transactions of type refund need to unify the response
308 * to be compliant with all platforms.
309 *
310 * @since 1.4.0
311 */
312
313 // manipulate the response to be compliant with the old payment system
314 $response = array(
315 'verified' => (int) $status->isVerified(),
316 'tot_refunded' => $status->amount,
317 'log' => $status->log,
318 );
319 }, 10, 3);
320
321 // manipulate response to be compliant with direct charge transaction
322 add_action('payment_after_direct_charge_vikbooking', function($payment, $status, &$response)
323 {
324 /**
325 * Transactions of type direct charge need to unify the response
326 * to be compliant with all platforms.
327 *
328 * @since 1.6.4
329 */
330
331 // manipulate the response to be compliant with any platform
332 $response = array(
333 'verified' => (int) $status->isVerified(),
334 'tot_paid' => $status->amount,
335 'log' => $status->log,
336 'transaction' => $status->transaction,
337 );
338 }, 10, 3);
339 }
340
341 /**
342 * Registers all the widget contained within the modules folder.
343 *
344 * @return void
345 */
346 public static function setupWidgets()
347 {
348 JLoader::import('adapter.module.factory');
349
350 // load all the modules
351 JModuleFactory::load(VIKBOOKING_BASE . DIRECTORY_SEPARATOR . 'modules');
352
353 /**
354 * Loads also the widgets to display within the
355 * admin dashboard of WordPress.
356 *
357 * @since 1.3.9
358 */
359 add_action('wp_dashboard_setup', function()
360 {
361 JLoader::import('adapter.dashboard.admin');
362
363 // set up folder containing the widget to load
364 $path = VIKBOOKING_LIBRARIES . DIRECTORY_SEPARATOR . 'dashboard';
365 // define the classname prefix
366 $prefix = 'JDashboardWidgetVikBooking';
367
368 try
369 {
370 // load and register widgets
371 JDashboardAdmin::load($path, $prefix);
372 }
373 catch (Exception $e)
374 {
375 // silently suppress exception to avoid breaking the website
376
377 if (VIKBOOKING_DEBUG)
378 {
379 // propagate error in case of debug enabled
380 throw $e;
381 }
382 }
383 });
384 }
385
386 /**
387 * Configures the RSS feeds reader.
388 *
389 * @return JRssReader
390 *
391 * @since 1.3.9
392 */
393 public static function setupRssReader()
394 {
395 // autoload RSS handler class
396 JLoader::import('adapter.rss.reader');
397
398 /**
399 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
400 *
401 * @param array $channels A list of RSS permalinks.
402 * @param boolean $status True to return only the published channels.
403 *
404 * @return array A list of supported channels.
405 *
406 * @since 1.3.9
407 */
408 $channels = apply_filters('vikbooking_fetch_rss_channels', array(), true);
409
410 if (VIKBOOKING_DEBUG)
411 {
412 /**
413 * Filters the transient lifetime of the feed cache.
414 *
415 * @since 2.8.0
416 *
417 * @param integer $lifetime Cache duration in seconds. Default is 43200 seconds (12 hours).
418 * @param string $filename Unique identifier for the cache object.
419 */
420 add_filter('wp_feed_cache_transient_lifetime', function($time, $url) use ($channels)
421 {
422 // in case of debug enabled, cache the feeds only for 60 seconds
423 if ($url == $channels || in_array($url, $channels))
424 {
425 $time = 60;
426 }
427
428 return $time;
429 }, 10, 2);
430 }
431
432 // instantiate RSS reader
433 $rss = JRssReader::getInstance($channels, 'vikbooking');
434
435 /**
436 * Hook used to apply some stuff before returning the RSS reader.
437 *
438 * @param JRssReader &$rss The RSS reader handler.
439 *
440 * @return void
441 *
442 * @since 1.3.9
443 */
444 do_action_ref_array('vikbooking_before_use_rss', array(&$rss));
445
446 return $rss;
447 }
448
449 /**
450 * Extends the backup framework.
451 *
452 * @return void
453 *
454 * @since 1.5
455 */
456 public static function setupBackupSystem()
457 {
458 /**
459 * Anonymous function used to check whether the manifest includes the shortcodes import.
460 *
461 * @param object $manifest The backup manifest.
462 *
463 * @return boolean
464 */
465 $hasShortcodes = function($manifest)
466 {
467 // look for the uninstall directive inside the manifest, which is mainly
468 // used during the sample data installation
469 if (isset($manifest->uninstall))
470 {
471 // iterate all uninstall queries
472 foreach ((array) $manifest->uninstall as $query)
473 {
474 // look for a table that uninstall the shortcodes
475 if (preg_match("/#__vikbooking_wpshortcodes\b/", $query))
476 {
477 return true;
478 }
479 }
480 }
481
482 // look for the directive containing the installation rules
483 if (isset($manifest->installers))
484 {
485 // iterate all install rules
486 foreach ((array) $manifest->installers as $rule)
487 {
488 // detect SQL File role
489 if ($rule->role === 'sqlfile')
490 {
491 // check shortcodes into the file path
492 $target = [$rule->data->path];
493 }
494 else if ($rule->role === 'sql')
495 {
496 // search into all the provided queries
497 $target = (array) $rule->data;
498 }
499 else
500 {
501 // nothing to check
502 $target = [];
503 }
504
505 foreach ($target as $tmp)
506 {
507 // check whether the current target mentions the shortcodes database table
508 if (preg_match("/#__vikbooking_wpshortcodes\b/", $tmp))
509 {
510 return true;
511 }
512 }
513 }
514 }
515
516 return false;
517 };
518
519 /**
520 * Trigger event to allow third party plugins to extend the backup import.
521 * This hook triggers before processing the import of an existing backup.
522 *
523 * It is possible to throw an exception to prevent the import process.
524 *
525 * Uninstalls all the pages that have been assigned to the existing shortcodes.
526 *
527 * @param object $manifest The backup manifest.
528 * @param string $path The path of the backup archive (uncompressed).
529 *
530 * @since 1.5
531 *
532 * @throws Exception
533 */
534 add_action('vikbooking_before_import_backup', function($manifest, $path) use ($hasShortcodes)
535 {
536 // check whether the manifest includes the shortcodes installation
537 $manifest->shortcodes = $hasShortcodes($manifest);
538
539 if (empty($manifest->shortcodes))
540 {
541 // shortcodes not included within the backup, do not uninstall
542 return;
543 }
544
545 // get shortcode admin model
546 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
547
548 // get all existing shortcodes
549 $shortcodes = $model->all(array('createdon', 'post_id'));
550
551 // iterate all shortcodes found
552 foreach ($shortcodes as $shortcode)
553 {
554 // make sure the shortcode has been assigned to a post
555 if ($shortcode->post_id)
556 {
557 // get post details
558 $post = get_post((int) $shortcode->post_id);
559
560 if (!$post)
561 {
562 continue;
563 }
564
565 // convert shortcode creation date
566 $shortcode->createdon = new JDate($shortcode->createdon);
567 // convert post creation date
568 $post->post_date_gmt = new JDate($post->post_date_gmt);
569
570 // compare ephocs and make sure the post was not created before the shortcode
571 if ((int) $shortcode->createdon->format('U') <= (int) $post->post_date_gmt->format('U'))
572 {
573 // permanently delete post
574 wp_delete_post($post->ID, $force_delete = true);
575 }
576 }
577 }
578 }, 10, 2);
579
580 /**
581 * Trigger event to allow third party plugins to extend the backup import.
582 * This hook triggers after processing the import of an existing backup.
583 *
584 * It is possible to throw an exception to prevent the import process.
585 *
586 * Assigns all the newly created shortcodes to new pages.
587 *
588 * @param object $manifest The backup manifest.
589 * @param string $path The path of the backup archive (uncompressed).
590 *
591 * @since 1.5
592 *
593 * @throws Exception
594 */
595 add_action('vikbooking_after_import_backup', function($manifest, $path)
596 {
597 if (!empty($manifest->shortcodes))
598 {
599 // get shortcodes admin model
600 $listModel = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
601
602 // get all existing shortcodes
603 $shortcodes = $listModel->all('id');
604
605 // get shortcode admin model
606 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
607
608 // iterate all shortcodes found
609 foreach ($shortcodes as $shortcode)
610 {
611 // assign the shortcode to a new page
612 $model->addPage($shortcode->id);
613 }
614 }
615
616 // trigger full files mirroring
617 VikBookingUpdateManager::triggerUploadFullMirroring();
618 }, 10, 2);
619
620 /**
621 * Trigger event to allow third party plugins to choose what are the columns to dump
622 * and whether the table should be skipped or not.
623 *
624 * Fires while attaching a rule to dump some SQL statements.
625 *
626 * Used to avoid dumping the post ID to which the shortcodes are attached
627 *
628 * @param boolean $include False to avoid including the table into the backup.
629 * @param array &$columns An associative array of supported database table columns,
630 * where the key is the column name and the value is a nested
631 * array holding the column information.
632 * @param string $table The name of the database table.
633 *
634 * @since 1.5
635 */
636 add_filter('vikbooking_before_backup_dump_sql', function($include, &$columns, $table)
637 {
638 if (is_null($include))
639 {
640 $include = true;
641 }
642
643 // check if we are exporting the shortcodes
644 if ($table === '#__vikbooking_wpshortcodes')
645 {
646 // avoid dumping the post ID column
647 unset($columns['post_id'], $columns['tmp_post_id']);
648 }
649
650 return $include;
651 }, 10, 3);
652 }
653
654 /**
655 * Implements the tools needed to manage the overrides
656 * without having to use a FTP client.
657 *
658 * @return void
659 *
660 * @since 1.6.5
661 */
662 public static function setupOverridesManager()
663 {
664 /**
665 * Trigger event to allow the plugins to include custom HTML within the view.
666 * It is possible to return an associative array to group the HTML strings
667 * under different fieldsets. Plain/html string will be always pushed within
668 * the "custom" fieldset instead.
669 *
670 * Displays the overrides configuration.
671 *
672 * @param mixed $forms The HTML to display.
673 * @param mixed $view The current view instance.
674 *
675 * @since 1.6.5
676 */
677 add_filter('vikbooking_display_view_config_global', function($forms, $view)
678 {
679 if (!$forms)
680 {
681 // init forms array
682 $forms = [];
683 }
684
685 // render configuration layout
686 $html = JLayoutHelper::render('html.overrides.config', [
687 'view' => $view,
688 ]);
689
690 // add fieldset to forms
691 $forms[__('Page Overrides', 'vikbooking')] = $html;
692
693 return $forms;
694 }, 8, 2);
695
696 /**
697 * Hook used to display a list of breaking changes after completing an update of the plugin.
698 * The message will be displayed only once within the dashboard of VikBooking.
699 *
700 * @since 1.6.5
701 */
702 add_action('vikbooking_before_display_dashboard', array('VikBookingInstaller', 'showBreakingChanges'));
703 }
704 }
705