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

933 lines 26.6 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.7.2
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 /**
274 * When saving a shortcode block through Gutenberg,
275 * WordPress tries to reach the page to check what happens.
276 * Some views of VikBooking may immediately redirect the users to
277 * another page URI.
278 * This redirect breaks the request made by WordPress for the
279 * validation of the page, which follows the new location.
280 * The code below prevents the execution of the controller
281 * in case the URI matches the REST API end-point.
282 *
283 * @since 1.7
284 */
285 $rest_prefix = trailingslashit(rest_get_url_prefix());
286 $is_rest_api = strpos($input->server->getString('REQUEST_URI', ''), $rest_prefix) !== false
287 || JUri::getInstance($input->server->getString('REQUEST_URI', ''))->hasVar('rest_route')
288 || strpos($input->server->getString('REQUEST_URI', ''), '/wp-admin/') !== false;
289
290 if ($is_rest_api && in_array($input->get('view'), ['tinyurl']))
291 {
292 // return an empty string to prevent any redirects
293 return '';
294 }
295
296 // dispatch the controller
297 return VikBookingBody::getHtml(true);
298 });
299
300 // the callback is fired before the VBO controller is dispatched
301 add_action('vikbooking_before_dispatch', function()
302 {
303 $app = JFactory::getApplication();
304 $user = Jfactory::getUser();
305
306 // initialize timezone handler
307 JDate::getDefaultTimezone();
308 date_default_timezone_set($app->get('offset', 'UTC'));
309
310 // check if the user is authorised to access the back-end (only if the client is 'admin')
311 if ($app->isAdmin() && !$user->authorise('core.manage', 'com_vikbooking'))
312 {
313 if ($user->guest)
314 {
315 // if the user is not logged, redirect to login page
316 $app->redirect('index.php');
317 exit;
318 }
319 else
320 {
321 // otherwise raise an exception
322 wp_die(
323 '<h1>' . JText::translate('FATAL_ERROR') . '</h1>' .
324 '<p>' . JText::translate('RESOURCE_AUTH_ERROR') . '</p>',
325 403
326 );
327 }
328 }
329
330 // main library
331 require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
332
333 if ($app->isAdmin())
334 {
335 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'vikbooking.php';
336 require_once VBO_ADMIN_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'jv_helper.php';
337 }
338 else
339 {
340 // Invoke VCM before the rendering
341 VikBooking::detectUserAgent();
342 VikBooking::invokeChannelManager();
343 VikBooking::getTracker();
344 VikBooking::loadPreferredColorStyles();
345 }
346
347 });
348
349 // instead using the default server timezone, try to use the one
350 // specified within the WordPress configuration
351 add_filter('vik_date_default_timezone', function($timezone)
352 {
353 return JFactory::getApplication()->get('offset', $timezone);
354 });
355
356 // the callback is fired once the VBO controller has been dispatched
357 add_action('vikbooking_after_dispatch', function()
358 {
359 // load assets after dispatching the controller to avoid
360 // including JS and CSS when an AJAX function exits or dies
361 VikBookingAssets::load();
362
363 /**
364 * Load javascript core.
365 *
366 * @since 1.1.8
367 */
368 JHtml::fetch('behavior.core');
369
370 // restore standard timezone
371 date_default_timezone_set(JDate::getDefaultTimezone());
372
373 /**
374 * @note when the headers have been sent or when
375 * the request is AJAX, the assets (CSS and JS) are
376 * appended to the document after the
377 * response dispatched by the controller.
378 */
379 });
380
381 // End-point for front-end post actions.
382 // The end-point URL must be built as .../wp-admin/admin-post.php
383 // and requires $_POST['action'] == 'vikbooking' to be submitted through a form or GET.
384 add_action('admin_post_vikbooking', 'handle_vikbooking_endpoint'); // if the user is logged in
385 add_action('admin_post_nopriv_vikbooking', 'handle_vikbooking_endpoint'); // if the user in not logged in
386
387 // handle POST end-point
388 function handle_vikbooking_endpoint()
389 {
390 // get PLAIN response
391 echo VikBookingBody::getResponse();
392 }
393
394 // Hook used to access the PAGE details when a user is
395 // creating or updating it. This is helpful to make a relation
396 // between the page and the injected shortcode.
397 add_action('save_post', function($post_id)
398 {
399 // get model to access all the existing shortcodes
400 $model = JModel::getInstance('vikbooking', 'shortcodes', 'admin');
401 $shortcodes = $model->all(array('id', 'shortcode', 'post_id'));
402
403 // get post data
404 $post = get_post($post_id);
405
406 /**
407 * Check if we are editing a child post as Gutenberg
408 * seems to use always the inherit status, which
409 * refers to a post parent.
410 *
411 * @since 1.0.17
412 */
413 if ($post->post_status != 'publish' && !empty($post->post_parent) && $post->post_parent != $post_id)
414 {
415 // fallback to obtain parent post data
416 $post = get_post($post->post_parent);
417
418 /**
419 * Use new post ID.
420 *
421 * @since 1.2.7 Fixed post ID property name.
422 */
423 $post_id = $post->ID;
424 }
425
426 if ($post->post_status != 'publish')
427 {
428 // ignore drafts auto-save
429 return;
430 }
431
432 // get shortcode model
433 $shortcodeModel = JModel::getInstance('vikbooking', 'shortcode', 'admin');
434
435 /**
436 * Since we need unique post IDs, all the shortcodes
437 * that are assigned to the specified $post_id should
438 * be detached.
439 *
440 * @since 1.0.17
441 */
442 foreach ($shortcodes as $data)
443 {
444 if ($data->post_id == $post_id)
445 {
446 // The post is already assigned to a shortcode.
447 // Unset it to avoid duplicated.
448 $data->post_id = 0;
449 $shortcodeModel->save($data);
450 }
451 }
452
453 // iterate the shortcodes
454 foreach ($shortcodes as $data)
455 {
456 // check if the content of the post contains the shortcode
457 if (strpos($post->post_content, html_entity_decode($data->shortcode)) !== false)
458 {
459 // inject the POST ID
460 $data->post_id = $post_id;
461
462 // update shortcode
463 $shortcodeModel->save($data);
464
465 // stop iterating
466 return;
467 }
468 }
469 });
470
471 // Hook used to unset temporarily the relationship
472 // between the trashed post and the shortcode.
473 add_action('trashed_post', function($post_id)
474 {
475 // get shortcode model
476 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
477
478 // get the shortcode attached to the trashed post ID
479 $item = $model->getItem(array('post_id' => $post_id), false);
480
481 // if the item exists, temporarily detach the relationship
482 if ($item)
483 {
484 $item->post_id = 0;
485 $item->tmp_post_id = $post_id;
486
487 $model->save($item);
488 }
489 });
490
491 // Hook used to restore permanently the relationship
492 // between the untrashed post and the shortcode.
493 add_action('untrashed_post', function($post_id)
494 {
495 // get shortcode model
496 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
497
498 // get the shortcode attached to the untrashed post ID
499 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
500
501 // if the item exists, re-attach the relationship
502 if ($item)
503 {
504 $item->post_id = $post_id;
505 $item->tmp_post_id = 0;
506
507 $model->save($item);
508 }
509 });
510
511 // Hook used to temporarily detach the relationship
512 // between the deleted post and the shortcode.
513 add_action('deleted_post', function($post_id)
514 {
515 // get shortcode model
516 $model = JModel::getInstance('vikbooking', 'shortcode', 'admin');
517
518 // get the shortcode attached to the trashed post ID
519 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
520
521 // If no item found, the "trash" feature is probably disabled.
522 // Try to take a look for a shortcode with an active relationship.
523 if (!$item)
524 {
525 $item = $model->getItem(array('post_id' => $post_id), false);
526 }
527
528 // if the item exists, permanently detach the relationship
529 if ($item)
530 {
531 $item->post_id = 0;
532 $item->tmp_post_id = 0;
533
534 $model->save($item);
535 }
536 });
537
538 if (JFactory::getApplication()->isAdmin() && !wp_doing_ajax())
539 {
540 /**
541 * @todo should we restrict these filters to the post managements pages only?
542 */
543
544 VikBookingLoader::import('system.mce');
545
546 // add new buttons
547 add_filter('mce_buttons', array('VikBookingTinyMCE', 'addShortcodesButton'));
548
549 // load the button handlers
550 add_filter('mce_external_plugins', array('VikBookingTinyMCE', 'registerShortcodesScript'));
551 }
552
553 /**
554 * Always load the Gutenberg shortcodes block to support the preview rendering.
555 *
556 * @since 1.6.7
557 */
558 VikBookingLoader::import('system.gutenberg');
559 add_action('init', ['VikBookingGutenberg', 'registerShortcodesScript']);
560
561 /**
562 * Dispatch the uninstallation of VikBooking
563 * every time a new blog (multisite) is deleted.
564 *
565 * Fires after the site is deleted from the network (WP 4.8.0 or higher).
566 *
567 * @param integer $blog_id The site ID.
568 * @param boolean $drop True if site's tables should be dropped. Default is false.
569 *
570 * @since 1.0.6
571 */
572 add_action('deleted_blog', function($blog_id, $drop)
573 {
574 VikBookingInstaller::uninstall($drop);
575 }, 10, 2);
576
577 /**
578 * Once the plugins have been loaded, evaluates to execute the
579 * scheduled cron jobs.
580 *
581 * Scheduling is processed in case a cron job is hitting wp-cron file
582 * or in case a user is visiting the website.
583 *
584 * @since 1.5.10 Schedules a different hook for each cron.
585 * @since 1.6.5 Added priority to PHP_INT_MAX - 1 to allow Vik Channel Manager
586 * to have all the intervals scheduled by Vik Booking.
587 */
588 add_action('plugins_loaded', array('VikBookingCron', 'setup'), (PHP_INT_MAX - 1));
589
590 /**
591 * Action used to register a periodic check of the automatic payments scheduled.
592 * This hook will be called by a scheduled event in WP-Cron.
593 *
594 * @since 1.6.10
595 */
596 add_action('vikbooking_cron_payments_scheduled', function()
597 {
598 // watch the automatic payments scheduled, if any
599 VBOModelPayschedules::getInstance()->watch();
600 });
601
602 /**
603 * Action used to register a periodic performance cleaning check.
604 * This hook will be called by a scheduled event in WP-Cron.
605 *
606 * @since 1.7.2
607 */
608 add_action('vikbooking_cron_performance_cleaner', ['VBOPerformanceCleaner', 'runCheck']);
609
610 /**
611 * Install the scheduling of the hook within WP-Cron needed
612 * to watch and process the automatic payments scheduled.
613 *
614 * @since 1.6.10
615 * @since 1.7.2 registered "vikbooking_cron_performance_cleaner".
616 */
617 add_action('plugins_loaded', function()
618 {
619 // make sure the cron event hasn't been yet scheduled.
620 if (!wp_next_scheduled('vikbooking_cron_payments_scheduled'))
621 {
622 // schedule event starting from the current time for "every half hour"
623 // such interval will be installed by VikBookingCron::setup()
624 wp_schedule_event(time(), 'half_hour', 'vikbooking_cron_payments_scheduled');
625 }
626
627 // make sure the cron event hasn't been yet scheduled.
628 if (!wp_next_scheduled('vikbooking_cron_performance_cleaner'))
629 {
630 // schedule event starting from the current time for "every week"
631 wp_schedule_event(time(), 'weekly', 'vikbooking_cron_performance_cleaner');
632 }
633 }, (PHP_INT_MAX - 1));
634
635 /**
636 * Filters the action links displayed for each plugin in the Plugins list table.
637 * Hook used to filter the "deactivation" link and ask a feedback every time that
638 * button is clicked.
639 *
640 * @param array $actions An array of plugin action links. By default this can include 'activate',
641 * 'deactivate', and 'delete'. With Multisite active this can also include
642 * 'network_active' and 'network_only' items.
643 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
644 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
645 * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
646 * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
647 *
648 * @since 1.2.13
649 */
650 add_filter('plugin_action_links', array('VikBookingFeedback', 'deactivate'), 10, 4);
651
652 /**
653 * Adjusts the timezone of the website before dispatching
654 * a widget as we are currently outside of the main plugin and
655 * the timezone have probably been restored to the default one.
656 *
657 * @param string $id The widget ID (path name).
658 * @param JObject &$params The widget configuration registry.
659 *
660 * @since 1.2.10
661 */
662 add_action('vik_widget_before_dispatch_site', function($id, &$params)
663 {
664 // initialize timezone handler
665 JDate::getDefaultTimezone();
666 date_default_timezone_set(JFactory::getApplication()->get('offset', 'UTC'));
667 }, 10, 2);
668
669 /**
670 * Restores the timezone of the website after dispatching
671 * a widget in order to avoid strange behaviors with other plugins.
672 *
673 * @param string $id The widget ID (path name).
674 * @param string &$html The HTML of the widget to display.
675 *
676 * @since 1.2.10
677 */
678 add_action('vik_widget_after_dispatch_site', function($id, &$html)
679 {
680 // restore standard timezone
681 date_default_timezone_set(JDate::getDefaultTimezone());
682 }, 10, 2);
683
684 /**
685 * Added support for Loco Translate.
686 * In case some translations have been edited by using this plugin,
687 * we should look within the Loco Translate folder to check whether
688 * the requested translation is available.
689 *
690 * @param boolean $loaded True if the translation has been already loaded.
691 * @param string $domain The plugin text domain to load.
692 *
693 * @return boolean True if a new translation is loaded.
694 *
695 * @since 1.6.0
696 */
697 add_filter('vik_plugin_load_language', function($loaded, $domain)
698 {
699 // proceed only in case the translation hasn't been loaded
700 // and Loco Translate plugin is installed
701 if (!$loaded && is_dir(WP_LANG_DIR . DIRECTORY_SEPARATOR . 'loco'))
702 {
703 // Build LOCO path.
704 // Since load_plugin_textdomain accepts only relative paths,
705 // we should go back to the /wp-contents/ folder first.
706 $loco = implode(DIRECTORY_SEPARATOR, array('..', 'languages', 'loco', 'plugins'));
707
708 // try to load the plugin translation from Loco folder
709 $loaded = load_plugin_textdomain($domain, false, $loco);
710 }
711
712 return $loaded;
713 }, 10, 2);
714
715 /**
716 * Display notice messages in third party plugins
717 * to suggest the import of the reservations.
718 *
719 * @since 1.3.5
720 */
721 add_action('admin_notices', function()
722 {
723 // main library
724 require_once VBO_SITE_PATH . DIRECTORY_SEPARATOR . 'helpers' . DIRECTORY_SEPARATOR . 'lib.vikbooking.php';
725
726 // load supported plugins
727 $supported_plugins = VikBooking::canImportBookingsFromThirdPartyPlugins();
728
729 if (wp_doing_ajax() || $supported_plugins === false)
730 {
731 return;
732 }
733
734 $lookup = array(
735 'admin.php' => 'page',
736 'edit.php' => 'post_type',
737 );
738
739 global $pagenow;
740
741 if (!isset($lookup[$pagenow]))
742 {
743 // page not observed
744 return;
745 }
746
747 $input = JFactory::getApplication()->input;
748
749 if (!preg_match("/^mphb_/i", $input->get($lookup[$pagenow])))
750 {
751 return;
752 }
753
754 // get logo URI
755 $backlogo = VikBooking::getBackendLogo();
756 ?>
757 <style>
758 #mphb-vbo-import-notice {
759 display: inline-block;
760 width: 100%;
761 box-sizing: border-box;
762 border-left-color: #cc9907;
763 box-shadow: 0 5px 10px rgba(0,0,0,.05);
764 }
765 #mphb-vbo-import-notice a.vbo-import-button {
766 float: right;
767 border: none;
768 font-size: 14px;
769 margin: 18px 10px;
770 padding: 12px 29px;
771 color: #FFF;
772 text-shadow: none;
773 font-weight: bold;
774 background: #3AA03C;
775 -moz-border-radius: 3px;
776 border-radius: 3px;
777 -webkit-border-radius: 3px;
778 text-decoration: none;
779 height: 50px;
780 text-align: center;
781 text-transform: uppercase;
782 box-shadow: none;
783 line-height: 26px;
784 }
785 a.vbo-import-button:hover {
786 background: #43BD45 !important;
787 }
788 .vbo-import-logo {
789 display: inline-block;
790 margin-top: 21px;
791 max-width: 49px;
792 }
793 .vbo-import-text {
794 font-size: 18px;
795 display: inline-block;
796 vertical-align: top;
797 margin: 31px 10px 10px 10px;
798 }
799 </style>
800
801 <div class="notice is-dismissible notice-info" id="mphb-vbo-import-notice">
802 <div class="vbo-import-wrap">
803 <p>
804 <span class="vbo-import-logo">
805 <img src="<?php echo VBO_ADMIN_URI . (!empty($backlogo) ? "resources/{$backlogo}" : 'vikbooking.png'); ?>" alt="VikBooking Logo" />
806 </span>
807 <span class="vbo-import-text"><?php echo JText::sprintf('VBO_IMPBFROM_INTO_VBO', $supported_plugins['mphb']); ?></span>
808 <a class="button vbo-import-button" href="admin.php?option=com_vikbooking&view=importbftpp"><?php echo JText::translate('VBO_IMPBFTPP_DOIMPORT_SHORT'); ?></a>
809 </p>
810 </div>
811 </div>
812 <?php
813 });
814
815 /**
816 * Downloads the RSS feeds after loading the dashboard of VikBooking.
817 *
818 * @since 1.3.9
819 */
820 add_action('vikbooking_after_display_dashboard', array('VikBookingRssFeeds', 'download'));
821
822 /**
823 * Trigger event to allow the plugins to include custom HTML within the view.
824 * It is possible to return an associative array to group the HTML strings
825 * under different fieldsets. Plain/html string will be always pushed within
826 * the "custom" fieldset instead.
827 *
828 * Displays the RSS configuration.
829 *
830 * @param mixed $forms The HTML to display.
831 * @param mixed $view The current view instance.
832 *
833 * @return mixed The HTML to display.
834 *
835 * @since 1.3.9
836 */
837 add_filter('vikbooking_display_view_config_global', array('VikBookingRssFeeds', 'config'), 10, 2);
838
839 /**
840 * Save the RSS configuration every time "saveconfig" task is reached.
841 *
842 * @since 1.3.9
843 */
844 add_action('vikbooking_before_dispatch', function()
845 {
846 $input = JFactory::getApplication()->input;
847
848 if ($input->get('task') == 'saveconfig')
849 {
850 VikBookingRssFeeds::save();
851 }
852 });
853
854 /**
855 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
856 *
857 * @param array $channels A list of RSS permalinks.
858 * @param boolean $status True to return only the published channels.
859 *
860 * @return array A list of supported channels.
861 *
862 * @since 1.3.9
863 */
864 add_filter('vikbooking_fetch_rss_channels', array('VikBookingRssFeeds', 'getChannels'), 10, 2);
865
866 /**
867 * Hook used to apply some stuff before returning the RSS reader.
868 *
869 * @param JRssReader &$rss The RSS reader handler.
870 *
871 * @since 1.3.9
872 */
873 add_action('vikbooking_before_use_rss', array('VikBookingRssFeeds', 'ready'));
874
875 /**
876 * Hook used to support browser notifications on any /wp-admin
877 * page that doesn't belong to Vik Booking. Note that the hook
878 * should be 'admin_footer' and not 'admin_print_footer_scripts'.
879 *
880 * @since 1.5.0
881 */
882 add_action('admin_footer', function()
883 {
884 $app = JFactory::getApplication();
885 $input = $app->input;
886
887 // make sure we are not inside Vik Booking
888 if ($input->get('option') == 'com_vikbooking' || $input->get('page') == 'vikbooking' || $input->get('action') == 'vikbooking')
889 {
890 return;
891 }
892
893 /**
894 * Let third party plugins stop Vik Booking from loading assets on other wp-admin pages.
895 *
896 * @since 1.6.1
897 */
898 $allowed = apply_filters('vikbooking_load_external_assets', true);
899 if (!$allowed)
900 {
901 return;
902 }
903
904 // initialize timezone handler
905 JDate::getDefaultTimezone();
906 date_default_timezone_set($app->get('offset', 'UTC'));
907
908 // load the necessary assets for external pages
909 VikBookingAssets::loadForExternal();
910
911 // restore standard timezone
912 date_default_timezone_set(JDate::getDefaultTimezone());
913
914 /**
915 * Reload system configuration scripts to allow
916 * Vik Booking to preload texts also on VCM.
917 *
918 * @since 1.6.0
919 */
920 JHtml::fetch('behavior.core');
921 });
922
923 /**
924 * Prevent WordPress Themes from running wptexturize() that may erroneously
925 * detect HTML tags among raw JavaScript code, by encoding ampersand symbols.
926 *
927 * @since 1.6.9
928 */
929 add_filter('run_wptexturize', function($run_texturize)
930 {
931 return is_admin() ? $run_texturize : false;
932 }, PHP_INT_MAX);
933