PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.3.34
HTML Forms – Simple WordPress Forms Plugin v1.3.34
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
html-forms / src / functions.php

functions.php in HTML Forms – Simple WordPress Forms Plugin 1.3.34, at src/functions.php

475 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use HTML_Forms\Form;
4 use HTML_Forms\Submission;
5
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 /**
26 * @param $form_id_or_slug int|string|WP_Post
27 * @return Form
28 * @throws Exception
29 */
30 function hf_get_form( $form_id_or_slug ) {
31
32 if ( is_numeric( $form_id_or_slug ) || $form_id_or_slug instanceof WP_Post ) {
33 $post = get_post( $form_id_or_slug );
34
35 if ( ! $post instanceof WP_Post || $post->post_type !== 'html-form' ) {
36 throw new Exception( 'Invalid form ID' );
37 }
38 } else {
39
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 }
56
57 // get all post meta in a single call for performance
58 $post_meta = get_post_meta( $post->ID );
59
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 );
74
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 );
82 $default_messages = apply_filters( 'hf_form_default_messages', $default_messages );
83 $messages = array();
84 foreach ( $post_meta as $meta_key => $meta_values ) {
85 if ( strpos( $meta_key, 'hf_message_' ) === 0 ) {
86 $message_key = substr( $meta_key, strlen( 'hf_message_' ) );
87 $messages[ $message_key ] = (string) $meta_values[0];
88 }
89 }
90 $messages = array_merge( $default_messages, $messages );
91
92 // finally, create form instance
93 $form = new Form( $post->ID );
94 $form->title = $post->post_title;
95 $form->slug = $post->post_name;
96 $form->markup = $post->post_content;
97 $form->settings = $settings;
98 $form->messages = $messages;
99 return $form;
100 }
101
102 /**
103 * @param $form_id
104 * @return int
105 */
106 function hf_count_form_submissions( $form_id ) {
107 global $wpdb;
108 $table = $wpdb->prefix . 'hf_submissions';
109 $result = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$table} s WHERE s.form_id = %d;", $form_id ) );
110 return (int) $result;
111 }
112
113 /**
114 * @param $form_id
115 * @param array $args
116 * @return Submission[]
117 */
118 function hf_get_form_submissions( $form_id, array $args = array() ) {
119 $default_args = array(
120 'offset' => 0,
121 'limit' => 1000,
122 );
123 $args = array_merge( $default_args, $args );
124
125 global $wpdb;
126 $table = $wpdb->prefix . 'hf_submissions';
127 $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 );
128 $submissions = array();
129 foreach ( $results as $key => $object ) {
130 $submission = Submission::from_object( $object );
131 $submissions[ $key ] = $submission;
132 }
133 return $submissions;
134 }
135
136 /**
137 * @param int $submission_id
138 * @return Submission
139 */
140 function hf_get_form_submission( $submission_id ) {
141 global $wpdb;
142 $table = $wpdb->prefix . 'hf_submissions';
143 $object = $wpdb->get_row( $wpdb->prepare( "SELECT s.* FROM {$table} s WHERE s.id = %d;", $submission_id ), OBJECT );
144 $submission = Submission::from_object( $object );
145 return $submission;
146 }
147 /**
148 * @return array
149 */
150 function hf_get_settings() {
151 $default_settings = array(
152 'load_stylesheet' => 0,
153 );
154
155 $settings = get_option( 'hf_settings', null );
156
157 // prevent a SQL query when option does not yet exist
158 if ( $settings === null ) {
159 update_option( 'hf_settings', array(), true );
160 $settings = array();
161 }
162
163 // merge with default settings
164 $settings = array_merge( $default_settings, $settings );
165
166 /**
167 * Filters the global HTML Forms hf_settings
168 *
169 * @param array $settings
170 */
171 $settings = apply_filters( 'hf_settings', $settings );
172
173 return $settings;
174 }
175
176 /**
177 * Get element from array, allows for dot notation eg: "foo.bar"
178 *
179 * @param array $array
180 * @param string $key
181 * @param mixed $default
182 * @return mixed
183 */
184 function hf_array_get( $array, $key, $default = null ) {
185 if ( is_null( $key ) ) {
186 return $array;
187 }
188
189 if ( isset( $array[ $key ] ) ) {
190 return $array[ $key ];
191 }
192
193 foreach ( explode( '.', $key ) as $segment ) {
194 if ( ! is_array( $array ) || ! array_key_exists( $segment, $array ) ) {
195 return $default;
196 }
197
198 $array = $array[ $segment ];
199 }
200
201 return $array;
202 }
203
204 /**
205 * Processes template tags like {{user.user_email}}
206 *
207 * @param string $template
208 *
209 * @return string
210 */
211 function hf_template( $template ) {
212 $replacers = new HTML_Forms\TagReplacers();
213 $tags = array(
214 'user' => array( $replacers, 'user' ),
215 'post' => array( $replacers, 'post' ),
216 'url_params' => array( $replacers, 'url_params' ),
217 );
218
219 /**
220 * Filters the available tags in HTML Forms templates, like {{user.user_email}}.
221 *
222 * Can be used to add simple scalar replacements or more advanced replacement functions that accept a parameter.
223 *
224 * @param array $tags
225 */
226 $tags = apply_filters( 'hf_template_tags', $tags );
227
228 $template = preg_replace_callback(
229 '/\{\{ *(\w+)(?:\.([\w\.]+))? *(?:\|\| *(\w+))? *\}\}/',
230 function( $matches ) use ( $tags ) {
231 $tag = $matches[1];
232 $param = ! isset( $matches[2] ) ? '' : $matches[2];
233 $default = ! isset( $matches[3] ) ? '' : $matches[3];
234
235 // do not change anything if we have no replacer with that key, could be custom user logic or another plugin.
236 if ( ! isset( $tags[ $tag ] ) ) {
237 return $matches[0];
238 }
239
240 $replacement = $tags[ $tag ];
241 $value = is_callable( $replacement ) ? call_user_func_array( $replacement, array( $param ) ) : $replacement;
242 return ! empty( $value ) ? $value : $default;
243 },
244 $template
245 );
246
247 return $template;
248 }
249
250 /**
251 * @param string $string
252 * @param array $data
253 * @param Closure|string $escape_function
254 * @return string
255 */
256 function hf_replace_data_variables( $string, $data = array(), $escape_function = null ) {
257 return preg_replace_callback(
258 '/\[(.+?)\]/',
259 function( $matches ) use ( $data, $escape_function ) {
260 $key = $matches[1];
261 // replace spaces in name with underscores to match PHP requirement for keys in $_POST superglobal
262 $key = str_replace( ' ', '_', $key );
263 $replacement = hf_array_get( $data, $key, '' );
264 $replacement = hf_field_value( $replacement, 0, $escape_function );
265 return $replacement;
266 },
267 $string
268 );
269 }
270
271 /**
272 * Returns a formatted & HTML-escaped field value. Detects file-, array- and date-types.
273 *
274 * 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).
275 *
276 * @param string|array $value
277 * @param int $limit
278 * @param Closure|string $escape_function
279 * @return string
280 * @since 1.3.1
281 */
282 function hf_field_value( $value, $limit = 0, $escape_function = 'esc_html' ) {
283 if ( $value === '' ) {
284 return $value;
285 }
286
287 if ( hf_is_file( $value ) ) {
288 $file_url = isset( $value['url'] ) ? $value['url'] : '';
289 if ( isset( $value['attachment_id'] ) && apply_filters( 'hf_file_upload_use_direct_links', false ) === false ) {
290 $file_url = admin_url( sprintf( 'post.php?action=edit&post=%d', $value['attachment_id'] ) );
291 }
292 $short_name = substr( $value['name'], 0, 20 );
293 $suffix = strlen( $value['name'] ) > 20 ? '...' : '';
294 return sprintf( '<a href="%s">%s%s</a> (%s)', esc_attr( $file_url ), esc_html( $short_name ), esc_html( $suffix ), hf_human_filesize( $value['size'] ) );
295 }
296
297 if ( hf_is_date( $value ) ) {
298 $date_format = get_option( 'date_format' );
299 return gmdate( $date_format, strtotime( str_replace( '/', '-', $value ) ) );
300 }
301
302 // join array-values with comma
303 if ( is_array( $value ) ) {
304 $value = join( ', ', $value );
305 }
306
307 // limit string to certain length
308 if ( $limit > 0 ) {
309 $limited = strlen( $value ) > $limit;
310 $value = substr( $value, 0, $limit );
311
312 if ( $limited ) {
313 $value .= '...';
314 }
315 }
316
317 // escape value
318 if ( $escape_function !== null && is_callable( $escape_function ) ) {
319 $value = $escape_function( $value );
320 }
321
322 // add line breaks, if not string limited to certain length
323 if ( $limit === 0 ) {
324 $value = nl2br( $value );
325 }
326
327 return $value;
328 }
329
330 /**
331 * Returns true if value is a "file"
332 *
333 * @param mixed $value
334 * @return bool
335 */
336 function hf_is_file( $value ) {
337 return is_array( $value )
338 && isset( $value['name'] )
339 && isset( $value['size'] )
340 && isset( $value['type'] );
341 }
342
343 /**
344 * Returns true if value looks like a date-string submitted from a <input type="date">
345 * @param mixed $value
346 * @return bool
347 * @since 1.3.1
348 */
349 function hf_is_date( $value ) {
350 if ( ! is_string( $value )
351 || strlen( $value ) !== 10
352 || (int) preg_match( '/\d{2,4}[-\/]\d{2}[-\/]\d{2,4}/', $value ) === 0 ) {
353 return false;
354 }
355
356 $timestamp = strtotime( $value );
357 return $timestamp != false;
358 }
359
360 /**
361 * @param int $size
362 * @param int $precision
363 * @return string
364 */
365 function hf_human_filesize( $size, $precision = 2 ) {
366 for ( $i = 0; ( $size / 1024 ) > 0.9; $i++, $size /= 1024 ) {
367 // nothing, loop logic contains everything
368 }
369 $steps = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
370 return round( $size, $precision ) . $steps[ $i ];
371 }
372
373 /**
374 * Gets all the form tabs to show in the admin.
375 * @param Form $form
376 * @return array
377 */
378 function hf_get_admin_tabs( Form $form ) {
379 $tabs = array(
380 'fields' => __( 'Fields', 'html-forms' ),
381 'messages' => __( 'Messages', 'html-forms' ),
382 'settings' => __( 'Settings', 'html-forms' ),
383 'actions' => __( 'Actions', 'html-forms' ),
384 );
385
386 if ( $form->settings['save_submissions'] ) {
387 $tabs['submissions'] = __( 'Submissions', 'html-forms' );
388 }
389 return apply_filters( 'hf_admin_tabs', $tabs, $form );
390 }
391
392 function _hf_on_plugin_activation() {
393 if ( is_multisite() ) {
394 _hf_on_plugin_activation_multisite();
395 return;
396 }
397
398 // install table for regular wp install
399 _hf_create_submissions_table();
400
401 // add "edit_forms" cap to user that activated the plugin
402 $user = wp_get_current_user();
403 $user->add_cap( 'edit_forms', true );
404 }
405
406 function _hf_on_plugin_activation_multisite() {
407 $added_caps = array();
408
409 foreach ( get_sites( array( 'number' => PHP_INT_MAX ) ) as $site ) {
410 switch_to_blog( (int) $site->blog_id );
411
412 // install table for current blog
413 _hf_create_submissions_table();
414
415 // iterate through current blog admins
416 foreach ( get_users(
417 array(
418 'blog_id' => (int) $site->blog_id,
419 'role' => 'administrator',
420 'fields' => 'ID',
421 )
422 ) as $admin_id ) {
423 if ( ! (int) $admin_id || in_array( $admin_id, $added_caps ) ) {
424 continue;
425 }
426
427 // add "edit_forms" cap to site admin
428 $user = new \WP_User( (int) $admin_id );
429 $user->add_cap( 'edit_forms', true );
430
431 $added_caps[] = $admin_id;
432 }
433
434 restore_current_blog();
435 }
436 }
437
438 // install table for main site on regular installs, or active site for multisite
439 function _hf_create_submissions_table() {
440 /** @var wpdb */
441 global $wpdb;
442
443 $charset_collate = $wpdb->get_charset_collate();
444
445 // create table for storing submissions
446 $table = $wpdb->prefix . 'hf_submissions';
447 $wpdb->query(
448 "CREATE TABLE IF NOT EXISTS {$table}(
449 `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
450 `form_id` INT UNSIGNED NOT NULL,
451 `data` TEXT NOT NULL,
452 `user_agent` TEXT NULL,
453 `ip_address` VARCHAR(255) NULL,
454 `referer_url` TEXT NULL,
455 `submitted_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
456 ) {$charset_collate};"
457 );
458 }
459
460 function _hf_on_add_user_to_blog( $user_id, $role, $blog_id ) {
461 if ( 'administrator' !== $role ) {
462 return;
463 }
464
465 // add "edit_forms" cap to site admin
466 $user = new \WP_User( (int) $user_id );
467 $user->add_cap( 'edit_forms', true );
468 }
469
470 function _hf_on_wp_insert_site( \WP_Site $site ) {
471 switch_to_blog( (int) $site->blog_id );
472 _hf_create_submissions_table();
473 restore_current_blog();
474 }
475