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 / admin / admin-internal-post-type.php
advanced-custom-fields / includes / admin Last commit date
post-types 5 months ago tools 6 months ago views 1 month ago admin-email-opt-in-banner.php 1 month ago admin-internal-post-type-list.php 6 months ago admin-internal-post-type.php 6 months ago admin-notices.php 6 months ago admin-options-pages-preview.php 6 months ago admin-tools.php 6 months ago admin-upgrade.php 6 months ago admin.php 1 month ago index.php 2 years ago
admin-internal-post-type.php
354 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_Internal_Post_Type' ) ) :
17
18 /**
19 * ACF Internal Post Type class.
20 *
21 * Adds logic to the edit page for ACF internal post types.
22 */
23 class ACF_Admin_Internal_Post_Type {
24
25 /**
26 * The slug for the internal post type.
27 *
28 * @since 6.1
29 * @var string
30 */
31 public $post_type = '';
32
33 /**
34 * The admin body class used for the post type.
35 *
36 * @since 6.1
37 * @var string
38 */
39 public $admin_body_class = '';
40
41 /**
42 * Constructs the class.
43 */
44 public function __construct() {
45 add_action( 'current_screen', array( $this, 'current_screen' ) );
46 add_action( 'save_post_' . $this->post_type, array( $this, 'save_post' ), 10, 2 );
47 add_action( 'wp_ajax_acf/link_field_groups', array( $this, 'ajax_link_field_groups' ) );
48 add_filter( 'use_block_editor_for_post_type', array( $this, 'use_block_editor_for_post_type' ), 10, 2 );
49 }
50
51 /**
52 * Prevents the block editor from loading when editing an ACF field group.
53 *
54 * @since 5.8.0
55 *
56 * @param boolean $use_block_editor Whether the post type can be edited or not. Default true.
57 * @param string $post_type The post type being checked.
58 * @return boolean
59 */
60 public function use_block_editor_for_post_type( $use_block_editor, $post_type ) {
61 if ( $post_type === $this->post_type ) {
62 return false;
63 }
64
65 return $use_block_editor;
66 }
67
68 /**
69 * This function will customize the message shown when editing a field group
70 *
71 * @since 5.0.0
72 *
73 * @param array $messages Post type messages.
74 * @return array
75 */
76 public function post_updated_messages( $messages ) {
77 return $messages;
78 }
79
80 /**
81 * This function is fired when loading the admin page before HTML has been rendered.
82 *
83 * @since 5.0.0
84 */
85 public function current_screen() {
86 if ( ! acf_is_screen( $this->post_type ) ) {
87 return;
88 }
89
90 acf_disable_filters();
91 acf_enqueue_scripts();
92
93 add_action( 'admin_body_class', array( $this, 'admin_body_class' ) );
94 add_filter( 'post_updated_messages', array( $this, 'post_updated_messages' ) );
95 add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) );
96 add_action( 'acf/input/admin_head', array( $this, 'admin_head' ) );
97 add_action( 'acf/input/form_data', array( $this, 'form_data' ) );
98 add_action( 'acf/input/admin_footer', array( $this, 'admin_footer' ) );
99
100 add_filter( 'acf/input/admin_l10n', array( $this, 'admin_l10n' ) );
101
102 do_action( 'acf/internal_post_type/current_screen', $this->post_type );
103 }
104
105 /**
106 * Modifies the admin body class.
107 *
108 * @since 6.0.0
109 *
110 * @param string $classes Space-separated list of CSS classes.
111 * @return string
112 */
113 public function admin_body_class( $classes ) {
114 $classes .= ' acf-admin-page acf-internal-post-type ' . esc_attr( $this->admin_body_class );
115 return apply_filters( 'acf/internal_post_type/admin_body_classes', $classes, $this->post_type );
116 }
117
118 /**
119 * Enqueues any scripts necessary for internal post type.
120 *
121 * @since 5.0.0
122 */
123 public function admin_enqueue_scripts() {
124 wp_enqueue_script( 'acf-internal-post-type' );
125
126 wp_dequeue_script( 'autosave' );
127 wp_enqueue_style( $this->post_type );
128 wp_enqueue_script( $this->post_type );
129 }
130
131 /**
132 * Set up functionality for the field group edit page.
133 *
134 * @since 3.1.8
135 */
136 public function admin_head() {
137 // Override as necessary.
138 }
139
140 /**
141 * Adds extra HTML to the acf form data element.
142 *
143 * @since 5.3.8
144 *
145 * @param array $args Arguments array to pass through to action.
146 * @return void
147 */
148 public function form_data( $args ) {
149 // Override as necessary.
150 }
151
152 /**
153 * Admin footer third party hook support
154 *
155 * @since 5.3.2
156 */
157 public function admin_footer() {
158 // Override as necessary.
159 }
160
161 /**
162 * This function will append extra l10n strings to the acf JS object
163 *
164 * @since 5.3.8
165 *
166 * @param array $l10n The array of translated strings.
167 * @return array $l10n
168 */
169 public function admin_l10n( $l10n ) {
170 // Override as necessary.
171 }
172
173 /**
174 * Ran during the `save_post` hook to verify that the post should be saved.
175 *
176 * @since 6.1
177 *
178 * @param integer $post_id The ID of the post being saved.
179 * @param WP_Post $post The post object.
180 * @return boolean
181 */
182 public function verify_save_post( $post_id, $post ) {
183 // Do not save if this is an auto save routine.
184 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
185 return false;
186 }
187
188 // Bail early if not an ACF internal post type.
189 if ( $post->post_type !== $this->post_type ) {
190 return false;
191 }
192
193 // Only save once! WordPress saves a revision as well.
194 if ( wp_is_post_revision( $post_id ) ) {
195 return false;
196 }
197
198 // Verify nonce.
199 $nonce_name = str_replace(
200 array( 'acf-', '-' ),
201 array( '', '_' ),
202 $this->post_type
203 );
204
205 if ( ! acf_verify_nonce( $nonce_name ) ) {
206 return false;
207 }
208
209 // Bail early if request came from an unauthorised user.
210 if ( ! current_user_can( acf_get_setting( 'capability' ) ) ) {
211 return false;
212 }
213
214 return true;
215 }
216
217 /**
218 * Powers the modal for linking field groups to newly-created CPTs/taxonomies.
219 *
220 * @since 6.1
221 */
222 public function ajax_link_field_groups() {
223 // Disable filters to ensure ACF loads raw data from DB.
224 acf_disable_filters();
225
226 // phpcs:disable WordPress.Security.NonceVerification.Missing
227 $args = acf_parse_args(
228 $_POST,
229 array(
230 'nonce' => '',
231 'post_id' => 0,
232 'field_groups' => array(),
233 )
234 );
235 // phpcs:enable WordPress.Security.NonceVerification.Missing
236
237 // Verify nonce and user capability.
238 if ( ! wp_verify_nonce( $args['nonce'], 'acf_nonce' ) || ! acf_current_user_can_admin() || ! $args['post_id'] ) {
239 die();
240 }
241
242 $post_type = get_post_type( $args['post_id'] );
243 $saved_post = acf_get_internal_post_type( $args['post_id'], $post_type );
244
245 // Link the selected field groups.
246 if ( is_array( $args['field_groups'] ) && ! empty( $args['field_groups'] ) && $saved_post ) {
247 foreach ( $args['field_groups'] as $field_group_id ) {
248 $field_group = acf_get_field_group( $field_group_id );
249
250 if ( ! is_array( $field_group ) ) {
251 continue;
252 }
253
254 if ( 'acf-post-type' === $post_type ) {
255 $param = 'post_type';
256 $value = $saved_post['post_type'];
257 } elseif ( 'acf-taxonomy' === $post_type ) {
258 $param = 'taxonomy';
259 $value = $saved_post['taxonomy'];
260 } else {
261 $param = 'options_page';
262 $value = $saved_post['menu_slug'];
263 }
264
265 $field_group['location'][] = array(
266 array(
267 'param' => $param,
268 'operator' => '==',
269 'value' => $value,
270 ),
271 );
272
273 acf_update_field_group( $field_group );
274 }
275
276 ob_start();
277 ?>
278 <p class="acf-link-successful">
279 <?php
280 $link_successful_text = _n(
281 'Field group linked successfully.',
282 'Field groups linked successfully.',
283 count( $args['field_groups'] ),
284 'acf'
285 );
286 echo esc_html( $link_successful_text );
287 ?>
288 </p>
289 <div class="acf-actions">
290 <button type="button" class="acf-btn acf-btn-secondary acf-close-popup"><?php esc_html_e( 'Close Modal', 'acf' ); ?></button>
291 </div>
292 <?php
293 $content = ob_get_clean();
294 wp_send_json_success( array( 'content' => $content ) );
295 }
296
297 // Render the field group select.
298 $field_groups = acf_get_field_groups();
299 $choices = array();
300
301 if ( ! empty( $field_groups ) ) {
302 foreach ( $field_groups as $field_group ) {
303 if ( ! $field_group['ID'] ) {
304 continue;
305 }
306
307 $choices[ $field_group['ID'] ] = $field_group['title'];
308 }
309 }
310
311 $instructions = sprintf(
312 /* translators: %s - either "post type" or "taxonomy" */
313 __( 'Add this %s to the location rules of the selected field groups.', 'acf' ),
314 'acf-post-type' === $post_type ? __( 'post type', 'acf' ) : __( 'taxonomy', 'acf' )
315 );
316
317 $field = acf_get_valid_field(
318 array(
319 'type' => 'select',
320 'name' => 'acf_field_groups',
321 'choices' => $choices,
322 'aria-label' => __( 'Please select the field groups to link.', 'acf' ),
323 'placeholder' => __( 'Select one or many field groups...', 'acf' ),
324 'label' => __( 'Field Group(s)', 'acf' ),
325 'instructions' => $instructions,
326 'ui' => true,
327 'multiple' => true,
328 'allow_null' => true,
329 )
330 );
331
332 ob_start();
333 ?>
334 <form id="acf-link-field-groups-form">
335 <?php acf_render_field_wrap( $field, 'div', 'field' ); ?>
336 <div class="acf-actions">
337 <button type="button" class="acf-btn acf-btn-secondary acf-close-popup"><?php esc_html_e( 'Cancel', 'acf' ); ?></button>
338 <button type="submit" class="acf-btn acf-btn-primary"><?php esc_html_e( 'Done', 'acf' ); ?></button>
339 </div>
340 </form>
341 <?php
342 $content = ob_get_clean();
343
344 wp_send_json_success(
345 array(
346 'content' => $content,
347 'title' => esc_html__( 'Link Existing Field Groups', 'acf' ),
348 )
349 );
350 }
351 }
352
353 endif; // Class exists check.
354