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-widget.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-widget.php
309 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_widget' ) ) :
13 class acf_form_widget {
14
15 /**
16 * Preview values.
17 * @var array
18 */
19 public $preview_values = array();
20
21 /**
22 * Preview reference.
23 * @var array
24 */
25 public $preview_reference = array();
26
27 /**
28 * Preview errors.
29 * @var array
30 */
31 public $preview_errors = array();
32
33 /**
34 * This function will setup the class functionality
35 *
36 * @type function
37 * @date 5/03/2014
38 * @since 5.0.0
39 *
40 * @param n/a
41 * @return n/a
42 */
43 function __construct() {
44
45 // actions
46 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
47 add_action( 'in_widget_form', array( $this, 'edit_widget' ), 10, 3 );
48 add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 );
49
50 // filters
51 add_filter( 'widget_update_callback', array( $this, 'save_widget' ), 10, 4 );
52 }
53
54
55 /**
56 * This action is run after post query but before any admin script / head actions.
57 * It is a good place to register all actions.
58 *
59 * @type action (admin_enqueue_scripts)
60 * @date 26/01/13
61 * @since 3.6.0
62 *
63 * @param N/A
64 * @return N/A
65 */
66 function admin_enqueue_scripts() {
67
68 // validate screen
69 if ( acf_is_screen( 'widgets' ) || acf_is_screen( 'customize' ) ) {
70
71 // valid
72 } else {
73 return;
74 }
75
76 // load acf scripts
77 acf_enqueue_scripts();
78
79 // actions
80 add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ), 1 );
81 }
82
83
84 /**
85 * This function will loop over $_POST data and validate
86 *
87 * @type action 'acf/validate_save_post' 5
88 * @since 5.4.0
89 */
90 public function acf_validate_save_post() {
91 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
92 // bail early if not widget
93 if ( ! isset( $_POST['_acf_widget_id'] ) ) {
94 return;
95 }
96
97 // vars
98 $id = sanitize_text_field( wp_unslash( $_POST['_acf_widget_id'] ) );
99 $number = acf_maybe_get_POST( '_acf_widget_number' );
100 $prefix = acf_maybe_get_POST( '_acf_widget_prefix' );
101 $values = ! empty( $_POST[ $id ][ $number ]['acf'] ) ? acf_sanitize_request_args( $_POST[ $id ][ $number ]['acf'] ) : ''; //phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash -- unslash not required.
102
103 // validate
104 acf_validate_values( $values, $prefix );
105 // phpcs:enable WordPress.Security.NonceVerification.Missing
106 }
107
108
109 /**
110 * This function will render the fields for a widget form
111 *
112 * @type function
113 * @date 11/06/2014
114 * @since 5.0.0
115 *
116 * @param $widget (object)
117 * @param $return (null)
118 * @param $instance (object)
119 * @return $post_id (int)
120 */
121 function edit_widget( $widget, $return, $instance ) {
122
123 // vars
124 $post_id = 0;
125 $prefix = 'widget-' . $widget->id_base . '[' . $widget->number . '][acf]';
126
127 // get id
128 if ( $widget->number !== '__i__' ) {
129 $post_id = "widget_{$widget->id}";
130 }
131
132 // get field groups
133 $field_groups = acf_get_field_groups(
134 array(
135 'widget' => $widget->id_base,
136 )
137 );
138
139 // render
140 if ( ! empty( $field_groups ) ) {
141
142 // render post data
143 acf_form_data(
144 array(
145 'screen' => 'widget',
146 'post_id' => $post_id,
147 'widget_id' => 'widget-' . $widget->id_base,
148 'widget_number' => $widget->number,
149 'widget_prefix' => $prefix,
150 )
151 );
152
153 // wrap
154 echo '<div class="acf-widget-fields acf-fields -clear">';
155
156 // loop
157 foreach ( $field_groups as $field_group ) {
158
159 // load fields
160 $fields = acf_get_fields( $field_group );
161
162 // bail if not fields
163 if ( empty( $fields ) ) {
164 continue;
165 }
166
167 // change prefix
168 acf_prefix_fields( $fields, $prefix );
169
170 // render
171 acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] );
172 }
173
174 // wrap
175 echo '</div>';
176
177 // jQuery selector looks odd, but is necessary due to WP adding an incremental number into the ID
178 // - not possible to find number via PHP parameters
179 if ( $widget->updated ) : ?>
180 <script type="text/javascript">
181 (function($) {
182
183 acf.doAction('append', $('[id^="widget"][id$="<?php echo esc_attr( $widget->id ); ?>"]') );
184
185 })(jQuery);
186 </script>
187 <?php
188 endif;
189 }
190 }
191
192
193 /**
194 * This function will hook into the widget update filter and save ACF data
195 *
196 * @type function
197 * @date 27/05/2015
198 * @since 5.2.3
199 *
200 * @param $instance (array) widget settings
201 * @param $new_instance (array) widget settings
202 * @param $old_instance (array) widget settings
203 * @param $widget (object) widget info
204 * @return $instance
205 */
206 function save_widget( $instance, $new_instance, $old_instance, $widget ) {
207
208 // validate nonce if we're not a REST API request.
209 // the $_POST object is not available to us to validate if we're in a REST API call.
210 if ( ! ( function_exists( 'wp_is_json_request' ) && wp_is_json_request() ) ) {
211 if ( ! acf_verify_nonce( 'widget' ) ) {
212 return $instance;
213 }
214 }
215
216 // bail early if not valid (!customize + acf values + nonce).
217 if ( isset( $_POST['wp_customize'] ) || ! isset( $new_instance['acf'] ) ) {
218 return $instance;
219 }
220
221 // save
222 acf_save_post( "widget_{$widget->id}", $new_instance['acf'] );
223
224 // return
225 return $instance;
226 }
227
228
229 /**
230 * This function will add some custom HTML to the footer of the edit page
231 *
232 * @type function
233 * @date 11/06/2014
234 * @since 5.0.0
235 *
236 * @param n/a
237 * @return n/a
238 */
239 function admin_footer() {
240 ?>
241 <script type="text/javascript">
242 (function($) {
243
244 // vars
245 acf.set('post_id', 'widgets');
246
247 // Only initialize visible fields.
248 acf.addFilter('find_fields', function( $fields ){
249
250 // not templates
251 $fields = $fields.not('#available-widgets .acf-field');
252
253 // not widget dragging in
254 $fields = $fields.not('.widget.ui-draggable-dragging .acf-field');
255
256 // return
257 return $fields;
258 });
259
260 // on publish
261 $('#widgets-right').on('click', '.widget-control-save', function( e ){
262
263 // vars
264 var $button = $(this);
265 var $form = $button.closest('form');
266
267 // validate
268 var valid = acf.validateForm({
269 form: $form,
270 event: e,
271 reset: true
272 });
273
274 // if not valid, stop event and allow validation to continue
275 if( !valid ) {
276 e.preventDefault();
277 e.stopImmediatePropagation();
278 }
279 });
280
281 // show
282 $('#widgets-right').on('click', '.widget-top', function(){
283 var $widget = $(this).parent();
284 if( $widget.hasClass('open') ) {
285 acf.doAction('hide', $widget);
286 } else {
287 acf.doAction('show', $widget);
288 }
289 });
290
291 $(document).on('widget-added', function( e, $widget ){
292
293 // - use delay to avoid rendering issues with customizer (ensures div is visible)
294 setTimeout(function(){
295 acf.doAction('append', $widget );
296 }, 100);
297 });
298
299 })(jQuery);
300 </script>
301 <?php
302 }
303 }
304
305 new acf_form_widget();
306 endif;
307
308 ?>
309