PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.7
VikBooking Hotel Booking Engine & PMS v1.6.7
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 1.7.3 1.7.4 All 35 releases
vikbooking / vikbooking.php

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

885 lines 24.8 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.7
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
523 // add new buttons
524 add_filter('mce_buttons', array('VikBookingTinyMCE', 'addShortcodesButton'));
525
526 // load the button handlers
527 add_filter('mce_external_plugins', array('VikBookingTinyMCE', 'registerShortcodesScript'));
528 }
529
530 /**
531 * Always load the Gutenberg shortcodes block to support the preview rendering.
532 *
533 * @since 1.6.7
534 */
535 VikBookingLoader::import('system.gutenberg');
536 add_action('init', ['VikBookingGutenberg', 'registerShortcodesScript']);
537
538 /**
539 * Dispatch the uninstallation of VikBooking
540 * every time a new blog (multisite) is deleted.
541 *
542 * Fires after the site is deleted from the network (WP 4.8.0 or higher).
543 *
544 * @param integer $blog_id The site ID.
545 * @param boolean $drop True if site's tables should be dropped. Default is false.
546 *
547 * @since 1.0.6
548 */
549 add_action('deleted_blog', function($blog_id, $drop)
550 {
551 VikBookingInstaller::uninstall($drop);
552 }, 10, 2);
553
554 /**
555 * Once the plugins have been loaded, evaluates to execute the
556 * scheduled cron jobs.
557 *
558 * Scheduling is processed in case a cron job is hitting wp-cron file
559 * or in case a user is visiting the website.
560 *
561 * @since 1.5.10 Schedules a different hook for each cron.
562 * @since 1.6.5 Added priority to PHP_INT_MAX - 1 to allow Vik Channel Manager
563 * to have all the intervals scheduled by Vik Booking.
564 */
565 add_action('plugins_loaded', array('VikBookingCron', 'setup'), (PHP_INT_MAX - 1));
566
567 /**
568 * Filters the action links displayed for each plugin in the Plugins list table.
569 * Hook used to filter the "deactivation" link and ask a feedback every time that
570 * button is clicked.
571 *
572 * @param array $actions An array of plugin action links. By default this can include 'activate',
573 * 'deactivate', and 'delete'. With Multisite active this can also include
574 * 'network_active' and 'network_only' items.
575 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
576 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
577 * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
578 * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
579 *
580 * @since 1.2.13
581 */
582 add_filter('plugin_action_links', array('VikBookingFeedback', 'deactivate'), 10, 4);
583
584 /**
585 * Adjusts the timezone of the website before dispatching
586 * a widget as we are currently outside of the main plugin and
587 * the timezone have probably been restored to the default one.
588 *
589 * @param string $id The widget ID (path name).
590 * @param JObject &$params The widget configuration registry.
591 *
592 * @since 1.2.10
593 */
594 add_action('vik_widget_before_dispatch_site', function($id, &$params)
595 {
596 // initialize timezone handler
597 JDate::getDefaultTimezone();
598 date_default_timezone_set(JFactory::getApplication()->get('offset', 'UTC'));
599 }, 10, 2);
600
601 /**
602 * Restores the timezone of the website after dispatching
603 * a widget in order to avoid strange behaviors with other plugins.
604 *
605 * @param string $id The widget ID (path name).
606 * @param string &$html The HTML of the widget to display.
607 *
608 * @since 1.2.10
609 */
610 add_action('vik_widget_after_dispatch_site', function($id, &$html)
611 {
612 // restore standard timezone
613 date_default_timezone_set(JDate::getDefaultTimezone());
614 }, 10, 2);
615
616 /**
617 * Added support for Loco Translate.
618 * In case some translations have been edited by using this plugin,
619 * we should look within the Loco Translate folder to check whether
620 * the requested translation is available.
621 *
622 * @param boolean $loaded True if the translation has been already loaded.
623 * @param string $domain The plugin text domain to load.
624 *
625 * @return boolean True if a new translation is loaded.
626 *
627 * @since 1.6.0
628 */
629 add_filter('vik_plugin_load_language', function($loaded, $domain)
630 {
631 // proceed only in case the translation hasn't been loaded
632 // and Loco Translate plugin is installed
633 if (!$loaded && is_dir(WP_LANG_DIR . DIRECTORY_SEPARATOR . 'loco'))
634 {
635 // Build LOCO path.
636 // Since load_plugin_textdomain accepts only relative paths,
637 // we should go back to the /wp-contents/ folder first.
638 $loco = implode(DIRECTORY_SEPARATOR, array('..', 'languages', 'loco', 'plugins'));
639
640 // try to load the plugin translation from Loco folder
641 $loaded = load_plugin_textdomain($domain, false, $loco);
642 }
643
644 return $loaded;
645 }, 10, 2);
646
647 /**
648 * Display notice messages in third party plugins
649 * to suggest the import of the reservations.
650 *
651 * @since 1.3.5
652 */
653 add_action('admin_notices', function()
654 {
655 // main library
656 require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
657
658 // load supported plugins
659 $supported_plugins = VikBooking::canImportBookingsFromThirdPartyPlugins();
660
661 if (wp_doing_ajax() || $supported_plugins === false)
662 {
663 return;
664 }
665
666 $lookup = array(
667 'admin.php' => 'page',
668 'edit.php' => 'post_type',
669 );
670
671 global $pagenow;
672
673 if (!isset($lookup[$pagenow]))
674 {
675 // page not observed
676 return;
677 }
678
679 $input = JFactory::getApplication()->input;
680
681 if (!preg_match("/^mphb_/i", $input->get($lookup[$pagenow])))
682 {
683 return;
684 }
685
686 // get logo URI
687 $backlogo = VikBooking::getBackendLogo();
688 ?>
689 <style>
690 #mphb-vbo-import-notice {
691 display: inline-block;
692 width: 100%;
693 box-sizing: border-box;
694 border-left-color: #cc9907;
695 box-shadow: 0 5px 10px rgba(0,0,0,.05);
696 }
697 #mphb-vbo-import-notice a.vbo-import-button {
698 float: right;
699 border: none;
700 font-size: 14px;
701 margin: 18px 10px;
702 padding: 12px 29px;
703 color: #FFF;
704 text-shadow: none;
705 font-weight: bold;
706 background: #3AA03C;
707 -moz-border-radius: 3px;
708 border-radius: 3px;
709 -webkit-border-radius: 3px;
710 text-decoration: none;
711 height: 50px;
712 text-align: center;
713 text-transform: uppercase;
714 box-shadow: none;
715 line-height: 26px;
716 }
717 a.vbo-import-button:hover {
718 background: #43BD45 !important;
719 }
720 .vbo-import-logo {
721 display: inline-block;
722 margin-top: 21px;
723 max-width: 49px;
724 }
725 .vbo-import-text {
726 font-size: 18px;
727 display: inline-block;
728 vertical-align: top;
729 margin: 31px 10px 10px 10px;
730 }
731 </style>
732
733 <div class="notice is-dismissible notice-info" id="mphb-vbo-import-notice">
734 <div class="vbo-import-wrap">
735 <p>
736 <span class="vbo-import-logo">
737 <img src="<?php echo VBO_ADMIN_URI . (!empty($backlogo) ? "resources/{$backlogo}" : 'vikbooking.png'); ?>" alt="VikBooking Logo" />
738 </span>
739 <span class="vbo-import-text"><?php echo JText::sprintf('VBO_IMPBFROM_INTO_VBO', $supported_plugins['mphb']); ?></span>
740 <a class="button vbo-import-button" href="admin.php?option=com_vikbooking&view=importbftpp"><?php echo JText::translate('VBO_IMPBFTPP_DOIMPORT_SHORT'); ?></a>
741 </p>
742 </div>
743 </div>
744 <?php
745 });
746
747 /**
748 * Downloads the RSS feeds after loading the dashboard of VikBooking.
749 *
750 * @since 1.3.9
751 */
752 add_action('vikbooking_after_display_dashboard', array('VikBookingRssFeeds', 'download'));
753
754 /**
755 * Trigger event to allow the plugins to include custom HTML within the view.
756 * It is possible to return an associative array to group the HTML strings
757 * under different fieldsets. Plain/html string will be always pushed within
758 * the "custom" fieldset instead.
759 *
760 * Displays the RSS configuration.
761 *
762 * @param mixed $forms The HTML to display.
763 * @param mixed $view The current view instance.
764 *
765 * @return mixed The HTML to display.
766 *
767 * @since 1.3.9
768 */
769 add_filter('vikbooking_display_view_config_global', array('VikBookingRssFeeds', 'config'), 10, 2);
770
771 /**
772 * Save the RSS configuration every time "saveconfig" task is reached.
773 *
774 * @since 1.3.9
775 */
776 add_action('vikbooking_before_dispatch', function()
777 {
778 $input = JFactory::getApplication()->input;
779
780 if ($input->get('task') == 'saveconfig')
781 {
782 VikBookingRssFeeds::save();
783 }
784 });
785
786 /**
787 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
788 *
789 * @param array $channels A list of RSS permalinks.
790 * @param boolean $status True to return only the published channels.
791 *
792 * @return array A list of supported channels.
793 *
794 * @since 1.3.9
795 */
796 add_filter('vikbooking_fetch_rss_channels', array('VikBookingRssFeeds', 'getChannels'), 10, 2);
797
798 /**
799 * Hook used to apply some stuff before returning the RSS reader.
800 *
801 * @param JRssReader &$rss The RSS reader handler.
802 *
803 * @since 1.3.9
804 */
805 add_action('vikbooking_before_use_rss', array('VikBookingRssFeeds', 'ready'));
806
807 /**
808 * Hook used to support browser notifications on any /wp-admin
809 * page that doesn't belong to Vik Booking. Note that the hook
810 * should be 'admin_footer' and not 'admin_print_footer_scripts'.
811 *
812 * @since 1.5.0
813 */
814 add_action('admin_footer', function()
815 {
816 $app = JFactory::getApplication();
817 $input = $app->input;
818
819 // make sure we are not inside Vik Booking
820 if ($input->get('option') == 'com_vikbooking' || $input->get('page') == 'vikbooking' || $input->get('action') == 'vikbooking')
821 {
822 return;
823 }
824
825 /**
826 * Let third party plugins stop Vik Booking from loading assets on other wp-admin pages.
827 *
828 * @since 1.6.1
829 */
830 $allowed = apply_filters('vikbooking_load_external_assets', true);
831 if (!$allowed)
832 {
833 return;
834 }
835
836 // initialize timezone handler
837 JDate::getDefaultTimezone();
838 date_default_timezone_set($app->get('offset', 'UTC'));
839
840 // load the necessary assets for external pages
841 VikBookingAssets::loadForExternal();
842
843 // restore standard timezone
844 date_default_timezone_set(JDate::getDefaultTimezone());
845
846 /**
847 * Reload system configuration scripts to allow
848 * Vik Booking to preload texts also on VCM.
849 *
850 * @since 1.6.0
851 */
852 JHtml::fetch('behavior.core');
853 });
854
855 /**
856 * Fixed issue with wptexturize() function, which might convert special characters contained
857 * within <script> tags into their corresponding HTML entities (e.g. "&" became "&#038;").
858 *
859 * @since 1.6.3
860 */
861 add_filter('the_content', function($content)
862 {
863 // look for any script tags
864 if (preg_match_all("/<script(?:.*?)>(?:.*?)<\/script>/s", $content, $matches))
865 {
866 // scan all the scripts
867 foreach ($matches[0] as $script)
868 {
869 // make sure the script contains "&#038;"
870 if (strpos($script, '&#038;') === false)
871 {
872 continue;
873 }
874
875 // fix the script by reverting the plain "&"
876 $fixedScript = str_replace('&#038;', '&', $script);
877
878 // replace the bugged script from the content with the fixed one
879 $content = str_replace($script, $fixedScript, $content);
880 }
881 }
882
883 return $content;
884 }, PHP_INT_MAX);
885