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

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