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

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