PluginProbe
Advanced Custom Fields (ACF®) / 5.9.0
Advanced Custom Fields (ACF®) v5.9.0
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / forms / form-front.php
form-front.php
646 lines 12.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
4
5 if( ! class_exists('acf_form_front') ) :
6
7 class acf_form_front {
8
9 /** @var array An array of registered form settings */
10 private $forms = array();
11
12 /** @var array An array of default fields */
13 public $fields = array();
14
15
16 /*
17 * __construct
18 *
19 * This function will setup the class functionality
20 *
21 * @type function
22 * @date 5/03/2014
23 * @since 5.0.0
24 *
25 * @param n/a
26 * @return n/a
27 */
28
29 function __construct() {
30
31 // vars
32 $this->fields = array(
33
34 '_post_title' => array(
35 'prefix' => 'acf',
36 'name' => '_post_title',
37 'key' => '_post_title',
38 'label' => __('Title', 'acf'),
39 'type' => 'text',
40 'required' => true,
41 ),
42
43 '_post_content' => array(
44 'prefix' => 'acf',
45 'name' => '_post_content',
46 'key' => '_post_content',
47 'label' => __('Content', 'acf'),
48 'type' => 'wysiwyg',
49 ),
50
51 '_validate_email' => array(
52 'prefix' => 'acf',
53 'name' => '_validate_email',
54 'key' => '_validate_email',
55 'label' => __('Validate Email', 'acf'),
56 'type' => 'text',
57 'value' => '',
58 'wrapper' => array('style' => 'display:none !important;')
59 )
60
61 );
62
63
64 // actions
65 add_action('acf/validate_save_post', array($this, 'validate_save_post'), 1);
66
67
68 // filters
69 add_filter('acf/pre_save_post', array($this, 'pre_save_post'), 5, 2);
70
71 }
72
73
74 /*
75 * validate_form
76 *
77 * description
78 *
79 * @type function
80 * @date 28/2/17
81 * @since 5.5.8
82 *
83 * @param $post_id (int)
84 * @return $post_id (int)
85 */
86
87 function validate_form( $args ) {
88
89 // defaults
90 // Todo: Allow message and button text to be generated by CPT settings.
91 $args = wp_parse_args( $args, array(
92 'id' => 'acf-form',
93 'post_id' => false,
94 'new_post' => false,
95 'field_groups' => false,
96 'fields' => false,
97 'post_title' => false,
98 'post_content' => false,
99 'form' => true,
100 'form_attributes' => array(),
101 'return' => add_query_arg( 'updated', 'true', acf_get_current_url() ),
102 'html_before_fields' => '',
103 'html_after_fields' => '',
104 'submit_value' => __("Update", 'acf'),
105 'updated_message' => __("Post updated", 'acf'),
106 'label_placement' => 'top',
107 'instruction_placement' => 'label',
108 'field_el' => 'div',
109 'uploader' => 'wp',
110 'honeypot' => true,
111 'html_updated_message' => '<div id="message" class="updated"><p>%s</p></div>', // 5.5.10
112 'html_submit_button' => '<input type="submit" class="acf-button button button-primary button-large" value="%s" />', // 5.5.10
113 'html_submit_spinner' => '<span class="acf-spinner"></span>', // 5.5.10
114 'kses' => true // 5.6.5
115 ));
116
117 $args['form_attributes'] = wp_parse_args( $args['form_attributes'], array(
118 'id' => $args['id'],
119 'class' => 'acf-form',
120 'action' => '',
121 'method' => 'post',
122 ));
123
124
125 // filter post_id
126 $args['post_id'] = acf_get_valid_post_id( $args['post_id'] );
127
128
129 // new post?
130 if( $args['post_id'] === 'new_post' ) {
131
132 $args['new_post'] = wp_parse_args( $args['new_post'], array(
133 'post_type' => 'post',
134 'post_status' => 'draft',
135 ));
136
137 }
138
139
140 // filter
141 $args = apply_filters('acf/validate_form', $args);
142
143
144 // return
145 return $args;
146
147 }
148
149
150 /*
151 * add_form
152 *
153 * description
154 *
155 * @type function
156 * @date 28/2/17
157 * @since 5.5.8
158 *
159 * @param $post_id (int)
160 * @return $post_id (int)
161 */
162
163 function add_form( $args = array() ) {
164
165 // validate
166 $args = $this->validate_form( $args );
167
168
169 // append
170 $this->forms[ $args['id'] ] = $args;
171
172 }
173
174
175 /*
176 * get_form
177 *
178 * description
179 *
180 * @type function
181 * @date 28/2/17
182 * @since 5.5.8
183 *
184 * @param $post_id (int)
185 * @return $post_id (int)
186 */
187
188 function get_form( $id = '' ) {
189
190 // bail early if not set
191 if( !isset($this->forms[ $id ]) ) return false;
192
193
194 // return
195 return $this->forms[ $id ];
196
197 }
198
199
200 /*
201 * validate_save_post
202 *
203 * This function will validate fields from the above array
204 *
205 * @type function
206 * @date 7/09/2016
207 * @since 5.4.0
208 *
209 * @param $post_id (int)
210 * @return $post_id (int)
211 */
212
213 function validate_save_post() {
214
215 // register field if isset in $_POST
216 foreach( $this->fields as $k => $field ) {
217
218 // bail early if no in $_POST
219 if( !isset($_POST['acf'][ $k ]) ) continue;
220
221
222 // register
223 acf_add_local_field($field);
224
225 }
226
227
228 // honeypot
229 if( !empty($_POST['acf']['_validate_email']) ) {
230
231 acf_add_validation_error( '', __('Spam Detected', 'acf') );
232
233 }
234
235 }
236
237
238 /*
239 * pre_save_post
240 *
241 * description
242 *
243 * @type function
244 * @date 7/09/2016
245 * @since 5.4.0
246 *
247 * @param $post_id (int)
248 * @return $post_id (int)
249 */
250
251 function pre_save_post( $post_id, $form ) {
252
253 // vars
254 $save = array(
255 'ID' => 0
256 );
257
258
259 // determine save data
260 if( is_numeric($post_id) ) {
261
262 // update post
263 $save['ID'] = $post_id;
264
265 } elseif( $post_id == 'new_post' ) {
266
267 // merge in new post data
268 $save = array_merge($save, $form['new_post']);
269
270 } else {
271
272 // not post
273 return $post_id;
274
275 }
276
277
278 // save post_title
279 if( isset($_POST['acf']['_post_title']) ) {
280
281 $save['post_title'] = acf_extract_var($_POST['acf'], '_post_title');
282
283 }
284
285
286 // save post_content
287 if( isset($_POST['acf']['_post_content']) ) {
288
289 $save['post_content'] = acf_extract_var($_POST['acf'], '_post_content');
290
291 }
292
293
294 // honeypot
295 if( !empty($_POST['acf']['_validate_email']) ) return false;
296
297
298 // validate
299 if( count($save) == 1 ) {
300
301 return $post_id;
302
303 }
304
305
306 // save
307 if( $save['ID'] ) {
308
309 wp_update_post( $save );
310
311 } else {
312
313 $post_id = wp_insert_post( $save );
314
315 }
316
317
318 // return
319 return $post_id;
320
321 }
322
323
324 /*
325 * enqueue
326 *
327 * This function will enqueue a form
328 *
329 * @type function
330 * @date 7/09/2016
331 * @since 5.4.0
332 *
333 * @param $post_id (int)
334 * @return $post_id (int)
335 */
336
337 function enqueue_form() {
338
339 // check
340 $this->check_submit_form();
341
342
343 // load acf scripts
344 acf_enqueue_scripts();
345
346 }
347
348
349 /*
350 * check_submit_form
351 *
352 * This function will maybe submit form data
353 *
354 * @type function
355 * @date 3/3/17
356 * @since 5.5.10
357 *
358 * @param n/a
359 * @return n/a
360 */
361
362 function check_submit_form() {
363
364 // Verify nonce.
365 if( !acf_verify_nonce('acf_form') ) {
366 return false;
367 }
368
369 // Confirm form was submit.
370 if( !isset($_POST['_acf_form']) ) {
371 return false;
372 }
373
374 // Load registered form using id.
375 $form = $this->get_form( $_POST['_acf_form'] );
376
377 // Fallback to encrypted JSON.
378 if( !$form ) {
379 $form = json_decode( acf_decrypt($_POST['_acf_form']), true );
380 if( !$form ) {
381 return false;
382 }
383 }
384
385 // Run kses on all $_POST data.
386 if( $form['kses'] && isset($_POST['acf']) ) {
387 $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] );
388 }
389
390 // Validate data and show errors.
391 // Todo: Return WP_Error and show above form, keeping input values.
392 acf_validate_save_post( true );
393
394 // Submit form.
395 $this->submit_form( $form );
396 }
397
398
399 /*
400 * submit_form
401 *
402 * This function will submit form data
403 *
404 * @type function
405 * @date 3/3/17
406 * @since 5.5.10
407 *
408 * @param n/a
409 * @return n/a
410 */
411
412 function submit_form( $form ) {
413
414 // filter
415 $form = apply_filters('acf/pre_submit_form', $form);
416
417
418 // vars
419 $post_id = acf_maybe_get($form, 'post_id', 0);
420
421
422 // add global for backwards compatibility
423 $GLOBALS['acf_form'] = $form;
424
425
426 // allow for custom save
427 $post_id = apply_filters('acf/pre_save_post', $post_id, $form);
428
429
430 // save
431 acf_save_post( $post_id );
432
433
434 // restore form (potentially modified)
435 $form = $GLOBALS['acf_form'];
436
437
438 // action
439 do_action('acf/submit_form', $form, $post_id);
440
441
442 // vars
443 $return = acf_maybe_get($form, 'return', '');
444
445
446 // redirect
447 if( $return ) {
448
449 // update %placeholders%
450 $return = str_replace('%post_id%', $post_id, $return);
451 $return = str_replace('%post_url%', get_permalink($post_id), $return);
452
453
454 // redirect
455 wp_redirect( $return );
456 exit;
457
458 }
459
460 }
461
462
463 /*
464 * render
465 *
466 * description
467 *
468 * @type function
469 * @date 7/09/2016
470 * @since 5.4.0
471 *
472 * @param $post_id (int)
473 * @return $post_id (int)
474 */
475
476 function render_form( $args = array() ) {
477
478 // Vars.
479 $is_registered = false;
480 $field_groups = array();
481 $fields = array();
482
483 // Allow form settings to be directly provided.
484 if( is_array($args) ) {
485 $args = $this->validate_form( $args );
486
487 // Otherwise, lookup registered form.
488 } else {
489 $is_registered = true;
490 $args = $this->get_form( $args );
491 if( !$args ) {
492 return false;
493 }
494 }
495
496 // Extract vars.
497 $post_id = $args['post_id'];
498
499 // Prevent ACF from loading values for "new_post".
500 if( $post_id === 'new_post' ) {
501 $post_id = false;
502 }
503
504 // Set uploader type.
505 acf_update_setting('uploader', $args['uploader']);
506
507 // Register local fields.
508 foreach( $this->fields as $k => $field ) {
509 acf_add_local_field($field);
510 }
511
512 // Append post_title field.
513 if( $args['post_title'] ) {
514 $_post_title = acf_get_field('_post_title');
515 $_post_title['value'] = $post_id ? get_post_field('post_title', $post_id) : '';
516 $fields[] = $_post_title;
517 }
518
519 // Append post_content field.
520 if( $args['post_content'] ) {
521 $_post_content = acf_get_field('_post_content');
522 $_post_content['value'] = $post_id ? get_post_field('post_content', $post_id) : '';
523 $fields[] = $_post_content;
524 }
525
526 // Load specific fields.
527 if( $args['fields'] ) {
528
529 // Lookup fields using $strict = false for better compatibility with field names.
530 foreach( $args['fields'] as $selector ) {
531 $fields[] = acf_maybe_get_field( $selector, $post_id, false );
532 }
533
534 // Load specific field groups.
535 } elseif( $args['field_groups'] ) {
536 foreach( $args['field_groups'] as $selector ) {
537 $field_groups[] = acf_get_field_group( $selector );
538 }
539
540 // Load fields for the given "new_post" args.
541 } elseif( $args['post_id'] == 'new_post' ) {
542 $field_groups = acf_get_field_groups( $args['new_post'] );
543
544 // Load fields for the given "post_id" arg.
545 } else {
546 $field_groups = acf_get_field_groups(array(
547 'post_id' => $args['post_id']
548 ));
549 }
550
551 // load fields from the found field groups.
552 if( $field_groups ) {
553 foreach( $field_groups as $field_group ) {
554 $_fields = acf_get_fields( $field_group );
555 if( $_fields ) {
556 foreach( $_fields as $_field ) {
557 $fields[] = $_field;
558 }
559 }
560 }
561 }
562
563 // Add honeypot field.
564 if( $args['honeypot'] ) {
565 $fields[] = acf_get_field('_validate_email');
566 }
567
568 // Display updated_message
569 if( !empty($_GET['updated']) && $args['updated_message'] ) {
570 printf( $args['html_updated_message'], $args['updated_message'] );
571 }
572
573 // display form
574 if( $args['form'] ): ?>
575 <form <?php echo acf_esc_attrs( $args['form_attributes'] ); ?>>
576 <?php endif;
577
578 // Render hidde form data.
579 acf_form_data(array(
580 'screen' => 'acf_form',
581 'post_id' => $args['post_id'],
582 'form' => $is_registered ? $args['id'] : acf_encrypt(json_encode($args))
583 ));
584
585 ?>
586 <div class="acf-fields acf-form-fields -<?php echo esc_attr($args['label_placement']); ?>">
587 <?php echo $args['html_before_fields']; ?>
588 <?php acf_render_fields( $fields, $post_id, $args['field_el'], $args['instruction_placement'] ); ?>
589 <?php echo $args['html_after_fields']; ?>
590 </div>
591 <?php if( $args['form'] ): ?>
592 <div class="acf-form-submit">
593 <?php printf( $args['html_submit_button'], $args['submit_value'] ); ?>
594 <?php echo $args['html_submit_spinner']; ?>
595 </div>
596 </form>
597 <?php endif;
598 }
599
600 }
601
602 // initialize
603 acf()->form_front = new acf_form_front();
604
605 endif; // class_exists check
606
607
608 /*
609 * Functions
610 *
611 * alias of acf()->form->functions
612 *
613 * @type function
614 * @date 11/06/2014
615 * @since 5.0.0
616 *
617 * @param n/a
618 * @return n/a
619 */
620
621
622 function acf_form_head() {
623
624 acf()->form_front->enqueue_form();
625
626 }
627
628 function acf_form( $args = array() ) {
629
630 acf()->form_front->render_form( $args );
631
632 }
633
634 function acf_get_form( $id = '' ) {
635
636 return acf()->form_front->get_form( $id );
637
638 }
639
640 function acf_register_form( $args ) {
641
642 acf()->form_front->add_form( $args );
643
644 }
645
646 ?>