PluginProbe
Guest Author / 2.6
Guest Author v2.6
2.4 2.5 2.6 2.61 2.62 trunk 2.1.6 2.1.7 2.1.8 2.1.9 2.1.91 2.2 2.3
guest-author / guest-author.php

guest-author.php in Guest Author 2.6, at guest-author.php

1,055 lines 33.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Guest Author class definition
5 *
6 * @package guest-author
7 * @since 1.0
8 */
9
10 if (!class_exists('BS_Guest_Author')) :
11
12 class BS_Guest_Author
13 {
14
15
16 function __construct()
17 {
18
19 /**
20 * This is done this way, because in ajax requests is_admin() returns true from the frontend and backend
21 */
22 if (!is_admin() || (function_exists('wp_doing_ajax') && wp_doing_ajax())) {
23 $this->plugin_front_setup();
24 }
25
26 if (is_admin()) {
27 $this->plugin_admin_setup();
28 }
29 }
30
31 /**
32 * Sets up the plugin on the front site,
33 * by adding the necessary filters and actions.
34 *
35 * @since 1.0
36 *
37 * @return void
38 */
39 public function plugin_front_setup()
40 {
41 add_action('wp_head', array($this, 'simple_front_end_css'));
42 add_filter('body_class', array($this, 'add_body_class'));
43
44 add_action('pre_get_posts', array($this, 'filter_guest_authors'));
45 add_action('the_post', array($this, 'register_authordata'));
46
47 add_filter('the_author', array($this, 'author_name'), 12);
48 add_filter('get_the_author_display_name', array($this, 'author_name'), 12);
49 add_filter('get_the_author_user_nicename', array($this, 'author_name'), 12);
50 add_filter('get_the_author_nickname', array($this, 'author_name'), 12);
51 add_filter('get_the_author_ID', array($this, 'author_ID'), 12);
52 add_filter('author_link', array($this, 'author_link'), 12);
53 add_filter('get_the_author_link', array($this, 'author_link'), 12);
54 add_filter('get_the_author_url', array($this, 'author_link'), 21);
55
56 add_filter('author_description', array($this, 'author_description'), 12);
57 add_filter('get_the_author_description', array($this, 'author_description'), 12);
58
59 add_filter('get_the_author_user_email', array($this, '__return_null_meta'), 12);
60 add_filter('pre_get_avatar_data', array($this, 'pre_get_author_avatar_data'), 12, 2);
61 }
62
63 /**
64 * Sets up the plugin on the dashboard,
65 * by adding the necessary filters and actions.
66 *
67 * @since 1.0
68 * @return void
69 */
70 public function plugin_admin_setup()
71 {
72 add_action('save_post', array($this, 'save'));
73
74 add_action('admin_enqueue_scripts', array($this, 'admin_scripts'));
75 add_action('current_screen', array($this, 'remove_default_author_meta_box'));
76 add_action('add_meta_boxes', array($this, 'add_new_author_box'));
77
78 add_filter('manage_posts_columns', array($this, 'add_author_column'));
79 add_action('manage_posts_custom_column', array($this, 'modify_author_column'), 10, 2);
80
81 // Ajax action to refresh the user image
82 add_action('wp_ajax_BS_get_image', array($this, 'BS_ajax_get_image'));
83 }
84
85 /*
86 * Adds the class 'guest-author' to the body of a post that's using a guest author
87 * */
88 public function add_body_class($classes)
89 {
90 if ($this->is_guest_author_available()) {
91 $classes[] = 'guest-author-' . BS_GUEST_AUTHOR_VERSION;
92 }
93
94 return $classes;
95 }
96
97 /*
98 * Adds the class 'guest-author' to the body of a post that's using a guest author
99 * */
100 public function simple_front_end_css()
101 {
102 if ($this->is_guest_author_available()) {
103 ?>
104 <style type="text/css">
105 body[class^="guest-author"] a[href=''] {
106 pointer-events: none;
107 color: inherit;
108 text-decoration: inherit;
109 }
110 </style>
111 <?php
112 }
113 }
114
115
116 /**
117 * Filters the author query results that are written by a guest author.
118 *
119 *
120 * This is needed because each post has the author ID under post_author.
121 * Therefore, even if the admin user adds a guest author to a post their ID
122 * will still be attached to the post.
123 *
124 * That being said, when a website user clicks on the a registered user's author link,
125 * we don't want to list the posts that have a guest author's name showing in the meta.
126 *
127 * @since 1.0
128 * @return void
129 */
130 public function filter_guest_authors($query)
131 {
132 if (
133 is_author()
134 || $query->is_author
135 || (isset($query->author__in) && count($query->author__in) > 0)
136 || (isset($query->author_name) && !empty($query->author_name))
137 || (isset($query->author) && !empty($query->author))
138 ) {
139 $query->set(
140 'meta_query',
141 array(
142 'relation' => 'OR',
143 array(
144 'key' => "BS_author_type",
145 'value' => 'BS_author_is_guest',
146 'compare' => '!='
147 ),
148 array(
149 'key' => "BS_author_type",
150 'compare' => 'NOT EXISTS'
151 )
152 )
153 );
154 };
155 }
156
157 /**
158 * Removes the default author meta box (surprise!). This is because
159 * we will replace it with an identical box that has a little more to it.
160 *
161 * @since 1.0
162 * @return void
163 */
164 public function remove_default_author_meta_box()
165 {
166 if (BS_is_gutenberg()) return;
167
168 $post_type = $this->get_current_post_type();
169
170 if (!$this->is_eligible_post_type($post_type)) {
171 $post_type = 'post';
172 }
173
174 remove_meta_box('authordiv', $post_type, 'normal');
175 }
176
177 /**
178 * Adds an author meta box that has more to it than the default one.
179 *
180 * @since 1.0
181 * @return void
182 */
183 public function add_new_author_box($post_type)
184 {
185 $post_type = $this->get_current_post_type();
186
187 if (!$this->is_eligible_post_type($post_type)) {
188 $post_type = 'post';
189 }
190
191 $context = (BS_is_gutenberg()) ? 'side' : 'normal';
192
193 add_meta_box('BS_authordiv', __('Author', 'guest-author'), array($this, 'render_meta_box'), $post_type, $context, 'core');
194 }
195
196 /**
197 * Renders the new author meta box
198 *
199 * @since 1.0
200 * @return void
201 */
202 public function render_meta_box()
203 {
204 include_once "templates/meta-box-content.php";
205 }
206
207 /**
208 * Adds the admin scripts and styles
209 *
210 * @since 1.0
211 * @return void
212 */
213 public function admin_scripts($page)
214 {
215 if ($page === 'post.php' || $page === 'post-new.php') {
216 wp_enqueue_style('BS_guest_author_styles', plugins_url('/css/style.css', __FILE__), [], BS_GUEST_AUTHOR_VERSION);
217
218 // Enqueue WordPress media scripts
219 wp_enqueue_media();
220 // Enqueue custom script that will interact with wp.media
221 wp_enqueue_script('BS_guest_author_script', plugins_url('/js/script.js', __FILE__), array('jquery'), BS_GUEST_AUTHOR_VERSION);
222
223 $js_localize = array(
224 'bs_ajax_nonce' => wp_create_nonce('bs_ajax'),
225 );
226 wp_localize_script('BS_guest_author_script', 'bs_guest_author', $js_localize);
227
228 }
229 }
230
231 /**
232 * Renders the new author meta box
233 *
234 * @since 1.0
235 * @return void
236 */
237 public function BS_ajax_get_image()
238 {
239 check_ajax_referer('bs_ajax');
240
241 if(!current_user_can('edit_posts')){
242 wp_send_json_error();
243 }
244
245 if (isset($_GET['id'])) {
246 $image = wp_get_attachment_image(filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT), 'medium', false, array('id' => 'BS-preview-image'));
247 $data = array('image' => $image);
248 wp_send_json_success($data);
249 } else {
250 wp_send_json_error();
251 }
252 }
253
254 /**
255 * Saves the custom meta fields when the post is saved/updated
256 *
257 * @since 1.0
258 * @return void
259 */
260 public function save($post_id)
261 {
262 global $post;
263
264 if ( !isset( $_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'update-post_' . $post_id ) ) {
265 return;
266 }
267
268 $post_type = $this->get_current_post_type();
269 if (!$post || !$this->is_eligible_post_type($post_type)) return;
270
271 if (
272 !isset($_POST['BS_author_type'])
273 || !isset($_POST['BS_guest_author_name'])
274 ) return;
275
276 $meta = [
277 'BS_author_type' => sanitize_text_field(wp_unslash($_POST['BS_author_type'])),
278 'BS_guest_author_name' => sanitize_text_field(wp_unslash($_POST['BS_guest_author_name'])),
279 'BS_guest_author_url' => isset($_POST['BS_guest_author_url']) ? sanitize_url(wp_unslash($_POST['BS_guest_author_url'])) : '',
280 'BS_guest_author_description' => isset($_POST['BS_guest_author_description']) ? sanitize_textarea_field(wp_unslash($_POST['BS_guest_author_description'])) : '',
281 'BS_guest_author_image_id' => isset($_POST['BS_guest_author_image_id']) ? sanitize_key(wp_unslash($_POST['BS_guest_author_image_id'])) : ''
282 ];
283
284 foreach ($meta as $key => $value) {
285 update_post_meta($post_id, $key, $value);
286 }
287 }
288
289 /**
290 * Retrieves the author's ID
291 *
292 * @since 2.2
293 *
294 * @global object $post
295 *
296 * @param string $id This parameter is only needed for when
297 * WordPress uses this function as filter.
298 *
299 * @return string | NULL returns NULL if it's a guest author post
300 *
301 */
302 public function author_ID($id = '')
303 {
304 global $post;
305
306 if ($post AND $this->is_guest_author_available()) {
307 return NULL;
308 }
309
310 return $id;
311 }
312
313 /**
314 * Retrieves the author's name
315 *
316 * @since 1.0
317 *
318 * @global object $post
319 *
320 * @param string $name This parameter is only needed for when
321 * WordPress uses this function as filter.
322 *
323 * @return string The guest author's name if available, otherwise
324 * it will return the original author's name.
325 */
326 public function author_name($name = '')
327 {
328 global $post;
329
330 if ($post) {
331 $guest_name = esc_html(get_post_meta($post->ID, 'BS_guest_author_name', true));
332 if (!$this->is_guest_author_available()) {
333 return $name;
334 }
335 }
336
337 if (isset($guest_name)) return $guest_name;
338
339 return $name;
340 }
341
342
343 /**
344 * Retrieves the author's email
345 *
346 * @since 2.1
347 *
348 * @global object $post
349 *
350 * @param string $info This parameter is only needed for when
351 * WordPress uses this function as filter.
352 *
353 * @return string|NULL .
354 */
355 public function __return_null_meta($info = '')
356 {
357 global $post;
358
359 if ($post && $this->is_guest_author_available()) {
360 return NULL;
361 }
362
363 return $info;
364 }
365
366 /**
367 * Retrieves the author's link
368 *
369 * @since 1.0
370 *
371 * @global object $post
372 *
373 * @param string $link This parameter is only needed for when WordPress
374 * uses this function as filter.
375 *
376 * @return string The guest author's link if the guest author
377 * is available, otherwise it is the original author's link
378 */
379 public function author_link($link = '')
380 {
381 if (!$this->is_guest_author_available()) return $link;
382
383 global $post;
384 return get_post_meta($post->ID, 'BS_guest_author_url', true);
385 }
386
387 /**
388 * Retrieves the author's descriptions
389 *
390 * @since 1.0
391 *
392 * @global object $post
393 *
394 * @param string $desc This parameter is only needed for when WordPress
395 * uses this function as filter.
396 *
397 * @return string The guest author's description if the guest author
398 * is available, otherwise it is the original author's description
399 */
400 public function author_description($desc = "")
401 {
402 global $post;
403
404 if (!$this->is_guest_author_available()) {
405 return $desc;
406 }
407
408 return esc_html(get_post_meta($post->ID, 'BS_guest_author_description', true));
409 }
410
411
412 /**
413 * Retrieves the author's avatar
414 *
415 * @since 1.0
416 *
417 * @global object $post
418 *
419 * @param string $img This parameter is only needed for when WordPress
420 * uses this function as filter.
421 *
422 * @return string The guest author's avatar as an <img> element if the guest author
423 * is available, otherwise it is the original author's avatar
424 */
425 public function author_avatar($img = '')
426 {
427 global $post;
428
429 if (!$this->is_guest_author_available()) {
430 return $img;
431 }
432
433 $image_id = get_post_meta($post->ID, 'BS_guest_author_image_id', true);
434
435 if ($image_id) {
436 return wp_get_attachment_image($image_id, array(100, 100), false);
437 } else {
438 // Default image
439 return "<img src=\"" . plugins_url('/img/default.jpg', __FILE__) . "\">";
440 }
441 }
442
443 /**
444 * Retrieves the author's avatar
445 *
446 * @since 1.9.1
447 *
448 * @global object $post
449 *
450 * @param string $args This parameter is only needed for when WordPress
451 * uses this function as filter.
452 *
453 * @return string The URL of the author image
454 *
455 */
456 public function pre_get_author_avatar_data($args = [], $id_or_email = '')
457 {
458 global $post;
459
460 if (!$post) return $args;
461
462 if (!$this->is_guest_author_available()) {
463 return $args;
464 }
465
466 // This assumes that if the id passed is empty, it means we're trying to get the guest author
467 //
468 // It also assumes that if the author id being fetched is the id of the real post author, then it probably
469 // means that we should replace it with the guest author. This is for developers that use $post->post_author to
470 // call the get_avatar_data() function
471 //
472 if (empty($id_or_email) || ($post && $post->post_author === $id_or_email)) {
473
474 if (isset($args['url'])) {
475 return $args;
476 }
477
478 $image_id = get_post_meta($post->ID, 'BS_guest_author_image_id', true);
479
480 if ($image_id) {
481
482 $img_size = $args['size'];
483
484 if ($args['width'] && $args['height']) {
485 $img_size = [$args['width'], $args['height']];
486 }
487
488 $image = wp_get_attachment_image_src(intval($image_id), $img_size);
489
490 $args['url'] = $image[0];
491 $args['found_avatar'] = true;
492 }
493 }
494
495 return $args;
496 }
497
498 /**
499 * Disables the avatar filter
500 *
501 * @since 1.0
502 *
503 * @return void
504 */
505 public function remove_author_avatar_filter()
506 {
507 remove_filter('get_avatar', array($this, 'author_avatar'));
508 }
509
510 /**
511 * Disables the avatar filter when the comments are rendered. Why?
512 * This kind of a weird measure, but it is needed because if we don't
513 * remove the filter at some point, EVERY avatar in page will have the author's
514 * image. So we figure, in MOST cases the comments will be rendered AFTER the post itself.
515 *
516 * @since 1.0
517 *
518 * @return void
519 */
520 public function remove_author_avatar_filter_at_comments()
521 {
522 $this->remove_author_avatar_filter();
523 }
524
525 /**
526 * Registers the guest author info into the global variable $authordata
527 *
528 * @since 1.2
529 *
530 * @return void
531 */
532 public function register_authordata()
533 {
534 global $authordata;
535 global $post;
536
537 if (!$this->is_guest_author_available()) {
538 return;
539 }
540
541 $guest_author = new WP_User();
542
543 $guest_author->ID = NULL;
544
545 $guest_author->user_url = $this->author_link();
546 $guest_author->user_description = $this->author_description();
547 $guest_author->display_name = $this->author_name();
548 $guest_author->user_nicename = $this->author_name();
549
550 $guest_author->user_login = NULL;
551 $guest_author->user_pass = NULL;
552 $guest_author->user_email = NULL;
553 $guest_author->user_registered = NULL;
554 $guest_author->user_activation_key = NULL;
555 $guest_author->user_status = NULL;
556
557 $authordata = $guest_author;
558 }
559
560 /**
561 * Simply replaces the default author column in the posts list (of the dashboard),
562 * with an identical one. The difference? the posts who have a guest author, will have the
563 * notation ' — Guest Entry' next to the authoring user's name
564 *
565 * @since 1.0
566 *
567 * @return array the new columns array.
568 */
569 public function add_author_column($columns)
570 {
571 $new_columns_array = [];
572
573 foreach ($columns as $key => $value) {
574 if ($key === 'author') {
575 $new_columns_array['author_modified'] = $value;
576 } else {
577 $new_columns_array[$key] = $value;
578 }
579 }
580 return $new_columns_array;
581 }
582 public function modify_author_column($columns)
583 {
584 global $post;
585 switch ($columns) {
586 case 'author_modified':
587 $is_guest_author = $this->is_guest_author_selected();
588 $args = array(
589 'post_type' => $post->post_type,
590 'author' => get_the_author_meta('ID')
591 );
592 $author_text = $this->get_edit_link($args, get_the_author());
593 if ($is_guest_author) {
594 $author_text .= ' — <b>Guest Entry</b>';
595 }
596 self::wp_kses_wf($author_text);
597 }
598 }
599
600 /**
601 * From WordPress core: /wp-admin/includes/class-wp-posts-list-table.php
602 *
603 * But it was protected so I had to copy it over
604 */
605 private function get_edit_link($args, $label)
606 {
607 $url = add_query_arg($args, 'edit.php');
608
609 $class_html = $aria_current = '';
610 if (!empty($class)) {
611 $class_html = sprintf(
612 ' class="%s"',
613 esc_attr($class)
614 );
615
616 if ('current' === $class) {
617 $aria_current = ' aria-current="page"';
618 }
619 }
620
621 return sprintf(
622 '<a href="%s"%s%s>%s</a>',
623 esc_url($url),
624 $class_html,
625 $aria_current,
626 $label
627 );
628 }
629
630 /**
631 * Determines whether the guest author tab is selected
632 *
633 * @since 1.0
634 *
635 * @global object $post
636 *
637 * @return boolean True if the is guest author tab is selected instead of the user author.
638 */
639 protected function is_guest_author_selected()
640 {
641 global $post;
642 $author_type = get_post_meta($post->ID, 'BS_author_type', true);
643
644 return $author_type === 'BS_author_is_guest';
645 }
646
647 /**
648 * Determines whether the guest author's name is empty or not
649 *
650 * @since 1.0
651 *
652 * @global object $post
653 *
654 * @return boolean True if there is a name entered to the guest author's field
655 */
656 protected function guest_author_has_name()
657 {
658 global $post;
659 $name = esc_html(get_post_meta($post->ID, 'BS_guest_author_name', true));
660 return !empty($name);
661 }
662
663 /**
664 * Combines the previous two.
665 *
666 * @since 1.0
667 *
668 * @return boolean True if the guest author is available to use
669 */
670 public function is_guest_author_available()
671 {
672 return $this->is_eligible_post_type() && $this->is_guest_author_selected() && $this->guest_author_has_name();
673 }
674
675 /**
676 * Checks to see if the post type is selected in the backend options
677 *
678 * @since 1.3
679 *
680 * @return boolean True if the guest author is available to use
681 */
682 protected function is_eligible_post_type($post_type = null)
683 {
684 if ($post_type === null)
685 $post_type = $this->get_current_post_type();
686
687 if (class_exists('BS_Guest_Author_Settings')) {
688 $valid_post_types = BS_Guest_Author_Settings::$options['bs-guest-author-integration']['post-types'];
689 if (in_array($post_type, $valid_post_types)) {
690 return true;
691 }
692 } else if ($post_type === 'post') {
693 return true;
694 }
695
696 return false;
697 }
698
699 /**
700 * Gets the current post type in the WordPress Admin
701 *
702 * @since 1.3
703 *
704 * @credit: https://gist.github.com/bradvin/1980309
705 *
706 * @return string|null post type name
707 */
708 function get_current_post_type()
709 {
710 global $post, $typenow, $current_screen;
711
712 //we have a post so we can just get the post type from that
713 if ($post && $post->post_type)
714 return $post->post_type;
715
716 //check the global $typenow - set in admin.php
717 elseif ($typenow)
718 return $typenow;
719
720 //check the global $current_screen object - set in sceen.php
721 elseif ($current_screen && $current_screen->post_type)
722 return $current_screen->post_type;
723
724 //lastly check the post_type querystring
725 //phpcs:ignore - can be called in non-nonced case
726 elseif (isset($_REQUEST['post_type'])) //phpcs:ignore
727 return sanitize_key($_REQUEST['post_type']); //phpcs:ignore
728
729 //we do not know the post type!
730 return null;
731 }
732
733 /**
734 * Checks if Gutenberg is enabled
735 *
736 * @since 1.9.1
737 *
738 * @credit: https://wordpress.stackexchange.com/questions/321368/how-to-check-if-current-admin-page-is-gutenberg-editor
739 *
740 * @return boolean True if gutenberg is enabled
741 */
742 protected function is_gutenberg()
743 {
744 global $current_screen;
745 $current_screen = get_current_screen();
746
747 return (method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor())
748 || ((function_exists('is_gutenberg_page')) && is_gutenberg_page());
749 }
750
751 public function wp_kses_wf($html)
752 {
753 add_filter('safe_style_css', function ($styles) {
754 $styles_wf = array(
755 'text-align',
756 'margin',
757 'color',
758 'float',
759 'border',
760 'background',
761 'background-color',
762 'border-bottom',
763 'border-bottom-color',
764 'border-bottom-style',
765 'border-bottom-width',
766 'border-collapse',
767 'border-color',
768 'border-left',
769 'border-left-color',
770 'border-left-style',
771 'border-left-width',
772 'border-right',
773 'border-right-color',
774 'border-right-style',
775 'border-right-width',
776 'border-spacing',
777 'border-style',
778 'border-top',
779 'border-top-color',
780 'border-top-style',
781 'border-top-width',
782 'border-width',
783 'caption-side',
784 'clear',
785 'cursor',
786 'direction',
787 'font',
788 'font-family',
789 'font-size',
790 'font-style',
791 'font-variant',
792 'font-weight',
793 'height',
794 'letter-spacing',
795 'line-height',
796 'margin-bottom',
797 'margin-left',
798 'margin-right',
799 'margin-top',
800 'overflow',
801 'padding',
802 'padding-bottom',
803 'padding-left',
804 'padding-right',
805 'padding-top',
806 'text-decoration',
807 'text-indent',
808 'vertical-align',
809 'width',
810 'display',
811 );
812
813 foreach ($styles_wf as $style_wf) {
814 $styles[] = $style_wf;
815 }
816 return $styles;
817 });
818
819 $allowed_tags = wp_kses_allowed_html('post');
820 $allowed_tags['input'] = array(
821 'type' => true,
822 'style' => true,
823 'class' => true,
824 'id' => true,
825 'checked' => true,
826 'disabled' => true,
827 'name' => true,
828 'size' => true,
829 'placeholder' => true,
830 'value' => true,
831 'data-*' => true,
832 'size' => true,
833 'disabled' => true
834 );
835
836 $allowed_tags['textarea'] = array(
837 'type' => true,
838 'style' => true,
839 'class' => true,
840 'id' => true,
841 'checked' => true,
842 'disabled' => true,
843 'name' => true,
844 'size' => true,
845 'placeholder' => true,
846 'value' => true,
847 'data-*' => true,
848 'cols' => true,
849 'rows' => true,
850 'disabled' => true,
851 'autocomplete' => true
852 );
853
854 $allowed_tags['select'] = array(
855 'type' => true,
856 'style' => true,
857 'class' => true,
858 'id' => true,
859 'checked' => true,
860 'disabled' => true,
861 'name' => true,
862 'size' => true,
863 'placeholder' => true,
864 'value' => true,
865 'data-*' => true,
866 'multiple' => true,
867 'disabled' => true
868 );
869
870 $allowed_tags['option'] = array(
871 'type' => true,
872 'style' => true,
873 'class' => true,
874 'id' => true,
875 'checked' => true,
876 'disabled' => true,
877 'name' => true,
878 'size' => true,
879 'placeholder' => true,
880 'value' => true,
881 'selected' => true,
882 'data-*' => true
883 );
884 $allowed_tags['optgroup'] = array(
885 'type' => true,
886 'style' => true,
887 'class' => true,
888 'id' => true,
889 'checked' => true,
890 'disabled' => true,
891 'name' => true,
892 'size' => true,
893 'placeholder' => true,
894 'value' => true,
895 'selected' => true,
896 'data-*' => true,
897 'label' => true
898 );
899
900 $allowed_tags['a'] = array(
901 'href' => true,
902 'data-*' => true,
903 'class' => true,
904 'style' => true,
905 'id' => true,
906 'target' => true,
907 'data-*' => true,
908 'role' => true,
909 'aria-controls' => true,
910 'aria-selected' => true,
911 'disabled' => true
912 );
913
914 $allowed_tags['div'] = array(
915 'style' => true,
916 'class' => true,
917 'id' => true,
918 'data-*' => true,
919 'role' => true,
920 'aria-labelledby' => true,
921 'value' => true,
922 'aria-modal' => true,
923 'tabindex' => true
924 );
925
926 $allowed_tags['li'] = array(
927 'style' => true,
928 'class' => true,
929 'id' => true,
930 'data-*' => true,
931 'role' => true,
932 'aria-labelledby' => true,
933 'value' => true,
934 'aria-modal' => true,
935 'tabindex' => true
936 );
937
938 $allowed_tags['span'] = array(
939 'style' => true,
940 'class' => true,
941 'id' => true,
942 'data-*' => true,
943 'aria-hidden' => true
944 );
945
946 $allowed_tags['style'] = array(
947 'class' => true,
948 'id' => true,
949 'type' => true
950 );
951
952 $allowed_tags['fieldset'] = array(
953 'class' => true,
954 'id' => true,
955 'type' => true
956 );
957
958 $allowed_tags['link'] = array(
959 'class' => true,
960 'id' => true,
961 'type' => true,
962 'rel' => true,
963 'href' => true,
964 'media' => true
965 );
966
967 $allowed_tags['form'] = array(
968 'style' => true,
969 'class' => true,
970 'id' => true,
971 'method' => true,
972 'action' => true,
973 'data-*' => true
974 );
975
976 $allowed_tags['script'] = array(
977 'class' => true,
978 'id' => true,
979 'type' => true,
980 'src' => true
981 );
982
983 echo wp_kses($html, $allowed_tags);
984
985 add_filter('safe_style_css', function ($styles) {
986 $styles_wf = array(
987 'text-align',
988 'margin',
989 'color',
990 'float',
991 'border',
992 'background',
993 'background-color',
994 'border-bottom',
995 'border-bottom-color',
996 'border-bottom-style',
997 'border-bottom-width',
998 'border-collapse',
999 'border-color',
1000 'border-left',
1001 'border-left-color',
1002 'border-left-style',
1003 'border-left-width',
1004 'border-right',
1005 'border-right-color',
1006 'border-right-style',
1007 'border-right-width',
1008 'border-spacing',
1009 'border-style',
1010 'border-top',
1011 'border-top-color',
1012 'border-top-style',
1013 'border-top-width',
1014 'border-width',
1015 'caption-side',
1016 'clear',
1017 'cursor',
1018 'direction',
1019 'font',
1020 'font-family',
1021 'font-size',
1022 'font-style',
1023 'font-variant',
1024 'font-weight',
1025 'height',
1026 'letter-spacing',
1027 'line-height',
1028 'margin-bottom',
1029 'margin-left',
1030 'margin-right',
1031 'margin-top',
1032 'overflow',
1033 'padding',
1034 'padding-bottom',
1035 'padding-left',
1036 'padding-right',
1037 'padding-top',
1038 'text-decoration',
1039 'text-indent',
1040 'vertical-align',
1041 'width'
1042 );
1043
1044 foreach ($styles_wf as $style_wf) {
1045 if (($key = array_search($style_wf, $styles)) !== false) {
1046 unset($styles[$key]);
1047 }
1048 }
1049 return $styles;
1050 });
1051 }
1052 }
1053
1054 endif;
1055