PluginProbe
Guest Author / 2.5
Guest Author v2.5
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.5, at guest-author.php

1,039 lines 33.2 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'), 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 }
224
225 /**
226 * Renders the new author meta box
227 *
228 * @since 1.0
229 * @return void
230 */
231 public function BS_ajax_get_image()
232 {
233 if (isset($_GET['id'])) {
234
235 $image = wp_get_attachment_image(filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT), 'medium', false, array('id' => 'BS-preview-image'));
236 $data = array('image' => $image);
237 wp_send_json_success($data);
238 } else {
239 wp_send_json_error();
240 }
241 }
242
243 /**
244 * Saves the custom meta fields when the post is saved/updated
245 *
246 * @since 1.0
247 * @return void
248 */
249 public function save($post_id)
250 {
251 global $post;
252
253 $post_type = $this->get_current_post_type();
254 if (!$post || !$this->is_eligible_post_type($post_type)) return;
255
256 if (
257 !isset($_POST['BS_author_type'])
258 || !isset($_POST['BS_guest_author_name'])
259 ) return;
260
261 $meta = [
262 'BS_author_type' => $_POST['BS_author_type'],
263 'BS_guest_author_name' => sanitize_text_field($_POST['BS_guest_author_name']),
264 'BS_guest_author_url' => isset($_POST['BS_guest_author_url']) ? sanitize_url($_POST['BS_guest_author_url']) : '',
265 'BS_guest_author_description' => isset($_POST['BS_guest_author_description']) ? sanitize_textarea_field($_POST['BS_guest_author_description']) : '',
266 'BS_guest_author_image_id' => isset($_POST['BS_guest_author_image_id']) ? sanitize_key($_POST['BS_guest_author_image_id']) : ''
267 ];
268
269 foreach ($meta as $key => $value) {
270 update_post_meta($post_id, $key, $value);
271 }
272 }
273
274 /**
275 * Retrieves the author's ID
276 *
277 * @since 2.2
278 *
279 * @global object $post
280 *
281 * @param string $id This parameter is only needed for when
282 * WordPress uses this function as filter.
283 *
284 * @return string | NULL returns NULL if it's a guest author post
285 *
286 */
287 public function author_ID($id = '')
288 {
289 global $post;
290
291 if ($post AND $this->is_guest_author_available()) {
292 return NULL;
293 }
294
295 return $id;
296 }
297
298 /**
299 * Retrieves the author's name
300 *
301 * @since 1.0
302 *
303 * @global object $post
304 *
305 * @param string $name This parameter is only needed for when
306 * WordPress uses this function as filter.
307 *
308 * @return string The guest author's name if available, otherwise
309 * it will return the original author's name.
310 */
311 public function author_name($name = '')
312 {
313 global $post;
314
315 if ($post) {
316 $guest_name = esc_html(get_post_meta($post->ID, 'BS_guest_author_name', true));
317 if (!$this->is_guest_author_available()) {
318 return $name;
319 }
320 }
321
322 if (isset($guest_name)) return $guest_name;
323
324 return $name;
325 }
326
327
328 /**
329 * Retrieves the author's email
330 *
331 * @since 2.1
332 *
333 * @global object $post
334 *
335 * @param string $info This parameter is only needed for when
336 * WordPress uses this function as filter.
337 *
338 * @return string|NULL .
339 */
340 public function __return_null_meta($info = '')
341 {
342 global $post;
343
344 if ($post && $this->is_guest_author_available()) {
345 return NULL;
346 }
347
348 return $info;
349 }
350
351 /**
352 * Retrieves the author's link
353 *
354 * @since 1.0
355 *
356 * @global object $post
357 *
358 * @param string $link This parameter is only needed for when WordPress
359 * uses this function as filter.
360 *
361 * @return string The guest author's link if the guest author
362 * is available, otherwise it is the original author's link
363 */
364 public function author_link($link = '')
365 {
366 if (!$this->is_guest_author_available()) return $link;
367
368 global $post;
369 return get_post_meta($post->ID, 'BS_guest_author_url', true);
370 }
371
372 /**
373 * Retrieves the author's descriptions
374 *
375 * @since 1.0
376 *
377 * @global object $post
378 *
379 * @param string $desc This parameter is only needed for when WordPress
380 * uses this function as filter.
381 *
382 * @return string The guest author's description if the guest author
383 * is available, otherwise it is the original author's description
384 */
385 public function author_description($desc = "")
386 {
387 global $post;
388
389 if (!$this->is_guest_author_available()) {
390 return $desc;
391 }
392
393 return esc_html(get_post_meta($post->ID, 'BS_guest_author_description', true));
394 }
395
396
397 /**
398 * Retrieves the author's avatar
399 *
400 * @since 1.0
401 *
402 * @global object $post
403 *
404 * @param string $img This parameter is only needed for when WordPress
405 * uses this function as filter.
406 *
407 * @return string The guest author's avatar as an <img> element if the guest author
408 * is available, otherwise it is the original author's avatar
409 */
410 public function author_avatar($img = '')
411 {
412 global $post;
413
414 if (!$this->is_guest_author_available()) {
415 return $img;
416 }
417
418 $image_id = get_post_meta($post->ID, 'BS_guest_author_image_id', true);
419
420 if ($image_id) {
421 return wp_get_attachment_image($image_id, array(100, 100), false);
422 } else {
423 // Default image
424 return "<img src=\"" . plugins_url('/img/default.jpg', __FILE__) . "\">";
425 }
426 }
427
428 /**
429 * Retrieves the author's avatar
430 *
431 * @since 1.9.1
432 *
433 * @global object $post
434 *
435 * @param string $args This parameter is only needed for when WordPress
436 * uses this function as filter.
437 *
438 * @return string The URL of the author image
439 *
440 */
441 public function pre_get_author_avatar_data($args = [], $id_or_email = '')
442 {
443 global $post;
444
445 if (!$post) return $args;
446
447 if (!$this->is_guest_author_available()) {
448 return $args;
449 }
450
451 // This assumes that if the id passed is empty, it means we're trying to get the guest author
452 //
453 // It also assumes that if the author id being fetched is the id of the real post author, then it probably
454 // means that we should replace it with the guest author. This is for developers that use $post->post_author to
455 // call the get_avatar_data() function
456 //
457 if (empty($id_or_email) || ($post && $post->post_author === $id_or_email)) {
458
459 if (isset($args['url'])) {
460 return $args;
461 }
462
463 $image_id = get_post_meta($post->ID, 'BS_guest_author_image_id', true);
464
465 if ($image_id) {
466
467 $img_size = $args['size'];
468
469 if ($args['width'] && $args['height']) {
470 $img_size = [$args['width'], $args['height']];
471 }
472
473 $image = wp_get_attachment_image_src(intval($image_id), $img_size);
474
475 $args['url'] = $image[0];
476 $args['found_avatar'] = true;
477 }
478 }
479
480 return $args;
481 }
482
483 /**
484 * Disables the avatar filter
485 *
486 * @since 1.0
487 *
488 * @return void
489 */
490 public function remove_author_avatar_filter()
491 {
492 remove_filter('get_avatar', array($this, 'author_avatar'));
493 }
494
495 /**
496 * Disables the avatar filter when the comments are rendered. Why?
497 * This kind of a weird measure, but it is needed because if we don't
498 * remove the filter at some point, EVERY avatar in page will have the author's
499 * image. So we figure, in MOST cases the comments will be rendered AFTER the post itself.
500 *
501 * @since 1.0
502 *
503 * @return void
504 */
505 public function remove_author_avatar_filter_at_comments()
506 {
507 $this->remove_author_avatar_filter();
508 }
509
510 /**
511 * Registers the guest author info into the global variable $authordata
512 *
513 * @since 1.2
514 *
515 * @return void
516 */
517 public function register_authordata()
518 {
519 global $authordata;
520 global $post;
521
522 if (!$this->is_guest_author_available()) {
523 return;
524 }
525
526 $guest_author = new WP_User();
527
528 $guest_author->ID = NULL;
529
530 $guest_author->user_url = $this->author_link();
531 $guest_author->user_description = $this->author_description();
532 $guest_author->display_name = $this->author_name();
533 $guest_author->user_nicename = $this->author_name();
534
535 $guest_author->user_login = NULL;
536 $guest_author->user_pass = NULL;
537 $guest_author->user_email = NULL;
538 $guest_author->user_registered = NULL;
539 $guest_author->user_activation_key = NULL;
540 $guest_author->user_status = NULL;
541
542 $authordata = $guest_author;
543 }
544
545 /**
546 * Simply replaces the default author column in the posts list (of the dashboard),
547 * with an identical one. The difference? the posts who have a guest author, will have the
548 * notation ' — Guest Entry' next to the authoring user's name
549 *
550 * @since 1.0
551 *
552 * @return array the new columns array.
553 */
554 public function add_author_column($columns)
555 {
556 $new_columns_array = [];
557
558 foreach ($columns as $key => $value) {
559 if ($key === 'author') {
560 $new_columns_array['author_modified'] = $value;
561 } else {
562 $new_columns_array[$key] = $value;
563 }
564 }
565 return $new_columns_array;
566 }
567 public function modify_author_column($columns)
568 {
569 global $post;
570 switch ($columns) {
571 case 'author_modified':
572 $is_guest_author = $this->is_guest_author_selected();
573 $args = array(
574 'post_type' => $post->post_type,
575 'author' => get_the_author_meta('ID')
576 );
577 $author_text = $this->get_edit_link($args, get_the_author());
578 if ($is_guest_author) {
579 $author_text .= ' — <b>Guest Entry</b>';
580 }
581 self::wp_kses_wf($author_text);
582 }
583 }
584
585 /**
586 * From WordPress core: /wp-admin/includes/class-wp-posts-list-table.php
587 *
588 * But it was protected so I had to copy it over
589 */
590 private function get_edit_link($args, $label)
591 {
592 $url = add_query_arg($args, 'edit.php');
593
594 $class_html = $aria_current = '';
595 if (!empty($class)) {
596 $class_html = sprintf(
597 ' class="%s"',
598 esc_attr($class)
599 );
600
601 if ('current' === $class) {
602 $aria_current = ' aria-current="page"';
603 }
604 }
605
606 return sprintf(
607 '<a href="%s"%s%s>%s</a>',
608 esc_url($url),
609 $class_html,
610 $aria_current,
611 $label
612 );
613 }
614
615 /**
616 * Determines whether the guest author tab is selected
617 *
618 * @since 1.0
619 *
620 * @global object $post
621 *
622 * @return boolean True if the is guest author tab is selected instead of the user author.
623 */
624 protected function is_guest_author_selected()
625 {
626 global $post;
627 $author_type = get_post_meta($post->ID, 'BS_author_type', true);
628
629 return $author_type === 'BS_author_is_guest';
630 }
631
632 /**
633 * Determines whether the guest author's name is empty or not
634 *
635 * @since 1.0
636 *
637 * @global object $post
638 *
639 * @return boolean True if there is a name entered to the guest author's field
640 */
641 protected function guest_author_has_name()
642 {
643 global $post;
644 $name = esc_html(get_post_meta($post->ID, 'BS_guest_author_name', true));
645 return !empty($name);
646 }
647
648 /**
649 * Combines the previous two.
650 *
651 * @since 1.0
652 *
653 * @return boolean True if the guest author is available to use
654 */
655 public function is_guest_author_available()
656 {
657 return $this->is_eligible_post_type() && $this->is_guest_author_selected() && $this->guest_author_has_name();
658 }
659
660 /**
661 * Checks to see if the post type is selected in the backend options
662 *
663 * @since 1.3
664 *
665 * @return boolean True if the guest author is available to use
666 */
667 protected function is_eligible_post_type($post_type = null)
668 {
669 if ($post_type === null)
670 $post_type = $this->get_current_post_type();
671
672 if (class_exists('BS_Guest_Author_Settings')) {
673 $valid_post_types = BS_Guest_Author_Settings::$options['bs-guest-author-integration']['post-types'];
674 if (in_array($post_type, $valid_post_types)) {
675 return true;
676 }
677 } else if ($post_type === 'post') {
678 return true;
679 }
680
681 return false;
682 }
683
684 /**
685 * Gets the current post type in the WordPress Admin
686 *
687 * @since 1.3
688 *
689 * @credit: https://gist.github.com/bradvin/1980309
690 *
691 * @return string|null post type name
692 */
693 function get_current_post_type()
694 {
695 global $post, $typenow, $current_screen;
696
697 //we have a post so we can just get the post type from that
698 if ($post && $post->post_type)
699 return $post->post_type;
700
701 //check the global $typenow - set in admin.php
702 elseif ($typenow)
703 return $typenow;
704
705 //check the global $current_screen object - set in sceen.php
706 elseif ($current_screen && $current_screen->post_type)
707 return $current_screen->post_type;
708
709 //lastly check the post_type querystring
710 elseif (isset($_REQUEST['post_type']))
711 return sanitize_key($_REQUEST['post_type']);
712
713 //we do not know the post type!
714 return null;
715 }
716
717 /**
718 * Checks if Gutenberg is enabled
719 *
720 * @since 1.9.1
721 *
722 * @credit: https://wordpress.stackexchange.com/questions/321368/how-to-check-if-current-admin-page-is-gutenberg-editor
723 *
724 * @return boolean True if gutenberg is enabled
725 */
726 protected function is_gutenberg()
727 {
728 global $current_screen;
729 $current_screen = get_current_screen();
730
731 return (method_exists($current_screen, 'is_block_editor') && $current_screen->is_block_editor())
732 || ((function_exists('is_gutenberg_page')) && is_gutenberg_page());
733 }
734
735 public function wp_kses_wf($html)
736 {
737 add_filter('safe_style_css', function ($styles) {
738 $styles_wf = array(
739 'text-align',
740 'margin',
741 'color',
742 'float',
743 'border',
744 'background',
745 'background-color',
746 'border-bottom',
747 'border-bottom-color',
748 'border-bottom-style',
749 'border-bottom-width',
750 'border-collapse',
751 'border-color',
752 'border-left',
753 'border-left-color',
754 'border-left-style',
755 'border-left-width',
756 'border-right',
757 'border-right-color',
758 'border-right-style',
759 'border-right-width',
760 'border-spacing',
761 'border-style',
762 'border-top',
763 'border-top-color',
764 'border-top-style',
765 'border-top-width',
766 'border-width',
767 'caption-side',
768 'clear',
769 'cursor',
770 'direction',
771 'font',
772 'font-family',
773 'font-size',
774 'font-style',
775 'font-variant',
776 'font-weight',
777 'height',
778 'letter-spacing',
779 'line-height',
780 'margin-bottom',
781 'margin-left',
782 'margin-right',
783 'margin-top',
784 'overflow',
785 'padding',
786 'padding-bottom',
787 'padding-left',
788 'padding-right',
789 'padding-top',
790 'text-decoration',
791 'text-indent',
792 'vertical-align',
793 'width',
794 'display',
795 );
796
797 foreach ($styles_wf as $style_wf) {
798 $styles[] = $style_wf;
799 }
800 return $styles;
801 });
802
803 $allowed_tags = wp_kses_allowed_html('post');
804 $allowed_tags['input'] = array(
805 'type' => true,
806 'style' => true,
807 'class' => true,
808 'id' => true,
809 'checked' => true,
810 'disabled' => true,
811 'name' => true,
812 'size' => true,
813 'placeholder' => true,
814 'value' => true,
815 'data-*' => true,
816 'size' => true,
817 'disabled' => true
818 );
819
820 $allowed_tags['textarea'] = 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 'cols' => true,
833 'rows' => true,
834 'disabled' => true,
835 'autocomplete' => true
836 );
837
838 $allowed_tags['select'] = array(
839 'type' => true,
840 'style' => true,
841 'class' => true,
842 'id' => true,
843 'checked' => true,
844 'disabled' => true,
845 'name' => true,
846 'size' => true,
847 'placeholder' => true,
848 'value' => true,
849 'data-*' => true,
850 'multiple' => true,
851 'disabled' => true
852 );
853
854 $allowed_tags['option'] = 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 'selected' => true,
866 'data-*' => true
867 );
868 $allowed_tags['optgroup'] = array(
869 'type' => true,
870 'style' => true,
871 'class' => true,
872 'id' => true,
873 'checked' => true,
874 'disabled' => true,
875 'name' => true,
876 'size' => true,
877 'placeholder' => true,
878 'value' => true,
879 'selected' => true,
880 'data-*' => true,
881 'label' => true
882 );
883
884 $allowed_tags['a'] = array(
885 'href' => true,
886 'data-*' => true,
887 'class' => true,
888 'style' => true,
889 'id' => true,
890 'target' => true,
891 'data-*' => true,
892 'role' => true,
893 'aria-controls' => true,
894 'aria-selected' => true,
895 'disabled' => true
896 );
897
898 $allowed_tags['div'] = array(
899 'style' => true,
900 'class' => true,
901 'id' => true,
902 'data-*' => true,
903 'role' => true,
904 'aria-labelledby' => true,
905 'value' => true,
906 'aria-modal' => true,
907 'tabindex' => true
908 );
909
910 $allowed_tags['li'] = array(
911 'style' => true,
912 'class' => true,
913 'id' => true,
914 'data-*' => true,
915 'role' => true,
916 'aria-labelledby' => true,
917 'value' => true,
918 'aria-modal' => true,
919 'tabindex' => true
920 );
921
922 $allowed_tags['span'] = array(
923 'style' => true,
924 'class' => true,
925 'id' => true,
926 'data-*' => true,
927 'aria-hidden' => true
928 );
929
930 $allowed_tags['style'] = array(
931 'class' => true,
932 'id' => true,
933 'type' => true
934 );
935
936 $allowed_tags['fieldset'] = array(
937 'class' => true,
938 'id' => true,
939 'type' => true
940 );
941
942 $allowed_tags['link'] = array(
943 'class' => true,
944 'id' => true,
945 'type' => true,
946 'rel' => true,
947 'href' => true,
948 'media' => true
949 );
950
951 $allowed_tags['form'] = array(
952 'style' => true,
953 'class' => true,
954 'id' => true,
955 'method' => true,
956 'action' => true,
957 'data-*' => true
958 );
959
960 $allowed_tags['script'] = array(
961 'class' => true,
962 'id' => true,
963 'type' => true,
964 'src' => true
965 );
966
967 echo wp_kses($html, $allowed_tags);
968
969 add_filter('safe_style_css', function ($styles) {
970 $styles_wf = array(
971 'text-align',
972 'margin',
973 'color',
974 'float',
975 'border',
976 'background',
977 'background-color',
978 'border-bottom',
979 'border-bottom-color',
980 'border-bottom-style',
981 'border-bottom-width',
982 'border-collapse',
983 'border-color',
984 'border-left',
985 'border-left-color',
986 'border-left-style',
987 'border-left-width',
988 'border-right',
989 'border-right-color',
990 'border-right-style',
991 'border-right-width',
992 'border-spacing',
993 'border-style',
994 'border-top',
995 'border-top-color',
996 'border-top-style',
997 'border-top-width',
998 'border-width',
999 'caption-side',
1000 'clear',
1001 'cursor',
1002 'direction',
1003 'font',
1004 'font-family',
1005 'font-size',
1006 'font-style',
1007 'font-variant',
1008 'font-weight',
1009 'height',
1010 'letter-spacing',
1011 'line-height',
1012 'margin-bottom',
1013 'margin-left',
1014 'margin-right',
1015 'margin-top',
1016 'overflow',
1017 'padding',
1018 'padding-bottom',
1019 'padding-left',
1020 'padding-right',
1021 'padding-top',
1022 'text-decoration',
1023 'text-indent',
1024 'vertical-align',
1025 'width'
1026 );
1027
1028 foreach ($styles_wf as $style_wf) {
1029 if (($key = array_search($style_wf, $styles)) !== false) {
1030 unset($styles[$key]);
1031 }
1032 }
1033 return $styles;
1034 });
1035 }
1036 }
1037
1038 endif;
1039