PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.9
Advanced Custom Fields (ACF®) v6.8.9
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 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.6.1 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10.2 6.3.11 6.3.12 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.6.1 6.4.0 6.4.0.1 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.6.0 6.6.1 6.6.2 6.7.0 6.7.1 6.7.2 6.8.0 trunk 1.0.0 1.0.2 1.0.3 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.1 2.1.3 2.1.4 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.6 3.0.7 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.8 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.4.10 4.4.11 4.4.12 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 5.10 5.10.1 5.10.2 5.11 5.11.1 5.11.2 5.11.3 5.11.4 5.12 5.12.1 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.6.10 5.6.2 5.6.3 5.6.4 5.6.5 5.6.6 5.6.7 5.6.8 5.6.9 5.7.0 5.7.1 5.7.10 5.7.12 5.7.13 5.7.2 5.7.3 5.7.4 5.7.5 5.7.6 5.7.7 5.7.8 5.7.9 5.8.0 5.8.1 5.8.10 5.8.11 5.8.12 5.8.13 5.8.14 5.8.2 5.8.3 5.8.4
advanced-custom-fields / includes / forms / form-comment.php
advanced-custom-fields / includes / forms Last commit date
form-attachment.php 5 months ago form-comment.php 4 weeks ago form-customizer.php 5 months ago form-front.php 2 months ago form-gutenberg.php 5 months ago form-nav-menu.php 5 months ago form-post.php 3 months ago form-taxonomy.php 2 months ago form-user.php 4 weeks ago form-widget.php 5 months ago index.php 2 years ago
form-comment.php
364 lines
1 <?php
2 /**
3 * @package ACF
4 * @author WP Engine
5 *
6 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
7 * "ACF" is a trademark of WP Engine.
8 * Licensed under the GNU General Public License v2 or later.
9 * https://www.gnu.org/licenses/gpl-2.0.html
10 */
11
12 if ( ! class_exists( 'acf_form_comment' ) ) :
13
14 class acf_form_comment {
15
16
17 /**
18 * This function will setup the class functionality
19 *
20 * @type function
21 * @date 5/03/2014
22 * @since 5.0.0
23 *
24 * @param n/a
25 * @return n/a
26 */
27 function __construct() {
28
29 // actions
30 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
31
32 // render
33 add_filter( 'comment_form_field_comment', array( $this, 'comment_form_field_comment' ), 999, 1 );
34
35 // add_action( 'comment_form_logged_in_after', array( $this, 'add_comment') );
36 // add_action( 'comment_form', array( $this, 'add_comment') );
37 // save
38 add_action( 'edit_comment', array( $this, 'save_comment' ), 10, 1 );
39 add_action( 'comment_post', array( $this, 'save_comment' ), 10, 1 );
40 }
41
42
43 /**
44 * This function will check if the current page is for a post/page edit form
45 *
46 * @type function
47 * @date 23/06/12
48 * @since 3.1.8
49 *
50 * @param n/a
51 * @return (boolean)
52 */
53 function validate_page() {
54
55 // global
56 global $pagenow;
57
58 // validate page
59 if ( $pagenow == 'comment.php' ) {
60 return true;
61 }
62
63 // return
64 return false;
65 }
66
67
68 /**
69 * This action is run after post query but before any admin script / head actions.
70 * It is a good place to register all actions.
71 *
72 * @type action (admin_enqueue_scripts)
73 * @date 26/01/13
74 * @since 3.6.0
75 *
76 * @param n/a
77 * @return n/a
78 */
79 function admin_enqueue_scripts() {
80
81 // validate page
82 if ( ! $this->validate_page() ) {
83 return;
84 }
85
86 // load acf scripts
87 acf_enqueue_scripts();
88
89 // actions
90 add_action( 'admin_footer', array( $this, 'admin_footer' ), 10, 1 );
91 add_action( 'add_meta_boxes_comment', array( $this, 'edit_comment' ), 10, 1 );
92 }
93
94
95 /**
96 * This function is run on the admin comment.php page and will render the ACF fields within custom metaboxes to look native
97 *
98 * @type function
99 * @date 19/10/13
100 * @since 5.0.0
101 *
102 * @param $comment (object)
103 * @return n/a
104 */
105 function edit_comment( $comment ) {
106
107 // vars
108 $post_id = "comment_{$comment->comment_ID}";
109
110 // get field groups
111 $field_groups = acf_get_field_groups(
112 array(
113 'comment' => get_post_type( $comment->comment_post_ID ),
114 )
115 );
116
117 // render
118 if ( ! empty( $field_groups ) ) {
119
120 // render post data
121 acf_form_data(
122 array(
123 'screen' => 'comment',
124 'post_id' => $post_id,
125 )
126 );
127
128 foreach ( $field_groups as $field_group ) {
129
130 // load fields
131 $fields = acf_get_fields( $field_group );
132
133 // vars
134 $o = array(
135 'id' => 'acf-' . $field_group['ID'],
136 'key' => $field_group['key'],
137 // 'style' => $field_group['style'],
138 'label' => $field_group['label_placement'],
139 'edit_url' => '',
140 'edit_title' => __( 'Edit field group', 'acf' ),
141 // 'visibility' => $visibility
142 );
143
144 // edit_url
145 if ( $field_group['ID'] && acf_current_user_can_admin() ) {
146 $o['edit_url'] = admin_url( 'post.php?post=' . $field_group['ID'] . '&action=edit' );
147 }
148
149 ?>
150 <div id="acf-<?php echo esc_attr( $field_group['ID'] ); ?>" class="stuffbox">
151 <h3 class="hndle"><?php echo acf_esc_html( acf_get_field_group_title( $field_group ) ); ?></h3>
152 <div class="inside">
153 <?php acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] ); ?>
154 <script type="text/javascript">
155 if( typeof acf !== 'undefined' ) {
156 acf.newPostbox(<?php echo json_encode( $o ); ?>);
157 }
158 </script>
159 </div>
160 </div>
161 <?php
162 }
163 }
164 }
165
166 /**
167 * description
168 *
169 * @type function
170 * @date 18/04/2016
171 * @since 5.3.8
172 *
173 * @param $post_id (int)
174 * @return $post_id (int)
175 */
176 function comment_form_field_comment( $html ) {
177
178 // global
179 global $post;
180
181 // vars
182 $post_id = false;
183
184 // get field groups
185 $field_groups = acf_get_field_groups(
186 array(
187 'comment' => $post->post_type,
188 )
189 );
190
191 // bail early if no field groups
192 if ( ! $field_groups ) {
193 return $html;
194 }
195
196 // enqueue scripts
197 acf_enqueue_scripts();
198
199 // ob
200 ob_start();
201
202 // render post data
203 acf_form_data(
204 array(
205 'screen' => 'comment',
206 'post_id' => $post_id,
207 )
208 );
209
210 echo '<div class="acf-comment-fields acf-fields -clear">';
211
212 foreach ( $field_groups as $field_group ) {
213 $fields = acf_get_fields( $field_group );
214
215 acf_render_fields( $fields, $post_id, 'p', $field_group['instruction_placement'] );
216 }
217
218 echo '</div>';
219
220 // append
221 $html .= ob_get_contents();
222 ob_end_clean();
223
224 // return
225 return $html;
226 }
227
228 /**
229 * Saves ACF field values to a comment.
230 *
231 * @since 5.0.0
232 *
233 * @param integer $comment_id The ID of the comment being saved to.
234 * @return integer|void
235 */
236 public function save_comment( $comment_id ) {
237 // bail early if not valid nonce
238 if ( ! acf_verify_nonce( 'comment' ) ) {
239 return $comment_id;
240 }
241
242 if ( isset( $_POST['acf'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified above.
243 if ( ! is_array( $_POST['acf'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified above.
244 return $comment_id;
245 }
246
247 // Restrict $_POST['acf'] to keys of fields belonging to field groups that apply to this comment.
248 $allowed_keys = $this->get_allowed_field_keys( $comment_id );
249 $_POST['acf'] = array_intersect_key( $_POST['acf'], array_flip( $allowed_keys ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- Verified above; sanitized below.
250
251 if ( empty( $_POST['acf'] ) ) {
252 return $comment_id;
253 }
254
255 $_POST['acf'] = wp_kses_post_deep( $_POST['acf'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized with wp_kses_post_deep().
256 }
257
258 // validate and save
259 if ( acf_validate_save_post( true ) ) {
260 acf_save_post( "comment_{$comment_id}" );
261 }
262 }
263
264 /**
265 * Returns the top-level ACF field keys that are allowed to be saved for
266 * the given comment. Built from the field groups whose comment location
267 * rules match the comment's post type.
268 *
269 * @since 6.8.7
270 *
271 * @param integer $comment_id The ID of comment being saved.
272 * @return array
273 */
274 private function get_allowed_field_keys( $comment_id ) {
275 $keys = array();
276 $comment = get_comment( $comment_id );
277
278 if ( $comment ) {
279 $field_groups = acf_get_field_groups(
280 array(
281 'comment' => get_post_type( $comment->comment_post_ID ),
282 )
283 );
284
285 foreach ( $field_groups as $field_group ) {
286 foreach ( acf_get_fields( $field_group ) as $field ) {
287 $prefix = $field['prefix'] ?? 'acf';
288
289 if ( $prefix === 'acf' ) {
290 if ( ! empty( $field['key'] ) ) {
291 $keys[] = $field['key'];
292 }
293 } elseif ( preg_match( '/^acf\[([^]]+)]$/', $prefix, $matches ) ) {
294 $keys[] = $matches[1];
295 }
296 }
297 }
298 }
299
300 $keys = array_values( array_unique( array_filter( $keys ) ) );
301
302 /**
303 * Filters the list of $_POST['acf'] keys a comment submission is allowed to save.
304 *
305 * Use this to permit additional field keys when a developer dynamically injects
306 * fields into the comment form via JavaScript that aren't part of a field group
307 * whose location rules target this comment.
308 *
309 * @since 6.8.7
310 *
311 * @param array $keys The allowed top-level $_POST['acf'] keys.
312 * @param int $comment_id The comment being saved.
313 */
314 $keys = apply_filters( 'acf/form/comment/allowed_field_keys', $keys, $comment_id );
315
316 // Re-normalize after the filter so a misbehaving callback can't break array_flip().
317 $keys = array_filter( (array) $keys, 'is_scalar' );
318 return array_values( array_unique( array_filter( array_map( 'strval', $keys ) ) ) );
319 }
320
321
322 /**
323 * description
324 *
325 * @type function
326 * @date 27/03/2015
327 * @since 5.1.5
328 *
329 * @param $post_id (int)
330 * @return $post_id (int)
331 */
332 function admin_footer() {
333
334 ?>
335 <script type="text/javascript">
336 (function($) {
337
338 // vars
339 var $spinner = $('#publishing-action .spinner');
340
341
342 // create spinner if not exists (may exist in future WP versions)
343 if( !$spinner.exists() ) {
344
345 // create spinner
346 $spinner = $('<span class="spinner"></span>');
347
348
349 // append
350 $('#publishing-action').prepend( $spinner );
351
352 }
353
354 })(jQuery);
355 </script>
356 <?php
357 }
358 }
359
360 new acf_form_comment();
361 endif;
362
363 ?>
364