PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.8
Advanced Custom Fields (ACF®) v6.8.8
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-customizer.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-customizer.php
450 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 ( ! defined( 'ABSPATH' ) ) {
13 exit; // Exit if accessed directly
14 }
15
16 if ( ! class_exists( 'acf_form_customizer' ) ) :
17 class acf_form_customizer {
18
19 /**
20 * Preview values.
21 * @var array
22 */
23 public $preview_values = array();
24
25 /**
26 * Preview fields.
27 * @var array
28 */
29 public $preview_fields = array();
30
31 /**
32 * Preview errors.
33 * @var array
34 */
35 public $preview_errors = array();
36
37 /**
38 * This function will setup the class functionality
39 *
40 * @type function
41 * @date 5/03/2014
42 * @since 5.0.0
43 *
44 * @param n/a
45 * @return n/a
46 */
47 function __construct() {
48
49 // actions
50 add_action( 'customize_controls_init', array( $this, 'customize_controls_init' ) );
51 add_action( 'customize_preview_init', array( $this, 'customize_preview_init' ), 1, 1 );
52 add_action( 'customize_save', array( $this, 'customize_save' ), 1, 1 );
53
54 // save
55 add_filter( 'widget_update_callback', array( $this, 'save_widget' ), 10, 4 );
56 }
57
58
59 /**
60 * This action is run after post query but before any admin script / head actions.
61 * It is a good place to register all actions.
62 *
63 * @type action (admin_enqueue_scripts)
64 * @date 26/01/13
65 * @since 3.6.0
66 *
67 * @param N/A
68 * @return N/A
69 */
70 function customize_controls_init() {
71
72 // load acf scripts
73 acf_enqueue_scripts(
74 array(
75 'context' => 'customize_controls',
76 )
77 );
78
79 // actions
80 add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ), 1 );
81 }
82
83
84 /**
85 * This function will hook into the widget update filter and save ACF data
86 *
87 * @type function
88 * @date 27/05/2015
89 * @since 5.2.3
90 *
91 * @param $instance (array) widget settings
92 * @param $new_instance (array) widget settings
93 * @param $old_instance (array) widget settings
94 * @param $widget (object) widget info
95 * @return $instance
96 */
97 function save_widget( $instance, $new_instance, $old_instance, $widget ) {
98
99 // bail early if not valid (customize + acf values + nonce)
100 if ( ! isset( $_POST['wp_customize'] ) || ! isset( $new_instance['acf'] ) || ! acf_verify_nonce( 'widget' ) ) {
101 return $instance;
102 }
103
104 // vars
105 $data = array(
106 'post_id' => "widget_{$widget->id}",
107 'values' => array(),
108 'fields' => array(),
109 );
110
111 // append values
112 $data['values'] = $new_instance['acf'];
113
114 // append fields (name => key relationship) - used later in 'acf/get_field_reference' for customizer previews
115 foreach ( $data['values'] as $k => $v ) {
116
117 // get field
118 $field = acf_get_field( $k );
119
120 // continue if no field
121 if ( ! $field ) {
122 continue;
123 }
124
125 // update
126 $data['fields'][ $field['name'] ] = $field['key'];
127 }
128
129 // append data to instance
130 $instance['acf'] = $data;
131
132 // return
133 return $instance;
134 }
135
136
137 /**
138 * This function will return an array of cutomizer settings that include ACF data
139 * similar to `$customizer->settings();`
140 *
141 * @type function
142 * @date 22/03/2016
143 * @since 5.3.2
144 *
145 * @param $customizer (object)
146 * @return $value (mixed)
147 */
148 function settings( $customizer ) {
149
150 // vars
151 $data = array();
152 $settings = $customizer->settings();
153
154 // bail early if no settings
155 if ( empty( $settings ) ) {
156 return false;
157 }
158
159 // loop over settings
160 foreach ( $settings as $setting ) {
161
162 // vars
163 $id = $setting->id;
164
165 // verify settings type
166 if ( substr( $id, 0, 6 ) == 'widget' || substr( $id, 0, 7 ) == 'nav_menu' ) {
167 // allow
168 } else {
169 continue;
170 }
171
172 // get value
173 $value = $setting->post_value();
174
175 // bail early if no acf
176 if ( ! is_array( $value ) || ! isset( $value['acf'] ) ) {
177 continue;
178 }
179
180 // set data
181 $setting->acf = $value['acf'];
182
183 // append
184 $data[] = $setting;
185 }
186
187 // bail early if no settings
188 if ( empty( $data ) ) {
189 return false;
190 }
191
192 // return
193 return $data;
194 }
195
196
197 /**
198 * This function is called when customizer preview is initialized
199 *
200 * @type function
201 * @date 22/03/2016
202 * @since 5.3.2
203 *
204 * @param $customizer (object)
205 * @return n/a
206 */
207 function customize_preview_init( $customizer ) {
208
209 // get customizer settings (widgets)
210 $settings = $this->settings( $customizer );
211
212 // bail early if no settings
213 if ( empty( $settings ) ) {
214 return;
215 }
216
217 // append values
218 foreach ( $settings as $setting ) {
219
220 // get acf data
221 $data = $setting->acf;
222
223 // append acf_value to preview_values
224 $this->preview_values[ $data['post_id'] ] = $data['values'];
225 $this->preview_fields[ $data['post_id'] ] = $data['fields'];
226 }
227
228 // bail early if no preview_values
229 if ( empty( $this->preview_values ) ) {
230 return;
231 }
232
233 // add filters
234 add_filter( 'acf/pre_load_value', array( $this, 'pre_load_value' ), 10, 3 );
235 add_filter( 'acf/pre_load_reference', array( $this, 'pre_load_reference' ), 10, 3 );
236 }
237
238 /**
239 * pre_load_value
240 *
241 * Used to inject preview value
242 *
243 * @date 2/2/18
244 * @since 5.6.5
245 *
246 * @param type $var Description. Default.
247 * @return type Description.
248 */
249 function pre_load_value( $value, $post_id, $field ) {
250
251 // check
252 if ( isset( $this->preview_values[ $post_id ][ $field['key'] ] ) ) {
253 return $this->preview_values[ $post_id ][ $field['key'] ];
254 }
255
256 // return
257 return $value;
258 }
259
260 /**
261 * pre_load_reference
262 *
263 * Used to inject preview value
264 *
265 * @date 2/2/18
266 * @since 5.6.5
267 *
268 * @param type $var Description. Default.
269 * @return type Description.
270 */
271 function pre_load_reference( $field_key, $field_name, $post_id ) {
272
273 // check
274 if ( isset( $this->preview_fields[ $post_id ][ $field_name ] ) ) {
275 return $this->preview_fields[ $post_id ][ $field_name ];
276 }
277
278 // return
279 return $field_key;
280 }
281
282
283 /**
284 * This function is called when customizer saves a widget.
285 * Normally, the widget_update_callback filter would be used, but the customizer disables this and runs a custom action
286 * class-customizer-settings.php will save the widget data via the function set_root_value which uses update_option
287 *
288 * @type function
289 * @date 22/03/2016
290 * @since 5.3.2
291 *
292 * @param $customizer (object)
293 * @return n/a
294 */
295 function customize_save( $customizer ) {
296
297 // get customizer settings (widgets)
298 $settings = $this->settings( $customizer );
299
300 // bail early if no settings
301 if ( empty( $settings ) ) {
302 return;
303 }
304
305 // append values
306 foreach ( $settings as $setting ) {
307
308 // get acf data
309 $data = $setting->acf;
310
311 // save acf data
312 acf_save_post( $data['post_id'], $data['values'] );
313
314 // remove [acf] data from saved widget array
315 $id_data = $setting->id_data();
316 add_filter( 'pre_update_option_' . $id_data['base'], array( $this, 'pre_update_option' ), 10, 3 );
317 }
318 }
319
320
321 /**
322 * This function will remove the [acf] data from widget insance
323 *
324 * @type function
325 * @date 22/03/2016
326 * @since 5.3.2
327 *
328 * @param $post_id (int)
329 * @return $post_id (int)
330 */
331 function pre_update_option( $value, $option, $old_value ) {
332
333 // bail early if no value
334 if ( empty( $value ) ) {
335 return $value;
336 }
337
338 // loop over widgets
339 // WP saves all widgets (of the same type) as an array of widgets
340 foreach ( $value as $i => $widget ) {
341
342 // bail early if no acf
343 if ( ! isset( $widget['acf'] ) ) {
344 continue;
345 }
346
347 // remove widget
348 unset( $value[ $i ]['acf'] );
349 }
350
351 // return
352 return $value;
353 }
354
355
356 /**
357 * This function will add some custom HTML to the footer of the edit page
358 *
359 * @type function
360 * @date 11/06/2014
361 * @since 5.0.0
362 *
363 * @param n/a
364 * @return n/a
365 */
366 function admin_footer() {
367
368 ?>
369 <script type="text/javascript">
370 (function($) {
371
372 // customizer saves widget on any input change, so unload is not needed
373 acf.unload.active = 0;
374
375
376 // hack customizer function to remove bug caused by WYSIWYG field using aunique ID
377 // customizer compares returned AJAX HTML with the HTML of the widget form.
378 // the _getInputsSignature() function is used to generate a string based of input name + id.
379 // because ACF generates a unique ID on the WYSIWYG field, this string will not match causing the preview function to bail.
380 // an attempt was made to remove the WYSIWYG unique ID, but this caused multiple issues in the wp-admin and altimately doesn't make sense with the tinymce rule that all editors must have a unique ID.
381 // source: wp-admin/js/customize-widgets.js
382
383 // vars
384 var WidgetControl = wp.customize.Widgets.WidgetControl.prototype;
385
386
387 // backup functions
388 WidgetControl.__getInputsSignature = WidgetControl._getInputsSignature;
389 WidgetControl.__setInputState = WidgetControl._setInputState;
390
391
392 // modify __getInputsSignature
393 WidgetControl._getInputsSignature = function( inputs ) {
394
395 // vars
396 var signature = this.__getInputsSignature( inputs );
397 safe = [];
398
399
400 // split
401 signature = signature.split(';');
402
403
404 // loop
405 for( var i in signature ) {
406
407 // vars
408 var bit = signature[i];
409
410
411 // bail early if acf is found
412 if( bit.indexOf('acf') !== -1 ) continue;
413
414
415 // append
416 safe.push( bit );
417
418 }
419
420
421 // update
422 signature = safe.join(';');
423
424
425 // return
426 return signature;
427
428 };
429
430
431 // modify _setInputState
432 // this function deosn't seem to run on widget title/content, only custom fields
433 // either way, this function is not needed and will break ACF fields
434 WidgetControl._setInputState = function( input, state ) {
435
436 return true;
437
438 };
439
440 })(jQuery);
441 </script>
442 <?php
443 }
444 }
445
446 new acf_form_customizer();
447 endif;
448
449 ?>
450