PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.3.30
HTML Forms – Simple WordPress Forms Plugin v1.3.30
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 +227 -25 1.3.161.3.30 View file →
@@ -41,9 +41,19 @@
41 41 add_action( 'enqueue_block_editor_assets', array( $this, 'enqueue_gutenberg_assets' ) );
42 42 }
43 43
44 44 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' ) );
45 + wp_enqueue_script(
46 + 'html-forms-block',
47 + plugins_url( 'assets/js/gutenberg-block.js', $this->plugin_file ),
48 + array(
49 + 'wp-blocks',
50 + 'wp-i18n',
51 + 'wp-element',
52 + 'wp-components',
53 + 'wp-block-editor',
54 + )
55 + );
46 56 $forms = hf_get_forms();
47 57 $data = array();
48 58 foreach ( $forms as $form ) {
49 59 $data[] = array(
@@ -74,8 +84,9 @@
74 84 }
75 85
76 86 /**
77 87 * @param array $dirty
88 + *
78 89 * @return array
79 90 */
80 91 public function sanitize_settings( $dirty ) {
81 92 return $dirty;
@@ -81,20 +92,27 @@
81 92 return $dirty;
82 93 }
83 94
84 95 public function listen() {
85 - $request = array_merge( $_GET, $_POST );
86 - if ( empty( $request['_hf_admin_action'] ) ) {
96 + if ( isset( $_GET['_hf_admin_action'] ) ) {
97 + $action = (string) $_GET['_hf_admin_action'];
98 + } elseif ( isset( $_POST['_hf_admin_action'] ) ) {
99 + $action = (string) $_POST['_hf_admin_action'];
100 + } else {
87 101 return;
88 102 }
89 103
104 + // verify nonce
105 + if ( ! isset( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( $_REQUEST['_wpnonce'], '_hf_admin_action' ) ) {
106 + wp_nonce_ays( $action );
107 + exit;
108 + }
109 +
90 110 // do nothing if logged in user is not of role administrator
91 111 if ( ! current_user_can( 'edit_forms' ) ) {
92 112 return;
93 113 }
94 114
95 - $action = (string) $request['_hf_admin_action'];
96 -
97 115 /**
98 116 * Allows you to hook into requests containing `_hf_admin_action` => action name.
99 117 *
100 118 * The dynamic portion of the hook name, `$action`, refers to the action name.
@@ -116,12 +134,10 @@
116 134 if ( empty( $_GET['page'] ) || strpos( $_GET['page'], 'html-forms' ) !== 0 ) {
117 135 return;
118 136 }
119 137
120 - $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
121 -
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 );
138 + wp_enqueue_style( 'html-forms-admin', plugins_url( 'assets/css/admin.css', $this->plugin_file ), array(), HTML_FORMS_VERSION );
139 + wp_enqueue_script( 'html-forms-admin', plugins_url( 'assets/js/admin.js', $this->plugin_file ), array(), HTML_FORMS_VERSION, true );
124 140 wp_localize_script(
125 141 'html-forms-admin',
126 142 'hf_options',
127 143 array(
@@ -135,16 +151,67 @@
135 151 public function menu() {
136 152 $capability = 'edit_forms';
137 153 $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 154 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' ) );
155 + add_menu_page(
156 + 'HTML Forms',
157 + 'HTML Forms',
158 + $capability,
159 + 'html-forms',
160 + array(
161 + $this,
162 + 'page_overview',
163 + ),
164 + 'data:image/svg+xml;base64,' . base64_encode( $svg_icon ),
165 + '99.88491'
166 + );
167 + add_submenu_page(
168 + 'html-forms',
169 + __( 'Forms', 'html-forms' ),
170 + __( 'All Forms', 'html-forms' ),
171 + $capability,
172 + 'html-forms',
173 + array(
174 + $this,
175 + 'page_overview',
176 + )
177 + );
178 + add_submenu_page(
179 + 'html-forms',
180 + __( 'Add new form', 'html-forms' ),
181 + __( 'Add New', 'html-forms' ),
182 + $capability,
183 + 'html-forms-add-form',
184 + array(
185 + $this,
186 + 'page_new_form',
187 + )
188 + );
189 + add_submenu_page(
190 + 'html-forms',
191 + __( 'Settings', 'html-forms' ),
192 + __( 'Settings', 'html-forms' ),
193 + $capability,
194 + 'html-forms-settings',
195 + array(
196 + $this,
197 + 'page_settings',
198 + )
199 + );
143 200
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 - // }
201 + if ( ! defined( 'HF_PREMIUM_VERSION' ) ) {
202 + add_submenu_page(
203 + 'html-forms',
204 + 'Premium',
205 + '<span style="color: #ea6ea6;">Premium</span>',
206 + $capability,
207 + 'html-forms-premium',
208 + array(
209 + $this,
210 + 'page_premium',
211 + )
212 + );
213 + }
147 214 }
148 215
149 216 public function add_screen_options() {
150 217 // only run on the submissions overview page (not detail)
@@ -162,9 +229,9 @@
162 229 $submissions = hf_get_form_submissions( $_GET['form_id'] );
163 230 $columns = $this->get_submission_columns( $submissions );
164 231 add_filter(
165 232 'manage_toplevel_page_html-forms_columns',
166 - function( $unused ) use ( $columns ) {
233 + function ( $unused ) use ( $columns ) {
167 234 return $columns;
168 235 }
169 236 );
170 237 add_screen_option( 'layout_columns' );
@@ -172,8 +239,9 @@
172 239
173 240 public function page_overview() {
174 241 if ( ! empty( $_GET['view'] ) && $_GET['view'] === 'edit' ) {
175 242 $this->page_edit_form();
243 +
176 244 return;
177 245 }
178 246
179 247 $settings = hf_get_settings();
@@ -241,8 +309,9 @@
241 309 $columns[ $field ] = esc_html( ucfirst( strtolower( str_replace( '_', ' ', $field ) ) ) );
242 310 }
243 311 }
244 312 }
313 +
245 314 return $columns;
246 315 }
247 316
248 317 public function tab_submissions_list( Form $form ) {
@@ -249,9 +318,21 @@
249 318 if ( ! empty( $_GET['submission_id'] ) ) {
250 319 return;
251 320 }
252 321
253 - $submissions = hf_get_form_submissions( $form->ID );
322 + $items_per_page = 500;
323 + $total_items = hf_count_form_submissions( $form->ID );
324 + $total_pages = max( 1, ceil( $total_items / $items_per_page ) );
325 + $current_page = isset( $_GET['paged'] ) ? intval( $_GET['paged'] ) : 1;
326 + $current_page = max( 1, $current_page );
327 + $current_page = min( $total_pages, $current_page );
328 + $submissions = hf_get_form_submissions(
329 + $form->ID,
330 + array(
331 + 'limit' => $items_per_page,
332 + 'offset' => ( $current_page - 1 ) * $items_per_page,
333 + )
334 + );
254 335 $columns = $this->get_submission_columns( $submissions );
255 336 $hidden_columns = get_hidden_columns( get_current_screen() );
256 337
257 338 require dirname( $this->plugin_file ) . '/views/tab-submissions-list.php';
@@ -293,8 +374,13 @@
293 374
294 375 // Fix for MultiSite stripping KSES for roles other than administrator
295 376 remove_all_filters( 'content_save_pre' );
296 377
378 + // run our own kses filter
379 + if (!current_user_can('unfiltered_html')) {
380 + $data['markup'] = $this->kses($data['markup']);
381 + }
382 +
297 383 // strip <form> tag from markup
298 384 $data['markup'] = preg_replace( '/<\/?form(.|\s)*?>/i', '', $data['markup'] );
299 385
300 386 $form_id = wp_insert_post(
@@ -328,12 +414,13 @@
328 414
329 415 /**
330 416 * Get URL for a tab on the current page.
331 417 *
418 + * @param $tab
419 + *
420 + * @return string
332 421 * @since 3.0
333 422 * @internal
334 - * @param $tab
335 - * @return string
336 423 */
337 424 public function get_tab_url( $tab ) {
338 425 return add_query_arg( array( 'tab' => $tab ), remove_query_arg( 'tab' ) );
339 426 }
@@ -360,13 +447,15 @@
360 447 if ( empty( $_POST['id'] ) ) {
361 448 return;
362 449 }
363 450
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 ) );
451 + $args = array_map( 'intval', $_POST['id'] );
452 + $table = $wpdb->prefix . 'hf_submissions';
453 + $placeholders = rtrim( str_repeat( '%d,', count( $args ) ), ',' );
454 + $wpdb->query( $wpdb->prepare( "DELETE FROM {$table} WHERE id IN( {$placeholders} );", $args ) );
455 +
456 + $args[] = '_hf_%%';
457 + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->postmeta} WHERE post_id IN ( {$placeholders} ) AND meta_key LIKE %s;", $args ) );
369 458 }
370 459
371 460 private function get_default_form_content() {
372 461 $html = '';
@@ -374,8 +463,121 @@
374 463 $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 464 $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 465 $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 466 $html .= sprintf( "<p>\n\t<input type=\"submit\" value=\"%s\" />\n</p>", __( 'Send', 'html-forms' ) );
467 +
378 468 return $html;
379 469 }
380 470
471 +
472 + /**
473 + * Filters string and strips out all HTML tags and attributes, except what's in our whitelist.
474 + *
475 + * @param string $string The string to apply KSES whitelist on
476 + * @return string
477 + */
478 + private function kses( $string ) {
479 + $always_allowed_attr = array_fill_keys(
480 + array(
481 + 'aria-describedby',
482 + 'aria-details',
483 + 'aria-label',
484 + 'aria-labelledby',
485 + 'aria-hidden',
486 + 'aria-*',
487 + 'class',
488 + 'id',
489 + 'style',
490 + 'title',
491 + 'role',
492 + 'data-*',
493 + 'data-confirm',
494 + 'tabindex',
495 + ),
496 + true
497 + );
498 + $input_allowed_attr = array_merge(
499 + $always_allowed_attr,
500 + array_fill_keys(
501 + array(
502 + 'type',
503 + 'required',
504 + 'placeholder',
505 + 'value',
506 + 'name',
507 + 'step',
508 + 'min',
509 + 'max',
510 + 'checked',
511 + 'width',
512 + 'autocomplete',
513 + 'autofocus',
514 + 'minlength',
515 + 'maxlength',
516 + 'size',
517 + 'pattern',
518 + 'disabled',
519 + 'readonly',
520 + ),
521 + true
522 + )
523 + );
524 +
525 + $allowed = array(
526 + 'p' => $always_allowed_attr,
527 + 'label' => array_merge( $always_allowed_attr, array( 'for' => true ) ),
528 + 'input' => $input_allowed_attr,
529 + 'button' => $input_allowed_attr,
530 + 'fieldset' => $always_allowed_attr,
531 + 'legend' => $always_allowed_attr,
532 + 'ul' => $always_allowed_attr,
533 + 'ol' => $always_allowed_attr,
534 + 'li' => $always_allowed_attr,
535 + 'select' => array_merge( $input_allowed_attr, array( 'multiple' => true ) ),
536 + 'option' => array_merge( $input_allowed_attr, array( 'selected' => true ) ),
537 + 'optgroup' => array(
538 + 'disabled' => true,
539 + 'label' => true,
540 + ),
541 + 'textarea' => array_merge(
542 + $input_allowed_attr,
543 + array(
544 + 'rows' => true,
545 + 'cols' => true,
546 + )
547 + ),
548 + 'div' => $always_allowed_attr,
549 + 'strong' => $always_allowed_attr,
550 + 'b' => $always_allowed_attr,
551 + 'i' => $always_allowed_attr,
552 + 'br' => array(),
553 + 'em' => $always_allowed_attr,
554 + 'span' => $always_allowed_attr,
555 + 'a' => array_merge( $always_allowed_attr, array( 'href' => true ) ),
556 + 'img' => array_merge(
557 + $always_allowed_attr,
558 + array(
559 + 'src' => true,
560 + 'alt' => true,
561 + 'width' => true,
562 + 'height' => true,
563 + 'srcset' => true,
564 + 'sizes' => true,
565 + 'referrerpolicy' => true,
566 + 'loading' => true,
567 + 'decoding' => true,
568 + )
569 + ),
570 + 'u' => $always_allowed_attr,
571 + 'table' => $always_allowed_attr,
572 + 'tr' => $always_allowed_attr,
573 + 'td' => $always_allowed_attr,
574 + 'th' => $always_allowed_attr,
575 + 'thead' => $always_allowed_attr,
576 + 'tbody' => $always_allowed_attr,
577 + 'picture' => $always_allowed_attr,
578 + 'video' => $always_allowed_attr,
579 + );
580 +
581 + return wp_kses( $string, $allowed );
582 + }
381 583 }