PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.5
VikBooking Hotel Booking Engine & PMS v1.6.5
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 / vikbooking.php

vikbooking.php in VikBooking Hotel Booking Engine & PMS 1.6.5, at vikbooking.php

881 lines 24.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: VikBooking
4 Plugin URI: https://vikwp.com/plugin/vikbooking
5 Description: Certified Booking Engine for Hotels and Accommodations.
6 Version: 1.6.5
7 Author: E4J s.r.l.
8 Author URI: https://vikwp.com
9 License: GPL2
10 License URI: https://www.gnu.org/licenses/gpl-2.0.html
11 Text Domain: vikbooking
12 Domain Path: /languages
13 */
14
15 // No direct access
16 defined('ABSPATH') or die('No script kiddies please!');
17
18 // autoload dependencies
19 require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'autoload.php';
20
21 // handle install/uninstall
22 register_activation_hook(__FILE__, array('VikBookingInstaller', 'activate'));
23 register_deactivation_hook(__FILE__, array('VikBookingInstaller', 'deactivate'));
24 register_uninstall_hook(__FILE__, array('VikBookingInstaller', 'delete'));
25
26 // init Installer
27 add_action('init', array('VikBookingInstaller', 'onInit'));
28
29 /**
30 * Fires after all automatic updates have run.
31 * Completes the update scheduled in background.
32 *
33 * @param array $results The results of all attempted updates.
34 *
35 * @since 1.3.12
36 */
37 add_action('automatic_updates_complete', array('VikBookingInstaller', 'automaticUpdate'));
38
39 /**
40 * Filters whether to automatically update core, a plugin, a theme, or a language.
41 * Used to automatically turn off the update in case a PRO version expired.
42 *
43 * @param bool|null $update Whether to update. The value of null is internally used
44 * to detect whether nothing has hooked into this filter.
45 * @param object $item The update offer.
46 *
47 * @since 1.3.12
48 */
49 add_filter('auto_update_plugin', array('VikBookingInstaller', 'useAutoUpdate'), 10, 2);
50
51 /**
52 * Fires at the end of the update message container in each
53 * row of the plugins list table.
54 *
55 * The dynamic portion of the hook name, `$file`, refers to the path
56 * of the plugin's primary file relative to the plugins directory.
57 *
58 * @link https://developer.wordpress.org/reference/hooks/in_plugin_update_message-file/
59 *
60 * @param array $data An array of plugin metadata.
61 * @param array $response An array of metadata about the available plugin update.
62 *
63 * @since 1.3.12
64 */
65 add_action('in_plugin_update_message-vikbooking/vikbooking.php', array('VikBookingInstaller', 'getUpdateMessage'), 10, 2);
66
67 // init pagination layout
68 VikBookingBuilder::setupPaginationLayout();
69 // init html helpers
70 VikBookingBuilder::setupHtmlHelpers();
71 // init payment framework
72 VikBookingBuilder::configurePaymentFramework();
73 // setup hooks to extend the backup functionalities
74 VikBookingBuilder::setupBackupSystem();
75
76 // setup plugin overrides management
77 add_action('plugins_loaded', array('VikBookingBuilder', 'setupOverridesManager'));
78
79 // setup lite system
80 add_action('plugins_loaded', array('VikBookingLiteManager', 'setup'));
81
82 /**
83 * Added support for screen options.
84 * Parameters such as the list limit can be changed from there.
85 *
86 * @since 1.2.5
87 */
88 add_action('current_screen', array('VikBookingScreen', 'options'));
89 add_filter('set-screen-option', array('VikBookingScreen', 'saveOption'), 10, 3);
90 /**
91 * Due to WordPress 5.4.2 changes, we need to attach
92 * VikBooking to a dedicated hook in order to
93 * allow the update of the list limit.
94 *
95 * @since 1.3.5
96 */
97 add_filter('set_screen_option_vikbooking_list_limit', array('VikBookingScreen', 'saveOption'), 10, 3);
98
99 // init Session
100 add_action('init', array('JSessionHandler', 'start'), 1);
101 add_action('wp_logout', array('JSessionHandler', 'destroy'));
102
103 // filter page link to rewrite URI
104 add_action('plugins_loaded', function()
105 {
106 // installer class will check the update status
107 VikBookingInstaller::update();
108
109 /**
110 *
111 * Fires once the plugins have loaded.
112 *
113 * Language is loaded through the filter 'plugins_loaded' in order to avoid to load language
114 * before the correct one has been set by WordPress or by another third-party plugin.
115 *
116 * @link https://developer.wordpress.org/reference/hooks/plugins_loaded/
117 *
118 * @since 1.4.2
119 */
120 VikBookingBuilder::loadLanguage();
121
122 global $pagenow;
123
124 $app = JFactory::getApplication();
125 $input = $app->input;
126
127 // check if the URI contains option=com_vikbooking
128 if ($input->get('option') == 'com_vikbooking')
129 {
130 // make sure we are not contacting the AJAX and POST end-points
131 if (!wp_doing_ajax() && $pagenow != 'admin-post.php')
132 {
133 /**
134 * Include page in query string only if we are in the back-end,
135 * because WordPress 5.5 seems to break the page loading in case
136 * that argument has been included in query string.
137 *
138 * It is not needed to include this argument in the front-end
139 * as the page should lean on the reached shortcode only.
140 *
141 * @since 1.3.7
142 */
143 if ($app->isAdmin())
144 {
145 // inject page=vikbooking in GET superglobal
146 $input->get->set('page', 'vikbooking');
147 }
148 }
149 else
150 {
151 // inject action=vikbooking in GET superglobal for AJAX and POST requests
152 $_GET['action'] = 'vikbooking';
153 }
154 }
155 elseif ($input->get('page') == 'vikbooking' || $input->get('action') == 'vikbooking')
156 {
157 // inject option=com_vikbooking in GET superglobal
158 $_GET['option'] = 'com_vikbooking';
159 }
160 });
161
162 // process the request and obtain the response
163 add_action('init', function()
164 {
165 $app = JFactory::getApplication();
166 $input = $app->input;
167
168 // if we are in the front-end, try to parse the URL to inject
169 // option, view and args in the input request
170 if ($app->isSite() && VIKBOOKING_SITE_PREPROCESS)
171 {
172 // get post ID from current URL
173 $id = url_to_postid(JUri::current());
174
175 if ($id)
176 {
177 // get shortcode admin model
178 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
179 // get shortcode searching by post ID (false to avoid returning a new item)
180 $shortcode = $model->getItem(array('post_id' => $id), false);
181
182 if ($shortcode)
183 {
184 // build args array using the shortcode attributes
185 $args = (array) json_decode($shortcode->json, true);
186 $args['view'] = $shortcode->type;
187 $args['option'] = 'com_vikbooking';
188
189 // inject the shortcode args into the input request
190 foreach ($args as $k => $v)
191 {
192 // inject only if not defined
193 $input->def($k, $v);
194 }
195 }
196 }
197 }
198
199 // process VikBooking only if it has been requested via GET or POST
200 if ($input->get('option') == 'com_vikbooking' || $input->get('page') == 'vikbooking')
201 {
202 VikBookingBody::process();
203 }
204 });
205
206 // handle AJAX requests
207 add_action('wp_ajax_vikbooking', 'handle_vikbooking_ajax');
208 add_action('wp_ajax_nopriv_vikbooking', 'handle_vikbooking_ajax');
209
210 function handle_vikbooking_ajax()
211 {
212 VikBookingBody::getHtml();
213
214 // die to get a valid response
215 wp_die();
216 }
217
218 // setup admin menu
219 add_action('admin_menu', array('VikBookingBuilder', 'setupAdminMenu'));
220
221 // register widgets
222 add_action('widgets_init', array('VikBookingBuilder', 'setupWidgets'));
223
224 // handle shortcodes (SITE controller dispatcher)
225 add_shortcode('vikbooking', function($atts, $content = null)
226 {
227 $app = JFactory::getApplication();
228
229 /**
230 * Force the application client to "site" every time a shortcode is executed.
231 *
232 * @since 1.5.5
233 */
234 $app->setClient('site');
235
236 // wrap attributes in a registry
237 $args = new JObject($atts);
238
239 // get the VIEW (empty if not set)
240 $view = $args->get('view', '');
241
242 // load the FORM of the view
243 JLoader::import('adapter.form.form');
244 $path = implode(DIRECTORY_SEPARATOR, array(VBO_SITE_PATH, 'views', $view, 'tmpl', 'default.xml'));
245 // raises an exception if the VIEW is not set
246 $form = JForm::getInstance($view, $path);
247
248 // get all the XML form fields
249 $fields = $form->getFields();
250
251 // filter the fields to get a list of allowed names
252 $fields = array_map(function($f)
253 {
254 return (string) $f->attributes()->name;
255 }, $fields);
256
257 // inject query vars
258 $input = $app->input;
259 // since we are going to render the controller manually,
260 // we don't need to push the option into $_REQUEST pool.
261 // $input->set('option', 'com_vikbooking');
262
263 // Inject shortcode vars only if they are not set
264 // in the request. This is used to allow the navigation
265 // between the pages.
266 $input->def('view', $view);
267
268 foreach ($fields as $k)
269 {
270 $input->def($k, $args->get($k));
271 }
272
273 // dispatch the controller
274 return VikBookingBody::getHtml(true);
275 });
276
277 // the callback is fired before the VBO controller is dispatched
278 add_action('vikbooking_before_dispatch', function()
279 {
280 $app = JFactory::getApplication();
281 $user = Jfactory::getUser();
282
283 // initialize timezone handler
284 JDate::getDefaultTimezone();
285 date_default_timezone_set($app->get('offset', 'UTC'));
286
287 // check if the user is authorised to access the back-end (only if the client is 'admin')
288 if ($app->isAdmin() && !$user->authorise('core.manage', 'com_vikbooking'))
289 {
290 if ($user->guest)
291 {
292 // if the user is not logged, redirect to login page
293 $app->redirect('index.php');
294 exit;
295 }
296 else
297 {
298 // otherwise raise an exception
299 wp_die(
300 '<h1>' . JText::translate('FATAL_ERROR') . '</h1>' .
301 '<p>' . JText::translate('RESOURCE_AUTH_ERROR') . '</p>',
302 403
303 );
304 }
305 }
306
307 // main library
308 require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
309
310 if ($app->isAdmin())
311 {
312 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'vikbooking.php';
313 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'jv_helper.php';
314 }
315 else
316 {
317 // Invoke VCM before the rendering
318 VikBooking::detectUserAgent();
319 VikBooking::invokeChannelManager();
320 VikBooking::getTracker();
321 VikBooking::loadPreferredColorStyles();
322 }
323
324 });
325
326 // instead using the default server timezone, try to use the one
327 // specified within the WordPress configuration
328 add_filter('vik_date_default_timezone', function($timezone)
329 {
330 return JFactory::getApplication()->get('offset', $timezone);
331 });
332
333 // the callback is fired once the VBO controller has been dispatched
334 add_action('vikbooking_after_dispatch', function()
335 {
336 // load assets after dispatching the controller to avoid
337 // including JS and CSS when an AJAX function exits or dies
338 VikBookingAssets::load();
339
340 /**
341 * Load javascript core.
342 *
343 * @since 1.1.8
344 */
345 JHtml::fetch('behavior.core');
346
347 // restore standard timezone
348 date_default_timezone_set(JDate::getDefaultTimezone());
349
350 /**
351 * @note when the headers have been sent or when
352 * the request is AJAX, the assets (CSS and JS) are
353 * appended to the document after the
354 * response dispatched by the controller.
355 */
356 });
357
358 // End-point for front-end post actions.
359 // The end-point URL must be built as .../wp-admin/admin-post.php
360 // and requires $_POST['action'] == 'vikbooking' to be submitted through a form or GET.
361 add_action('admin_post_vikbooking', 'handle_vikbooking_endpoint'); // if the user is logged in
362 add_action('admin_post_nopriv_vikbooking', 'handle_vikbooking_endpoint'); // if the user in not logged in
363
364 // handle POST end-point
365 function handle_vikbooking_endpoint()
366 {
367 // get PLAIN response
368 echo VikBookingBody::getResponse();
369 }
370
371 // Hook used to access the PAGE details when a user is
372 // creating or updating it. This is helpful to make a relation
373 // between the page and the injected shortcode.
374 add_action('save_post', function($post_id)
375 {
376 // get model to access all the existing shortcodes
377 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
378 $shortcodes = $model->all(array('id', 'shortcode', 'post_id'));
379
380 // get post data
381 $post = get_post($post_id);
382
383 /**
384 * Check if we are editing a child post as Gutenberg
385 * seems to use always the inherit status, which
386 * refers to a post parent.
387 *
388 * @since 1.0.17
389 */
390 if ($post->post_status != 'publish' && !empty($post->post_parent) && $post->post_parent != $post_id)
391 {
392 // fallback to obtain parent post data
393 $post = get_post($post->post_parent);
394
395 /**
396 * Use new post ID.
397 *
398 * @since 1.2.7 Fixed post ID property name.
399 */
400 $post_id = $post->ID;
401 }
402
403 if ($post->post_status != 'publish')
404 {
405 // ignore drafts auto-save
406 return;
407 }
408
409 // get shortcode model
410 $shortcodeModel = JModel::getInstance('vikbooking', 'shortcode', 'admin');
411
412 /**
413 * Since we need unique post IDs, all the shortcodes
414 * that are assigned to the specified $post_id should
415 * be detached.
416 *
417 * @since 1.0.17
418 */
419 foreach ($shortcodes as $data)
420 {
421 if ($data->post_id == $post_id)
422 {
423 // The post is already assigned to a shortcode.
424 // Unset it to avoid duplicated.
425 $data->post_id = 0;
426 $shortcodeModel->save($data);
427 }
428 }
429
430 // iterate the shortcodes
431 foreach ($shortcodes as $data)
432 {
433 // check if the content of the post contains the shortcode
434 if (strpos($post->post_content, html_entity_decode($data->shortcode)) !== false)
435 {
436 // inject the POST ID
437 $data->post_id = $post_id;
438
439 // update shortcode
440 $shortcodeModel->save($data);
441
442 // stop iterating
443 return;
444 }
445 }
446 });
447
448 // Hook used to unset temporarily the relationship
449 // between the trashed post and the shortcode.
450 add_action('trashed_post', function($post_id)
451 {
452 // get shortcode model
453 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
454
455 // get the shortcode attached to the trashed post ID
456 $item = $model->getItem(array('post_id' => $post_id), false);
457
458 // if the item exists, temporarily detach the relationship
459 if ($item)
460 {
461 $item->post_id = 0;
462 $item->tmp_post_id = $post_id;
463
464 $model->save($item);
465 }
466 });
467
468 // Hook used to restore permanently the relationship
469 // between the untrashed post and the shortcode.
470 add_action('untrashed_post', function($post_id)
471 {
472 // get shortcode model
473 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
474
475 // get the shortcode attached to the untrashed post ID
476 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
477
478 // if the item exists, re-attach the relationship
479 if ($item)
480 {
481 $item->post_id = $post_id;
482 $item->tmp_post_id = 0;
483
484 $model->save($item);
485 }
486 });
487
488 // Hook used to temporarily detach the relationship
489 // between the deleted post and the shortcode.
490 add_action('deleted_post', function($post_id)
491 {
492 // get shortcode model
493 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
494
495 // get the shortcode attached to the trashed post ID
496 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
497
498 // If no item found, the "trash" feature is probably disabled.
499 // Try to take a look for a shortcode with an active relationship.
500 if (!$item)
501 {
502 $item = $model->getItem(array('post_id' => $post_id), false);
503 }
504
505 // if the item exists, permanently detach the relationship
506 if ($item)
507 {
508 $item->post_id = 0;
509 $item->tmp_post_id = 0;
510
511 $model->save($item);
512 }
513 });
514
515 if (JFactory::getApplication()->isAdmin() && !wp_doing_ajax())
516 {
517 /**
518 * @todo should we restrict these filters to the post managements pages only?
519 */
520
521 VikBookingLoader::import('system.mce');
522 VikBookingLoader::import('system.gutenberg');
523
524 // add new buttons
525 add_filter('mce_buttons', array('VikBookingTinyMCE', 'addShortcodesButton'));
526
527 // load the button handlers
528 add_filter('mce_external_plugins', array('VikBookingTinyMCE', 'registerShortcodesScript'));
529
530 // add support for Gutenberg shortcode block
531 add_action('init', array('VikBookingGutenberg', 'registerShortcodesScript'));
532 }
533
534 /**
535 * Dispatch the uninstallation of VikBooking
536 * every time a new blog (multisite) is deleted.
537 *
538 * Fires after the site is deleted from the network (WP 4.8.0 or higher).
539 *
540 * @param integer $blog_id The site ID.
541 * @param boolean $drop True if site's tables should be dropped. Default is false.
542 *
543 * @since 1.0.6
544 */
545 add_action('deleted_blog', function($blog_id, $drop)
546 {
547 VikBookingInstaller::uninstall($drop);
548 }, 10, 2);
549
550 /**
551 * Once the plugins have been loaded, evaluates to execute the
552 * scheduled cron jobs.
553 *
554 * Scheduling is processed in case a cron job is hitting wp-cron file
555 * or in case a user is visiting the website.
556 *
557 * @since 1.5.10 Schedules a different hook for each cron.
558 * @since 1.6.5 Added priority to PHP_INT_MAX - 1 to allow Vik Channel Manager
559 * to have all the intervals scheduled by Vik Booking.
560 */
561 add_action('plugins_loaded', array('VikBookingCron', 'setup'), (PHP_INT_MAX - 1));
562
563 /**
564 * Filters the action links displayed for each plugin in the Plugins list table.
565 * Hook used to filter the "deactivation" link and ask a feedback every time that
566 * button is clicked.
567 *
568 * @param array $actions An array of plugin action links. By default this can include 'activate',
569 * 'deactivate', and 'delete'. With Multisite active this can also include
570 * 'network_active' and 'network_only' items.
571 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
572 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
573 * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
574 * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
575 *
576 * @since 1.2.13
577 */
578 add_filter('plugin_action_links', array('VikBookingFeedback', 'deactivate'), 10, 4);
579
580 /**
581 * Adjusts the timezone of the website before dispatching
582 * a widget as we are currently outside of the main plugin and
583 * the timezone have probably been restored to the default one.
584 *
585 * @param string $id The widget ID (path name).
586 * @param JObject &$params The widget configuration registry.
587 *
588 * @since 1.2.10
589 */
590 add_action('vik_widget_before_dispatch_site', function($id, &$params)
591 {
592 // initialize timezone handler
593 JDate::getDefaultTimezone();
594 date_default_timezone_set(JFactory::getApplication()->get('offset', 'UTC'));
595 }, 10, 2);
596
597 /**
598 * Restores the timezone of the website after dispatching
599 * a widget in order to avoid strange behaviors with other plugins.
600 *
601 * @param string $id The widget ID (path name).
602 * @param string &$html The HTML of the widget to display.
603 *
604 * @since 1.2.10
605 */
606 add_action('vik_widget_after_dispatch_site', function($id, &$html)
607 {
608 // restore standard timezone
609 date_default_timezone_set(JDate::getDefaultTimezone());
610 }, 10, 2);
611
612 /**
613 * Added support for Loco Translate.
614 * In case some translations have been edited by using this plugin,
615 * we should look within the Loco Translate folder to check whether
616 * the requested translation is available.
617 *
618 * @param boolean $loaded True if the translation has been already loaded.
619 * @param string $domain The plugin text domain to load.
620 *
621 * @return boolean True if a new translation is loaded.
622 *
623 * @since 1.6.0
624 */
625 add_filter('vik_plugin_load_language', function($loaded, $domain)
626 {
627 // proceed only in case the translation hasn't been loaded
628 // and Loco Translate plugin is installed
629 if (!$loaded && is_dir(WP_LANG_DIR . DIRECTORY_SEPARATOR . 'loco'))
630 {
631 // Build LOCO path.
632 // Since load_plugin_textdomain accepts only relative paths,
633 // we should go back to the /wp-contents/ folder first.
634 $loco = implode(DIRECTORY_SEPARATOR, array('..', 'languages', 'loco', 'plugins'));
635
636 // try to load the plugin translation from Loco folder
637 $loaded = load_plugin_textdomain($domain, false, $loco);
638 }
639
640 return $loaded;
641 }, 10, 2);
642
643 /**
644 * Display notice messages in third party plugins
645 * to suggest the import of the reservations.
646 *
647 * @since 1.3.5
648 */
649 add_action('admin_notices', function()
650 {
651 // main library
652 require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
653
654 // load supported plugins
655 $supported_plugins = VikBooking::canImportBookingsFromThirdPartyPlugins();
656
657 if (wp_doing_ajax() || $supported_plugins === false)
658 {
659 return;
660 }
661
662 $lookup = array(
663 'admin.php' => 'page',
664 'edit.php' => 'post_type',
665 );
666
667 global $pagenow;
668
669 if (!isset($lookup[$pagenow]))
670 {
671 // page not observed
672 return;
673 }
674
675 $input = JFactory::getApplication()->input;
676
677 if (!preg_match("/^mphb_/i", $input->get($lookup[$pagenow])))
678 {
679 return;
680 }
681
682 // get logo URI
683 $backlogo = VikBooking::getBackendLogo();
684 ?>
685 <style>
686 #mphb-vbo-import-notice {
687 display: inline-block;
688 width: 100%;
689 box-sizing: border-box;
690 border-left-color: #cc9907;
691 box-shadow: 0 5px 10px rgba(0,0,0,.05);
692 }
693 #mphb-vbo-import-notice a.vbo-import-button {
694 float: right;
695 border: none;
696 font-size: 14px;
697 margin: 18px 10px;
698 padding: 12px 29px;
699 color: #FFF;
700 text-shadow: none;
701 font-weight: bold;
702 background: #3AA03C;
703 -moz-border-radius: 3px;
704 border-radius: 3px;
705 -webkit-border-radius: 3px;
706 text-decoration: none;
707 height: 50px;
708 text-align: center;
709 text-transform: uppercase;
710 box-shadow: none;
711 line-height: 26px;
712 }
713 a.vbo-import-button:hover {
714 background: #43BD45 !important;
715 }
716 .vbo-import-logo {
717 display: inline-block;
718 margin-top: 21px;
719 max-width: 49px;
720 }
721 .vbo-import-text {
722 font-size: 18px;
723 display: inline-block;
724 vertical-align: top;
725 margin: 31px 10px 10px 10px;
726 }
727 </style>
728
729 <div class="notice is-dismissible notice-info" id="mphb-vbo-import-notice">
730 <div class="vbo-import-wrap">
731 <p>
732 <span class="vbo-import-logo">
733 <img src="<?php echo VBO_ADMIN_URI . (!empty($backlogo) ? "resources/{$backlogo}" : 'vikbooking.png'); ?>" alt="VikBooking Logo" />
734 </span>
735 <span class="vbo-import-text"><?php echo JText::sprintf('VBO_IMPBFROM_INTO_VBO', $supported_plugins['mphb']); ?></span>
736 <a class="button vbo-import-button" href="admin.php?option=com_vikbooking&view=importbftpp"><?php echo JText::translate('VBO_IMPBFTPP_DOIMPORT_SHORT'); ?></a>
737 </p>
738 </div>
739 </div>
740 <?php
741 });
742
743 /**
744 * Downloads the RSS feeds after loading the dashboard of VikBooking.
745 *
746 * @since 1.3.9
747 */
748 add_action('vikbooking_after_display_dashboard', array('VikBookingRssFeeds', 'download'));
749
750 /**
751 * Trigger event to allow the plugins to include custom HTML within the view.
752 * It is possible to return an associative array to group the HTML strings
753 * under different fieldsets. Plain/html string will be always pushed within
754 * the "custom" fieldset instead.
755 *
756 * Displays the RSS configuration.
757 *
758 * @param mixed $forms The HTML to display.
759 * @param mixed $view The current view instance.
760 *
761 * @return mixed The HTML to display.
762 *
763 * @since 1.3.9
764 */
765 add_filter('vikbooking_display_view_config_global', array('VikBookingRssFeeds', 'config'), 10, 2);
766
767 /**
768 * Save the RSS configuration every time "saveconfig" task is reached.
769 *
770 * @since 1.3.9
771 */
772 add_action('vikbooking_before_dispatch', function()
773 {
774 $input = JFactory::getApplication()->input;
775
776 if ($input->get('task') == 'saveconfig')
777 {
778 VikBookingRssFeeds::save();
779 }
780 });
781
782 /**
783 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
784 *
785 * @param array $channels A list of RSS permalinks.
786 * @param boolean $status True to return only the published channels.
787 *
788 * @return array A list of supported channels.
789 *
790 * @since 1.3.9
791 */
792 add_filter('vikbooking_fetch_rss_channels', array('VikBookingRssFeeds', 'getChannels'), 10, 2);
793
794 /**
795 * Hook used to apply some stuff before returning the RSS reader.
796 *
797 * @param JRssReader &$rss The RSS reader handler.
798 *
799 * @since 1.3.9
800 */
801 add_action('vikbooking_before_use_rss', array('VikBookingRssFeeds', 'ready'));
802
803 /**
804 * Hook used to support browser notifications on any /wp-admin
805 * page that doesn't belong to Vik Booking. Note that the hook
806 * should be 'admin_footer' and not 'admin_print_footer_scripts'.
807 *
808 * @since 1.5.0
809 */
810 add_action('admin_footer', function()
811 {
812 $app = JFactory::getApplication();
813 $input = $app->input;
814
815 // make sure we are not inside Vik Booking
816 if ($input->get('option') == 'com_vikbooking' || $input->get('page') == 'vikbooking' || $input->get('action') == 'vikbooking')
817 {
818 return;
819 }
820
821 /**
822 * Let third party plugins stop Vik Booking from loading assets on other wp-admin pages.
823 *
824 * @since 1.6.1
825 */
826 $allowed = apply_filters('vikbooking_load_external_assets', true);
827 if (!$allowed)
828 {
829 return;
830 }
831
832 // initialize timezone handler
833 JDate::getDefaultTimezone();
834 date_default_timezone_set($app->get('offset', 'UTC'));
835
836 // load the necessary assets for external pages
837 VikBookingAssets::loadForExternal();
838
839 // restore standard timezone
840 date_default_timezone_set(JDate::getDefaultTimezone());
841
842 /**
843 * Reload system configuration scripts to allow
844 * Vik Booking to preload texts also on VCM.
845 *
846 * @since 1.6.0
847 */
848 JHtml::fetch('behavior.core');
849 });
850
851 /**
852 * Fixed issue with wptexturize() function, which might convert special characters contained
853 * within <script> tags into their corresponding HTML entities (e.g. "&" became "&#038;").
854 *
855 * @since 1.6.3
856 */
857 add_filter('the_content', function($content)
858 {
859 // look for any script tags
860 if (preg_match_all("/<script(?:.*?)>(?:.*?)<\/script>/s", $content, $matches))
861 {
862 // scan all the scripts
863 foreach ($matches[0] as $script)
864 {
865 // make sure the script contains "&#038;"
866 if (strpos($script, '&#038;') === false)
867 {
868 continue;
869 }
870
871 // fix the script by reverting the plain "&"
872 $fixedScript = str_replace('&#038;', '&', $script);
873
874 // replace the bugged script from the content with the fixed one
875 $content = str_replace($script, $fixedScript, $content);
876 }
877 }
878
879 return $content;
880 }, PHP_INT_MAX);
881