PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.3.21
HTML Forms – Simple WordPress Forms Plugin v1.3.21
trunk 1.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.3.0 1.3.1 1.3.10 1.3.11 1.3.12 1.3.13 1.3.14 1.3.15 1.3.16 1.3.17 All 66 releases
← All changes | src/admin/class-admin.php +29 -294 trunk1.3.21 View file →
@@ -22,16 +22,14 @@
22 22 }
23 23
24 24 public function hook() {
25 25 add_action( 'admin_menu', array( $this, 'menu' ) );
26 - add_action( 'admin_enqueue_scripts', array( $this, 'menu_icon' ) );
27 26 add_action( 'init', array( $this, 'register_settings' ) );
28 27 add_action( 'admin_init', array( $this, 'run_migrations' ) );
29 28 add_action( 'admin_init', array( $this, 'listen' ) );
30 29 add_action( 'admin_print_styles', array( $this, 'assets' ) );
31 30 add_action( 'admin_head', array( $this, 'add_screen_options' ) );
32 - add_action( 'hf_admin_action_create_form', array( $this, 'process_create_form' ) );
33 - add_action( 'wp_ajax_hf_dismiss_recaptcha_notice', array( $this, 'dismiss_recaptcha_notice' ) );
31 + add_action( 'hf_admin_action_create_form', array( $this, 'process_create_form' ) );
34 32 add_action( 'hf_admin_action_save_form', array( $this, 'process_save_form' ) );
35 33 add_action( 'hf_admin_action_bulk_delete_submissions', array( $this, 'process_bulk_delete_submissions' ) );
36 34
37 35 add_action( 'hf_admin_output_form_tab_fields', array( $this, 'tab_fields' ) );
@@ -43,19 +41,9 @@
43 41 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_gutenberg_assets' ) );
44 42 }
45 43
46 44 public function enqueue_gutenberg_assets() {
47 - wp_enqueue_script(
48 - 'html-forms-block',
49 - plugins_url( 'assets/js/gutenberg-block.js', $this->plugin_file ),
50 - array(
51 - 'wp-blocks',
52 - 'wp-i18n',
53 - 'wp-element',
54 - 'wp-components',
55 - 'wp-block-editor',
56 - )
57 - );
45 + wp_enqueue_script( 'html-forms-block', plugins_url( 'assets/js/gutenberg-block.js', $this->plugin_file ), array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-components' ) );
58 46 $forms = hf_get_forms();
59 47 $data = array();
60 48 foreach ( $forms as $form ) {
61 49 $data[] = array(
@@ -86,36 +74,11 @@
86 74 }
87 75
88 76 /**
89 77 * @param array $dirty
90 - *
91 78 * @return array
92 79 */
93 80 public function sanitize_settings( $dirty ) {
94 - $int_fields = array( 'enable_nonce', 'load_stylesheet', 'direct_links', 'media_library_uploads', 'maximum_filesize' );
95 - foreach ( $int_fields as $field ) {
96 - if ( isset( $dirty[ $field ] ) ) {
97 - $dirty[ $field ] = absint( $dirty[ $field ] );
98 - }
99 - }
100 -
101 - if ( isset( $dirty['wrapper_tag'] ) ) {
102 - $allowed_tags = array( 'p', 'div', 'span' );
103 - $dirty['wrapper_tag'] = in_array( $dirty['wrapper_tag'], $allowed_tags, true ) ? $dirty['wrapper_tag'] : 'p';
104 - }
105 -
106 - if ( isset( $dirty['submissions_export_delimiter'] ) ) {
107 - $dirty['submissions_export_delimiter'] = sanitize_text_field( $dirty['submissions_export_delimiter'] );
108 - }
109 -
110 - if ( isset( $dirty['google_recaptcha'] ) && is_array( $dirty['google_recaptcha'] ) ) {
111 - foreach ( array( 'site_key', 'secret_key' ) as $key ) {
112 - if ( isset( $dirty['google_recaptcha'][ $key ] ) ) {
113 - $dirty['google_recaptcha'][ $key ] = sanitize_text_field( $dirty['google_recaptcha'][ $key ] );
114 - }
115 - }
116 - }
117 -
118 81 return $dirty;
119 82 }
120 83
121 84 public function listen() {
@@ -160,12 +123,12 @@
160 123 if ( empty( $_GET['page'] ) || strpos( $_GET['page'], 'html-forms' ) !== 0 ) {
161 124 return;
162 125 }
163 126
164 - $settings = hf_get_settings();
127 + $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
165 128
166 - wp_enqueue_style( 'html-forms-admin', plugins_url( 'assets/css/admin.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
167 - wp_enqueue_script( 'html-forms-admin', plugins_url( 'assets/js/admin.js', $this->plugin_file ), array(), HTML_FORMS_VERSION, true );
129 + wp_enqueue_style( 'html-forms-admin', plugins_url( 'assets/css/admin' . $suffix . '.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
130 + wp_enqueue_script( 'html-forms-admin', plugins_url( 'assets/js/admin' . $suffix . '.js', $this->plugin_file ), array(), HTML_FORMS_VERSION, true );
168 131 wp_localize_script(
169 132 'html-forms-admin',
170 133 'hf_options',
171 134 array(
@@ -171,9 +134,8 @@
171 134 array(
172 135 'page' => $_GET['page'],
173 136 'view' => empty( $_GET['view'] ) ? '' : $_GET['view'],
174 137 'form_id' => empty( $_GET['form_id'] ) ? 0 : (int) $_GET['form_id'],
175 - 'wrapper_tag' => empty( $settings['wrapper_tag'] ) ? 'p' : $settings['wrapper_tag'],
176 138 )
177 139 );
178 140 }
179 141
@@ -178,79 +140,20 @@
178 140 }
179 141
180 142 public function menu() {
181 143 $capability = 'edit_forms';
182 -
183 - add_menu_page(
184 - 'HTML Forms',
185 - 'HTML Forms',
186 - $capability,
187 - 'html-forms',
188 - array(
189 - $this,
190 - 'page_overview',
191 - ),
192 - 'none',
193 - '99.88491'
194 - );
144 + $svg_icon = '<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="256.000000pt" height="256.000000pt" viewBox="0 0 256.000000 256.000000" preserveAspectRatio="xMidYMid meet"><g transform="translate(0.000000,256.000000) scale(0.100000,-0.100000)"
145 + fill="#000000" stroke="none"><path d="M0 1280 l0 -1280 1280 0 1280 0 0 1280 0 1280 -1280 0 -1280 0 0 -1280z m2031 593 c8 -8 9 -34 4 -78 -6 -56 -9 -65 -23 -60 -43 16 -98 15 -132 -2 -50 -26 -72 -72 -78 -159 l-5 -74 92 0 91 0 0 -70 0 -70 -90 0 -90 0 0 -345 0 -345 -90 0 -90 0 0 345 0 345 -55 0 -55 0 0 70 0 70 55 0 55 0 0 38 c0 63 20 153 45 202 54 105 141 152 273 147 45 -2 87 -8 93 -14z m-1291 -288 l0 -235 230 0 230 0 0 235 0 235 90 0 90 0 0 -575 0 -575 -90 0 -90 0 0 260 0 260 -230 0 -230 0 0 -260 0 -260 -90 0 -90 0 0 575 0 575 90 0 90 0 0 -235z"/></g></svg>';
146 + add_menu_page( 'HTML Forms', 'HTML Forms', $capability, 'html-forms', array( $this, 'page_overview' ), 'data:image/svg+xml;base64,' . base64_encode( $svg_icon ), '99.88491' );
147 + add_submenu_page( 'html-forms', __( 'Forms', 'html-forms' ), __( 'All Forms', 'html-forms' ), $capability, 'html-forms', array( $this, 'page_overview' ) );
148 + add_submenu_page( 'html-forms', __( 'Add new form', 'html-forms' ), __( 'Add New', 'html-forms' ), $capability, 'html-forms-add-form', array( $this, 'page_new_form' ) );
149 + add_submenu_page( 'html-forms', __( 'Settings', 'html-forms' ), __( 'Settings', 'html-forms' ), $capability, 'html-forms-settings', array( $this, 'page_settings' ) );
195 150
196 - add_submenu_page(
197 - 'html-forms',
198 - __( 'Forms', 'html-forms' ),
199 - __( 'All Forms', 'html-forms' ),
200 - $capability,
201 - 'html-forms',
202 - array(
203 - $this,
204 - 'page_overview',
205 - )
206 - );
207 -
208 - add_submenu_page(
209 - 'html-forms',
210 - __( 'Add New Form', 'html-forms' ),
211 - __( 'Add New', 'html-forms' ),
212 - $capability,
213 - 'html-forms-add-form',
214 - array(
215 - $this,
216 - 'page_new_form',
217 - )
218 - );
219 -
220 - add_submenu_page(
221 - 'html-forms',
222 - __( 'Settings', 'html-forms' ),
223 - __( 'Settings', 'html-forms' ),
224 - $capability,
225 - 'html-forms-settings',
226 - array(
227 - $this,
228 - 'page_settings',
229 - )
230 - );
231 -
232 151 if ( ! defined( 'HF_PREMIUM_VERSION' ) ) {
233 - add_submenu_page(
234 - 'html-forms',
235 - 'Premium',
236 - '<span style="color: #ea6ea6;">Premium</span>',
237 - $capability,
238 - 'html-forms-premium',
239 - array(
240 - $this,
241 - 'page_premium',
242 - )
243 - );
152 + add_submenu_page( 'html-forms', 'Premium', '<span style="color: #ea6ea6;">Premium</span>', $capability, 'html-forms-premium', array( $this, 'page_premium' ) );
244 153 }
245 154 }
246 155
247 - public function menu_icon() {
248 - $html_forms_icon = 'data:image/svg+xml;base64,'.base64_encode('<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 256 256"><path d="M0 0v256h256V0zm203.1 68.7c.8.8.9 3.4.4 7.8-.6 5.6-.9 6.5-2.3 6-4.3-1.6-9.8-1.5-13.2.2-5 2.6-7.2 7.2-7.8 15.9l-.5 7.4H198v14h-18v69h-18v-69h-11v-14h11v-3.8c0-6.3 2-15.3 4.5-20.2 5.4-10.5 14.1-15.2 27.3-14.7 4.5.2 8.7.8 9.3 1.4M74 74v47h46V74h18v115h-18v-52H74v52H56V74z" /></svg>');
249 -
250 - wp_add_inline_style( 'wp-admin', '#toplevel_page_html-forms .wp-menu-image { background-color: currentColor; mask-image: url("'.$html_forms_icon.'"); mask-size: 20px; mask-repeat: no-repeat; mask-position: center; }' );
251 - }
252 -
253 156 public function add_screen_options() {
254 157 // only run on the submissions overview page (not detail)
255 158 if ( empty( $_GET['page'] ) || $_GET['page'] !== 'html-forms' || empty( $_GET['view'] ) || $_GET['view'] !== 'edit' || empty( $_GET['form_id'] ) || ! empty( $_GET['submission_id'] ) ) {
256 159 return;
@@ -266,9 +169,9 @@
266 169 $submissions = hf_get_form_submissions( $_GET['form_id'] );
267 170 $columns = $this->get_submission_columns( $submissions );
268 171 add_filter(
269 172 'manage_toplevel_page_html-forms_columns',
270 - function ( $unused ) use ( $columns ) {
173 + function( $unused ) use ( $columns ) {
271 174 return $columns;
272 175 }
273 176 );
274 177 add_screen_option( 'layout_columns' );
@@ -276,9 +179,8 @@
276 179
277 180 public function page_overview() {
278 181 if ( ! empty( $_GET['view'] ) && $_GET['view'] === 'edit' ) {
279 182 $this->page_edit_form();
280 -
281 183 return;
282 184 }
283 185
284 186 $settings = hf_get_settings();
@@ -294,10 +196,8 @@
294 196 }
295 197
296 198 public function page_settings() {
297 199 $settings = hf_get_settings();
298 - $wrapper_tags = array ( 'p', 'div', 'span' );
299 -
300 200 require dirname( $this->plugin_file ) . '/views/page-global-settings.php';
301 201 }
302 202
303 203 public function page_premium() {
@@ -348,9 +248,8 @@
348 248 $columns[ $field ] = esc_html( ucfirst( strtolower( str_replace( '_', ' ', $field ) ) ) );
349 249 }
350 250 }
351 251 }
352 -
353 252 return $columns;
354 253 }
355 254
356 255 public function tab_submissions_list( Form $form ) {
@@ -357,21 +256,9 @@
357 256 if ( ! empty( $_GET['submission_id'] ) ) {
358 257 return;
359 258 }
360 259
361 - $items_per_page = 500;
362 - $total_items = hf_count_form_submissions( $form->ID );
363 - $total_pages = max( 1, ceil( $total_items / $items_per_page ) );
364 - $current_page = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 1;
365 - $current_page = max( 1, $current_page );
366 - $current_page = min( $total_pages, $current_page );
367 - $submissions = hf_get_form_submissions(
368 - $form->ID,
369 - array(
370 - 'limit' => $items_per_page,
371 - 'offset' => ( $current_page - 1 ) * $items_per_page,
372 - )
373 - );
260 + $submissions = hf_get_form_submissions( $form->ID );
374 261 $columns = $this->get_submission_columns( $submissions );
375 262 $hidden_columns = get_hidden_columns( get_current_screen() );
376 263
377 264 require dirname( $this->plugin_file ) . '/views/tab-submissions-list.php';
@@ -382,12 +269,12 @@
382 269 return;
383 270 }
384 271
385 272 $submission = hf_get_form_submission( (int) $_GET['submission_id'] );
386 - do_action( 'hf_admin_form_submissions_detail', $submission );
387 273 require dirname( $this->plugin_file ) . '/views/tab-submissions-detail.php';
388 274 }
389 275
276 +
390 277 public function process_create_form() {
391 278 // Fix for MultiSite stripping KSES for roles other than administrator
392 279 remove_all_filters( 'content_save_pre' );
393 280
@@ -413,13 +300,8 @@
413 300
414 301 // Fix for MultiSite stripping KSES for roles other than administrator
415 302 remove_all_filters( 'content_save_pre' );
416 303
417 - // run our own kses filter
418 - if ( ! current_user_can( 'unfiltered_html' ) ) {
419 - $data['markup'] = $this->kses( $data['markup'] );
420 - }
421 -
422 304 // strip <form> tag from markup
423 305 $data['markup'] = preg_replace( '/<\/?form(.|\s)*?>/i', '', $data['markup'] );
424 306
425 307 $form_id = wp_insert_post(
@@ -433,26 +315,14 @@
433 315 )
434 316 );
435 317
436 318 if ( ! empty( $data['settings'] ) ) {
437 - // Reject redirect URLs with non-http(s) schemes
438 - if ( isset( $data['settings']['redirect_url'] ) && $data['settings']['redirect_url'] !== '' ) {
439 - $scheme = wp_parse_url( $data['settings']['redirect_url'], PHP_URL_SCHEME );
440 - if ( $scheme !== null && ! in_array( strtolower( $scheme ), array( 'http', 'https' ), true ) ) {
441 - $data['settings']['redirect_url'] = '';
442 - }
443 - }
444 -
445 319 update_post_meta( $form_id, '_hf_settings', $data['settings'] );
446 320 }
447 321
448 322 // save form messages in individual meta keys
449 323 foreach ( $data['messages'] as $key => $message ) {
450 - if ( current_user_can( 'unfiltered_html' ) ) {
451 - update_post_meta( $form_id, 'hf_message_' . $key, $message );
452 - } else {
453 - update_post_meta( $form_id, 'hf_message_' . $key, wp_kses_post( $message ) );
454 - }
324 + update_post_meta( $form_id, 'hf_message_' . $key, $message );
455 325 }
456 326
457 327 $redirect_url_args = array(
458 328 'form_id' => $form_id,
@@ -465,36 +335,15 @@
465 335
466 336 /**
467 337 * Get URL for a tab on the current page.
468 338 *
339 + * @since 3.0
340 + * @internal
469 341 * @param $tab
470 - *
471 342 * @return string
472 - * @since 3.0
473 - * @internal
474 343 */
475 344 public function get_tab_url( $tab ) {
476 - $tab_url = add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) );
477 -
478 - $url_parts = parse_url($tab_url);
479 - if ( isset( $url_parts['query'] ) ) {
480 - parse_str( $url_parts['query'], $query_params );
481 -
482 - if ( isset( $query_params['submission_id'] ) ) {
483 - unset( $query_params['submission_id'] );
484 - }
485 -
486 - $new_query = http_build_query( $query_params );
487 - $new_tab_url = $url_parts['path'];
488 -
489 - if ( ! empty( $new_query ) ) {
490 - $new_tab_url .= '?' . $new_query;
491 - }
492 -
493 - return $new_tab_url;
494 - }
495 -
496 - return $tab_url;
345 + return add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) );
497 346 }
498 347
499 348 /**
500 349 * @return array
@@ -518,136 +367,22 @@
518 367 if ( empty( $_POST['id'] ) ) {
519 368 return;
520 369 }
521 370
522 - $args = array_map( 'intval', $_POST['id'] );
523 - $table = $wpdb->prefix . 'hf_submissions';
524 - $placeholders = rtrim( str_repeat( '%d,', count( $args ) ), ',' );
525 - $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE id IN( {$placeholders} );", $args ) );
371 + $ids = $_POST['id'];
372 + $table = $wpdb->prefix . 'hf_submissions';
373 + $ids = join( ',', array_map( 'esc_sql', $ids ) );
374 + $wpdb->query( sprintf( "DELETE FROM {$table} WHERE id IN( %s );", $ids ) );
375 + $wpdb->query( sprintf( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN ( %s ) AND meta_key LIKE '_hf_%%';", $ids ) );
526 376 }
527 377
528 378 private function get_default_form_content() {
529 - $settings = hf_get_settings();
530 - $wrapper_tag = ( isset( $settings['wrapper_tag'] ) ) ? $settings['wrapper_tag'] : 'p';
531 -
532 379 $html = '';
533 - $html .= sprintf( "<%1\$s>\n\t<label>%2\$s</label>\n\t<input type=\"text\" name=\"NAME\" placeholder=\"%2\$s\" required />\n</%1\$s>", $wrapper_tag, __( 'Your name', 'html-forms' ) ) . PHP_EOL;
534 - $html .= sprintf( "<%1\$s>\n\t<label>%2\$s</label>\n\t<input type=\"email\" name=\"EMAIL\" placeholder=\"%2\$s\" required />\n</%1\$s>", $wrapper_tag, __( 'Your email', 'html-forms' ) ) . PHP_EOL;
535 - $html .= sprintf( "<%1\$s>\n\t<label>%2\$s</label>\n\t<input type=\"text\" name=\"SUBJECT\" placeholder=\"%2\$s\" required />\n</%1\$s>", $wrapper_tag, __( 'Subject', 'html-forms' ) ) . PHP_EOL;
536 - $html .= sprintf( "<%1\$s>\n\t<label>%2\$s</label>\n\t<textarea name=\"MESSAGE\" placeholder=\"%2\$s\" required></textarea>\n</%1\$s>", $wrapper_tag, __( 'Message', 'html-forms' ) ) . PHP_EOL;
537 - $html .= sprintf( "<%1\$s>\n\t<input type=\"submit\" value=\"%2\$s\" />\n</%1\$s>", $wrapper_tag, __( 'Send', 'html-forms' ) );
538 -
380 + $html .= sprintf( "<p>\n\t<label>%1\$s</label>\n\t<input type=\"text\" name=\"NAME\" placeholder=\"%1\$s\" required />\n</p>", __( 'Your name', 'html-forms' ) ) . PHP_EOL;
381 + $html .= sprintf( "<p>\n\t<label>%1\$s</label>\n\t<input type=\"email\" name=\"EMAIL\" placeholder=\"%1\$s\" required />\n</p>", __( 'Your email', 'html-forms' ) ) . PHP_EOL;
382 + $html .= sprintf( "<p>\n\t<label>%1\$s</label>\n\t<input type=\"text\" name=\"SUBJECT\" placeholder=\"%1\$s\" required />\n</p>", __( 'Subject', 'html-forms' ) ) . PHP_EOL;
383 + $html .= sprintf( "<p>\n\t<label>%1\$s</label>\n\t<textarea name=\"MESSAGE\" placeholder=\"%1\$s\" required></textarea>\n</p>", __( 'Message', 'html-forms' ) ) . PHP_EOL;
384 + $html .= sprintf( "<p>\n\t<input type=\"submit\" value=\"%s\" />\n</p>", __( 'Send', 'html-forms' ) );
539 385 return $html;
540 386 }
541 387
542 - /**
543 - * Filters string and strips out all HTML tags and attributes, except what's in our whitelist.
544 - *
545 - * @param string $string The string to apply KSES whitelist on
546 - * @return string
547 - */
548 - private function kses( $string ) {
549 - $always_allowed_attr = array_fill_keys(
550 - array(
551 - 'aria-describedby',
552 - 'aria-details',
553 - 'aria-label',
554 - 'aria-labelledby',
555 - 'aria-hidden',
556 - 'aria-*',
557 - 'class',
558 - 'id',
559 - 'style',
560 - 'title',
561 - 'role',
562 - 'data-*',
563 - 'data-confirm',
564 - 'tabindex',
565 - ),
566 - true
567 - );
568 - $input_allowed_attr = array_merge(
569 - $always_allowed_attr,
570 - array_fill_keys(
571 - array(
572 - 'type',
573 - 'required',
574 - 'placeholder',
575 - 'value',
576 - 'name',
577 - 'step',
578 - 'min',
579 - 'max',
580 - 'checked',
581 - 'width',
582 - 'autocomplete',
583 - 'autofocus',
584 - 'minlength',
585 - 'maxlength',
586 - 'size',
587 - 'pattern',
588 - 'disabled',
589 - 'readonly',
590 - ),
591 - true
592 - )
593 - );
594 -
595 - $allowed = array(
596 - 'p' => $always_allowed_attr,
597 - 'label' => array_merge( $always_allowed_attr, array( 'for' => true ) ),
598 - 'input' => $input_allowed_attr,
599 - 'button' => $input_allowed_attr,
600 - 'fieldset' => $always_allowed_attr,
601 - 'legend' => $always_allowed_attr,
602 - 'ul' => $always_allowed_attr,
603 - 'ol' => $always_allowed_attr,
604 - 'li' => $always_allowed_attr,
605 - 'select' => array_merge( $input_allowed_attr, array( 'multiple' => true ) ),
606 - 'option' => array_merge( $input_allowed_attr, array( 'selected' => true ) ),
607 - 'optgroup' => array(
608 - 'disabled' => true,
609 - 'label' => true,
610 - ),
611 - 'textarea' => array_merge(
612 - $input_allowed_attr,
613 - array(
614 - 'rows' => true,
615 - 'cols' => true,
616 - )
617 - ),
618 - 'div' => $always_allowed_attr,
619 - 'strong' => $always_allowed_attr,
620 - 'b' => $always_allowed_attr,
621 - 'i' => $always_allowed_attr,
622 - 'br' => array(),
623 - 'em' => $always_allowed_attr,
624 - 'span' => $always_allowed_attr,
625 - 'a' => array_merge( $always_allowed_attr, array( 'href' => true ) ),
626 - 'img' => array_merge(
627 - $always_allowed_attr,
628 - array(
629 - 'src' => true,
630 - 'alt' => true,
631 - 'width' => true,
632 - 'height' => true,
633 - 'srcset' => true,
634 - 'sizes' => true,
635 - 'referrerpolicy' => true,
636 - 'loading' => true,
637 - 'decoding' => true,
638 - )
639 - ),
640 - 'u' => $always_allowed_attr,
641 - 'table' => $always_allowed_attr,
642 - 'tr' => $always_allowed_attr,
643 - 'td' => $always_allowed_attr,
644 - 'th' => $always_allowed_attr,
645 - 'thead' => $always_allowed_attr,
646 - 'tbody' => $always_allowed_attr,
647 - 'picture' => $always_allowed_attr,
648 - 'video' => $always_allowed_attr,
649 - );
650 -
651 - return wp_kses( $string, $allowed );
652 - }
653 388 }