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

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