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-nav-menu.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-nav-menu.php
375 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_nav_menu' ) ) :
17
18 class acf_form_nav_menu {
19
20 /**
21 * This function will setup the class functionality
22 *
23 * @type function
24 * @date 5/03/2014
25 * @since 5.0.0
26 *
27 * @param n/a
28 * @return n/a
29 */
30 function __construct() {
31
32 // actions
33 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
34 add_action( 'wp_update_nav_menu', array( $this, 'update_nav_menu' ) );
35 add_action( 'acf/validate_save_post', array( $this, 'acf_validate_save_post' ), 5 );
36 add_action( 'wp_nav_menu_item_custom_fields', array( $this, 'wp_nav_menu_item_custom_fields' ), 10, 5 );
37
38 // filters
39 add_filter( 'wp_get_nav_menu_items', array( $this, 'wp_get_nav_menu_items' ), 10, 3 );
40 add_filter( 'wp_edit_nav_menu_walker', array( $this, 'wp_edit_nav_menu_walker' ), 10, 2 );
41 }
42
43
44 /**
45 * This action is run after post query but before any admin script / head actions.
46 * It is a good place to register all actions.
47 *
48 * @type action (admin_enqueue_scripts)
49 * @date 26/01/13
50 * @since 3.6.0
51 *
52 * @param N/A
53 * @return N/A
54 */
55 function admin_enqueue_scripts() {
56
57 // validate screen
58 if ( ! acf_is_screen( 'nav-menus' ) ) {
59 return;
60 }
61
62 // load acf scripts
63 acf_enqueue_scripts();
64
65 // actions
66 add_action( 'admin_footer', array( $this, 'admin_footer' ), 1 );
67 }
68
69
70 /**
71 * wp_nav_menu_item_custom_fields
72 *
73 * description
74 *
75 * @date 30/7/18
76 * @since 5.6.9
77 *
78 * @param type $var Description. Default.
79 * @return type Description.
80 */
81 function wp_nav_menu_item_custom_fields( $item_id, $item, $depth, $args, $id = '' ) {
82
83 // vars
84 $prefix = "menu-item-acf[$item_id]";
85
86 // get field groups
87 $field_groups = acf_get_field_groups(
88 array(
89 'nav_menu_item' => $item->type,
90 'nav_menu_item_id' => $item_id,
91 'nav_menu_item_depth' => $depth,
92 )
93 );
94
95 // render
96 if ( ! empty( $field_groups ) ) {
97
98 // open
99 echo '<div class="acf-menu-item-fields acf-fields -clear">';
100
101 // loop
102 foreach ( $field_groups as $field_group ) {
103
104 // load fields
105 $fields = acf_get_fields( $field_group );
106
107 // bail if not fields
108 if ( empty( $fields ) ) {
109 continue;
110 }
111
112 // change prefix
113 acf_prefix_fields( $fields, $prefix );
114
115 // render
116 acf_render_fields( $fields, $item_id, 'div', $field_group['instruction_placement'] );
117 }
118
119 // close
120 echo '</div>';
121
122 // Trigger append for newly created menu item (via AJAX)
123 if ( acf_is_ajax( 'add-menu-item' ) ) : ?>
124 <script type="text/javascript">
125 (function($) {
126 acf.doAction('append', $('#menu-item-settings-<?php echo esc_attr( $item_id ); ?>') );
127 })(jQuery);
128 </script>
129 <?php
130 endif;
131 }
132 }
133
134
135 /**
136 * description
137 *
138 * @type function
139 * @date 26/5/17
140 * @since 5.6.0
141 *
142 * @param $post_id (int)
143 * @return $post_id (int)
144 */
145 function update_nav_menu( $menu_id ) {
146
147 // vars
148 $post_id = 'term_' . $menu_id;
149
150 // verify and remove nonce
151 if ( ! acf_verify_nonce( 'nav_menu' ) ) {
152 return $menu_id;
153 }
154
155 // validate and show errors
156 acf_validate_save_post( true );
157
158 // save
159 acf_save_post( $post_id );
160
161 // save nav menu items
162 $this->update_nav_menu_items( $menu_id );
163 }
164
165
166 /**
167 * description
168 *
169 * @type function
170 * @date 26/5/17
171 * @since 5.6.0
172 *
173 * @param $post_id (int)
174 * @return $post_id (int)
175 */
176 function update_nav_menu_items( $menu_id ) {
177
178 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
179 if ( empty( $_POST['menu-item-acf'] ) ) {
180 return;
181 }
182
183 $posted_values = acf_sanitize_request_args( $_POST['menu-item-acf'] );
184
185 foreach ( $posted_values as $post_id => $values ) {
186 acf_save_post( $post_id, $values );
187 }
188 // phpcs:enable WordPress.Security.NonceVerification.Missing
189 }
190
191
192 /**
193 * wp_get_nav_menu_items
194 *
195 * WordPress does not provide an easy way to find the current menu being edited.
196 * This function listens to when a menu's items are loaded and stores the menu.
197 * Needed on nav-menus.php page for new menu with no items
198 *
199 * @date 23/2/18
200 * @since 5.6.9
201 *
202 * @param type $var Description. Default.
203 * @return type Description.
204 */
205 function wp_get_nav_menu_items( $items, $menu, $args ) {
206 acf_set_data( 'nav_menu_id', $menu->term_id );
207 return $items;
208 }
209
210 /**
211 * Called when WP renders a menu edit form.
212 * Used to set global data and customize the Walker class.
213 *
214 * @date 26/5/17
215 * @since 5.6.0
216 *
217 * @param string $class The walker class to use. Default 'Walker_Nav_Menu_Edit'.
218 * @param integer $menu_id ID of the menu being rendered.
219 * @return string
220 */
221 function wp_edit_nav_menu_walker( $class, $menu_id = 0 ) {
222
223 // update data (needed for ajax location rules to work)
224 acf_set_data( 'nav_menu_id', $menu_id );
225
226 // Return class.
227 return $class;
228 }
229
230
231 /**
232 * This function will loop over $_POST data and validate
233 *
234 * @type action 'acf/validate_save_post' 5
235 * @date 7/09/2016
236 * @since 5.4.0
237 *
238 * @param n/a
239 * @return n/a
240 */
241 function acf_validate_save_post() {
242
243 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Verified elsewhere.
244 if ( empty( $_POST['menu-item-acf'] ) ) {
245 return;
246 }
247
248 $posted_values = acf_sanitize_request_args( $_POST['menu-item-acf'] );
249
250 foreach ( $posted_values as $post_id => $values ) {
251
252 // vars
253 $prefix = 'menu-item-acf[' . $post_id . ']';
254
255 // validate
256 acf_validate_values( $values, $prefix );
257 }
258 // phpcs:enable // phpcs:disable WordPress.Security.NonceVerification.Missing
259 }
260
261 /**
262 * This function will add some custom HTML to the footer of the edit page
263 *
264 * @type function
265 * @date 11/06/2014
266 * @since 5.0.0
267 *
268 * @param n/a
269 * @return n/a
270 */
271 function admin_footer() {
272
273 // vars
274 $nav_menu_id = acf_get_data( 'nav_menu_id' );
275 $post_id = 'term_' . $nav_menu_id;
276
277 // get field groups
278 $field_groups = acf_get_field_groups(
279 array(
280 'nav_menu' => $nav_menu_id,
281 )
282 );
283
284 ?>
285 <div id="tmpl-acf-menu-settings" style="display: none;">
286 <?php
287
288 // data (always needed to save nav menu items)
289 acf_form_data(
290 array(
291 'screen' => 'nav_menu',
292 'post_id' => $post_id,
293 'ajax' => 1,
294 )
295 );
296
297 // render
298 if ( ! empty( $field_groups ) ) {
299
300 // loop
301 foreach ( $field_groups as $field_group ) {
302 $fields = acf_get_fields( $field_group );
303
304 echo '<div class="acf-menu-settings -' . esc_attr( $field_group['style'] ) . '">';
305
306 echo '<h2>' . acf_esc_html( acf_get_field_group_title( $field_group ) ) . '</h2>';
307
308 echo '<div class="acf-fields -left -clear">';
309
310 acf_render_fields( $fields, $post_id, 'div', $field_group['instruction_placement'] );
311
312 echo '</div>';
313
314 echo '</div>';
315 }
316 }
317
318 ?>
319 </div>
320 <script type="text/javascript">
321 (function($) {
322
323 // append html
324 var html = $('#tmpl-acf-menu-settings').html();
325 $('#tmpl-acf-menu-settings').remove();
326 $('#post-body-content').append( html );
327
328
329 // avoid WP over-writing $_POST data
330 // - https://core.trac.wordpress.org/ticket/41502#ticket
331 $(document).on('submit', '#update-nav-menu', function() {
332
333 // vars
334 var $form = $(this);
335 var $input = $('input[name="nav-menu-data"]');
336
337
338 // decode json
339 var json = $form.serializeArray();
340 var json2 = [];
341
342
343 // loop
344 $.each( json, function( i, pair ) {
345
346 // avoid nesting (unlike WP)
347 if( pair.name === 'nav-menu-data' ) return;
348
349
350 // bail early if is 'acf[' input
351 if( pair.name.indexOf('acf[') > -1 ) return;
352
353
354 // append
355 json2.push( pair );
356
357 });
358
359
360 // update
361 $input.val( JSON.stringify(json2) );
362
363 });
364
365
366 })(jQuery);
367 </script>
368 <?php
369 }
370 }
371
372 acf_new_instance( 'acf_form_nav_menu' );
373 endif;
374 ?>
375