PluginProbe
Boxzilla – WordPress Popup Builder / 3.2
Boxzilla – WordPress Popup Builder v3.2
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
boxzilla / src / admin / class-admin.php

class-admin.php in Boxzilla – WordPress Popup Builder 3.2, at src/admin/class-admin.php

769 lines 19.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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 $method_name = 'post_type_column_' . $column . '_content';
160 if ( method_exists( $this, $method_name ) ) {
161 call_user_func( array( $this, $method_name ), $post_id );
162 }
163 }
164
165 /**
166 * @param $columns
167 *
168 * @return mixed
169 */
170 public function post_type_column_titles( $columns ) {
171 $columns = self::array_insert( $columns, array(
172 'box_id' => __( 'Box ID', 'boxzilla' )
173 ), 1 );
174
175 $columns['title'] = __( 'Box Title', 'boxzilla' );
176
177 return $columns;
178 }
179
180 /**
181 * Register stuffs
182 */
183 public function register() {
184
185 // register settings
186 register_setting( 'boxzilla_settings', 'boxzilla_settings', array( $this, 'sanitize_settings' ) );
187
188 // register scripts
189 $pre_suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
190
191 wp_register_script( 'boxzilla-admin', $this->plugin->url( '/assets/js/admin-script' . $pre_suffix . '.js' ), array(
192 'jquery',
193 'wp-util',
194 'wp-color-picker',
195 'suggest'
196 ), $this->plugin->version(), true );
197
198 // load stylesheets
199 wp_register_style( 'boxzilla-admin', $this->plugin->url( '/assets/css/admin-styles' . $pre_suffix . '.css' ), array(), $this->plugin->version() );
200 }
201
202 /**
203 * Renders the STB Menu items
204 */
205 public function menu() {
206
207 $menu_items = array(
208 array(
209 __( 'Settings', 'boxzilla' ),
210 __( 'Settings', 'boxzilla' ),
211 'boxzilla-settings',
212 array( $this, 'show_settings_page' )
213 ),
214 array(
215 __( 'Extensions', 'boxzilla' ),
216 '<span style="color: orange">' . __( 'Extensions', 'boxzilla' ) . '</span>',
217 'boxzilla-extensions',
218 array( $this, 'show_extensions_page' )
219 )
220 );
221
222 $menu_items = apply_filters( 'boxzilla_admin_menu_items', $menu_items );
223
224 foreach ( $menu_items as $item ) {
225 add_submenu_page( 'edit.php?post_type=boxzilla-box', $item[0] . '- Boxzilla', $item[1], 'manage_options', $item[2], $item[3] );
226 }
227 }
228
229 /**
230 * Shows the settings page
231 */
232 public function show_settings_page() {
233 $opts = $this->boxzilla->options;
234 require __DIR__ . '/views/settings.php';
235 }
236
237 /**
238 * Shows the extensions page
239 */
240 public function show_extensions_page() {
241 $extensions = $this->fetch_extensions();
242 require __DIR__ . '/views/extensions.php';
243 }
244
245 /**
246 * Are we currently editing a box?
247 *
248 * @return bool
249 */
250 protected function on_edit_box_page() {
251 global $pagenow;
252
253 if ( ! in_array( $pagenow, array( 'post-new.php', 'post.php' ) ) ) {
254 return false;
255 }
256
257 if ( isset( $_GET['post_type'] ) && $_GET['post_type'] === 'boxzilla-box' ) {
258 return true;
259 }
260
261 if ( get_post_type() === 'boxzilla-box' ) {
262 return true;
263 }
264
265 return false;
266 }
267
268 /**
269 * @param $args
270 *
271 * @return mixed
272 */
273 public function tinymce_init( $args ) {
274
275 // only act on our post type
276 if ( get_post_type() !== 'boxzilla-box' ) {
277 return $args;
278 }
279
280 $args['setup'] = 'function( editor ) { if(typeof(window.Boxzilla_Admin) === \'undefined\') { return; } editor.on("PreInit", window.Boxzilla_Admin.Designer.init ); }';
281
282 return $args;
283 }
284
285 /**
286 * Load plugin assets
287 */
288 public function load_assets() {
289
290 $screen = get_current_screen();
291
292 if ( ! $screen instanceof WP_Screen ) {
293 return false;
294 }
295
296 if ( $screen->base === 'edit' && $screen->post_type === 'boxzilla-box' ) {
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 $data = 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 wp_localize_script( 'boxzilla-admin' ,'boxzilla_i18n', $data );
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 wp_enqueue_style( 'boxzilla-admin' );
325 }
326
327 }
328
329 /**
330 * Register meta boxes
331 *
332 * @param string $post_type
333 *
334 * @return bool
335 */
336 public function add_meta_boxes( $post_type ) {
337
338 if ( $post_type !== 'boxzilla-box' ) {
339 return false;
340 }
341
342 add_meta_box(
343 'boxzilla-box-appearance-controls',
344 __( 'Box Appearance', 'boxzilla' ),
345 array( $this, 'metabox_box_appearance_controls' ),
346 'boxzilla-box',
347 'normal',
348 'core'
349 );
350
351 add_meta_box(
352 'boxzilla-box-options-controls',
353 __( 'Box Options', 'boxzilla' ),
354 array( $this, 'metabox_box_option_controls' ),
355 'boxzilla-box',
356 'normal',
357 'core'
358 );
359
360 add_meta_box(
361 'boxzilla-support',
362 __( 'Looking for help?', 'boxzilla' ),
363 array( $this, 'metabox_support' ),
364 'boxzilla-box',
365 'side'
366 );
367
368 add_meta_box(
369 'boxzilla-email-optin',
370 __( 'Subscribe to our newsletter', 'boxzilla' ),
371 array( $this, 'metabox_email_optin' ),
372 'boxzilla-box',
373 'side'
374 );
375
376 return true;
377 }
378
379 /**
380 * @param \WP_Post $post
381 * @param $metabox
382 */
383 public function metabox_box_appearance_controls( \WP_Post $post, $metabox ) {
384
385 // get box options
386 $box = new Box( $post );
387 $opts = $box->get_options();
388
389 // include view
390 include __DIR__ . '/views/metaboxes/box-appearance-controls.php';
391 }
392
393 /**
394 * @param \WP_Post $post
395 * @param $metabox
396 */
397 public function metabox_box_option_controls( \WP_Post $post, $metabox ) {
398
399 // get box options
400 $box = new Box( $post );
401 $opts = $box->get_options();
402 $global_opts = $this->boxzilla->options;
403
404 if ( empty( $opts['rules'] ) ) {
405 $opts['rules'][] = array( 'condition' => '', 'qualifier' => 1, 'value' => '' );
406 }
407
408 // include view
409 include __DIR__ . '/views/metaboxes/box-option-controls.php';
410 }
411
412 /**
413 * @param \WP_Post $post
414 * @param $metabox
415 */
416 public function metabox_email_optin( \WP_Post $post, $metabox ) {
417 include __DIR__ . '/views/metaboxes/email-optin.php';
418 }
419
420 /**
421 * @param \WP_Post $post
422 * @param $metabox
423 */
424 public function metabox_support( \WP_Post $post, $metabox ) {
425 include __DIR__ . '/views/metaboxes/need-help.php';
426 }
427
428
429 /**
430 * Saves box options and rules
431 *
432 * @param int $box_id
433 *
434 * @return bool
435 */
436 public function save_box_options( $box_id, $post ) {
437
438 // Only act on our own post type
439 if ( $post->post_type !== 'boxzilla-box' ) {
440 return false;
441 }
442
443 // is this a revision save?
444 if ( wp_is_post_revision( $box_id ) || ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ) {
445 return false;
446 }
447
448 // can user edit this post?
449 if ( ! current_user_can( 'edit_post', $box_id ) ) {
450 return false;
451 }
452
453 // make sure options array is set
454 if ( ! isset( $_POST['boxzilla_box'] ) || ! is_array( $_POST['boxzilla_box'] ) ) {
455 return false;
456 }
457
458 // get new options from $_POST
459 $opts = $this->sanitize_box_options( $_POST['boxzilla_box'] );
460
461 // allow extensions to filter the saved options
462 $opts = apply_filters( 'boxzilla_saved_options', $opts, $box_id );
463
464 // save individual box settings
465 update_post_meta( $box_id, 'boxzilla_options', $opts );
466
467 // update global settings if given
468 if( ! empty( $_POST['boxzilla_global_settings'] ) ) {
469 $global_settings = get_option( 'boxzilla_settings', array() );
470 if( ! is_array( $global_settings ) ) { $global_settings = array(); }
471 $global_settings = array_merge( $global_settings, $_POST['boxzilla_global_settings'] );
472 update_option( 'boxzilla_settings', $global_settings );
473 }
474
475 $this->flush_rules( $box_id );
476
477 return true;
478 }
479
480 /**
481 * @param array $opts
482 *
483 * @return array
484 */
485 public function sanitize_settings( $opts ) {
486 return $opts;
487 }
488
489 /**
490 * @param string $url_string
491 *
492 * @return string
493 */
494 public function sanitize_url( $url_string ) {
495
496 // if empty, just return a slash
497 if( empty( $url_string ) ) {
498 return '/';
499 }
500
501 // if string looks like an absolute URL, extract just the path
502 if( preg_match( '/^((https|http)?\:\/\/)?(\w+\.)?\w+\.\w+\.*/i', $url_string ) ) {
503
504 // make sure URL has scheme prepended, to make parse_url() understand..
505 $url_string = 'https://' . str_replace( array( 'http://', 'https://' ), '', $url_string );
506
507 // get just the path
508 $url_string = parse_url( $url_string, PHP_URL_PATH );
509 }
510
511 // leading slash it
512 return '/' . ltrim( $url_string, '/' );
513 }
514
515 /**
516 * @param array $rule
517 * @return array The sanitized rule array
518 */
519 public function sanitize_box_rule( $rule) {
520
521 $rule['value'] = trim( $rule['value'] );
522
523 // convert to array
524 $rule['value'] = explode( ',', trim( $rule['value'], ',' ) );
525
526 // trim all whitespace in value field
527 $rule['value'] = array_map( 'trim', $rule['value'] );
528
529 // Make sure "is_url" values have a leading slash
530 if ( $rule['condition'] === 'is_url' ) {
531 $rule['value'] = array_map( array( $this, 'sanitize_url' ), $rule['value'] );
532 }
533
534 // (re)set value to 0 when condition is everywhere
535 if ( $rule['condition'] === 'everywhere' ) {
536 $rule['value'] = '';
537 }
538
539 // convert back to string before saving
540 if ( is_array( $rule['value'] ) ) {
541 $rule['value'] = join( ',', $rule['value'] );
542 }
543
544 $rule['qualifier'] = isset( $rule['qualifier'] ) && ! $rule['qualifier'] ? 0 : 1;
545
546 return $rule;
547 }
548
549 /**
550 * @param array $css
551 * @return array
552 */
553 public function sanitize_box_css( $css ) {
554
555 // sanitize settings
556 if ( '' !== $css['width'] ) {
557 $css['width'] = absint( $css['width'] );
558 }
559
560 if ( '' !== $css['border_width'] ) {
561 $css['border_width'] = absint( $css['border_width'] );
562 }
563
564 // make sure colors start with `#`
565 $color_keys = array( 'color', 'background_color', 'border_color' );
566 foreach ( $color_keys as $key ) {
567 $value = $css[ $key ];
568 $color = sanitize_text_field( $value );
569
570 // make sure color starts with `#`
571 if ( '' !== $color && $color[0] !== '#' ) {
572 $color = '#' . $color;
573 }
574 $css[ $key ] = $color;
575 }
576
577 return $css;
578 }
579
580 /**
581 * Sanitize the options for this box.
582 *
583 * @param array $opts
584 *
585 * @return array
586 */
587 protected function sanitize_box_options( $opts ) {
588
589 static $defaults = array(
590 'rules' => array(),
591 'css' => array()
592 );
593
594 $opts = array_replace_recursive( $defaults, $opts );
595
596 $opts['rules'] = array_map( array( $this, 'sanitize_box_rule' ), $opts['rules'] );
597 $opts['css'] = $this->sanitize_box_css( $opts['css'] );
598 $opts['cookie']['triggered'] = absint( $opts['cookie']['triggered'] );
599 $opts['cookie']['dismissed'] = absint( $opts['cookie']['dismissed'] );
600 $opts['trigger'] = sanitize_text_field( $opts['trigger'] );
601 $opts['trigger_percentage'] = absint( $opts['trigger_percentage'] );
602 $opts['trigger_element'] = sanitize_text_field( $opts['trigger_element'] );
603 $opts['screen_size_condition']['value'] = intval( $opts['screen_size_condition']['value'] );
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() || ! is_array( $links ) ) {
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 $request = wp_remote_get( 'https://api.boxzillaplugin.com/v1/plugins' );
703
704 if ( is_wp_error( $request ) ) {
705 return array();
706 }
707
708 $response = wp_remote_retrieve_body( $request );
709 $response = json_decode( $response );
710
711 if ( is_array( $response->data ) ) {
712 set_transient( 'boxzilla_remote_extensions', $response->data, 24 * HOUR_IN_SECONDS );
713
714 return $response->data;
715 }
716
717 return array();
718 }
719
720 /**
721 * @param $arr
722 * @param $insert
723 * @param $position
724 *
725 * @return array
726 */
727 public static function array_insert( $arr, $insert, $position ) {
728 $i = 0;
729 $ret = array();
730 foreach ( $arr as $key => $value ) {
731 if ( $i == $position ) {
732 foreach ( $insert as $ikey => $ivalue ) {
733 $ret[ $ikey ] = $ivalue;
734 }
735 }
736 $ret[ $key ] = $value;
737 $i ++;
738 }
739
740 return $ret;
741 }
742
743 /**
744 * @param string $text
745 *
746 * @return string
747 */
748 public function admin_footer_text( $text ) {
749 $screen = get_current_screen();
750
751 if ( ! $screen instanceof WP_Screen ) {
752 return $text;
753 }
754
755 $on_edit_page = $screen->parent_base === 'edit' && $screen->post_type === 'boxzilla-box';
756 if ( $on_edit_page ) {
757 return sprintf( 'If you enjoy using <strong>Boxzilla</strong>, please <a href="%s" target="_blank">leave us a �
758
759
760
761
762 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' );
763 }
764
765 return $text;
766 }
767
768 }
769