PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.6.4
VikBooking Hotel Booking Engine & PMS v1.6.4
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.4, at vikbooking.php

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