PluginProbe
HTML Forms – Simple WordPress Forms Plugin / 1.3.23
HTML Forms – Simple WordPress Forms Plugin v1.3.23
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.23, at src/functions.php

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