PluginProbe
VikRestaurants Table Reservations and Take-Away / 1.4
VikRestaurants Table Reservations and Take-Away v1.4
trunk 1.4 1.5 1.5.1 1.5.2 1.5.3 1.5.4
vikrestaurants / vikrestaurants.php

vikrestaurants.php in VikRestaurants Table Reservations and Take-Away 1.4, at vikrestaurants.php

926 lines 28.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: VikRestaurants
4 Plugin URI: https://vikwp.com/plugin/vikrestaurants
5 Description: A professional tool for managing your restaurant reservations and take-away orders.
6 Version: 1.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: vikrestaurants
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('VikRestaurantsInstaller', 'activate'));
23 register_deactivation_hook(__FILE__, array('VikRestaurantsInstaller', 'deactivate'));
24 register_uninstall_hook(__FILE__, array('VikRestaurantsInstaller', 'delete'));
25
26 // init Installer
27 add_action('init', array('VikRestaurantsInstaller', 'update'));
28 add_action('init', array('VikRestaurantsInstaller', 'onInit'));
29
30 /**
31 * Fires after all automatic updates have run.
32 * Completes the update scheduled in background.
33 *
34 * @param array $results The results of all attempted updates.
35 *
36 * @since 1.2
37 */
38 add_action('automatic_updates_complete', array('VikRestaurantsInstaller', 'automaticUpdate'));
39
40 /**
41 * Filters whether to automatically update core, a plugin, a theme, or a language.
42 * Used to automatically turn off the update in case a PRO version expired.
43 *
44 * @param bool|null $update Whether to update. The value of null is internally used
45 * to detect whether nothing has hooked into this filter.
46 * @param object $item The update offer.
47 *
48 * @since 1.2
49 */
50 add_filter('auto_update_plugin', array('VikRestaurantsInstaller', 'useAutoUpdate'), 10, 2);
51
52 /**
53 * Fires at the end of the update message container in each
54 * row of the plugins list table.
55 *
56 * The dynamic portion of the hook name, `$file`, refers to the path
57 * of the plugin's primary file relative to the plugins directory.
58 *
59 * @link https://developer.wordpress.org/reference/hooks/in_plugin_update_message-file/
60 *
61 * @param array $data An array of plugin metadata.
62 * @param array $response An array of metadata about the available plugin update.
63 *
64 * @since 1.2
65 */
66 add_action('in_plugin_update_message-vikrestaurants/vikrestaurants.php', array('VikRestaurantsInstaller', 'getUpdateMessage'), 10, 2);
67
68 /**
69 * Hook used to display a list of breaking changes after completing an update of the plugin.
70 * The message will be displayed only once within the dashboard of VikRestaurants.
71 *
72 * @since 1.2
73 */
74 add_action('vikrestaurants_before_display_restaurant', array('VikRestaurantsInstaller', 'showBreakingChanges'));
75
76 /**
77 * Load plugin language only once all the plugins
78 * have been loaded, so that they are able to use
79 * the filters to extend the language functionalities.
80 *
81 * @since 1.4 Load language on init to prevent a WP warning.
82 */
83 add_action('init', array('VikRestaurantsBuilder', 'loadLanguage'));
84
85 // init html helpers
86 VikRestaurantsBuilder::setupHtmlHelpers();
87 // init payment framework
88 VikRestaurantsBuilder::configurePaymentFramework();
89 // init sms framework
90 VikRestaurantsBuilder::configureSmsFramework();
91 // init mirroring functions for extendable files
92 VikRestaurantsBuilder::setupMirroring();
93 // fix scripts loading via AJAX
94 VikRestaurantsAssets::fixAjax();
95 // setup hooks to be used for the configuration of the wizard
96 VikRestaurantsBuilder::setupWizard();
97
98 // setup plugin overrides management
99 add_action('plugins_loaded', array('VikRestaurantsBuilder', 'setupOverridesManager'));
100
101 // setup lite system
102 add_action('plugins_loaded', array('VikRestaurantsLiteManager', 'setup'));
103
104 // add support for Help tabs
105 add_action('current_screen', array('VikRestaurantsScreen', 'help'));
106 // add support for screen options
107 add_action('current_screen', array('VikRestaurantsScreen', 'options'));
108 // always attempt to save screen options
109 add_filter('set-screen-option', array('VikRestaurantsScreen', 'saveOption'), 10, 3);
110 /**
111 * Due to WordPress 5.4.2 changes, we need to attach
112 * VikRestaurants to a dedicated hook in order to
113 * allow the update of the list limit.
114 */
115 add_filter('set_screen_option_vikrestaurants_list_limit', array('VikRestaurantsScreen', 'saveOption'), 10, 3);
116
117 // init Session
118 add_action('init', array('JSessionHandler', 'start'), 1);
119 add_action('wp_logout', array('JSessionHandler', 'destroy'));
120
121 // filter page link to rewrite URI
122 add_action('plugins_loaded', function()
123 {
124 global $pagenow;
125
126 $app = JFactory::getApplication();
127 $input = $app->input;
128
129 // check if the URI contains option=com_vikrestaurants
130 if ($input->get('option') == 'com_vikrestaurants')
131 {
132 // make sure we are not contacting the AJAX and POST end-points
133 if (!wp_doing_ajax() && $pagenow != 'admin-post.php')
134 {
135 /**
136 * Include page in query string only if we are in the back-end,
137 * because WordPress 5.5 seems to break the page loading in case
138 * that argument has been included in query string.
139 *
140 * It is not needed to include this argument in the front-end
141 * as the page should lean on the reached shortcode only.
142 */
143 if ($app->isAdmin())
144 {
145 // inject page=vikrestaurants in GET superglobal
146 $input->get->set('page', 'vikrestaurants');
147 }
148 }
149 else
150 {
151 // inject action=vikrestaurants in GET superglobal for AJAX and POST requests
152 $input->get->set('action', 'vikrestaurants');
153 }
154 }
155 else if ($input->get('page') == 'vikrestaurants' || $input->get('action') == 'vikrestaurants')
156 {
157 // inject option=com_vikrestaurants in GET superglobal for internal component detection
158 $input->get->set('option', 'com_vikrestaurants');
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 /**
169 * Added support to custom code blocks (snippets).
170 *
171 * @since 1.3
172 */
173 VREFactory::getCodeHub()->import();
174
175 /**
176 * Hook used to fetch the site pre-processing flag.
177 * When this flag is enabled, the plugin will try to dispatch the
178 * site controller within the "init" action. This is made by
179 * fetching the shortcode assigned to the current URI.
180 *
181 * By disabling this flag, the site controller will be dispatched
182 * with the headers already sent.
183 *
184 * @param boolean $preprocess The default preprocess flag.
185 *
186 * @since 1.2
187 */
188 $preprocess = apply_filters('vikrestaurants_site_preprocess', VIKRESTAURANTS_SITE_PREPROCESS);
189
190 // if we are in the front-end, try to parse the URL to inject
191 // option, view and args in the input request
192 if ($app->isSite() && $preprocess)
193 {
194 // get post ID from current URL
195 $id = url_to_postid(JUri::current());
196
197 if ($id)
198 {
199 // get shortcode admin model
200 $model = JModel::getInstance('vikrestaurants', 'shortcode', 'admin');
201 // get shortcode searching by post ID (false to avoid returning a new item)
202 $shortcode = $model->getItem(array('post_id' => $id), false);
203
204 if ($shortcode)
205 {
206 // build args array using the shortcode attributes
207 $args = (array) json_decode($shortcode->json, true);
208 $args['view'] = $shortcode->type;
209 $args['option'] = 'com_vikrestaurants';
210
211 // inject the shortcode args into the input request
212 foreach ($args as $k => $v)
213 {
214 // inject only if not defined
215 $input->def($k, $v);
216 }
217 }
218 }
219 }
220
221 /**
222 * Process VikRestaurants only if it has been requested via GET or POST.
223 *
224 * The pre-process should occur only if we are in the back-end or in case
225 * the related flag is turned on, otherwise the pre-processing technique
226 * would still take effect for those URLs that own "com_vikrestaurants"
227 * set in request (@since 1.2.3).
228 */
229 if (($app->isAdmin() || $preprocess) && ($input->get('option') == 'com_vikrestaurants' || $input->get('page') == 'vikrestaurants'))
230 {
231 VikRestaurantsBody::process();
232 }
233 });
234
235 // handle AJAX requests for both logged and guest users
236 add_action('wp_ajax_vikrestaurants', 'handle_vikrestaurants_ajax');
237 add_action('wp_ajax_nopriv_vikrestaurants', 'handle_vikrestaurants_ajax');
238
239 /**
240 * Callback used to handle AJAX requests coming
241 * from both the front-end and back-end sections.
242 *
243 * @since 1.1
244 */
245 function handle_vikrestaurants_ajax()
246 {
247 // process controller request
248 VikRestaurantsBody::getHtml();
249
250 // die to get a valid response
251 wp_die();
252 }
253
254 // setup admin menu
255 add_action('admin_menu', array('VikRestaurantsBuilder', 'setupAdminMenu'));
256
257 // register widgets
258 add_action('widgets_init', array('VikRestaurantsBuilder', 'setupWidgets'));
259
260 // handle shortcodes (SITE controller dispatcher)
261 add_shortcode('vikrestaurants', function($atts, $content = null)
262 {
263 $app = JFactory::getApplication();
264
265 /**
266 * Force the application client to "site" every time a shortcode is executed.
267 *
268 * @since 1.2.7
269 */
270 $app->setClient('site');
271
272 // wrap attributes in a registry
273 $args = new JObject($atts);
274
275 // get the VIEW (empty if not set)
276 $view = $args->get('view', '');
277
278 if (!$view)
279 {
280 return $content;
281 }
282
283 // load the FORM of the view
284 JLoader::import('adapter.form.form');
285 $path = implode(DIRECTORY_SEPARATOR, array(VREBASE, 'views', $view, 'tmpl', 'default.xml'));
286 // raises an exception if the VIEW is not set
287 $form = JForm::getInstance($view, $path);
288
289 // get all the XML form fields
290 $fields = $form->getFields();
291
292 // filter the fields to get a list of allowed names
293 $fields = array_map(function($f)
294 {
295 return (string) $f->attributes()->name;
296 }, $fields);
297
298 // inject query vars
299 $input = $app->input;
300
301 // since we are going to render the controller manually,
302 // we need to push the option into $_REQUEST pool only
303 // whether it hasn't been added yet
304 $input->def('option', 'com_vikrestaurants');
305
306 // Inject shortcode vars only if they are not set
307 // in the request. This is used to allow the navigation
308 // between the pages.
309 $input->def('view', $view);
310
311 foreach ($fields as $k)
312 {
313 $input->def($k, $args->get($k));
314 }
315
316 /**
317 * When saving a shortcode block through Gutenberg,
318 * WordPress tries to reach the page to check what happens.
319 * The "takeawayconfirm" view of VikRestaurants, in case of
320 * no selected orders, immediately redirects the users to
321 * the "takeaway" page.
322 * This redirect breaks the request made by WordPress for the
323 * validation of the page, which follows the new location.
324 * The code below prevents the execution of the controller
325 * in case the URI matches the REST API end-point.
326 *
327 * @since 1.2.7 The rest_get_url_prefix(), which should be equals
328 * to /wp-json is available only on websites with pretty permalinks
329 * enabled. On sites without pretty permalinks, the route is instead
330 * added to the URL as the rest_route parameter.
331 *
332 * @since 1.3 Included additional condition to make sure we are not
333 * under the management page in the back-end.
334 */
335 $rest_prefix = trailingslashit(rest_get_url_prefix());
336 $is_rest_api = strpos($input->server->getString('REQUEST_URI', ''), $rest_prefix) !== false
337 || JUri::getInstance($input->server->getString('REQUEST_URI', ''))->hasVar('rest_route')
338 || strpos($input->server->getString('REQUEST_URI', ''), '/wp-admin/') !== false;
339
340 if ($is_rest_api && in_array($input->get('view'), ['confirmres', 'takeawayconfirm']))
341 {
342 // return an empty string to prevent any redirects
343 return '';
344 }
345
346 // dispatch the controller
347 return VikRestaurantsBody::getHtml(true);
348 });
349
350 // the callback is fired before the VRE controller is dispatched
351 add_action('vikrestaurants_before_dispatch', function()
352 {
353 $app = JFactory::getApplication();
354 $user = Jfactory::getUser();
355
356 // initialize timezone handler
357 JDate::getDefaultTimezone();
358 date_default_timezone_set($app->get('offset', 'UTC'));
359
360 // check if the user is authorised to access the back-end (only if the client is 'admin')
361 if ($app->isAdmin() && !$user->authorise('core.manage', 'com_vikrestaurants'))
362 {
363 if ($user->guest)
364 {
365 // if the user is not logged, redirect to login page
366 $app->redirect('index.php');
367 exit;
368 }
369 else
370 {
371 // otherwise raise an exception
372 wp_die(
373 '<h1>' . JText::translate('FATAL_ERROR') . '</h1>' .
374 '<p>' . JText::translate('RESOURCE_AUTH_ERROR') . '</p>',
375 403
376 );
377 }
378 }
379
380 if ($app->isAdmin())
381 {
382 // require helper files
383 require_once JPath::clean(VREADMIN . '/helpers/vikrestaurants.php');
384
385 // remove expired credit cards
386 // check every 15 minutes only
387 VikRestaurants::removeExpiredCreditCards();
388 }
389
390 if (!wp_doing_ajax())
391 {
392 // load assets only if we are not doing an AJAX call
393 VikRestaurantsAssets::load();
394 }
395
396 /**
397 * Prevent the confirmation pages from performing an auto-redirect when running
398 * the Bricks plugin preview.
399 *
400 * @since 1.4
401 */
402 if ($app->input->get('bricks') === 'run' && in_array($app->input->get('view'), ['confirmres', 'takeawayconfirm']))
403 {
404 $app->input->set('view', '');
405 }
406 });
407
408 // the callback is fired before displaying MANAGEMAP view
409 add_action('vikrestaurants_after_display_managemap', function()
410 {
411 // if we are not doing AJAX, include CSS to support full screen
412 if (!wp_doing_ajax())
413 {
414 JHtml::fetch(
415 'stylesheet',
416 VIKRESTAURANTS_CORE_MEDIA_URI . 'css/fullscreen.css',
417 array('version' => VIKRESTAURANTS_SOFTWARE_VERSION),
418 array('id' => 'vre-fullscreen-css')
419 );
420 }
421 });
422
423 // the callback is fired before displaying DASHBOARD view
424 add_action('vikrestaurants_before_display_restaurant', function()
425 {
426 $app = JFactory::getApplication();
427 $user = JFactory::getUser();
428
429 // make sure we are not doing AJAX, we are in the back-end and the user is an administrator
430 if (!wp_doing_ajax() && $app->isClient('administrator') && $user->authorise('core.admin', 'com_vikrestaurants'))
431 {
432 JToolbarHelper::shortcodes('com_vikrestaurants');
433 }
434 });
435
436 // instead using the default server timezone, try to use the one
437 // specified within the WordPress configuration
438 add_filter('vik_date_default_timezone', function($timezone)
439 {
440 return JFactory::getApplication()->get('offset', $timezone);
441 });
442
443 // the callback is fired once the VRE controller has been dispatched
444 add_action('vikrestaurants_after_dispatch', function()
445 {
446 // load assets after dispatching the controller to avoid
447 // including JS and CSS when an AJAX function exits or dies
448 // VikRestaurantsAssets::load();
449
450 // load javascript core
451 JHtml::fetch('behavior.core');
452
453 // reload Joomla options after registering the plugin scripts
454 JFactory::getDocument()->addScriptDeclaration('JoomlaCore.loadOptions();');
455
456 // restore standard timezone
457 date_default_timezone_set(JDate::getDefaultTimezone());
458
459 /**
460 * WordPress has some reserved values that shouldn't be used
461 * in query string or within the forms, otherwise they could
462 * be used to rewrite the URLs of the website.
463 *
464 * In example, by using the 'day' argument in query string,
465 * WordPress will start searching for POSTS that were created
466 * on the specified day (of the month), completely ignoring
467 * whether the current URL is used by a shortcode.
468 *
469 * For this reason, within the site section of VikRestaurants,
470 * we should unset all the reserved arguments from the superglobals
471 * once the plugin finished using them.
472 *
473 * @link https://codex.wordpress.org/WordPress_Query_Vars
474 */
475
476 $app = JFactory::getApplication();
477
478 if ($app->isSite())
479 {
480 // define here the list of all the reserved arguments
481 // that are used by VikRestaurants
482 $reserved_args_for_date_query = array(
483 'year',
484 'day',
485 'hour',
486 );
487
488 foreach ($reserved_args_for_date_query as $arg)
489 {
490 // unset argument from REQUEST
491 $app->input->delete($arg);
492 // unset argument from GET
493 $app->input->get->delete($arg);
494 // unset argument from POST
495 $app->input->post->delete($arg);
496 }
497 }
498
499 /**
500 * When the headers have been sent or when the request is AJAX
501 * the assets (CSS and JS) are appended into the document after
502 * the response is dispatched by the controller.
503 * Obviously only in case the controller doesn't manually exit.
504 */
505
506 if ($app->isAdmin())
507 {
508 /**
509 * Includes the manifest.json link within the head of the document for a better compliance
510 * with the Web Application requirements.
511 *
512 * We can attach the manifest after executing the plugin as, in case of redirect or exit,
513 * it doesn't make sense to include a link within the document.
514 *
515 * @since 1.3
516 */
517 (new E4J\VikRestaurants\Document\WebApp(
518 new E4J\VikRestaurants\Document\WebApp\Apps\VikRestaurantsAdminManifest
519 ))->load();
520 }
521 });
522
523 // End-point for front-end post actions.
524 // The end-point URL must be built as .../wp-admin/admin-post.php
525 // and requires $_POST['action'] == 'vikrestaurants' to be submitted through a form or GET.
526 add_action('admin_post_vikrestaurants', 'handle_vikrestaurants_endpoint'); // if the user is logged in
527 add_action('admin_post_nopriv_vikrestaurants', 'handle_vikrestaurants_endpoint'); // if the user in not logged in
528
529 // handle POST end-point
530 function handle_vikrestaurants_endpoint()
531 {
532 // get PLAIN response
533 echo VikRestaurantsBody::getResponse();
534 }
535
536 // Hook used to access the PAGE details when a user is
537 // creating or updating it. This is helpful to make a relation
538 // between the page and the injected shortcode.
539 add_action('save_post', function($post_id)
540 {
541 // get model to access all the existing shortcodes
542 $model = JModel::getInstance('vikrestaurants', 'shortcodes', 'admin');
543 $shortcodes = $model->all(array('id', 'shortcode', 'post_id'));
544
545 // get post data
546 $post = get_post($post_id);
547
548 // include private posts and future schedules
549 $accepted = array(
550 'publish',
551 'private',
552 'future',
553 );
554
555 /**
556 * Check if we are editing a child post as Gutenberg
557 * seems to use always the inherit status, which
558 * refers to a post parent.
559 */
560 if (!in_array($post->post_status, $accepted) && !empty($post->post_parent) && $post->post_parent != $post_id)
561 {
562 // fallback to obtain parent post data
563 $post = get_post($post->post_parent);
564
565 // use new post ID
566 $post_id = $post->ID;
567 }
568
569 if (!in_array($post->post_status, $accepted))
570 {
571 // ignore drafts auto-save
572 return;
573 }
574
575 // get shortcode model
576 $shortcodeModel = JModel::getInstance('vikrestaurants', 'shortcode', 'admin');
577
578 /**
579 * Since we need unique post IDs, all the shortcodes
580 * that are assigned to the specified $post_id should
581 * be detached.
582 */
583 foreach ($shortcodes as $data)
584 {
585 if ($data->post_id == $post_id)
586 {
587 // The post is already assigned to a shortcode.
588 // Unset it to avoid duplicated.
589 $data->post_id = 0;
590 $shortcodeModel->save($data);
591 }
592 }
593
594 // iterate the shortcodes
595 foreach ($shortcodes as $data)
596 {
597 // check if the content of the post contains the shortcode
598 if (strpos($post->post_content, html_entity_decode($data->shortcode)) !== false)
599 {
600 // inject the POST ID
601 $data->post_id = $post_id;
602
603 // update shortcode
604 $shortcodeModel->save($data);
605
606 // stop iterating
607 return;
608 }
609 }
610 });
611
612 // Hook used to unset temporarily the relationship
613 // between the trashed post and the shortcode.
614 add_action('trashed_post', function($post_id)
615 {
616 // get shortcode model
617 $model = JModel::getInstance('vikrestaurants', 'shortcode', 'admin');
618
619 // get the shortcode attached to the trashed post ID
620 $item = $model->getItem(array('post_id' => $post_id), false);
621
622 // if the item exists, temporarily detach the relationship
623 if ($item)
624 {
625 $item->post_id = 0;
626 $item->tmp_post_id = $post_id;
627
628 $model->save($item);
629 }
630 });
631
632 // Hook used to restore permanently the relationship
633 // between the untrashed post and the shortcode.
634 add_action('untrashed_post', function($post_id)
635 {
636 // get shortcode model
637 $model = JModel::getInstance('vikrestaurants', 'shortcode', 'admin');
638
639 // get the shortcode attached to the untrashed post ID
640 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
641
642 // if the item exists, re-attach the relationship
643 if ($item)
644 {
645 $item->post_id = $post_id;
646 $item->tmp_post_id = 0;
647
648 $model->save($item);
649 }
650 });
651
652 // Hook used to temporarily detach the relationship
653 // between the deleted post and the shortcode.
654 add_action('deleted_post', function($post_id)
655 {
656 // get shortcode model
657 $model = JModel::getInstance('vikrestaurants', 'shortcode', 'admin');
658
659 // get the shortcode attached to the trashed post ID
660 $item = $model->getItem(array('tmp_post_id' => $post_id), false);
661
662 // If no item found, the "trash" feature is probably disabled.
663 // Try to take a look for a shortcode with an active relationship.
664 if (!$item)
665 {
666 $item = $model->getItem(array('post_id' => $post_id), false);
667 }
668
669 // if the item exists, permanently detach the relationship
670 if ($item)
671 {
672 $item->post_id = 0;
673 $item->tmp_post_id = 0;
674
675 $model->save($item);
676 }
677 });
678
679 if (JFactory::getApplication()->isAdmin() && !wp_doing_ajax())
680 {
681 VikRestaurantsLoader::import('system.mce');
682
683 // add new buttons
684 add_filter('mce_buttons', ['VikRestaurantsTinyMCE', 'addShortcodesButton']);
685
686 // load the button handlers
687 add_filter('mce_external_plugins', ['VikRestaurantsTinyMCE', 'registerShortcodesScript']);
688 }
689
690 /**
691 * Always load the Gutenberg shortcodes block to support the preview rendering.
692 *
693 * @since 1.3.2
694 */
695 VikRestaurantsLoader::import('system.gutenberg');
696 add_action('init', ['VikRestaurantsGutenberg', 'registerShortcodesScript']);
697
698 /**
699 * Dispatch the uninstallation of VikRestaurants
700 * every time a new blog (multisite) is deleted.
701 *
702 * Fires after the site is deleted from the network (WP 4.8.0 or higher).
703 *
704 * @param integer $blog_id The site ID.
705 * @param boolean $drop True if site's tables should be dropped. Default is false.
706 */
707 add_action('deleted_blog', function($blog_id, $drop)
708 {
709 VikRestaurantsInstaller::uninstall($drop);
710 }, 10, 2);
711
712 /**
713 * Suppress WP Date Query warnings when visiting the views of VikRestaurants as
714 * they might use reserved arguments in query string with wrong values, such
715 * as 'day' with UNIX timestamps.
716 *
717 * @param boolean $trigger Whether to trigger the error for _doing_it_wrong() calls. Default true.
718 * @param string $function The function that was called.
719 * @param string $message A message explaining what has been done incorrectly.
720 * @param string $version The version of WordPress where the message was added.
721 */
722 add_filter('doing_it_wrong_trigger_error', function($show, $function, $message, $version)
723 {
724 $input = JFactory::getApplication()->input;
725
726 // suppress any WP_Date_Query error messages in VikRestaurants
727 if ($function == 'WP_Date_Query' && $input->get('option') == 'com_vikrestaurants')
728 {
729 // suppress the error
730 return false;
731 }
732
733 // keep the current value otherwise
734 return $show;
735 }, 10, 4);
736
737 /**
738 * Once the plugins have been loaded, evaluates to execute the
739 * scheduled cron jobs.
740 *
741 * Scheduling is processed in case a cron job is hitting wp-cron file
742 * or in case a user is visiting the website.
743 *
744 * @since 1.4
745 */
746 add_action('plugins_loaded', array('VikRestaurantsCron', 'setup'), PHP_INT_MAX);
747
748 /**
749 * Filters the action links displayed for each plugin in the Plugins list table.
750 * Hook used to filter the "deactivation" link and ask a feedback every time that
751 * button is clicked.
752 *
753 * @param array $actions An array of plugin action links. By default this can include 'activate',
754 * 'deactivate', and 'delete'. With Multisite active this can also include
755 * 'network_active' and 'network_only' items.
756 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
757 * @param array $plugin_data An array of plugin data. See `get_plugin_data()`.
758 * @param string $context The plugin context. By default this can include 'all', 'active', 'inactive',
759 * 'recently_activated', 'upgrade', 'mustuse', 'dropins', and 'search'.
760 */
761 add_filter('plugin_action_links', array('VikRestaurantsFeedback', 'deactivate'), 10, 4);
762
763 /**
764 * Adjusts the timezone of the website before dispatching
765 * a widget as we are currently outside of the main plugin and
766 * the timezone have probably been restored to the default one.
767 *
768 * @param string $id The widget ID (path name).
769 * @param JObject &$params The widget configuration registry.
770 */
771 add_action('vik_widget_before_dispatch_site', function($id, &$params)
772 {
773 // initialize timezone handler
774 JDate::getDefaultTimezone();
775 date_default_timezone_set(JFactory::getApplication()->get('offset', 'UTC'));
776 }, 10, 2);
777
778 /**
779 * Restores the timezone of the website after dispatching
780 * a widget in order to avoid strange behaviors with other plugins.
781 *
782 * @param string $id The widget ID (path name).
783 * @param string &$html The HTML of the widget to display.
784 */
785 add_action('vik_widget_after_dispatch_site', function($id, &$html)
786 {
787 // restore standard timezone
788 date_default_timezone_set(JDate::getDefaultTimezone());
789 }, 10, 2);
790
791 /**
792 * Action triggered before loading the text domain.
793 * Loads the language handlers when needed from a
794 * different application client.
795 *
796 * @param string $domain The plugin text domain to look for.
797 * @param string $basePath The base path containing the languages.
798 * @param mixed $langtag An optional language tag to use.
799 */
800 add_action('vik_plugin_before_load_language', function($domain, $basePath, $langtag)
801 {
802 if ($domain != 'vikrestaurants')
803 {
804 // do not go ahead
805 return;
806 }
807
808 $app = JFactory::getApplication();
809 $lang = JFactory::getLanguage();
810
811 $handler = VIKRESTAURANTS_LIBRARIES . DIRECTORY_SEPARATOR . 'language' . DIRECTORY_SEPARATOR;
812
813 // check if we are in the site client and the system
814 // needs to load the language used in the back-end
815 if ($app->isSite() && $basePath == JPATH_ADMINISTRATOR)
816 {
817 // load back-end language handler
818 $lang->attachHandler($handler . 'admin.php', $domain);
819 }
820 // check if we are in the admin client and the system
821 // needs to load the language used in the front-end
822 else if ($app->isAdmin() && $basePath == JPATH_SITE)
823 {
824 // load front-end language handler
825 $lang->attachHandler($handler . 'site.php', $domain);
826 }
827 }, 10, 3);
828
829 /**
830 * Added support for Loco Translate.
831 * In case some translations have been edited by using this plugin,
832 * we should look within the Loco Translate folder to check whether
833 * the requested translation is available.
834 *
835 * @param boolean $loaded True if the translation has been already loaded.
836 * @param string $domain The plugin text domain to load.
837 *
838 * @return boolean True if a new translation is loaded.
839 */
840 add_filter('vik_plugin_load_language', function($loaded, $domain)
841 {
842 // proceed only in case the translation hasn't been loaded
843 // and Loco Translate plugin is installed
844 if (!$loaded && is_dir(WP_LANG_DIR . DIRECTORY_SEPARATOR . 'loco'))
845 {
846 // Build LOCO path.
847 // Since load_plugin_textdomain accepts only relative paths,
848 // we should go back to the /wp-contents/ folder first.
849 $loco = implode(DIRECTORY_SEPARATOR, array('..', 'languages', 'loco', 'plugins'));
850
851 // try to load the plugin translation from Loco folder
852 $loaded = load_plugin_textdomain($domain, false, $loco);
853 }
854
855 return $loaded;
856 }, 10, 2);
857
858 /**
859 * Downloads the RSS feeds after loading the dashboard of VikRestaurants.
860 *
861 * @since 1.1
862 */
863 add_action('vikrestaurants_after_display_restaurant', ['VikRestaurantsRssFeeds', 'download']);
864
865 /**
866 * Trigger event to allow the plugins to include custom HTML within the view.
867 * It is possible to return an associative array to group the HTML strings
868 * under different fieldsets. Plain/html string will be always pushed within
869 * the "custom" fieldset instead.
870 *
871 * Displays the RSS configuration.
872 *
873 * @param mixed $forms The HTML to display.
874 * @param mixed $view The current view instance.
875 * @param object $setup An object holding the panel setup.
876 *
877 * @since 1.1
878 */
879 add_filter('vikrestaurants_display_view_config_global', ['VikRestaurantsRssFeeds', 'config'], 10, 3);
880
881 /**
882 * Trigger event to allow the plugins to make something after saving
883 * a record in the database.
884 *
885 * @param mixed $dummy A dummy argument for BC.
886 * @param array $args The saved record.
887 * @param JTable $table The table instance.
888 *
889 * @since 1.1
890 */
891 add_action('vikrestaurants_after_save_config', ['VikRestaurantsRssFeeds', 'save'], 10, 3);
892
893 /**
894 * Hook used to manipulate the RSS channels to which the plugin is subscribed.
895 *
896 * @param array $channels A list of RSS permalinks.
897 * @param bool $status True to return only the published channels.
898 *
899 * @since 1.1
900 */
901 add_filter('vikrestaurants_fetch_rss_channels', ['VikRestaurantsRssFeeds', 'getChannels'], 10, 2);
902
903 /**
904 * Hook used to apply some stuff before returning the RSS reader.
905 *
906 * @param JRssReader &$rss The RSS reader handler.
907 *
908 * @since 1.1
909 */
910 add_action('vikrestaurants_before_use_rss', ['VikRestaurantsRssFeeds', 'ready']);
911
912 /**
913 * Fixed the issue with wptexturize() function, which might convert special characters contained
914 * within <script> tags into an HTML-encoded version (e.g. "&" became "&#038;").
915 *
916 * Short-circuit the usage of wptexturize for the whole front-end.
917 *
918 * @param bool $run Whether to short-circuit wptexturize().
919 *
920 * @since 1.4
921 */
922 add_filter('run_wptexturize', function($run)
923 {
924 return is_admin() ? $run : false;
925 }, PHP_INT_MAX);
926