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/functions.php +457 -152 1.2.01.7.0 View file →
@@ -1,11 +1,29 @@
1 1 <?php
2 2
3 3 use HTML_Forms\Form;
4 4 use HTML_Forms\Submission;
5 -use WP_Post;
6 5
7 6 /**
7 + * @param array $args
8 + * @return array
9 + */
10 +function hf_get_forms( array $args = array() ) {
11 + $default_args = array(
12 + 'post_type' => 'html-form',
13 + 'post_status' => array( 'publish', 'draft', 'pending', 'future' ),
14 + 'posts_per_page' => -1,
15 + 'ignore_sticky_posts' => true,
16 + 'no_found_rows' => true,
17 + );
18 + $args = array_merge( $default_args, $args );
19 + $query = new WP_Query;
20 + $posts = $query->query( $args );
21 + $forms = array_map( 'hf_get_form', $posts );
22 + return $forms;
23 +}
24 +
25 +/**
8 26 * @param $form_id_or_slug int|string|WP_Post
9 27 * @return Form
10 28 * @throws Exception
11 29 */
@@ -10,95 +28,129 @@
10 28 * @throws Exception
11 29 */
12 30 function hf_get_form( $form_id_or_slug ) {
13 31
14 - if( is_numeric( $form_id_or_slug ) || $form_id_or_slug instanceof WP_Post ) {
15 - $post = get_post( $form_id_or_slug );
32 + if ( is_numeric( $form_id_or_slug ) || $form_id_or_slug instanceof WP_Post ) {
33 + $post = get_post( $form_id_or_slug );
16 34
17 - if( ! $post || $post->post_type !== 'html-form' ) {
18 - throw new Exception( "Invalid form ID" );
19 - }
20 - } else {
21 - $posts = get_posts(
22 - array(
23 - 'post_type' => 'html-form',
24 - 'name' => $form_id_or_slug,
25 - 'post_status' => 'publish',
26 - 'numberposts' => 1,
27 - )
28 - );
35 + if ( ! $post instanceof WP_Post || $post->post_type !== 'html-form' ) {
36 + throw new Exception( 'Invalid form ID' );
37 + }
38 + } else {
29 39
30 - if( empty( $posts ) ) {
31 - throw new Exception( 'Invalid form slug' );
32 - }
33 - $post = $posts[0];
34 - }
40 + $query = new WP_Query;
41 + $posts = $query->query(
42 + array(
43 + 'post_type' => 'html-form',
44 + 'name' => $form_id_or_slug,
45 + 'post_status' => 'publish',
46 + 'posts_per_page' => 1,
47 + 'ignore_sticky_posts' => true,
48 + 'no_found_rows' => true,
49 + )
50 + );
51 + if ( empty( $posts ) ) {
52 + throw new Exception( 'Invalid form slug' );
53 + }
54 + $post = $posts[0];
55 + }
35 56
36 - // get all post meta in a single call for performance
37 - $post_meta = get_post_meta( $post->ID );
57 + // get all post meta in a single call for performance
58 + $post_meta = get_post_meta( $post->ID );
38 59
39 - // grab & merge form settings
40 - $default_settings = array(
41 - 'save_submissions' => 1,
42 - 'hide_after_success' => 0,
43 - 'redirect_url' => '',
44 - 'required_fields' =>'',
45 - 'email_fields' => '',
46 - );
47 - $default_settings = apply_filters( 'hf_form_default_settings', $default_settings );
48 - $settings = array();
49 - if( ! empty( $post_meta['_hf_settings'][0] ) ) {
50 - $settings = (array) maybe_unserialize( $post_meta['_hf_settings'][0] );
51 - }
52 - $settings = array_merge( $default_settings, $settings );
60 + // grab & merge form settings
61 + $default_settings = array(
62 + 'save_submissions' => 1,
63 + 'hide_after_success' => 0,
64 + 'redirect_url' => '',
65 + 'required_fields' => '',
66 + 'email_fields' => '',
67 + );
68 + $default_settings = apply_filters( 'hf_form_default_settings', $default_settings );
69 + $settings = array();
70 + if ( ! empty( $post_meta['_hf_settings'][0] ) ) {
71 + $settings = (array) maybe_unserialize( $post_meta['_hf_settings'][0] );
72 + }
73 + $settings = array_merge( $default_settings, $settings );
53 74
54 - // grab & merge form messages
55 - $default_messages = array(
56 - 'success' => __('Thank you! We will be in touch soon.', 'html-forms'),
57 - 'invalid_email' => __( 'Sorry, that email address looks invalid.', 'html-forms' ),
58 - 'required_field_missing' => __( "Please fill in the required fields.", "html-forms" ),
59 - 'error' => __( 'Oops. An error occurred.', 'html-forms' ),
60 - );
61 - $messages = array();
62 - foreach( $post_meta as $meta_key => $meta_values ) {
63 - if( strpos( $meta_key, 'hf_message_' ) === 0 ) {
64 - $message_key = substr( $meta_key, strlen( 'hf_message_' ) );
65 - $messages[$message_key] = (string) $meta_values[0];
66 - }
67 - }
68 - $messages = array_merge( $default_messages, $messages );
75 + // grab & merge form messages
76 + $default_messages = array(
77 + 'success' => __( 'Thank you! We will be in touch soon.', 'html-forms' ),
78 + 'invalid_email' => __( 'Sorry, that email address looks invalid.', 'html-forms' ),
79 + 'required_field_missing' => __( 'Please fill in the required fields.', 'html-forms' ),
80 + 'error' => __( 'Oops. An error occurred.', 'html-forms' ),
81 + 'recaptcha_failed' => __( 'reCAPTCHA verification failed. Please try again.', 'html-forms' ),
82 + 'recaptcha_low_score' => __( 'Your submission appears to be spam. Please try again.', 'html-forms' ),
83 + );
84 + $default_messages = apply_filters( 'hf_form_default_messages', $default_messages );
85 + $messages = array();
86 + foreach ( $post_meta as $meta_key => $meta_values ) {
87 + if ( strpos( $meta_key, 'hf_message_' ) === 0 ) {
88 + $message_key = substr( $meta_key, strlen( 'hf_message_' ) );
89 + $messages[ $message_key ] = (string) $meta_values[0];
90 + }
91 + }
92 + $messages = array_merge( $default_messages, $messages );
69 93
70 - // finally, create form instance
71 - $form = new Form( $post->ID );
72 - $form->title = $post->post_title;
73 - $form->slug = $post->post_name;
74 - $form->markup = $post->post_content;
75 - $form->settings = $settings;
76 - $form->messages = $messages;
77 - return $form;
94 + // finally, create form instance
95 + $form = new Form( $post->ID );
96 + $form->title = $post->post_title;
97 + $form->slug = $post->post_name;
98 + $form->markup = $post->post_content;
99 + $form->settings = $settings;
100 + $form->messages = $messages;
101 + return $form;
78 102 }
79 103
80 104 /**
81 105 * @param $form_id
106 + * @return int
107 + */
108 +function hf_count_form_submissions( $form_id, $search = '' ) {
109 + global $wpdb;
110 + $table = $wpdb->prefix . 'hf_submissions';
111 + if ( $search !== '' ) {
112 + $result = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} s WHERE s.form_id = %d AND s.data LIKE %s;", $form_id, '%' . $wpdb->esc_like( $search ) . '%' ) );
113 + } else {
114 + $result = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} s WHERE s.form_id = %d;", $form_id ) );
115 + }
116 + return (int) $result;
117 +}
118 +
119 +/**
120 + * @param $form_id
82 121 * @param array $args
83 122 * @return Submission[]
84 123 */
85 124 function hf_get_form_submissions( $form_id, array $args = array() ) {
86 - $default_args = array(
87 - 'offset' => 0,
88 - 'limit' => 1000,
89 - );
90 - $args = array_merge( $default_args, $args );
125 + $default_args = array(
126 + 'offset' => 0,
127 + 'limit' => 1000,
128 + 'orderby' => 'submitted_at',
129 + 'order' => 'DESC',
130 + 'search' => '',
131 + );
132 + $args = array_merge( $default_args, $args );
91 133
92 - global $wpdb;
93 - $table = $wpdb->prefix .'hf_submissions';
94 - $results = $wpdb->get_results( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.form_id = %d ORDER BY s.submitted_at DESC LIMIT %d, %d;", $form_id, $args['offset'], $args['limit'] ), OBJECT_K );
95 - $submissions = array();
96 - foreach( $results as $key => $object ) {
97 - $submission = Submission::from_object( $object );
98 - $submissions[$key] = $submission;
99 - }
100 - return $submissions;
134 + $allowed_orderby = array( 'submitted_at', 'id' );
135 + $orderby = in_array( $args['orderby'], $allowed_orderby, true ) ? $args['orderby'] : 'submitted_at';
136 + $order = strtoupper( $args['order'] ) === 'ASC' ? 'ASC' : 'DESC';
137 +
138 + global $wpdb;
139 + $table = $wpdb->prefix . 'hf_submissions';
140 + if ( $args['search'] !== '' ) {
141 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby and $order are whitelisted above
142 + $results = $wpdb->get_results( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.form_id = %d AND s.data LIKE %s ORDER BY s.{$orderby} {$order} LIMIT %d, %d;", $form_id, '%' . $wpdb->esc_like( $args['search'] ) . '%', $args['offset'], $args['limit'] ), OBJECT_K );
143 + } else {
144 + // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $orderby and $order are whitelisted above
145 + $results = $wpdb->get_results( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.form_id = %d ORDER BY s.{$orderby} {$order} LIMIT %d, %d;", $form_id, $args['offset'], $args['limit'] ), OBJECT_K );
146 + }
147 + $submissions = array();
148 + foreach ( $results as $key => $object ) {
149 + $submission = Submission::from_object( $object );
150 + $submissions[ $key ] = $submission;
151 + }
152 + return $submissions;
101 153 }
102 154
103 155 /**
104 156 * @param int $submission_id
@@ -104,35 +156,55 @@
104 156 * @param int $submission_id
105 157 * @return Submission
106 158 */
107 159 function hf_get_form_submission( $submission_id ) {
108 - global $wpdb;
109 - $table = $wpdb->prefix .'hf_submissions';
110 - $object = $wpdb->get_row( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.id = %d;", $submission_id ), OBJECT );
111 - $submission = Submission::from_object( $object );
112 - return $submission;
160 + global $wpdb;
161 + $table = $wpdb->prefix . 'hf_submissions';
162 + $object = $wpdb->get_row( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.id = %d;", $submission_id ), OBJECT );
163 + $submission = Submission::from_object( $object );
164 + return $submission;
113 165 }
114 166 /**
115 167 * @return array
116 168 */
117 169 function hf_get_settings() {
118 - $default_settings = array(
119 - 'load_stylesheet' => 0,
120 - );
170 + $default_settings = array(
171 + 'enable_nonce' => 0,
172 + 'load_stylesheet' => 0,
173 + 'wrapper_tag' => 'p',
174 + 'google_recaptcha' => array(
175 + 'site_key' => '',
176 + 'secret_key' => '',
177 + ),
178 + );
121 179
122 - $settings = get_option( 'hf_settings', array() );
180 + $settings = get_option( 'hf_settings', null );
123 181
124 - // merge with default settings
125 - $settings = array_merge( $default_settings, $settings );
182 + // prevent a SQL query when option does not yet exist
183 + if ( $settings === null ) {
184 + update_option( 'hf_settings', array(), true );
185 + $settings = array();
186 + }
126 187
127 - /**
128 - * Filters the global HTML Forms hf_settings
129 - *
130 - * @param array $settings
131 - */
132 - $settings = apply_filters( 'hf_settings', $settings );
188 + // merge with default settings
189 + $settings = array_merge( $default_settings, $settings );
190 +
191 + // Ensure nested arrays are properly merged
192 + if ( isset( $default_settings['google_recaptcha'] ) ) {
193 + $settings['google_recaptcha'] = array_merge(
194 + $default_settings['google_recaptcha'],
195 + isset( $settings['google_recaptcha'] ) ? $settings['google_recaptcha'] : array()
196 + );
197 + }
133 198
134 - return $settings;
199 + /**
200 + * Filters the global HTML Forms hf_settings
201 + *
202 + * @param array $settings
203 + */
204 + $settings = apply_filters( 'hf_settings', $settings );
205 +
206 + return $settings;
135 207 }
136 208
137 209 /**
138 210 * Get element from array, allows for dot notation eg: "foo.bar"
@@ -142,25 +214,25 @@
142 214 * @param mixed $default
143 215 * @return mixed
144 216 */
145 217 function hf_array_get( $array, $key, $default = null ) {
146 - if ( is_null( $key ) ) {
147 - return $array;
148 - }
218 + if ( is_null( $key ) ) {
219 + return $array;
220 + }
149 221
150 - if ( isset( $array[$key] ) ) {
151 - return $array[$key];
152 - }
222 + if ( isset( $array[ $key ] ) ) {
223 + return $array[ $key ];
224 + }
153 225
154 - foreach (explode( '.', $key ) as $segment) {
155 - if ( ! is_array( $array ) || ! array_key_exists( $segment, $array ) ) {
156 - return $default;
157 - }
226 + foreach ( explode( '.', $key ) as $segment ) {
227 + if ( ! is_array( $array ) || ! array_key_exists( $segment, $array ) ) {
228 + return $default;
229 + }
158 230
159 - $array = $array[$segment];
160 - }
231 + $array = $array[ $segment ];
232 + }
161 233
162 - return $array;
234 + return $array;
163 235 }
164 236
165 237 /**
166 238 * Processes template tags like {{user.user_email}}
@@ -169,74 +241,307 @@
169 241 *
170 242 * @return string
171 243 */
172 244 function hf_template( $template ) {
173 - $replacers = new HTML_Forms\TagReplacers();
174 - $tags = array(
175 - 'user' => array( $replacers, 'user' ),
176 - 'post' => array( $replacers, 'post'),
177 - 'url_params' => array( $replacers, 'url_params' ),
178 - );
245 + $replacers = new HTML_Forms\TagReplacers();
246 + $tags = array(
247 + 'user' => array( $replacers, 'user' ),
248 + 'post' => array( $replacers, 'post' ),
249 + 'url_params' => array( $replacers, 'url_params' ),
250 + );
179 251
180 - /**
181 - * Filters the available tags in HTML Forms templates, like {{user.user_email}}.
182 - *
183 - * Can be used to add simple scalar replacements or more advanced replacement functions that accept a parameter.
184 - *
185 - * @param array $tags
186 - */
187 - $tags = apply_filters( 'hf_template_tags', $tags );
252 + /**
253 + * Filters the available tags in HTML Forms templates, like {{user.user_email}}.
254 + *
255 + * Can be used to add simple scalar replacements or more advanced replacement functions that accept a parameter.
256 + *
257 + * @param array $tags
258 + */
259 + $tags = apply_filters( 'hf_template_tags', $tags );
188 260
189 - $template = preg_replace_callback( '/\{\{ *(\w+)(?:\.([\w\.]+))? *(?:\|\| *(\w+))? *\}\}/', function( $matches ) use ( $tags ) {
190 - $tag = $matches[1];
191 - $param = ! isset( $matches[2] ) ? "" : $matches[2];
192 - $default = ! isset( $matches[3] ) ? "" : $matches[3];
193 - $value = "";
261 + $template = preg_replace_callback(
262 + '/\{\{ *(\w+)(?:\.([\w\.]+))? *(?:\|\| *(\w+))? *\}\}/',
263 + function( $matches ) use ( $tags ) {
264 + $tag = $matches[1];
265 + $param = ! isset( $matches[2] ) ? '' : $matches[2];
266 + $default = ! isset( $matches[3] ) ? '' : $matches[3];
194 267
195 - // do not change anything if we have no replacer with that key, could be custom user logic or another plugin.
196 - if( ! isset( $tags[ $tag] ) ) {
197 - return $matches[0];
198 - }
268 + // do not change anything if we have no replacer with that key, could be custom user logic or another plugin.
269 + if ( ! isset( $tags[ $tag ] ) ) {
270 + return $matches[0];
271 + }
199 272
200 - $replacement = $tags[$tag];
201 - $value = is_callable( $replacement ) ? call_user_func_array( $replacement, array( $param ) ) : $replacement;
202 - return ! empty( $value ) ? $value : $default;
203 - }, $template );
273 + $replacement = $tags[ $tag ];
274 + $value = is_callable( $replacement ) ? call_user_func_array( $replacement, array( $param ) ) : $replacement;
275 + return ! empty( $value ) ? $value : $default;
276 + },
277 + $template
278 + );
204 279
205 - return $template;
280 + return $template;
206 281 }
207 282
208 283 /**
209 284 * @param string $string
210 285 * @param array $data
211 - *
286 + * @param Closure|string $escape_function
212 287 * @return string
213 288 */
214 -function hf_replace_data_variables( $string, $data = array() ) {
215 - $string = preg_replace_callback( '/\[([a-zA-Z0-9\-\._]+)\]/', function( $matches ) use ( $data ) {
216 - $key = $matches[1];
217 - $replacement = hf_array_get( $data, $key, '' );
218 - $replacement = is_array( $replacement ) ? join( ', ', $replacement ) : $replacement;
219 - return $replacement;
220 - }, $string );
221 - return $string;
289 +function hf_replace_data_variables( $string, Submission $submission, $escape_function = null ) {
290 + $data = ( !empty( $submission->data ) ? $submission->data : array() );
291 + $submission_fields = array( 'HF_TIMESTAMP', 'HF_USER_AGENT', 'HF_IP_ADDRESS', 'HF_REFERRER_URL' );
292 +
293 + return preg_replace_callback(
294 + '/\[(.+?)\]/',
295 + function( $matches ) use ( $submission, $submission_fields, $escape_function ) {
296 + $key = $matches[1];
297 +
298 + if ( in_array( $key, $submission_fields ) ) {
299 + $replacement = '';
300 +
301 + switch ( $key ) {
302 + case 'HF_TIMESTAMP' :
303 + $replacement = $submission->submitted_at;
304 + break;
305 + case 'HF_USER_AGENT' :
306 + $replacement = $submission->user_agent;
307 + break;
308 + case 'HF_IP_ADDRESS' :
309 + $replacement = $submission->ip_address;
310 + break;
311 + case 'HF_REFERRER_URL' :
312 + $replacement = $submission->referer_url;
313 + break;
314 + default :
315 + $replacement = '';
316 + break;
317 + }
318 + } else {
319 + // replace spaces in name with underscores to match PHP requirement for keys in $_POST superglobal
320 + $key = str_replace( ' ', '_', $key );
321 + $replacement = hf_array_get( $submission->data, $key, '' );
322 + $replacement = hf_field_value( $replacement, 0, $escape_function );
323 + }
324 +
325 + return $replacement;
326 + },
327 + $string
328 + );
222 329 }
223 330
224 331 /**
225 -* Poor man's file object, compatible with serialization..
332 +* Returns a formatted & HTML-escaped field value. Detects file-, array- and date-types.
226 333 *
334 +* Caveat: if value is a file, an HTML string is returned (which means email action should use "Content-Type: html" when it includes a file field).
335 +*
336 +* @param string|array $value
337 +* @param int $limit
338 +* @param Closure|string $escape_function
339 +* @return string
340 +* @since 1.3.1
341 +*/
342 +function hf_field_value( $value, $limit = 0, $escape_function = 'esc_html' ) {
343 + if ( $value === '' ) {
344 + return $value;
345 + }
346 +
347 + if ( hf_is_file( $value ) ) {
348 + if ( ! is_array( $value )
349 + || ! isset( $value['name'] )
350 + || ! isset( $value['size'] )
351 + || ! isset( $value['type'] ) ) {
352 + return false;
353 + }
354 +
355 + // Verify attachment exists
356 + if ( isset( $value['attachment_id'] ) && get_post( $value['attachment_id'] ) == null ) {
357 + return __( 'File not found', 'html-forms' );
358 + }
359 +
360 + $file_url = isset( $value['url'] ) ? $value['url'] : '';
361 + if ( isset( $value['attachment_id'] ) && apply_filters( 'hf_file_upload_use_direct_links', false ) === false ) {
362 + $file_url = admin_url( sprintf( 'post.php?action=edit&post=%d', $value['attachment_id'] ) );
363 + }
364 +
365 + $short_name = substr( $value['name'], 0, 20 );
366 + $suffix = strlen( $value['name'] ) > 20 ? '...' : '';
367 + return sprintf( '<a href="%s">%s%s</a> (%s)', esc_url( $file_url ), esc_html( $short_name ), esc_html( $suffix ), hf_human_filesize( $value['size'] ) );
368 + }
369 +
370 + if ( hf_is_date( $value ) ) {
371 + $date_format = get_option( 'date_format' );
372 + return gmdate( $date_format, strtotime( str_replace( '/', '-', $value ) ) );
373 + }
374 +
375 + // join array-values with comma
376 + if ( is_array( $value ) ) {
377 + $value = join( ', ', $value );
378 + }
379 +
380 + // limit string to certain length
381 + if ( $limit > 0 ) {
382 + $limited = strlen( $value ) > $limit;
383 + $value = substr( $value, 0, $limit );
384 +
385 + if ( $limited ) {
386 + $value .= '...';
387 + }
388 + }
389 +
390 + // escape value
391 + if ( $escape_function !== null && is_callable( $escape_function ) ) {
392 + $value = $escape_function( $value );
393 + }
394 +
395 + // add line breaks, if not string limited to certain length
396 + if ( $limit === 0 ) {
397 + $value = nl2br( $value );
398 + }
399 +
400 + return $value;
401 +}
402 +
403 +/**
404 +* Returns true if value is a "file"
405 +*
406 +* @param mixed $value
227 407 * @return bool
228 408 */
229 -function hf_is_file( $file ) {
230 - return isset( $file['name'] ) && isset( $file['size'] ) && isset( $file['type'] );
409 +function hf_is_file( $value ) {
410 + return is_array( $value )
411 + && isset( $value['name'] )
412 + && isset( $value['size'] )
413 + && isset( $value['type'] );
231 414 }
232 415
233 -/**
234 -* @return string
416 +/**
417 +* Returns true if value looks like a date-string submitted from a <input type="date">
418 +* @param mixed $value
419 +* @return bool
420 +* @since 1.3.1
235 421 */
236 -function hf_human_filesize($size, $precision = 2) {
237 - for( $i = 0; ($size / 1024) > 0.9; $i++, $size /= 1024 ) {
238 - // nothing, loop logic contains everything
239 - }
240 - $steps = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
241 - return round($size, $precision) . $steps[$i];
422 +function hf_is_date( $value ) {
423 + if ( ! is_string( $value )
424 + || strlen( $value ) !== 10
425 + || (int) preg_match( '/\d{2,4}[-\/]\d{2}[-\/]\d{2,4}/', $value ) === 0 ) {
426 + return false;
427 + }
428 +
429 + $timestamp = strtotime( $value );
430 + return $timestamp != false;
431 +}
432 +
433 +/**
434 + * @param int $size
435 + * @param int $precision
436 + * @return string
437 +*/
438 +function hf_human_filesize( $size, $precision = 2 ) {
439 + for ( $i = 0; ( $size / 1024 ) > 0.9; $i++, $size /= 1024 ) {
440 + // nothing, loop logic contains everything
441 + }
442 + $steps = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
443 + return round( $size, $precision ) . $steps[ $i ];
444 +}
445 +
446 +/**
447 + * Gets all the form tabs to show in the admin.
448 + * @param Form $form
449 + * @return array
450 + */
451 +function hf_get_admin_tabs( Form $form ) {
452 + $tabs = array(
453 + 'fields' => __( 'Fields', 'html-forms' ),
454 + 'messages' => __( 'Messages', 'html-forms' ),
455 + 'settings' => __( 'Settings', 'html-forms' ),
456 + 'actions' => __( 'Actions', 'html-forms' ),
457 + );
458 +
459 + if ( $form->settings['save_submissions'] ) {
460 + $tabs['submissions'] = __( 'Submissions', 'html-forms' );
461 + }
462 + return apply_filters( 'hf_admin_tabs', $tabs, $form );
463 +}
464 +
465 +function _hf_on_plugin_activation() {
466 + if ( is_multisite() ) {
467 + _hf_on_plugin_activation_multisite();
468 + return;
469 + }
470 +
471 + // install table for regular wp install
472 + _hf_create_submissions_table();
473 +
474 + // add "edit_forms" cap to user that activated the plugin
475 + $user = wp_get_current_user();
476 + $user->add_cap( 'edit_forms', true );
477 +}
478 +
479 +function _hf_on_plugin_activation_multisite() {
480 + $added_caps = array();
481 +
482 + foreach ( get_sites( array( 'number' => PHP_INT_MAX ) ) as $site ) {
483 + switch_to_blog( (int) $site->blog_id );
484 +
485 + // install table for current blog
486 + _hf_create_submissions_table();
487 +
488 + // iterate through current blog admins
489 + foreach ( get_users(
490 + array(
491 + 'blog_id' => (int) $site->blog_id,
492 + 'role' => 'administrator',
493 + 'fields' => 'ID',
494 + )
495 + ) as $admin_id ) {
496 + if ( ! (int) $admin_id || in_array( $admin_id, $added_caps ) ) {
497 + continue;
498 + }
499 +
500 + // add "edit_forms" cap to site admin
501 + $user = new \WP_User( (int) $admin_id );
502 + $user->add_cap( 'edit_forms', true );
503 +
504 + $added_caps[] = $admin_id;
505 + }
506 +
507 + restore_current_blog();
508 + }
509 +}
510 +
511 +// install table for main site on regular installs, or active site for multisite
512 +function _hf_create_submissions_table() {
513 + /** @var wpdb */
514 + global $wpdb;
515 +
516 + $charset_collate = $wpdb->get_charset_collate();
517 +
518 + // create table for storing submissions
519 + $table = $wpdb->prefix . 'hf_submissions';
520 + $wpdb->query(
521 + "CREATE TABLE IF NOT EXISTS {$table}(
522 + `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
523 + `form_id` INT UNSIGNED NOT NULL,
524 + `data` TEXT NOT NULL,
525 + `user_agent` TEXT NULL,
526 + `ip_address` VARCHAR(255) NULL,
527 + `referer_url` TEXT NULL,
528 + `submitted_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
529 +) {$charset_collate};"
530 + );
531 +}
532 +
533 +function _hf_on_add_user_to_blog( $user_id, $role, $blog_id ) {
534 + if ( 'administrator' !== $role ) {
535 + return;
536 + }
537 +
538 + // add "edit_forms" cap to site admin
539 + $user = new \WP_User( (int) $user_id );
540 + $user->add_cap( 'edit_forms', true );
541 +}
542 +
543 +function _hf_on_wp_insert_site( \WP_Site $site ) {
544 + switch_to_blog( (int) $site->blog_id );
545 + _hf_create_submissions_table();
546 + restore_current_blog();
242 547 }