PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.7.0
HTML Forms – Simple WordPress Forms Plugin v1.7.0
1.7.0 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 All 67 releases
← All changes | src/admin/class-admin.php +327 -35 1.3.151.7.0 View file →
@@ -22,14 +22,16 @@
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' ) );
26 27 add_action( 'init', array( $this, 'register_settings' ) );
27 28 add_action( 'admin_init', array( $this, 'run_migrations' ) );
28 29 add_action( 'admin_init', array( $this, 'listen' ) );
29 30 add_action( 'admin_print_styles', array( $this, 'assets' ) );
30 31 add_action( 'admin_head', array( $this, 'add_screen_options' ) );
31 - add_action( 'hf_admin_action_create_form', array( $this, 'process_create_form' ) );
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' ) );
32 34 add_action( 'hf_admin_action_save_form', array( $this, 'process_save_form' ) );
33 35 add_action( 'hf_admin_action_bulk_delete_submissions', array( $this, 'process_bulk_delete_submissions' ) );
34 36
35 37 add_action( 'hf_admin_output_form_tab_fields', array( $this, 'tab_fields' ) );
@@ -38,12 +40,25 @@
38 40 add_action( 'hf_admin_output_form_tab_actions', array( $this, 'tab_actions' ) );
39 41 add_action( 'hf_admin_output_form_tab_submissions', array( $this, 'tab_submissions_list' ) );
40 42 add_action( 'hf_admin_output_form_tab_submissions', array( $this, 'tab_submissions_detail' ) );
41 43 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_gutenberg_assets' ) );
44 + add_filter( 'set_screen_option_hf_submissions_per_page', function( $keep, $option, $value ) {
45 + return (int) $value;
46 + }, 10, 3 );
42 47 }
43 48
44 49 public function enqueue_gutenberg_assets() {
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' ) );
50 + wp_enqueue_script(
51 + 'html-forms-block',
52 + plugins_url( 'assets/js/gutenberg-block.js', $this->plugin_file ),
53 + array(
54 + 'wp-blocks',
55 + 'wp-i18n',
56 + 'wp-element',
57 + 'wp-components',
58 + 'wp-block-editor',
59 + )
60 + );
46 61 $forms = hf_get_forms();
47 62 $data = array();
48 63 foreach ( $forms as $form ) {
49 64 $data[] = array(
@@ -74,27 +89,59 @@
74 89 }
75 90
76 91 /**
77 92 * @param array $dirty
93 + *
78 94 * @return array
79 95 */
80 96 public function sanitize_settings( $dirty ) {
97 + $int_fields = array( 'enable_nonce', 'load_stylesheet', 'direct_links', 'media_library_uploads', 'maximum_filesize' );
98 + foreach ( $int_fields as $field ) {
99 + if ( isset( $dirty[ $field ] ) ) {
100 + $dirty[ $field ] = absint( $dirty[ $field ] );
101 + }
102 + }
103 +
104 + if ( isset( $dirty['wrapper_tag'] ) ) {
105 + $allowed_tags = array( 'p', 'div', 'span' );
106 + $dirty['wrapper_tag'] = in_array( $dirty['wrapper_tag'], $allowed_tags, true ) ? $dirty['wrapper_tag'] : 'p';
107 + }
108 +
109 + if ( isset( $dirty['submissions_export_delimiter'] ) ) {
110 + $dirty['submissions_export_delimiter'] = sanitize_text_field( $dirty['submissions_export_delimiter'] );
111 + }
112 +
113 + if ( isset( $dirty['google_recaptcha'] ) && is_array( $dirty['google_recaptcha'] ) ) {
114 + foreach ( array( 'site_key', 'secret_key' ) as $key ) {
115 + if ( isset( $dirty['google_recaptcha'][ $key ] ) ) {
116 + $dirty['google_recaptcha'][ $key ] = sanitize_text_field( $dirty['google_recaptcha'][ $key ] );
117 + }
118 + }
119 + }
120 +
81 121 return $dirty;
82 122 }
83 123
84 124 public function listen() {
85 - $request = array_merge( $_GET, $_POST );
86 - if ( empty( $request['_hf_admin_action'] ) ) {
125 + if ( isset( $_GET['_hf_admin_action'] ) ) {
126 + $action = (string) $_GET['_hf_admin_action'];
127 + } elseif ( isset( $_POST['_hf_admin_action'] ) ) {
128 + $action = (string) $_POST['_hf_admin_action'];
129 + } else {
87 130 return;
88 131 }
89 132
133 + // verify nonce
134 + if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], '_hf_admin_action' ) ) {
135 + wp_nonce_ays( $action );
136 + exit;
137 + }
138 +
90 139 // do nothing if logged in user is not of role administrator
91 140 if ( ! current_user_can( 'edit_forms' ) ) {
92 141 return;
93 142 }
94 143
95 - $action = (string) $request['_hf_admin_action'];
96 -
97 144 /**
98 145 * Allows you to hook into requests containing `_hf_admin_action` => action name.
99 146 *
100 147 * The dynamic portion of the hook name, `$action`, refers to the action name.
@@ -116,12 +163,12 @@
116 163 if ( empty( $_GET['page'] ) || strpos( $_GET['page'], 'html-forms' ) !== 0 ) {
117 164 return;
118 165 }
119 166
120 - $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
167 + $settings = hf_get_settings();
121 168
122 - wp_enqueue_style( 'html-forms-admin', plugins_url( 'assets/css/admin' . $suffix . '.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
123 - wp_enqueue_script( 'html-forms-admin', plugins_url( 'assets/js/admin' . $suffix . '.js', $this->plugin_file ), array(), HTML_FORMS_VERSION, true );
169 + wp_enqueue_style( 'html-forms-admin', plugins_url( 'assets/css/admin.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
170 + wp_enqueue_script( 'html-forms-admin', plugins_url( 'assets/js/admin.js', $this->plugin_file ), array(), HTML_FORMS_VERSION, true );
124 171 wp_localize_script(
125 172 'html-forms-admin',
126 173 'hf_options',
127 174 array(
@@ -127,8 +174,9 @@
127 174 array(
128 175 'page' => $_GET['page'],
129 176 'view' => empty( $_GET['view'] ) ? '' : $_GET['view'],
130 177 'form_id' => empty( $_GET['form_id'] ) ? 0 : (int) $_GET['form_id'],
178 + 'wrapper_tag' => empty( $settings['wrapper_tag'] ) ? 'p' : $settings['wrapper_tag'],
131 179 )
132 180 );
133 181 }
134 182
@@ -133,20 +181,79 @@
133 181 }
134 182
135 183 public function menu() {
136 184 $capability = 'edit_forms';
137 - $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)"
138 - 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>';
139 - 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' );
140 - add_submenu_page( 'html-forms', __( 'Forms', 'html-forms' ), __( 'All Forms', 'html-forms' ), $capability, 'html-forms', array( $this, 'page_overview' ) );
141 - add_submenu_page( 'html-forms', __( 'Add new form', 'html-forms' ), __( 'Add New', 'html-forms' ), $capability, 'html-forms-add-form', array( $this, 'page_new_form' ) );
142 - add_submenu_page( 'html-forms', __( 'Settings', 'html-forms' ), __( 'Settings', 'html-forms' ), $capability, 'html-forms-settings', array( $this, 'page_settings' ) );
185 +
186 + add_menu_page(
187 + 'HTML Forms',
188 + 'HTML Forms',
189 + $capability,
190 + 'html-forms',
191 + array(
192 + $this,
193 + 'page_overview',
194 + ),
195 + 'none',
196 + '99.88491'
197 + );
143 198
144 - // if( ! defined( 'HF_PREMIUM_VERSION' ) ) {
145 - // add_submenu_page( 'html-forms', 'Premium', '<span style="color: #ea6ea6;">Premium</span>', $capability, 'html-forms-premium', array( $this, 'page_premium' ) );
146 - // }
199 + add_submenu_page(
200 + 'html-forms',
201 + __( 'Forms', 'html-forms' ),
202 + __( 'All Forms', 'html-forms' ),
203 + $capability,
204 + 'html-forms',
205 + array(
206 + $this,
207 + 'page_overview',
208 + )
209 + );
210 +
211 + add_submenu_page(
212 + 'html-forms',
213 + __( 'Add New Form', 'html-forms' ),
214 + __( 'Add New', 'html-forms' ),
215 + $capability,
216 + 'html-forms-add-form',
217 + array(
218 + $this,
219 + 'page_new_form',
220 + )
221 + );
222 +
223 + add_submenu_page(
224 + 'html-forms',
225 + __( 'Settings', 'html-forms' ),
226 + __( 'Settings', 'html-forms' ),
227 + $capability,
228 + 'html-forms-settings',
229 + array(
230 + $this,
231 + 'page_settings',
232 + )
233 + );
234 +
235 + if ( ! defined( 'HF_PREMIUM_VERSION' ) ) {
236 + add_submenu_page(
237 + 'html-forms',
238 + 'Premium',
239 + '<span style="color: #ea6ea6;">Premium</span>',
240 + $capability,
241 + 'html-forms-premium',
242 + array(
243 + $this,
244 + 'page_premium',
245 + )
246 + );
247 + }
147 248 }
148 249
250 + public function menu_icon() {
251 + $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>');
252 +
253 + 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; }' );
254 + }
255 +
149 256 public function add_screen_options() {
150 257 // only run on the submissions overview page (not detail)
151 258 if ( empty( $_GET['page'] ) || $_GET['page'] !== 'html-forms' || empty( $_GET['view'] ) || $_GET['view'] !== 'edit' || empty( $_GET['form_id'] ) || ! empty( $_GET['submission_id'] ) ) {
152 259 return;
@@ -162,18 +269,24 @@
162 269 $submissions = hf_get_form_submissions( $_GET['form_id'] );
163 270 $columns = $this->get_submission_columns( $submissions );
164 271 add_filter(
165 272 'manage_toplevel_page_html-forms_columns',
166 - function( $unused ) use ( $columns ) {
273 + function ( $unused ) use ( $columns ) {
167 274 return $columns;
168 275 }
169 276 );
170 277 add_screen_option( 'layout_columns' );
278 + add_screen_option( 'per_page', array(
279 + 'label' => __( 'Submissions per page', 'html-forms' ),
280 + 'default' => 20,
281 + 'option' => 'hf_submissions_per_page',
282 + ) );
171 283 }
172 284
173 285 public function page_overview() {
174 286 if ( ! empty( $_GET['view'] ) && $_GET['view'] === 'edit' ) {
175 287 $this->page_edit_form();
288 +
176 289 return;
177 290 }
178 291
179 292 $settings = hf_get_settings();
@@ -189,8 +302,10 @@
189 302 }
190 303
191 304 public function page_settings() {
192 305 $settings = hf_get_settings();
306 + $wrapper_tags = array ( 'p', 'div', 'span' );
307 +
193 308 require dirname( $this->plugin_file ) . '/views/page-global-settings.php';
194 309 }
195 310
196 311 public function page_premium() {
@@ -241,8 +356,9 @@
241 356 $columns[ $field ] = esc_html( ucfirst( strtolower( str_replace( '_', ' ', $field ) ) ) );
242 357 }
243 358 }
244 359 }
360 +
245 361 return $columns;
246 362 }
247 363
248 364 public function tab_submissions_list( Form $form ) {
@@ -249,9 +365,33 @@
249 365 if ( ! empty( $_GET['submission_id'] ) ) {
250 366 return;
251 367 }
252 368
253 - $submissions = hf_get_form_submissions( $form->ID );
369 + $items_per_page = (int) get_user_option( 'hf_submissions_per_page' );
370 + if ( $items_per_page < 1 ) {
371 + $items_per_page = 20;
372 + }
373 +
374 + $allowed_orderby = array( 'submitted_at' );
375 + $orderby = isset( $_GET['orderby'] ) && in_array( $_GET['orderby'], $allowed_orderby, true ) ? $_GET['orderby'] : 'submitted_at';
376 + $order = isset( $_GET['order'] ) && strtolower( $_GET['order'] ) === 'asc' ? 'asc' : 'desc';
377 + $search = isset( $_GET['s'] ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : '';
378 +
379 + $total_items = hf_count_form_submissions( $form->ID, $search );
380 + $total_pages = max( 1, ceil( $total_items / $items_per_page ) );
381 + $current_page = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 1;
382 + $current_page = max( 1, $current_page );
383 + $current_page = min( $total_pages, $current_page );
384 + $submissions = hf_get_form_submissions(
385 + $form->ID,
386 + array(
387 + 'limit' => $items_per_page,
388 + 'offset' => ( $current_page - 1 ) * $items_per_page,
389 + 'orderby' => $orderby,
390 + 'order' => $order,
391 + 'search' => $search,
392 + )
393 + );
254 394 $columns = $this->get_submission_columns( $submissions );
255 395 $hidden_columns = get_hidden_columns( get_current_screen() );
256 396
257 397 require dirname( $this->plugin_file ) . '/views/tab-submissions-list.php';
@@ -262,12 +402,12 @@
262 402 return;
263 403 }
264 404
265 405 $submission = hf_get_form_submission( (int) $_GET['submission_id'] );
406 + do_action( 'hf_admin_form_submissions_detail', $submission );
266 407 require dirname( $this->plugin_file ) . '/views/tab-submissions-detail.php';
267 408 }
268 409
269 -
270 410 public function process_create_form() {
271 411 // Fix for MultiSite stripping KSES for roles other than administrator
272 412 remove_all_filters( 'content_save_pre' );
273 413
@@ -293,8 +433,13 @@
293 433
294 434 // Fix for MultiSite stripping KSES for roles other than administrator
295 435 remove_all_filters( 'content_save_pre' );
296 436
437 + // run our own kses filter
438 + if ( ! current_user_can( 'unfiltered_html' ) ) {
439 + $data['markup'] = $this->kses( $data['markup'] );
440 + }
441 +
297 442 // strip <form> tag from markup
298 443 $data['markup'] = preg_replace( '/<\/?form(.|\s)*?>/i', '', $data['markup'] );
299 444
300 445 $form_id = wp_insert_post(
@@ -308,14 +453,26 @@
308 453 )
309 454 );
310 455
311 456 if ( ! empty( $data['settings'] ) ) {
457 + // Reject redirect URLs with non-http(s) schemes
458 + if ( isset( $data['settings']['redirect_url'] ) && $data['settings']['redirect_url'] !== '' ) {
459 + $scheme = wp_parse_url( $data['settings']['redirect_url'], PHP_URL_SCHEME );
460 + if ( $scheme !== null && ! in_array( strtolower( $scheme ), array( 'http', 'https' ), true ) ) {
461 + $data['settings']['redirect_url'] = '';
462 + }
463 + }
464 +
312 465 update_post_meta( $form_id, '_hf_settings', $data['settings'] );
313 466 }
314 467
315 468 // save form messages in individual meta keys
316 469 foreach ( $data['messages'] as $key => $message ) {
317 - update_post_meta( $form_id, 'hf_message_' . $key, $message );
470 + if ( current_user_can( 'unfiltered_html' ) ) {
471 + update_post_meta( $form_id, 'hf_message_' . $key, $message );
472 + } else {
473 + update_post_meta( $form_id, 'hf_message_' . $key, wp_kses_post( $message ) );
474 + }
318 475 }
319 476
320 477 $redirect_url_args = array(
321 478 'form_id' => $form_id,
@@ -328,15 +485,36 @@
328 485
329 486 /**
330 487 * Get URL for a tab on the current page.
331 488 *
489 + * @param $tab
490 + *
491 + * @return string
332 492 * @since 3.0
333 493 * @internal
334 - * @param $tab
335 - * @return string
336 494 */
337 495 public function get_tab_url( $tab ) {
338 - return add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) );
496 + $tab_url = add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) );
497 +
498 + $url_parts = parse_url($tab_url);
499 + if ( isset( $url_parts['query'] ) ) {
500 + parse_str( $url_parts['query'], $query_params );
501 +
502 + if ( isset( $query_params['submission_id'] ) ) {
503 + unset( $query_params['submission_id'] );
504 + }
505 +
506 + $new_query = http_build_query( $query_params );
507 + $new_tab_url = $url_parts['path'];
508 +
509 + if ( ! empty( $new_query ) ) {
510 + $new_tab_url .= '?' . $new_query;
511 + }
512 +
513 + return $new_tab_url;
514 + }
515 +
516 + return $tab_url;
339 517 }
340 518
341 519 /**
342 520 * @return array
@@ -360,22 +538,136 @@
360 538 if ( empty( $_POST['id'] ) ) {
361 539 return;
362 540 }
363 541
364 - $ids = $_POST['id'];
365 - $table = $wpdb->prefix . 'hf_submissions';
366 - $ids = join( ',', array_map( 'esc_sql', $ids ) );
367 - $wpdb->query( sprintf( "DELETE FROM {$table} WHERE id IN( %s );", $ids ) );
368 - $wpdb->query( sprintf( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN ( %s ) AND meta_key LIKE '_hf_%%';", $ids ) );
542 + $args = array_map( 'intval', $_POST['id'] );
543 + $table = $wpdb->prefix . 'hf_submissions';
544 + $placeholders = rtrim( str_repeat( '%d,', count( $args ) ), ',' );
545 + $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE id IN( {$placeholders} );", $args ) );
369 546 }
370 547
371 548 private function get_default_form_content() {
549 + $settings = hf_get_settings();
550 + $wrapper_tag = ( isset( $settings['wrapper_tag'] ) ) ? $settings['wrapper_tag'] : 'p';
551 +
372 552 $html = '';
373 - $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;
374 - $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;
375 - $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;
376 - $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;
377 - $html .= sprintf( "<p>\n\t<input type=\"submit\" value=\"%s\" />\n</p>", __( 'Send', 'html-forms' ) );
553 + $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;
554 + $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;
555 + $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;
556 + $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;
557 + $html .= sprintf( "<%1\$s>\n\t<input type=\"submit\" value=\"%2\$s\" />\n</%1\$s>", $wrapper_tag, __( 'Send', 'html-forms' ) );
558 +
378 559 return $html;
379 560 }
380 561
562 + /**
563 + * Filters string and strips out all HTML tags and attributes, except what's in our whitelist.
564 + *
565 + * @param string $string The string to apply KSES whitelist on
566 + * @return string
567 + */
568 + private function kses( $string ) {
569 + $always_allowed_attr = array_fill_keys(
570 + array(
571 + 'aria-describedby',
572 + 'aria-details',
573 + 'aria-label',
574 + 'aria-labelledby',
575 + 'aria-hidden',
576 + 'aria-*',
577 + 'class',
578 + 'id',
579 + 'style',
580 + 'title',
581 + 'role',
582 + 'data-*',
583 + 'data-confirm',
584 + 'tabindex',
585 + ),
586 + true
587 + );
588 + $input_allowed_attr = array_merge(
589 + $always_allowed_attr,
590 + array_fill_keys(
591 + array(
592 + 'type',
593 + 'required',
594 + 'placeholder',
595 + 'value',
596 + 'name',
597 + 'step',
598 + 'min',
599 + 'max',
600 + 'checked',
601 + 'width',
602 + 'autocomplete',
603 + 'autofocus',
604 + 'minlength',
605 + 'maxlength',
606 + 'size',
607 + 'pattern',
608 + 'disabled',
609 + 'readonly',
610 + ),
611 + true
612 + )
613 + );
614 +
615 + $allowed = array(
616 + 'p' => $always_allowed_attr,
617 + 'label' => array_merge( $always_allowed_attr, array( 'for' => true ) ),
618 + 'input' => $input_allowed_attr,
619 + 'button' => $input_allowed_attr,
620 + 'fieldset' => $always_allowed_attr,
621 + 'legend' => $always_allowed_attr,
622 + 'ul' => $always_allowed_attr,
623 + 'ol' => $always_allowed_attr,
624 + 'li' => $always_allowed_attr,
625 + 'select' => array_merge( $input_allowed_attr, array( 'multiple' => true ) ),
626 + 'option' => array_merge( $input_allowed_attr, array( 'selected' => true ) ),
627 + 'optgroup' => array(
628 + 'disabled' => true,
629 + 'label' => true,
630 + ),
631 + 'textarea' => array_merge(
632 + $input_allowed_attr,
633 + array(
634 + 'rows' => true,
635 + 'cols' => true,
636 + )
637 + ),
638 + 'div' => $always_allowed_attr,
639 + 'strong' => $always_allowed_attr,
640 + 'b' => $always_allowed_attr,
641 + 'i' => $always_allowed_attr,
642 + 'br' => array(),
643 + 'em' => $always_allowed_attr,
644 + 'span' => $always_allowed_attr,
645 + 'a' => array_merge( $always_allowed_attr, array( 'href' => true ) ),
646 + 'img' => array_merge(
647 + $always_allowed_attr,
648 + array(
649 + 'src' => true,
650 + 'alt' => true,
651 + 'width' => true,
652 + 'height' => true,
653 + 'srcset' => true,
654 + 'sizes' => true,
655 + 'referrerpolicy' => true,
656 + 'loading' => true,
657 + 'decoding' => true,
658 + )
659 + ),
660 + 'u' => $always_allowed_attr,
661 + 'table' => $always_allowed_attr,
662 + 'tr' => $always_allowed_attr,
663 + 'td' => $always_allowed_attr,
664 + 'th' => $always_allowed_attr,
665 + 'thead' => $always_allowed_attr,
666 + 'tbody' => $always_allowed_attr,
667 + 'picture' => $always_allowed_attr,
668 + 'video' => $always_allowed_attr,
669 + );
670 +
671 + return wp_kses( $string, $allowed );
672 + }
381 673 }