PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.7
Advanced Custom Fields (ACF®) v6.8.7
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 / admin / admin.php
advanced-custom-fields / includes / admin Last commit date
post-types 5 months ago tools 5 months ago views 1 month ago admin-email-opt-in-banner.php 1 month ago admin-internal-post-type-list.php 5 months ago admin-internal-post-type.php 5 months ago admin-notices.php 5 months ago admin-options-pages-preview.php 5 months ago admin-tools.php 5 months ago admin-upgrade.php 5 months ago admin.php 1 month ago index.php 2 years ago
admin.php
442 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_Admin' ) ) :
17
18 class ACF_Admin {
19
20 /**
21 * Constructor.
22 *
23 * @since 5.0.0
24 */
25 public function __construct() {
26 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
27 add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
28 add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );
29 add_action( 'current_screen', array( $this, 'current_screen' ) );
30 add_action( 'admin_notices', array( $this, 'maybe_show_escaped_html_notice' ) );
31 add_action( 'admin_notices', array( $this, 'maybe_show_select2_v3_deprecation_notice' ) );
32 add_action( 'admin_init', array( $this, 'dismiss_escaped_html_notice' ) );
33 add_action( 'admin_init', array( $this, 'clear_escaped_html_log' ) );
34 add_filter( 'parent_file', array( $this, 'ensure_menu_selection' ) );
35 add_filter( 'submenu_file', array( $this, 'ensure_submenu_selection' ) );
36 }
37
38 /**
39 * Adds the ACF menu item.
40 *
41 * @date 28/09/13
42 * @since 5.0.0
43 */
44 public function admin_menu() {
45
46 // Bail early if ACF is hidden.
47 if ( ! acf_get_setting( 'show_admin' ) ) {
48 return;
49 }
50
51 // Vars.
52 $cap = acf_get_setting( 'capability' );
53 $parent_slug = 'edit.php?post_type=acf-field-group';
54
55 // Add menu items.
56 add_menu_page( __( 'ACF', 'acf' ), __( 'ACF', 'acf' ), $cap, $parent_slug, false, 'dashicons-welcome-widgets-menus', 80 );
57 }
58
59 /**
60 * Enqueues global admin styling.
61 *
62 * @since 5.0.0
63 */
64 public function admin_enqueue_scripts() {
65 wp_enqueue_style( 'acf-global' );
66 wp_enqueue_script( 'acf-escaped-html-notice' );
67
68 wp_localize_script(
69 'acf-escaped-html-notice',
70 'acf_escaped_html_notice',
71 array(
72 'show_details' => __( 'Show&nbsp;details', 'acf' ),
73 'hide_details' => __( 'Hide&nbsp;details', 'acf' ),
74 )
75 );
76 }
77
78 /**
79 * Appends custom admin body classes.
80 *
81 * @date 5/11/19
82 * @since 5.8.7
83 *
84 * @param string $classes Space-separated list of CSS classes.
85 * @return string
86 */
87 public function admin_body_class( $classes ) {
88 global $wp_version;
89
90 // Add body class.
91 $classes .= ' acf-admin-5-3';
92
93 if ( version_compare( $wp_version, '7.0', '>=' ) ) {
94 $classes .= ' acf-admin-7-0';
95 }
96
97 // Add browser for specific CSS.
98 $classes .= ' acf-browser-' . esc_attr( acf_get_browser() );
99
100 // Return classes.
101 return $classes;
102 }
103
104 /**
105 * Adds custom functionality to "ACF" admin pages.
106 *
107 * @date 7/4/20
108 * @since 5.9.0
109 *
110 * @param void
111 * @return void
112 */
113 public function current_screen( $screen ) {
114 // Determine if the current page being viewed is "ACF" related.
115 if ( isset( $screen->post_type ) && in_array( $screen->post_type, acf_get_internal_post_types(), true ) ) {
116 add_action( 'in_admin_header', array( $this, 'in_admin_header' ) );
117 add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ) );
118 add_filter( 'update_footer', array( $this, 'admin_footer_version_text' ) );
119 $this->setup_help_tab();
120 $this->maybe_show_import_from_cptui_notice();
121 }
122 }
123
124 /**
125 * Sets up the admin help tab.
126 *
127 * @date 20/4/20
128 * @since 5.9.0
129 *
130 * @param void
131 * @return void
132 */
133 public function setup_help_tab() {
134 $screen = get_current_screen();
135
136 // Overview tab.
137 $screen->add_help_tab(
138 array(
139 'id' => 'overview',
140 'title' => __( 'Overview', 'acf' ),
141 'content' =>
142 '<p><strong>' . __( 'Overview', 'acf' ) . '</strong></p>' .
143 '<p>' . __( 'The Advanced Custom Fields plugin provides a visual form builder to customize WordPress edit screens with extra fields, and an intuitive API to display custom field values in any theme template file.', 'acf' ) . '</p>' .
144 '<p>' . sprintf(
145 __( 'Before creating your first Field Group, we recommend first reading our <a href="%s" target="_blank">Getting started</a> guide to familiarize yourself with the plugin\'s philosophy and best practises.', 'acf' ),
146 acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/getting-started-with-acf/', 'docs', 'help-tab' )
147 ) . '</p>' .
148 '<p>' . __( 'Please use the Help & Support tab to get in touch should you find yourself requiring assistance.', 'acf' ) . '</p>' .
149 '',
150 )
151 );
152
153 // Help tab.
154 $screen->add_help_tab(
155 array(
156 'id' => 'help',
157 'title' => __( 'Help & Support', 'acf' ),
158 'content' =>
159 '<p><strong>' . __( 'Help & Support', 'acf' ) . '</strong></p>' .
160 '<p>' . __( 'We are fanatical about support, and want you to get the best out of your website with ACF. If you run into any difficulties, there are several places you can find help:', 'acf' ) . '</p>' .
161 '<ul>' .
162 '<li>' . sprintf(
163 __( '<a href="%s" target="_blank">Documentation</a>. Our extensive documentation contains references and guides for most situations you may encounter.', 'acf' ),
164 acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/', 'docs', 'help-tab' )
165 ) . '</li>' .
166 '<li>' . sprintf(
167 __( '<a href="%s" target="_blank">Discussions</a>. We have an active and friendly community on our Community Forums who may be able to help you figure out the \'how-tos\' of the ACF world.', 'acf' ),
168 acf_add_url_utm_tags( 'https://support.advancedcustomfields.com/', 'docs', 'help-tab' )
169 ) . '</li>' .
170 '<li>' . sprintf(
171 __( '<a href="%s" target="_blank">Help Desk</a>. The support professionals on our Help Desk will assist with your more in depth, technical challenges.', 'acf' ),
172 acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/support/', 'docs', 'help-tab' )
173 ) . '</li>' .
174 '</ul>',
175 )
176 );
177
178 // Sidebar.
179 $screen->set_help_sidebar(
180 '<p><strong>' . __( 'Information', 'acf' ) . '</strong></p>' .
181 '<p><span class="dashicons dashicons-admin-plugins"></span> ' . sprintf( __( 'Version %s', 'acf' ), ACF_VERSION ) . '</p>' .
182 '<p><span class="dashicons dashicons-wordpress"></span> <a href="https://wordpress.org/plugins/advanced-custom-fields/" target="_blank">' . __( 'View details', 'acf' ) . '</a></p>' .
183 '<p><span class="dashicons dashicons-admin-home"></span> <a href="' . acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/', 'docs', 'help-tab' ) . '" target="_blank" target="_blank">' . __( 'Visit website', 'acf' ) . '</a></p>' .
184 ''
185 );
186 }
187
188 /**
189 * Shows a notice to import post types and taxonomies from CPTUI if that plugin is active.
190 *
191 * @since 6.1
192 */
193 public function maybe_show_import_from_cptui_notice() {
194 global $plugin_page;
195
196 // Only show if CPTUI is active and post types are enabled.
197 if ( ! acf_get_setting( 'enable_post_types' ) || ! is_plugin_active( 'custom-post-type-ui/custom-post-type-ui.php' ) ) {
198 return;
199 }
200
201 // No need to show on the tools page.
202 if ( 'acf-tools' === $plugin_page ) {
203 return;
204 }
205
206 $text = sprintf(
207 /* translators: %s - URL to ACF tools page. */
208 __( 'Import Post Types and Taxonomies registered with Custom Post Type UI and manage them with ACF. <a href="%s">Get Started</a>.', 'acf' ),
209 acf_get_admin_tools_url()
210 );
211
212 acf_add_admin_notice( $text, 'success', true, true );
213 }
214
215 /**
216 * Notifies the user that fields rendered via shortcode or the_field() have
217 * had HTML removed/altered due to unsafe HTML being escaped.
218 *
219 * @since 6.2.5
220 */
221 public function maybe_show_escaped_html_notice() {
222 // Only show to editors and above.
223 if ( ! current_user_can( 'edit_others_posts' ) ) {
224 return;
225 }
226
227 // Allow opting-out of the notice.
228 if ( apply_filters( 'acf/admin/prevent_escaped_html_notice', true ) ) {
229 return;
230 }
231
232 if ( get_option( 'acf_escaped_html_notice_dismissed' ) ) {
233 return;
234 }
235
236 $escaped = _acf_get_escaped_html_log();
237
238 // Notice for when HTML has already been escaped.
239 if ( ! empty( $escaped ) ) {
240 acf_get_view( 'escaped-html-notice', array( 'acf_escaped' => $escaped ) );
241 }
242 }
243
244 /**
245 * Dismisses the escaped unsafe HTML notice.
246 *
247 * @since 6.2.5
248 */
249 public function dismiss_escaped_html_notice() {
250 if ( empty( $_GET['acf-dismiss-esc-html-notice'] ) ) {
251 return;
252 }
253
254 $nonce = sanitize_text_field( wp_unslash( $_GET['acf-dismiss-esc-html-notice'] ) );
255
256 if (
257 ! wp_verify_nonce( $nonce, 'acf/dismiss_escaped_html_notice' ) ||
258 ! current_user_can( acf_get_setting( 'capability' ) )
259 ) {
260 return;
261 }
262
263 update_option( 'acf_escaped_html_notice_dismissed', true );
264
265 _acf_delete_escaped_html_log();
266
267 wp_safe_redirect( remove_query_arg( 'acf-dismiss-esc-html-notice' ) );
268 exit;
269 }
270
271 /**
272 * Clear the escaped unsafe HTML log.
273 *
274 * @since 6.2.5
275 */
276 public function clear_escaped_html_log() {
277 if ( empty( $_GET['acf-clear-esc-html-log'] ) ) {
278 return;
279 }
280
281 $nonce = sanitize_text_field( wp_unslash( $_GET['acf-clear-esc-html-log'] ) );
282
283 if (
284 ! wp_verify_nonce( $nonce, 'acf/clear_escaped_html_log' ) ||
285 ! current_user_can( acf_get_setting( 'capability' ) )
286 ) {
287 return;
288 }
289
290 _acf_delete_escaped_html_log();
291
292 wp_safe_redirect( remove_query_arg( 'acf-clear-esc-html-log' ) );
293 exit;
294 }
295
296 /**
297 * Notifies the user that Select2 v3 has been deprecated and will be removed.
298 *
299 * @since 6.4.3
300 *
301 * @return void
302 */
303 public function maybe_show_select2_v3_deprecation_notice() {
304 // Only show to editors and above.
305 if ( ! current_user_can( 'edit_others_posts' ) ) {
306 return;
307 }
308
309 if ( 3 === acf_get_setting( 'select2_version' ) ) {
310 $acf_plugin_name = acf_is_pro() ? 'ACF PRO' : 'ACF';
311 $acf_plugin_name = '<strong>' . $acf_plugin_name . ' &mdash;</strong>';
312
313 $text = sprintf(
314 /* translators: %1$s - Plugin name, %2$s URL to documentation */
315 __( '%1$s We have detected that this website is configured to use v3 of the Select2 jQuery library, which has been deprecated in favor of v4 and will be removed in a future version of ACF. <a href="%2$s" target="_blank">Learn more</a>.', 'acf' ),
316 $acf_plugin_name,
317 acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/select2-v3-deprecation/', 'docs', 'select2-deprecation-notice' ),
318 );
319
320 acf_add_admin_notice( $text, 'warning', false );
321 }
322 }
323
324 /**
325 * Renders the admin navigation element.
326 *
327 * @date 27/3/20
328 * @since 5.9.0
329 *
330 * @param void
331 * @return void
332 */
333 function in_admin_header() {
334 acf_get_view( 'global/navigation' );
335
336 $screen = get_current_screen();
337
338 if ( isset( $screen->base ) && 'post' === $screen->base ) {
339 acf_get_view( 'global/form-top' );
340 }
341
342 do_action( 'acf/in_admin_header' );
343 }
344
345 /**
346 * Modifies the admin footer text.
347 *
348 * @date 7/4/20
349 * @since 5.9.0
350 *
351 * @param string $text The current admin footer text.
352 * @return string
353 */
354 public function admin_footer_text( $text ) {
355 $wp_engine_link = acf_add_url_utm_tags( 'https://wpengine.com/', 'bx_prod_referral', acf_is_pro() ? 'acf_pro_plugin_footer_text' : 'acf_free_plugin_footer_text', false, 'acf_plugin', 'referral' );
356 $acf_link = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/', 'footer', 'footer' );
357
358 if ( acf_is_pro() ) {
359 return sprintf(
360 /* translators: This text is prepended by a link to ACF's website, and appended by a link to WP Engine's website. */
361 '<a href="%1$s" target="_blank">ACF&#174;</a> and <a href="%1$s" target="_blank">ACF&#174; PRO</a> ' . __( 'are developed and maintained by', 'acf' ) . ' <a href="%2$s" target="_blank">WP Engine</a>.',
362 $acf_link,
363 $wp_engine_link
364 );
365 }
366
367 return sprintf(
368 /* translators: This text is prepended by a link to ACF's website, and appended by a link to WP Engine's website. */
369 '<a href="%1$s" target="_blank">ACF&#174;</a> ' . __( 'is developed and maintained by', 'acf' ) . ' <a href="%2$s" target="_blank">WP Engine</a>.',
370 $acf_link,
371 $wp_engine_link
372 );
373 }
374
375 /**
376 * Modifies the admin footer version text.
377 *
378 * @since 6.2
379 *
380 * @param string $text The current admin footer version text.
381 * @return string
382 */
383 public function admin_footer_version_text( $text ) {
384 $documentation_link = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/', 'footer', 'footer' );
385 $support_link = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/support/', 'footer', 'footer' );
386 $feedback_link = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/feedback/', 'footer', 'footer' );
387 $version_link = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/changelog/', 'footer', 'footer' );
388
389 return sprintf(
390 '<a href="%s" target="_blank">%s</a> &#8729; <a href="%s" target="_blank">%s</a> &#8729; <a href="%s" target="_blank">%s</a> &#8729; <a href="%s" target="_blank">%s %s</a>',
391 $documentation_link,
392 __( 'Documentation', 'acf' ),
393 $support_link,
394 __( 'Support', 'acf' ),
395 $feedback_link,
396 __( 'Feedback', 'acf' ),
397 $version_link,
398 acf_is_pro() ? __( 'ACF PRO', 'acf' ) : __( 'ACF', 'acf' ),
399 ACF_VERSION
400 );
401 }
402
403 /**
404 * Ensure the ACF parent menu is selected for add-new.php
405 *
406 * @since 6.1
407 * @param string $parent_file The parent file checked against menu activation.
408 * @return string The modified parent file
409 */
410 public function ensure_menu_selection( $parent_file ) {
411 if ( ! is_string( $parent_file ) ) {
412 return $parent_file;
413 }
414 if ( strpos( $parent_file, 'edit.php?post_type=acf-' ) === 0 ) {
415 return 'edit.php?post_type=acf-field-group';
416 }
417 return $parent_file;
418 }
419
420
421 /**
422 * Ensure the correct ACF submenu item is selected when in post-new versions of edit pages
423 *
424 * @since 6.1
425 * @param string $submenu_file The submenu filename.
426 * @return string The modified submenu filename
427 */
428 public function ensure_submenu_selection( $submenu_file ) {
429 if ( ! is_string( $submenu_file ) ) {
430 return $submenu_file;
431 }
432 if ( strpos( $submenu_file, 'post-new.php?post_type=acf-' ) === 0 ) {
433 return str_replace( 'post-new', 'edit', $submenu_file );
434 }
435 return $submenu_file;
436 }
437 }
438
439 // Instantiate.
440 acf_new_instance( 'ACF_Admin' );
441 endif; // class_exists check
442