PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.3.27
HTML Forms – Simple WordPress Forms Plugin v1.3.27
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.27, at src/functions.php

470 lines 12.6 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( $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 return $value;
323 }
324
325 /**
326 * Returns true if value is a "file"
327 *
328 * @param mixed $value
329 * @return bool
330 */
331 function hf_is_file( $value ) {
332 return is_array( $value )
333 && isset( $value['name'] )
334 && isset( $value['size'] )
335 && isset( $value['type'] );
336 }
337
338 /**
339 * Returns true if value looks like a date-string submitted from a <input type="date">
340 * @param mixed $value
341 * @return bool
342 * @since 1.3.1
343 */
344 function hf_is_date( $value ) {
345 if ( ! is_string( $value )
346 || strlen( $value ) !== 10
347 || (int) preg_match( '/\d{2,4}[-\/]\d{2}[-\/]\d{2,4}/', $value ) === 0 ) {
348 return false;
349 }
350
351 $timestamp = strtotime( $value );
352 return $timestamp != false;
353 }
354
355 /**
356 * @param int $size
357 * @param int $precision
358 * @return string
359 */
360 function hf_human_filesize( $size, $precision = 2 ) {
361 for ( $i = 0; ( $size / 1024 ) > 0.9; $i++, $size /= 1024 ) {
362 // nothing, loop logic contains everything
363 }
364 $steps = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB' );
365 return round( $size, $precision ) . $steps[ $i ];
366 }
367
368 /**
369 * Gets all the form tabs to show in the admin.
370 * @param Form $form
371 * @return array
372 */
373 function hf_get_admin_tabs( Form $form ) {
374 $tabs = array(
375 'fields' => __( 'Fields', 'html-forms' ),
376 'messages' => __( 'Messages', 'html-forms' ),
377 'settings' => __( 'Settings', 'html-forms' ),
378 'actions' => __( 'Actions', 'html-forms' ),
379 );
380
381 if ( $form->settings['save_submissions'] ) {
382 $tabs['submissions'] = __( 'Submissions', 'html-forms' );
383 }
384 return apply_filters( 'hf_admin_tabs', $tabs, $form );
385 }
386
387 function _hf_on_plugin_activation() {
388 if ( is_multisite() ) {
389 _hf_on_plugin_activation_multisite();
390 return;
391 }
392
393 // install table for regular wp install
394 _hf_create_submissions_table();
395
396 // add "edit_forms" cap to user that activated the plugin
397 $user = wp_get_current_user();
398 $user->add_cap( 'edit_forms', true );
399 }
400
401 function _hf_on_plugin_activation_multisite() {
402 $added_caps = array();
403
404 foreach ( get_sites( array( 'number' => PHP_INT_MAX ) ) as $site ) {
405 switch_to_blog( (int) $site->blog_id );
406
407 // install table for current blog
408 _hf_create_submissions_table();
409
410 // iterate through current blog admins
411 foreach ( get_users(
412 array(
413 'blog_id' => (int) $site->blog_id,
414 'role' => 'administrator',
415 'fields' => 'ID',
416 )
417 ) as $admin_id ) {
418 if ( ! (int) $admin_id || in_array( $admin_id, $added_caps ) ) {
419 continue;
420 }
421
422 // add "edit_forms" cap to site admin
423 $user = new \WP_User( (int) $admin_id );
424 $user->add_cap( 'edit_forms', true );
425
426 $added_caps[] = $admin_id;
427 }
428
429 restore_current_blog();
430 }
431 }
432
433 // install table for main site on regular installs, or active site for multisite
434 function _hf_create_submissions_table() {
435 /** @var wpdb */
436 global $wpdb;
437
438 $charset_collate = $wpdb->get_charset_collate();
439
440 // create table for storing submissions
441 $table = $wpdb->prefix . 'hf_submissions';
442 $wpdb->query(
443 "CREATE TABLE IF NOT EXISTS {$table}(
444 `id` INT UNSIGNED NOT NULL PRIMARY KEY AUTO_INCREMENT,
445 `form_id` INT UNSIGNED NOT NULL,
446 `data` TEXT NOT NULL,
447 `user_agent` TEXT NULL,
448 `ip_address` VARCHAR(255) NULL,
449 `referer_url` TEXT NULL,
450 `submitted_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
451 ) {$charset_collate};"
452 );
453 }
454
455 function _hf_on_add_user_to_blog( $user_id, $role, $blog_id ) {
456 if ( 'administrator' !== $role ) {
457 return;
458 }
459
460 // add "edit_forms" cap to site admin
461 $user = new \WP_User( (int) $user_id );
462 $user->add_cap( 'edit_forms', true );
463 }
464
465 function _hf_on_wp_insert_site( \WP_Site $site ) {
466 switch_to_blog( (int) $site->blog_id );
467 _hf_create_submissions_table();
468 restore_current_blog();
469 }
470