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

767 lines 19.4 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 $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 return $rule;
545 }
546
547 /**
548 * @param array $css
549 * @return array
550 */
551 public function sanitize_box_css( $css ) {
552
553 // sanitize settings
554 if ( '' !== $css['width'] ) {
555 $css['width'] = absint( $css['width'] );
556 }
557
558 if ( '' !== $css['border_width'] ) {
559 $css['border_width'] = absint( $css['border_width'] );
560 }
561
562 // make sure colors start with `#`
563 $color_keys = array( 'color', 'background_color', 'border_color' );
564 foreach ( $color_keys as $key ) {
565 $value = $css[ $key ];
566 $color = sanitize_text_field( $value );
567
568 // make sure color starts with `#`
569 if ( '' !== $color && $color[0] !== '#' ) {
570 $color = '#' . $color;
571 }
572 $css[ $key ] = $color;
573 }
574
575 return $css;
576 }
577
578 /**
579 * Sanitize the options for this box.
580 *
581 * @param array $opts
582 *
583 * @return array
584 */
585 protected function sanitize_box_options( $opts ) {
586
587 static $defaults = array(
588 'rules' => array(),
589 'css' => array()
590 );
591
592 $opts = array_replace_recursive( $defaults, $opts );
593
594 $opts['rules'] = array_map( array( $this, 'sanitize_box_rule' ), $opts['rules'] );
595 $opts['css'] = $this->sanitize_box_css( $opts['css'] );
596 $opts['cookie']['triggered'] = absint( $opts['cookie']['triggered'] );
597 $opts['cookie']['dismissed'] = absint( $opts['cookie']['dismissed'] );
598 $opts['trigger'] = sanitize_text_field( $opts['trigger'] );
599 $opts['trigger_percentage'] = absint( $opts['trigger_percentage'] );
600 $opts['trigger_element'] = sanitize_text_field( $opts['trigger_element'] );
601 $opts['screen_size_condition']['value'] = intval( $opts['screen_size_condition']['value'] );
602
603 return $opts;
604 }
605
606 /**
607 * Add the settings link to the Plugins overview
608 *
609 * @param array $links
610 * @param string $slug
611 *
612 * @return array
613 */
614 public function add_plugin_settings_link( $links, $slug ) {
615 if ( $slug !== $this->plugin->slug() || ! is_array( $links ) ) {
616 return $links;
617 }
618
619 $settings_link = '<a href="' . admin_url( 'edit.php?post_type=boxzilla-box' ) . '">' . __( 'Boxes' ) . '</a>';
620 array_unshift( $links, $settings_link );
621
622 return $links;
623 }
624
625 /**
626 * Adds meta links to the plugin in the WP Admin > Plugins screen
627 *
628 * @param array $links
629 * @param string $slug
630 *
631 * @return array
632 */
633 public function add_plugin_meta_links( $links, $slug ) {
634 if ( $slug !== $this->plugin->slug() ) {
635 return $links;
636 }
637
638 $links[] = '<a href="https://kb.boxzillaplugin.com/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Documentation</a>';
639 $links[] = '<a href="https://boxzillaplugin.com/add-ons/#utm_source=wp-plugin&utm_medium=boxzilla&utm_campaign=plugins-page">Add-ons</a>';
640
641 return $links;
642 }
643
644 /**
645 * Flush all box rules
646 *
647 * Loops through all published boxes and fills the rules option
648 *
649 * @param int $post_id
650 */
651 public function flush_rules( $post_id ) {
652
653 // only act on our own post type
654 $post = get_post( $post_id );
655 if ( ! $post instanceof WP_Post || $post->post_type !== 'boxzilla-box' ) {
656 return;
657 }
658
659 // get all published boxes
660 $boxes = get_posts(
661 array(
662 'post_type' => 'boxzilla-box',
663 'post_status' => 'publish',
664 'numberposts' => - 1
665 )
666 );
667
668 // setup empty array of rules
669 $rules = array();
670
671 // fill rules array
672 if ( is_array( $boxes ) ) {
673
674 foreach ( $boxes as $box ) {
675 // get box meta data
676 $box_meta = get_post_meta( $box->ID, 'boxzilla_options', true );
677
678 // add box rules to all rules
679 $rules[ $box->ID ] = $box_meta['rules'];
680 $rules[ $box->ID ]['comparision'] = isset( $box_meta['rules_comparision'] ) ? $box_meta['rules_comparision'] : 'any';
681
682 }
683
684 }
685
686 update_option( 'boxzilla_rules', $rules );
687 }
688
689 /**
690 * Fetches a list of available add-on plugins
691 *
692 * @return array
693 */
694 protected function fetch_extensions() {
695
696 $extensions = get_transient( 'boxzilla_remote_extensions' );
697 if ( $extensions ) {
698 return $extensions;
699 }
700 $request = wp_remote_get( 'https://api.boxzillaplugin.com/v1/plugins' );
701
702 if ( is_wp_error( $request ) ) {
703 return array();
704 }
705
706 $response = wp_remote_retrieve_body( $request );
707 $response = json_decode( $response );
708
709 if ( is_array( $response->data ) ) {
710 set_transient( 'boxzilla_remote_extensions', $response->data, 24 * HOUR_IN_SECONDS );
711
712 return $response->data;
713 }
714
715 return array();
716 }
717
718 /**
719 * @param $arr
720 * @param $insert
721 * @param $position
722 *
723 * @return array
724 */
725 public static function array_insert( $arr, $insert, $position ) {
726 $i = 0;
727 $ret = array();
728 foreach ( $arr as $key => $value ) {
729 if ( $i == $position ) {
730 foreach ( $insert as $ikey => $ivalue ) {
731 $ret[ $ikey ] = $ivalue;
732 }
733 }
734 $ret[ $key ] = $value;
735 $i ++;
736 }
737
738 return $ret;
739 }
740
741 /**
742 * @param string $text
743 *
744 * @return string
745 */
746 public function admin_footer_text( $text ) {
747 $screen = get_current_screen();
748
749 if ( ! $screen instanceof WP_Screen ) {
750 return $text;
751 }
752
753 $on_edit_page = $screen->parent_base === 'edit' && $screen->post_type === 'boxzilla-box';
754 if ( $on_edit_page ) {
755 return sprintf( 'If you enjoy using <strong>Boxzilla</strong>, please <a href="%s" target="_blank">leave us a �
756
757
758
759
760 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' );
761 }
762
763 return $text;
764 }
765
766 }
767