PluginProbe
Boxzilla – WordPress Popup Builder / 3.1.9
Boxzilla – WordPress Popup Builder v3.1.9
3.4.11 3.4.10 3.4.9 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 trunk 3.0 3.0.1 3.0.2 3.0.3 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 All 72 releases
← All changes | src/admin/class-admin.php +764 -827 3.4.43.1.9 View file →
@@ -1,827 +1,764 @@
1 -<?php
2 -
3 -namespace Boxzilla\Admin;
4 -
5 -use Boxzilla\Plugin;
6 -use Boxzilla\Box;
7 -use Boxzilla\Boxzilla;
8 -use WP_Post;
9 -use WP_Screen;
10 -
11 -class Admin
12 -{
13 - /**
14 - * @var Plugin $plugin
15 - */
16 - private $plugin;
17 -
18 - /**
19 - * @var Boxzilla
20 - */
21 - protected $boxzilla;
22 -
23 - /**
24 - * @var ReviewNotice
25 - */
26 - protected $review_notice;
27 -
28 - /**
29 - * @param Plugin $plugin
30 - * @param Boxzilla $boxzilla
31 - */
32 - public function __construct(Plugin $plugin, Boxzilla $boxzilla)
33 - {
34 - $this->plugin = $plugin;
35 - $this->boxzilla = $boxzilla;
36 - $this->review_notice = new ReviewNotice();
37 - }
38 -
39 - /**
40 - * Initialise the all admin related stuff
41 - */
42 - public function init()
43 - {
44 - $this->add_hooks();
45 - $this->run_migrations();
46 - $this->review_notice->init();
47 - }
48 -
49 - /**
50 - * Add necessary hooks
51 - */
52 - protected function add_hooks()
53 - {
54 - add_action('admin_init', [ $this, 'lazy_add_hooks' ]);
55 - add_action('admin_init', [ $this, 'register' ]);
56 - add_action('init', [ $this, 'listen_for_actions' ]);
57 - add_action('admin_menu', [ $this, 'menu' ]);
58 - add_action('admin_notices', [ $this, 'notices' ]);
59 - add_action('save_post_boxzilla-box', [ $this, 'save_box_options' ], 20, 2);
60 - add_action('trashed_post', [ $this, 'flush_rules' ]);
61 - add_action('untrashed_post', [ $this, 'flush_rules' ]);
62 - add_filter('bulk_actions-edit-boxzilla-box', [ $this, 'bulk_action_add' ]);
63 - add_filter('handle_bulk_actions-edit-boxzilla-box', [ $this, 'bulk_action_handle' ], 10, 3);
64 - }
65 -
66 - /**
67 - * Listen for admin actions.
68 - */
69 - public function listen_for_actions()
70 - {
71 - // triggered?
72 - $vars = array_merge($_POST, $_GET);
73 - if (empty($vars['_boxzilla_admin_action'])) {
74 - return false;
75 - }
76 -
77 - // authorized?
78 - if (! current_user_can('edit_posts')) {
79 - return false;
80 - }
81 -
82 - // fire action
83 - $action = $vars['_boxzilla_admin_action'];
84 - do_action('boxzilla_admin_' . $action);
85 -
86 - return true;
87 - }
88 -
89 - public function bulk_action_add($bulk_actions)
90 - {
91 - $bulk_actions['boxzilla_duplicate_box'] = esc_attr__('Duplicate box', 'boxzilla');
92 - return $bulk_actions;
93 - }
94 -
95 - public function bulk_action_handle($redirect_to, $doaction, $post_ids)
96 - {
97 - if ($doaction !== 'boxzilla_duplicate_box' || empty($post_ids)) {
98 - return $redirect_to;
99 - }
100 -
101 - foreach ($post_ids as $post_id) {
102 - $post = get_post($post_id);
103 - if ($post->post_type !== 'boxzilla-box') {
104 - continue;
105 - }
106 -
107 - $new_post_id = wp_insert_post(
108 - [
109 - 'post_type' => $post->post_type,
110 - 'post_title' => $post->post_title,
111 - 'post_content' => $post->post_content,
112 - 'post_status' => 'draft',
113 - ]
114 - );
115 -
116 - $options = get_post_meta($post_id, 'boxzilla_options', true);
117 - add_post_meta($new_post_id, 'boxzilla_options', $options);
118 -
119 - $this->flush_rules($new_post_id);
120 - }
121 -
122 - return $redirect_to;
123 - }
124 -
125 - /**
126 - * All logic for admin notices lives here.
127 - */
128 - public function notices()
129 - {
130 - global $pagenow,
131 - $current_screen;
132 -
133 - if (( $pagenow === 'plugins.php' || ( $current_screen && $current_screen->post_type === 'boxzilla-box' ) )
134 - && current_user_can('install_plugins')
135 - && is_plugin_active('scroll-triggered-boxes/index.php')
136 - ) {
137 - ?>
138 - <div class="notice notice-info">
139 - <p><?php esc_html_e('Awesome, you are using Boxzilla! You can now safely deactivate the Scroll Triggered Boxes plugin.', 'boxzilla'); ?></p>
140 - </div>
141 - <?php
142 - }
143 - }
144 -
145 - /**
146 - * Checks current version against stored version & runs necessary update routines.
147 - *
148 - * @return bool
149 - */
150 - protected function run_migrations()
151 - {
152 -
153 - // Only run if db option is at older version than code constant
154 - $previous_version = get_option('boxzilla_version', '0');
155 - $current_version = $this->plugin->version();
156 -
157 - if (version_compare($current_version, $previous_version, '<=')) {
158 - return false;
159 - }
160 -
161 - $upgrade_routines = new Migrations($previous_version, $current_version, __DIR__ . '/migrations');
162 - $upgrade_routines->run();
163 - update_option('boxzilla_version', $current_version);
164 - }
165 -
166 - public function lazy_add_hooks()
167 - {
168 - global $pagenow;
169 -
170 - add_action('admin_enqueue_scripts', [ $this, 'load_assets' ]);
171 - add_action('add_meta_boxes', [ $this, 'add_meta_boxes' ]);
172 - add_filter('tiny_mce_before_init', [ $this, 'tinymce_init' ]);
173 - add_filter('manage_edit-boxzilla-box_columns', [ $this, 'post_type_column_titles' ]);
174 - add_action('manage_boxzilla-box_posts_custom_column', [ $this, 'post_type_column_content' ], 10, 2);
175 - add_filter('admin_footer_text', [ $this, 'admin_footer_text' ]);
176 -
177 - if ($pagenow === 'plugins.php') {
178 - add_filter('plugin_action_links', [ $this, 'add_plugin_settings_link' ], 10, 2);
179 - add_filter('plugin_row_meta', [ $this, 'add_plugin_meta_links' ], 10, 2);
180 - }
181 - }
182 -
183 - /**
184 - * @param $post_id
185 - */
186 - public function post_type_column_box_id_content($post_id)
187 - {
188 - echo $post_id;
189 - }
190 -
191 - /**
192 - * @param $column
193 - * @param $post_id
194 - */
195 - public function post_type_column_content($column, $post_id)
196 - {
197 - $method_name = 'post_type_column_' . $column . '_content';
198 - if (method_exists($this, $method_name)) {
199 - call_user_func([ $this, $method_name ], $post_id);
200 - }
201 - }
202 -
203 - /**
204 - * @param $columns
205 - *
206 - * @return mixed
207 - */
208 - public function post_type_column_titles($columns)
209 - {
210 - $columns = self::array_insert(
211 - $columns,
212 - [
213 - 'box_id' => esc_html__('Box ID', 'boxzilla'),
214 - ],
215 - 1
216 - );
217 -
218 - $columns['title'] = esc_html__('Box Title', 'boxzilla');
219 -
220 - return $columns;
221 - }
222 -
223 - /**
224 - * Register stuffs
225 - */
226 - public function register()
227 - {
228 -
229 - register_setting('boxzilla_settings', 'boxzilla_settings', [ $this, 'sanitize_settings' ]);
230 -
231 - wp_register_script(
232 - 'boxzilla-admin',
233 - $this->plugin->url('/assets/js/admin-script.js'),
234 - [
235 - 'jquery',
236 - 'wp-util',
237 - 'wp-color-picker',
238 - 'suggest',
239 - ],
240 - $this->plugin->version(),
241 - true
242 - );
243 -
244 - wp_register_style('boxzilla-admin', $this->plugin->url('/assets/css/admin-styles.css'), [], $this->plugin->version());
245 - }
246 -
247 - /**
248 - * Renders the Boxzilla admin menu items
249 - */
250 - public function menu()
251 - {
252 - $menu_items = [
253 - [
254 - esc_html__('Settings', 'boxzilla'),
255 - esc_html__('Settings', 'boxzilla'),
256 - 'boxzilla-settings',
257 - [ $this, 'show_settings_page' ],
258 - ],
259 - [
260 - esc_html__('Extensions', 'boxzilla'),
261 - '<span style="color: orange">' . esc_html__('Extensions', 'boxzilla') . '</span>',
262 - 'boxzilla-extensions',
263 - [ $this, 'show_extensions_page' ],
264 - ],
265 - ];
266 -
267 - $menu_items = apply_filters('boxzilla_admin_menu_items', $menu_items);
268 -
269 - foreach ($menu_items as $item) {
270 - add_submenu_page('edit.php?post_type=boxzilla-box', $item[0] . '- Boxzilla', $item[1], 'manage_options', $item[2], $item[3]);
271 - }
272 - }
273 -
274 - /**
275 - * Shows the settings page
276 - */
277 - public function show_settings_page()
278 - {
279 - $opts = $this->boxzilla->options;
280 - require __DIR__ . '/views/settings.php';
281 - }
282 -
283 - /**
284 - * Shows the extensions page
285 - */
286 - public function show_extensions_page()
287 - {
288 - $extensions = $this->fetch_extensions();
289 - require __DIR__ . '/views/extensions.php';
290 - }
291 -
292 - /**
293 - * Are we currently editing a box?
294 - *
295 - * @return bool
296 - */
297 - protected function on_edit_box_page()
298 - {
299 - global $pagenow;
300 -
301 - if (! in_array($pagenow, [ 'post-new.php', 'post.php' ], true)) {
302 - return false;
303 - }
304 -
305 - if (isset($_GET['post_type']) && $_GET['post_type'] === 'boxzilla-box') {
306 - return true;
307 - }
308 -
309 - if (get_post_type() === 'boxzilla-box') {
310 - return true;
311 - }
312 -
313 - return false;
314 - }
315 -
316 - /**
317 - * @param $args
318 - *
319 - * @return mixed
320 - */
321 - public function tinymce_init($args)
322 - {
323 -
324 - // only act on our post type
325 - if (get_post_type() !== 'boxzilla-box') {
326 - return $args;
327 - }
328 -
329 - $args['setup'] = 'function( editor ) { if(typeof(window.Boxzilla_Admin) === \'undefined\') { return; } editor.on("PreInit", window.Boxzilla_Admin.Designer.init ); }';
330 -
331 - return $args;
332 - }
333 -
334 - /**
335 - * Load plugin assets
336 - */
337 - public function load_assets()
338 - {
339 - $screen = get_current_screen();
340 -
341 - if (! $screen instanceof WP_Screen) {
342 - return false;
343 - }
344 -
345 - if ($screen->base === 'edit' && $screen->post_type === 'boxzilla-box') {
346 - wp_enqueue_style('boxzilla-admin');
347 - }
348 -
349 - if ($screen->base === 'post' && $screen->post_type === 'boxzilla-box') {
350 - // color picker
351 - wp_enqueue_style('wp-color-picker');
352 -
353 - // load scripts
354 - wp_enqueue_script('boxzilla-admin');
355 -
356 - $data = [
357 - 'and' => esc_html__('and', 'boxzilla'),
358 - 'or' => esc_html__('or', 'boxzilla'),
359 - 'enterCommaSeparatedValues' => esc_html__('Enter a comma-separated list of values.', 'boxzilla'),
360 - 'enterCommaSeparatedPosts' => esc_html__("Enter a comma-separated list of post slugs or post ID's..", 'boxzilla'),
361 - 'enterCommaSeparatedPages' => esc_html__("Enter a comma-separated list of page slugs or page ID's..", 'boxzilla'),
362 - 'enterCommaSeparatedPostTypes' => esc_html__('Enter a comma-separated list of post types..', 'boxzilla'),
363 - 'enterCommaSeparatedRelativeUrls' => esc_html__("Enter a comma-separated list of relative URL's, eg /contact/", 'boxzilla'),
364 - ];
365 - wp_localize_script('boxzilla-admin', 'boxzilla_i18n', $data);
366 -
367 - // load stylesheets
368 - wp_enqueue_style('boxzilla-admin');
369 -
370 - // allow add-ons to easily load their own scripts or stylesheets
371 - do_action('boxzilla_load_admin_assets');
372 - }
373 -
374 - if (isset($_GET['page']) && $_GET['page'] === 'boxzilla-settings') {
375 - wp_enqueue_style('boxzilla-admin');
376 - }
377 - }
378 -
379 - /**
380 - * Register meta boxes
381 - *
382 - * @param string $post_type
383 - *
384 - * @return bool
385 - */
386 - public function add_meta_boxes($post_type)
387 - {
388 - if ($post_type !== 'boxzilla-box') {
389 - return false;
390 - }
391 -
392 - add_meta_box(
393 - 'boxzilla-box-appearance-controls',
394 - esc_html__('Box Appearance', 'boxzilla'),
395 - [ $this, 'metabox_box_appearance_controls' ],
396 - 'boxzilla-box',
397 - 'normal',
398 - 'core'
399 - );
400 -
401 - add_meta_box(
402 - 'boxzilla-box-options-controls',
403 - esc_html__('Box Options', 'boxzilla'),
404 - [ $this, 'metabox_box_option_controls' ],
405 - 'boxzilla-box',
406 - 'normal',
407 - 'core'
408 - );
409 -
410 - add_meta_box(
411 - 'boxzilla-support',
412 - esc_html__('Looking for help?', 'boxzilla'),
413 - [ $this, 'metabox_support' ],
414 - 'boxzilla-box',
415 - 'side'
416 - );
417 -
418 - add_meta_box(
419 - 'boxzilla-our-other-plugins',
420 - esc_html__('Our other plugins', 'boxzilla'),
421 - [ $this, 'metabox_our_other_plugins' ],
422 - 'boxzilla-box',
423 - 'side'
424 - );
425 -
426 - return true;
427 - }
428 -
429 - /**
430 - * @param \WP_Post $post
431 - * @param $metabox
432 - */
433 - public function metabox_box_appearance_controls(\WP_Post $post, $metabox)
434 - {
435 -
436 - // get box options
437 - $box = new Box($post);
438 - $opts = $box->get_options();
439 -
440 - // include view
441 - include __DIR__ . '/views/metaboxes/box-appearance-controls.php';
442 - }
443 -
444 - /**
445 - * @param \WP_Post $post
446 - * @param $metabox
447 - */
448 - public function metabox_box_option_controls(\WP_Post $post, $metabox)
449 - {
450 -
451 - // get box options
452 - $box = new Box($post);
453 - $opts = $box->get_options();
454 - $global_opts = $this->boxzilla->options;
455 -
456 - if (empty($opts['rules'])) {
457 - $opts['rules'][] = [
458 - 'condition' => '',
459 - 'qualifier' => 1,
460 - 'value' => '',
461 - ];
462 - }
463 -
464 - // include view
465 - include __DIR__ . '/views/metaboxes/box-option-controls.php';
466 - }
467 -
468 - /**
469 - * @param \WP_Post $post
470 - * @param $metabox
471 - */
472 - public function metabox_our_other_plugins(\WP_Post $post, $metabox)
473 - {
474 - include __DIR__ . '/views/metaboxes/our-other-plugins.php';
475 - }
476 -
477 - /**
478 - * @param \WP_Post $post
479 - * @param $metabox
480 - */
481 - public function metabox_support(\WP_Post $post, $metabox)
482 - {
483 - include __DIR__ . '/views/metaboxes/need-help.php';
484 - }
485 -
486 -
487 - /**
488 - * Saves box options and rules
489 - *
490 - * @param int $box_id
491 - *
492 - * @return bool
493 - */
494 - public function save_box_options($box_id, $post)
495 - {
496 -
497 - // Only act on our own post type
498 - if ($post->post_type !== 'boxzilla-box') {
499 - return false;
500 - }
501 -
502 - // is this a revision save?
503 - if (wp_is_post_revision($box_id) || ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )) {
504 - return false;
505 - }
506 -
507 - // can user edit this post?
508 - if (! current_user_can('edit_post', $box_id)) {
509 - return false;
510 - }
511 -
512 - // make sure options array is set
513 - if (! isset($_POST['boxzilla_box']) || ! is_array($_POST['boxzilla_box'])) {
514 - return false;
515 - }
516 -
517 - // get new options from $_POST
518 - $opts = $this->sanitize_box_options($_POST['boxzilla_box']);
519 -
520 - // allow extensions to filter the saved options
521 - $opts = apply_filters('boxzilla_saved_options', $opts, $box_id);
522 -
523 - // save individual box settings
524 - update_post_meta($box_id, 'boxzilla_options', $opts);
525 -
526 - // update global settings if given
527 - if (! empty($_POST['boxzilla_global_settings'])) {
528 - $global_settings = get_option('boxzilla_settings', []);
529 - if (! is_array($global_settings)) {
530 - $global_settings = [];
531 - }
532 - $global_settings = array_merge($global_settings, $_POST['boxzilla_global_settings']);
533 - update_option('boxzilla_settings', $global_settings);
534 - }
535 -
536 - $this->flush_rules($box_id);
537 -
538 - return true;
539 - }
540 -
541 - /**
542 - * @param array $opts
543 - *
544 - * @return array
545 - */
546 - public function sanitize_settings($opts)
547 - {
548 - return $opts;
549 - }
550 -
551 - /**
552 - * @param string $url_string
553 - *
554 - * @return string
555 - */
556 - public function sanitize_url($url_string)
557 - {
558 -
559 - // if empty, just return a slash
560 - if (empty($url_string)) {
561 - return '/';
562 - }
563 -
564 - // if string looks like an absolute URL, extract just the path
565 - if (preg_match('/^((https|http)?\:\/\/)?(\w+\.)?\w+\.\w+\.*/i', $url_string)) {
566 - // make sure URL has scheme prepended, to make parse_url() understand..
567 - $url_string = 'https://' . str_replace([ 'http://', 'https://' ], '', $url_string);
568 -
569 - // get just the path
570 - $url_string = parse_url($url_string, PHP_URL_PATH);
571 - }
572 -
573 - // leading slash it
574 - return $url_string;
575 - }
576 -
577 - /**
578 - * @param array $rule
579 - * @return array The sanitized rule array
580 - */
581 - public function sanitize_box_rule($rule)
582 - {
583 - $rule['value'] = trim($rule['value']);
584 -
585 - // convert to array
586 - $rule['value'] = explode(',', trim($rule['value'], ','));
587 -
588 - // trim all whitespace in value field
589 - $rule['value'] = array_map('trim', $rule['value']);
590 -
591 - // Make sure "is_url" values have a leading slash
592 - if ($rule['condition'] === 'is_url') {
593 - $rule['value'] = array_map([ $this, 'sanitize_url' ], $rule['value']);
594 - }
595 -
596 - // (re)set value to 0 when condition is everywhere
597 - if ($rule['condition'] === 'everywhere') {
598 - $rule['value'] = '';
599 - }
600 -
601 - // convert back to string before saving
602 - if (is_array($rule['value'])) {
603 - $rule['value'] = join(',', $rule['value']);
604 - }
605 -
606 - return $rule;
607 - }
608 -
609 - /**
610 - * @param array $css
611 - * @return array
612 - */
613 - public function sanitize_box_css($css)
614 - {
615 -
616 - // sanitize settings
617 - if ('' !== $css['width']) {
618 - $css['width'] = absint($css['width']);
619 - }
620 -
621 - if ('' !== $css['border_width']) {
622 - $css['border_width'] = absint($css['border_width']);
623 - }
624 -
625 - // make sure colors start with `#`
626 - $color_keys = [ 'color', 'background_color', 'border_color' ];
627 - foreach ($color_keys as $key) {
628 - $value = $css[ $key ];
629 - $color = sanitize_text_field($value);
630 -
631 - // make sure color starts with `#`
632 - if ('' !== $color && $color[0] !== '#') {
633 - $color = '#' . $color;
634 - }
635 - $css[ $key ] = $color;
636 - }
637 -
638 - return $css;
639 - }
640 -
641 - /**
642 - * Sanitize the options for this box.
643 - *
644 - * @param array $opts
645 - *
646 - * @return array
647 - */
648 - protected function sanitize_box_options($opts)
649 - {
650 - $defaults = [
651 - 'rules' => [],
652 - 'css' => [],
653 - ];
654 -
655 - $opts = array_replace_recursive($defaults, $opts);
656 -
657 - $opts['rules'] = array_map([ $this, 'sanitize_box_rule' ], $opts['rules']);
658 - $opts['css'] = $this->sanitize_box_css($opts['css']);
659 - $opts['cookie']['triggered'] = absint($opts['cookie']['triggered']);
660 - $opts['cookie']['dismissed'] = absint($opts['cookie']['dismissed']);
661 - $opts['trigger'] = sanitize_text_field($opts['trigger']);
662 - $opts['trigger_percentage'] = absint($opts['trigger_percentage']);
663 - $opts['trigger_element'] = sanitize_text_field($opts['trigger_element']);
664 - $opts['screen_size_condition']['value'] = intval($opts['screen_size_condition']['value']);
665 -
666 - return $opts;
667 - }
668 -
669 - /**
670 - * Add the settings link to the Plugins overview
671 - *
672 - * @param array $links
673 - * @param string $slug
674 - *
675 - * @return array
676 - */
677 - public function add_plugin_settings_link($links, $slug)
678 - {
679 - if ($slug !== $this->plugin->slug() || ! is_array($links)) {
680 - return $links;
681 - }
682 -
683 - $href = admin_url('edit.php?post_type=boxzilla-box');
684 - $label = esc_html__('Boxes', 'boxzilla');
685 - $settings_link = "<a href=\"{$href}\">{$label}</a>";
686 - array_unshift($links, $settings_link);
687 - return $links;
688 - }
689 -
690 - /**
691 - * Adds meta links to the plugin in the WP Admin > Plugins screen
692 - *
693 - * @param array $links
694 - * @param string $slug
695 - *
696 - * @return array
697 - */
698 - public function add_plugin_meta_links($links, $slug)
699 - {
700 - if ($slug !== $this->plugin->slug()) {
701 - return $links;
702 - }
703 -
704 - $links[] = '<a href="https://kb.boxzillaplugin.com/">Documentation</a>';
705 - $links[] = '<a href="https://boxzillaplugin.com/add-ons/">Add-ons</a>';
706 -
707 - return $links;
708 - }
709 -
710 - /**
711 - * Flush all box rules
712 - *
713 - * Loops through all published boxes and fills the rules option
714 - *
715 - * @param int $post_id
716 - */
717 - public function flush_rules($post_id)
718 - {
719 -
720 - // only act on our own post type
721 - $post = get_post($post_id);
722 - if (! $post instanceof WP_Post || $post->post_type !== 'boxzilla-box') {
723 - return;
724 - }
725 -
726 - // get all published boxes
727 - $query = new \WP_Query();
728 - $boxes = $query->query(
729 - [
730 - 'post_type' => 'boxzilla-box',
731 - 'post_status' => 'publish',
732 - 'posts_per_page' => - 1,
733 - 'ignore_sticky_posts' => true,
734 - 'no_found_rows' => true,
735 - ]
736 - );
737 -
738 - // setup empty array of rules
739 - $rules = [];
740 -
741 - // fill rules array
742 - if (is_array($boxes)) {
743 - foreach ($boxes as $box) {
744 - // get box meta data
745 - $box_meta = get_post_meta($box->ID, 'boxzilla_options', true);
746 -
747 - // add box rules to all rules
748 - $rules[ $box->ID ] = (array) $box_meta['rules'];
749 - $rules[ $box->ID ]['comparision'] = isset($box_meta['rules_comparision']) ? $box_meta['rules_comparision'] : 'any';
750 - }
751 - }
752 -
753 - update_option('boxzilla_rules', $rules);
754 - }
755 -
756 - /**
757 - * Fetches a list of available add-on plugins
758 - *
759 - * @return array
760 - */
761 - protected function fetch_extensions()
762 - {
763 - $extensions = get_transient('boxzilla_remote_extensions');
764 - if ($extensions) {
765 - return $extensions;
766 - }
767 -
768 - $response = wp_remote_get('https://my.boxzillaplugin.com/api/v2/plugins');
769 - if (is_wp_error($response) || wp_remote_retrieve_response_code($response) >= 400) {
770 - return [];
771 - }
772 -
773 - $body = wp_remote_retrieve_body($response);
774 - $data = json_decode($body);
775 - if (is_array($data)) {
776 - set_transient('boxzilla_remote_extensions', $data, 24 * HOUR_IN_SECONDS);
777 - return $data;
778 - }
779 -
780 - return [];
781 - }
782 -
783 - /**
784 - * @param $arr
785 - * @param $insert
786 - * @param $position
787 - *
788 - * @return array
789 - */
790 - public static function array_insert($arr, $insert, $position)
791 - {
792 - $i = 0;
793 - $ret = [];
794 - foreach ($arr as $key => $value) {
795 - if ($i == $position) {
796 - foreach ($insert as $ikey => $ivalue) {
797 - $ret[ $ikey ] = $ivalue;
798 - }
799 - }
800 - $ret[ $key ] = $value;
801 - $i++;
802 - }
803 -
804 - return $ret;
805 - }
806 -
807 - /**
808 - * @param string $text
809 - *
810 - * @return string
811 - */
812 - public function admin_footer_text($text)
813 - {
814 - $screen = get_current_screen();
815 -
816 - if (! $screen instanceof WP_Screen) {
817 - return $text;
818 - }
819 -
820 - $on_edit_page = $screen->parent_base === 'edit' && $screen->post_type === 'boxzilla-box';
821 - if ($on_edit_page) {
822 - return sprintf('If you enjoy using <strong>Boxzilla</strong>, please <a href="%s" target="_blank">leave us a ★★★★★ rating</a>. A <strong style="text-decoration: underline;">huge</strong> thank you in advance!', 'https://wordpress.org/support/view/plugin-reviews/boxzilla?rate=5#postform');
823 - }
824 -
825 - return $text;
826 - }
827 -}
1 +<?php
2 +
3 +namespace Boxzilla\Admin;
4 +
5 +use Boxzilla\Plugin,
6 + Boxzilla\Box,
7 + Boxzilla\Boxzilla;
8 +use WP_Post;
9 +use WP_Screen;
10 +
11 +class Admin {
12 +
13 + /**
14 + * @var Plugin $plugin
15 + */
16 + private $plugin;
17 +
18 + /**
19 + * @var Boxzilla
20 + */
21 + protected $boxzilla;
22 +
23 + /**
24 + * @var ReviewNotice
25 + */
26 + protected $review_notice;
27 +
28 + /**
29 + * @param Plugin $plugin
30 + * @param Boxzilla $boxzilla
31 + */
32 + public function __construct( Plugin $plugin, Boxzilla $boxzilla ) {
33 + $this->plugin = $plugin;
34 + $this->boxzilla = $boxzilla;
35 + $this->review_notice = new ReviewNotice();
36 + }
37 +
38 + /**
39 + * Initialise the all admin related stuff
40 + */
41 + public function init() {
42 +
43 + // Load the plugin textdomain
44 + load_plugin_textdomain( 'boxzilla', null, basename( $this->plugin->dir() ) . '/languages' );
45 +
46 + // action hooks
47 + $this->add_hooks();
48 + $this->run_migrations();
49 + }
50 +
51 + /**
52 + * Add necessary hooks
53 + */
54 + protected function add_hooks() {
55 + add_action( 'admin_init', array( $this, 'lazy_add_hooks' ) );
56 + add_action( 'admin_init', array( $this, 'register' ) );
57 + add_action( 'init', array( $this, 'listen_for_actions' ) );
58 + add_action( 'admin_menu', array( $this, 'menu' ) );
59 + add_action( 'admin_notices', array( $this, 'notices' ) );
60 + add_action( 'save_post_boxzilla-box', array( $this, 'save_box_options' ), 20, 2 );
61 + add_action( 'trashed_post', array( $this, 'flush_rules' ) );
62 + add_action( 'untrashed_post', array( $this, 'flush_rules' ) );
63 +
64 + $this->review_notice->add_hooks();
65 + }
66 +
67 + /**
68 + * Listen for admin actions.
69 + */
70 + public function listen_for_actions() {
71 +
72 + // triggered?
73 + $vars = array_merge( $_POST, $_GET );
74 + if( empty( $vars['_boxzilla_admin_action'] ) ) {
75 + return false;
76 + }
77 +
78 + // authorized?
79 + if( ! current_user_can( 'edit_posts' ) ) {
80 + return false;
81 + }
82 +
83 + // fire action
84 + $action = $vars['_boxzilla_admin_action'];
85 + do_action( 'boxzilla_admin_' . $action );
86 +
87 + return true;
88 + }
89 +
90 + /**
91 + * All logic for admin notices lives here.
92 + */
93 + public function notices() {
94 + global $pagenow,
95 + $current_screen;
96 +
97 + if( ( $pagenow === 'plugins.php' || ( $current_screen && $current_screen->post_type === 'boxzilla-box' ) )
98 + && current_user_can( 'install_plugins' )
99 + && is_plugin_active( 'scroll-triggered-boxes/index.php' ) ) {
100 +
101 + $url = wp_nonce_url( 'plugins.php?action=deactivate&plugin=scroll-triggered-boxes/index.php', 'deactivate-plugin_' . 'scroll-triggered-boxes/index.php' );
102 + ?>
103 + <div class="notice notice-info">
104 + <p><?php printf( __( 'Awesome, you are using Boxzilla! You can now safely <a href="%s">deactivate the Scroll Triggered Boxes plugin</a>.', 'boxzilla' ), $url ); ?></p>
105 + </div>
106 + <?php
107 + }
108 +
109 + }
110 +
111 + /**
112 + * Checks current version against stored version & runs necessary update routines.
113 + *
114 + * @return bool
115 + */
116 + protected function run_migrations() {
117 +
118 + // Only run if db option is at older version than code constant
119 + $previous_version = get_option( 'boxzilla_version', '0' );
120 + $current_version = $this->plugin->version();
121 +
122 + if( version_compare( $current_version, $previous_version, '<=' ) ) {
123 + return false;
124 + }
125 +
126 + $upgrade_routines = new Migrations( $previous_version, $current_version, __DIR__ . '/migrations' );
127 + $upgrade_routines->run();
128 + update_option( 'boxzilla_version', $current_version );
129 + }
130 +
131 + public function lazy_add_hooks() {
132 + global $pagenow;
133 +
134 + add_action( 'admin_enqueue_scripts', array( $this, 'load_assets' ) );
135 + add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
136 + add_filter( 'tiny_mce_before_init', array( $this, 'tinymce_init' ) );
137 + add_filter( 'manage_edit-boxzilla-box_columns', array( $this, 'post_type_column_titles' ) );
138 + add_action( 'manage_boxzilla-box_posts_custom_column', array( $this, 'post_type_column_content' ), 10, 2 );
139 + add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) );
140 +
141 + if ( $pagenow === 'plugins.php' ) {
142 + add_filter( 'plugin_action_links', array( $this, 'add_plugin_settings_link' ), 10, 2 );
143 + add_filter( 'plugin_row_meta', array( $this, 'add_plugin_meta_links' ), 10, 2 );
144 + }
145 + }
146 +
147 + /**
148 + * @param $post_id
149 + */
150 + public function post_type_column_box_id_content( $post_id ) {
151 + echo $post_id;
152 + }
153 +
154 + /**
155 + * @param $column
156 + * @param $post_id
157 + */
158 + public function post_type_column_content( $column, $post_id ) {
159 + if ( method_exists( $this, 'post_type_column_' . $column . '_content' ) ) {
160 + call_user_func( array( $this, 'post_type_column_' . $column . '_content' ), $post_id );
161 + }
162 + }
163 +
164 + /**
165 + * @param $columns
166 + *
167 + * @return mixed
168 + */
169 + public function post_type_column_titles( $columns ) {
170 + $columns = self::array_insert( $columns, array(
171 + 'box_id' => __( 'Box ID', 'boxzilla' )
172 + ), 1 );
173 +
174 + $columns['title'] = __( 'Box Title', 'boxzilla' );
175 +
176 + return $columns;
177 + }
178 +
179 + /**
180 + * Register stuffs
181 + */
182 + public function register() {
183 +
184 + // register settings
185 + register_setting( 'boxzilla_settings', 'boxzilla_settings', array( $this, 'sanitize_settings' ) );
186 +
187 + // register scripts
188 + $pre_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
189 +
190 + wp_register_script( 'boxzilla-admin', $this->plugin->url( '/assets/js/admin-script' . $pre_suffix . '.js' ), array(
191 + 'jquery',
192 + 'wp-util',
193 + 'wp-color-picker',
194 + 'suggest'
195 + ), $this->plugin->version(), true );
196 +
197 + // load stylesheets
198 + wp_register_style( 'boxzilla-admin', $this->plugin->url( '/assets/css/admin-styles' . $pre_suffix . '.css' ), array(), $this->plugin->version() );
199 + }
200 +
201 + /**
202 + * Renders the STB Menu items
203 + */
204 + public function menu() {
205 +
206 + $menu_items = array(
207 + array(
208 + __( 'Settings', 'boxzilla' ),
209 + __( 'Settings', 'boxzilla' ),
210 + 'boxzilla-settings',
211 + array( $this, 'show_settings_page' )
212 + ),
213 + array(
214 + __( 'Extensions', 'boxzilla' ),
215 + '<span style="color: orange">' . __( 'Extensions', 'boxzilla' ) . '</span>',
216 + 'boxzilla-extensions',
217 + array( $this, 'show_extensions_page' )
218 + )
219 + );
220 +
221 + $menu_items = apply_filters( 'boxzilla_admin_menu_items', $menu_items );
222 +
223 + foreach ( $menu_items as $item ) {
224 + add_submenu_page( 'edit.php?post_type=boxzilla-box', $item[0] . '- Boxzilla', $item[1], 'manage_options', $item[2], $item[3] );
225 + }
226 + }
227 +
228 + /**
229 + * Shows the settings page
230 + */
231 + public function show_settings_page() {
232 + $opts = $this->boxzilla->options;
233 + require __DIR__ . '/views/settings.php';
234 + }
235 +
236 + /**
237 + * Shows the extensions page
238 + */
239 + public function show_extensions_page() {
240 + $extensions = $this->fetch_extensions();
241 + require __DIR__ . '/views/extensions.php';
242 + }
243 +
244 + /**
245 + * Are we currently editing a box?
246 + *
247 + * @return bool
248 + */
249 + protected function on_edit_box_page() {
250 + global $pagenow;
251 +
252 + if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php' ) ) ) {
253 + return false;
254 + }
255 +
256 + if ( isset( $_GET['post_type'] ) && $_GET['post_type'] === 'boxzilla-box' ) {
257 + return true;
258 + }
259 +
260 + if ( get_post_type() === 'boxzilla-box' ) {
261 + return true;
262 + }
263 +
264 + return false;
265 + }
266 +
267 + /**
268 + * @param $args
269 + *
270 + * @return mixed
271 + */
272 + public function tinymce_init( $args ) {
273 +
274 + // only act on our post type
275 + if ( get_post_type() !== 'boxzilla-box' ) {
276 + return $args;
277 + }
278 +
279 + $args['setup'] = 'function( editor ) { if(typeof(window.Boxzilla_Admin) === \'undefined\') { return; } editor.on("PreInit", window.Boxzilla_Admin.Designer.init ); }';
280 +
281 + return $args;
282 + }
283 +
284 + /**
285 + * Load plugin assets
286 + */
287 + public function load_assets() {
288 +
289 + $screen = get_current_screen();
290 +
291 + if ( ! $screen instanceof WP_Screen ) {
292 + return false;
293 + }
294 +
295 + if ( $screen->base === 'edit' && $screen->post_type === 'boxzilla-box' ) {
296 + // load stylesheets
297 + wp_enqueue_style( 'boxzilla-admin' );
298 + }
299 +
300 + if ( $screen->base === 'post' && $screen->post_type === 'boxzilla-box' ) {
301 + // color picker
302 + wp_enqueue_style( 'wp-color-picker' );
303 +
304 + // load scripts
305 + wp_enqueue_script( 'boxzilla-admin' );
306 +
307 + wp_localize_script( 'boxzilla-admin' ,'boxzilla_i18n', array(
308 + 'enterCommaSeparatedValues' => __( 'Enter a comma-separated list of values.', 'boxzilla' ),
309 + 'enterCommaSeparatedPosts' => __( "Enter a comma-separated list of post slugs or post ID's..", 'boxzilla' ),
310 + 'enterCommaSeparatedPages' => __( "Enter a comma-separated list of page slugs or page ID's..", 'boxzilla' ),
311 + 'enterCommaSeparatedPostTypes' => __( "Enter a comma-separated list of post types..", 'boxzilla' ),
312 + 'enterCommaSeparatedRelativeUrls' => __( "Enter a comma-separated list of relative URL's, eg /contact/", 'boxzilla' ),
313 + )
314 + );
315 +
316 + // load stylesheets
317 + wp_enqueue_style( 'boxzilla-admin' );
318 +
319 + // allow add-ons to easily load their own scripts or stylesheets
320 + do_action( 'boxzilla_load_admin_assets' );
321 + }
322 +
323 + if ( isset( $_GET['page'] ) && $_GET['page'] === 'boxzilla-settings' ) {
324 + // load stylesheets
325 + wp_enqueue_style( 'boxzilla-admin' );
326 + }
327 +
328 + }
329 +
330 + /**
331 + * Register meta boxes
332 + *
333 + * @param string $post_type
334 + *
335 + * @return bool
336 + */
337 + public function add_meta_boxes( $post_type ) {
338 +
339 + if ( $post_type !== 'boxzilla-box' ) {
340 + return false;
341 + }
342 +
343 + add_meta_box(
344 + 'boxzilla-box-appearance-controls',
345 + __( 'Box Appearance', 'boxzilla' ),
346 + array( $this, 'metabox_box_appearance_controls' ),
347 + 'boxzilla-box',
348 + 'normal',
349 + 'core'
350 + );
351 +
352 + add_meta_box(
353 + 'boxzilla-box-options-controls',
354 + __( 'Box Options', 'boxzilla' ),
355 + array( $this, 'metabox_box_option_controls' ),
356 + 'boxzilla-box',
357 + 'normal',
358 + 'core'
359 + );
360 +
361 + add_meta_box(
362 + 'boxzilla-support',
363 + __( 'Looking for help?', 'boxzilla' ),
364 + array( $this, 'metabox_support' ),
365 + 'boxzilla-box',
366 + 'side'
367 + );
368 +
369 + add_meta_box(
370 + 'boxzilla-email-optin',
371 + __( 'Subscribe to our newsletter', 'boxzilla' ),
372 + array( $this, 'metabox_email_optin' ),
373 + 'boxzilla-box',
374 + 'side'
375 + );
376 +
377 + return true;
378 + }
379 +
380 + /**
381 + * @param \WP_Post $post
382 + * @param $metabox
383 + */
384 + public function metabox_box_appearance_controls( \WP_Post $post, $metabox ) {
385 +
386 + // get box options
387 + $box = new Box( $post );
388 + $opts = $box->get_options();
389 +
390 + // include view
391 + include __DIR__ . '/views/metaboxes/box-appearance-controls.php';
392 + }
393 +
394 + /**
395 + * @param \WP_Post $post
396 + * @param $metabox
397 + */
398 + public function metabox_box_option_controls( \WP_Post $post, $metabox ) {
399 +
400 + // get box options
401 + $box = new Box( $post );
402 + $opts = $box->get_options();
403 + $global_opts = $this->boxzilla->options;
404 +
405 + if ( empty( $opts['rules'] ) ) {
406 + $opts['rules'][] = array( 'condition' => '', 'qualifier' => 1, 'value' => '' );
407 + }
408 +
409 + // include view
410 + include __DIR__ . '/views/metaboxes/box-option-controls.php';
411 + }
412 +
413 + /**
414 + * @param \WP_Post $post
415 + * @param $metabox
416 + */
417 + public function metabox_email_optin( \WP_Post $post, $metabox ) {
418 + include __DIR__ . '/views/metaboxes/email-optin.php';
419 + }
420 +
421 + /**
422 + * @param \WP_Post $post
423 + * @param $metabox
424 + */
425 + public function metabox_support( \WP_Post $post, $metabox ) {
426 + include __DIR__ . '/views/metaboxes/need-help.php';
427 + }
428 +
429 +
430 + /**
431 + * Saves box options and rules
432 + *
433 + * @param int $box_id
434 + *
435 + * @return bool
436 + */
437 + public function save_box_options( $box_id, $post ) {
438 +
439 + // Only act on our own post type
440 + if ( $post->post_type !== 'boxzilla-box' ) {
441 + return false;
442 + }
443 +
444 + // is this a revision save?
445 + if ( wp_is_post_revision( $box_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
446 + return false;
447 + }
448 +
449 + // can user edit this post?
450 + if ( ! current_user_can( 'edit_post', $box_id ) ) {
451 + return false;
452 + }
453 +
454 + // make sure options array is set
455 + if ( ! isset( $_POST['boxzilla_box'] ) || ! is_array( $_POST['boxzilla_box'] ) ) {
456 + return false;
457 + }
458 +
459 + // get new options from $_POST
460 + $opts = $this->sanitize_box_options( $_POST['boxzilla_box'] );
461 +
462 + // allow extensions to filter the saved options
463 + $opts = apply_filters( 'boxzilla_saved_options', $opts, $box_id );
464 +
465 + // save individual box settings
466 + update_post_meta( $box_id, 'boxzilla_options', $opts );
467 +
468 + // update global settings if given
469 + if( ! empty( $_POST['boxzilla_global_settings'] ) ) {
470 + $global_settings = get_option( 'boxzilla_settings', array() );
471 + if( ! is_array( $global_settings ) ) { $global_settings = array(); }
472 + $global_settings = array_merge( $global_settings, $_POST['boxzilla_global_settings'] );
473 + update_option( 'boxzilla_settings', $global_settings );
474 + }
475 +
476 + $this->flush_rules( $box_id );
477 +
478 + return true;
479 + }
480 +
481 + /**
482 + * @param array $opts
483 + *
484 + * @return array
485 + */
486 + public function sanitize_settings( $opts ) {
487 + return $opts;
488 + }
489 +
490 + /**
491 + * @param string $url_string
492 + *
493 + * @return string
494 + */
495 + public function sanitize_url( $url_string ) {
496 +
497 + // if empty, just return a slash
498 + if( empty( $url_string ) ) {
499 + return '/';
500 + }
501 +
502 + // if string looks like an absolute URL, extract just the path
503 + if( preg_match( '/^((https|http)?\:\/\/)?(\w+\.)?\w+\.\w+\.*/i', $url_string ) ) {
504 +
505 + // make sure URL has scheme prepended, to make parse_url() understand..
506 + $url_string = 'https://' . str_replace( array( 'http://', 'https://' ), '', $url_string );
507 +
508 + // get just the path
509 + $url_string = parse_url( $url_string, PHP_URL_PATH );
510 + }
511 +
512 + // leading slash it
513 + return '/' . ltrim( $url_string, '/' );
514 + }
515 +
516 + /**
517 + * @param array $rule
518 + * @return array The sanitized rule array
519 + */
520 + public function sanitize_box_rule( $rule) {
521 +
522 + $rule['value'] = trim( $rule['value'] );
523 +
524 + // convert to array
525 + $rule['value'] = explode( ',', trim( $rule['value'], ',' ) );
526 +
527 + // trim all whitespace in value field
528 + $rule['value'] = array_map( 'trim', $rule['value'] );
529 +
530 + // Make sure "is_url" values have a leading slash
531 + if ( $rule['condition'] === 'is_url' ) {
532 + $rule['value'] = array_map( array( $this, 'sanitize_url' ), $rule['value'] );
533 + }
534 +
535 + // (re)set value to 0 when condition is everywhere
536 + if ( $rule['condition'] === 'everywhere' ) {
537 + $rule['value'] = '';
538 + }
539 +
540 + // convert back to string before saving
541 + if ( is_array( $rule['value'] ) ) {
542 + $rule['value'] = join( ',', $rule['value'] );
543 + }
544 +
545 + $rule['qualifier'] = isset( $rule['qualifier'] ) && ! $rule['qualifier'] ? 0 : 1;
546 +
547 + return $rule;
548 + }
549 +
550 + /**
551 + * @param array $css
552 + * @return array
553 + */
554 + public function sanitize_box_css( $css ) {
555 +
556 + // sanitize settings
557 + if ( '' !== $css['width'] ) {
558 + $css['width'] = absint( $css['width'] );
559 + }
560 +
561 + if ( '' !== $css['border_width'] ) {
562 + $css['border_width'] = absint( $css['border_width'] );
563 + }
564 +
565 + // make sure colors start with `#`
566 + $color_keys = array( 'color', 'background_color', 'border_color' );
567 + foreach ( $color_keys as $key ) {
568 + $value = $css[ $key ];
569 + $color = sanitize_text_field( $value );
570 +
571 + // make sure color starts with `#`
572 + if ( '' !== $color && $color[0] !== '#' ) {
573 + $color = '#' . $color;
574 + }
575 + $css[ $key ] = $color;
576 + }
577 +
578 + return $css;
579 + }
580 +
581 + /**
582 + * Sanitize the options for this box.
583 + *
584 + * @param array $opts
585 + *
586 + * @return array
587 + */
588 + protected function sanitize_box_options( $opts ) {
589 +
590 + static $defaults = array(
591 + 'rules' => array(),
592 + 'css' => array()
593 + );
594 +
595 + $opts = array_replace_recursive( $defaults, $opts );
596 +
597 + $opts['rules'] = array_map( array( $this, 'sanitize_box_rule' ), $opts['rules'] );
598 + $opts['css'] = $this->sanitize_box_css( $opts['css'] );
599 + $opts['cookie']['triggered'] = absint( $opts['cookie']['triggered'] );
600 + $opts['cookie']['dismissed'] = absint( $opts['cookie']['dismissed'] );
601 + $opts['trigger'] = sanitize_text_field( $opts['trigger'] );
602 + $opts['trigger_percentage'] = absint( $opts['trigger_percentage'] );
603 + $opts['trigger_element'] = sanitize_text_field( $opts['trigger_element'] );
604 +
605 + return $opts;
606 + }
607 +
608 + /**
609 + * Add the settings link to the Plugins overview
610 + *
611 + * @param array $links
612 + * @param string $slug
613 + *
614 + * @return array
615 + */
616 + public function add_plugin_settings_link( $links, $slug ) {
617 + if ( $slug !== $this->plugin->slug() ) {
618 + return $links;
619 + }
620 +
621 + $settings_link = '<a href="' . admin_url( 'edit.php?post_type=boxzilla-box' ) . '">' . __( 'Boxes' ) . '</a>';
622 + array_unshift( $links, $settings_link );
623 +
624 + return $links;
625 + }
626 +
627 + /**
628 + * Adds meta links to the plugin in the WP Admin > Plugins screen
629 + *
630 + * @param array $links
631 + * @param string $slug
632 + *
633 + * @return array
634 + */
635 + public function add_plugin_meta_links( $links, $slug ) {
636 + if ( $slug !== $this->plugin->slug() ) {
637 + return $links;
638 + }
639 +
640 + $links[] = '<a href="https://kb.boxzillaplugin.com/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Documentation</a>';
641 + $links[] = '<a href="https://boxzillaplugin.com/add-ons/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Add-ons</a>';
642 +
643 + return $links;
644 + }
645 +
646 + /**
647 + * Flush all box rules
648 + *
649 + * Loops through all published boxes and fills the rules option
650 + *
651 + * @param int $post_id
652 + */
653 + public function flush_rules( $post_id ) {
654 +
655 + // only act on our own post type
656 + $post = get_post( $post_id );
657 + if ( $post instanceof WP_Post && $post->post_type !== 'boxzilla-box' ) {
658 + return;
659 + }
660 +
661 + // get all published boxes
662 + $boxes = get_posts(
663 + array(
664 + 'post_type' => 'boxzilla-box',
665 + 'post_status' => 'publish',
666 + 'numberposts' => - 1
667 + )
668 + );
669 +
670 + // setup empty array of rules
671 + $rules = array();
672 +
673 + // fill rules array
674 + if ( is_array( $boxes ) ) {
675 +
676 + foreach ( $boxes as $box ) {
677 + // get box meta data
678 + $box_meta = get_post_meta( $box->ID, 'boxzilla_options', true );
679 +
680 + // add box rules to all rules
681 + $rules[ $box->ID ] = $box_meta['rules'];
682 + $rules[ $box->ID ]['comparision'] = isset( $box_meta['rules_comparision'] ) ? $box_meta['rules_comparision'] : 'any';
683 +
684 + }
685 +
686 + }
687 +
688 + update_option( 'boxzilla_rules', $rules );
689 + }
690 +
691 + /**
692 + * Fetches a list of available add-on plugins
693 + *
694 + * @return array
695 + */
696 + protected function fetch_extensions() {
697 +
698 + $extensions = get_transient( 'boxzilla_remote_extensions' );
699 + if ( $extensions ) {
700 + return $extensions;
701 + }
702 +
703 + $request = wp_remote_get( 'https://api.boxzillaplugin.com/v1/plugins' );
704 +
705 + if ( is_wp_error( $request ) ) {
706 + return array();
707 + }
708 +
709 + $response = wp_remote_retrieve_body( $request );
710 + $response = json_decode( $response );
711 +
712 + if ( is_array( $response->data ) ) {
713 + set_transient( 'boxzilla_remote_extensions', $response->data, HOUR_IN_SECONDS );
714 +
715 + return $response->data;
716 + }
717 +
718 + return array();
719 + }
720 +
721 + /**
722 + * @param $arr
723 + * @param $insert
724 + * @param $position
725 + *
726 + * @return array
727 + */
728 + public static function array_insert( $arr, $insert, $position ) {
729 + $i = 0;
730 + $ret = array();
731 + foreach ( $arr as $key => $value ) {
732 + if ( $i == $position ) {
733 + foreach ( $insert as $ikey => $ivalue ) {
734 + $ret[ $ikey ] = $ivalue;
735 + }
736 + }
737 + $ret[ $key ] = $value;
738 + $i ++;
739 + }
740 +
741 + return $ret;
742 + }
743 +
744 + /**
745 + * @param string $text
746 + *
747 + * @return string
748 + */
749 + public function admin_footer_text( $text ) {
750 + $screen = get_current_screen();
751 +
752 + if ( ! $screen instanceof WP_Screen ) {
753 + return $text;
754 + }
755 +
756 + $on_edit_page = $screen->parent_base === 'edit' && $screen->post_type === 'boxzilla-box';
757 + if ( $on_edit_page ) {
758 + return sprintf( 'If you enjoy using <strong>Boxzilla</strong>, please <a href="%s" target="_blank">leave us a ★★★★★ rating</a>. A <strong style="text-decoration: underline;">huge</strong> thank you in advance!', 'https://wordpress.org/support/view/plugin-reviews/boxzilla?rate=5#postform' );
759 + }
760 +
761 + return $text;
762 + }
763 +
764 +}