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