PluginProbe
Boxzilla – WordPress Popup Builder / 3.1.15
Boxzilla – WordPress Popup Builder v3.1.15
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.1.15, at src/admin/class-admin.php

770 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 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 $opts['screen_size_condition']['value'] = intval( $opts['screen_size_condition']['value'] );
605
606 return $opts;
607 }
608
609 /**
610 * Add the settings link to the Plugins overview
611 *
612 * @param array $links
613 * @param string $slug
614 *
615 * @return array
616 */
617 public function add_plugin_settings_link( $links, $slug ) {
618 if ( $slug !== $this->plugin->slug() ) {
619 return $links;
620 }
621
622 $settings_link = '<a href="' . admin_url( 'edit.php?post_type=boxzilla-box' ) . '">' . __( 'Boxes' ) . '</a>';
623 array_unshift( $links, $settings_link );
624
625 return $links;
626 }
627
628 /**
629 * Adds meta links to the plugin in the WP Admin > Plugins screen
630 *
631 * @param array $links
632 * @param string $slug
633 *
634 * @return array
635 */
636 public function add_plugin_meta_links( $links, $slug ) {
637 if ( $slug !== $this->plugin->slug() ) {
638 return $links;
639 }
640
641 $links[] = '<a href="https://kb.boxzillaplugin.com/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Documentation</a>';
642 $links[] = '<a href="https://boxzillaplugin.com/add-ons/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Add-ons</a>';
643
644 return $links;
645 }
646
647 /**
648 * Flush all box rules
649 *
650 * Loops through all published boxes and fills the rules option
651 *
652 * @param int $post_id
653 */
654 public function flush_rules( $post_id ) {
655
656 // only act on our own post type
657 $post = get_post( $post_id );
658 if ( $post instanceof WP_Post && $post->post_type !== 'boxzilla-box' ) {
659 return;
660 }
661
662 // get all published boxes
663 $boxes = get_posts(
664 array(
665 'post_type' => 'boxzilla-box',
666 'post_status' => 'publish',
667 'numberposts' => - 1
668 )
669 );
670
671 // setup empty array of rules
672 $rules = array();
673
674 // fill rules array
675 if ( is_array( $boxes ) ) {
676
677 foreach ( $boxes as $box ) {
678 // get box meta data
679 $box_meta = get_post_meta( $box->ID, 'boxzilla_options', true );
680
681 // add box rules to all rules
682 $rules[ $box->ID ] = $box_meta['rules'];
683 $rules[ $box->ID ]['comparision'] = isset( $box_meta['rules_comparision'] ) ? $box_meta['rules_comparision'] : 'any';
684
685 }
686
687 }
688
689 update_option( 'boxzilla_rules', $rules );
690 }
691
692 /**
693 * Fetches a list of available add-on plugins
694 *
695 * @return array
696 */
697 protected function fetch_extensions() {
698
699 $extensions = get_transient( 'boxzilla_remote_extensions' );
700 if ( $extensions ) {
701 return $extensions;
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 �
759
760
761
762
763 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' );
764 }
765
766 return $text;
767 }
768
769 }
770