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 / admin / post-types / admin-post-type.php
advanced-custom-fields / includes / admin / post-types Last commit date
admin-field-group.php 5 months ago admin-field-groups.php 6 months ago admin-post-type.php 6 months ago admin-post-types.php 6 months ago admin-taxonomies.php 6 months ago admin-taxonomy.php 6 months ago index.php 2 years ago
admin-post-type.php
363 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_Admin_Post_Type' ) ) :
13
14 /**
15 * ACF Admin Post Type Class
16 *
17 * All the logic for editing a post type.
18 */
19 class ACF_Admin_Post_type extends ACF_Admin_Internal_Post_Type {
20
21 /**
22 * The slug for the internal post type.
23 *
24 * @since 6.1
25 * @var string
26 */
27 public $post_type = 'acf-post-type';
28
29 /**
30 * The admin body class used for the post type.
31 *
32 * @since 6.1
33 * @var string
34 */
35 public $admin_body_class = 'acf-admin-single-post-type';
36
37 /**
38 * This function will customize the message shown when editing a post type.
39 *
40 * @since 5.0.0
41 *
42 * @param array $messages Post type messages.
43 * @return array
44 */
45 public function post_updated_messages( $messages ) {
46 $messages['acf-post-type'] = array(
47 0 => '', // Unused. Messages start at index 1.
48 1 => $this->post_type_created_message(), // Updated.
49 2 => $this->post_type_created_message(),
50 3 => __( 'Post type deleted.', 'acf' ),
51 4 => __( 'Post type updated.', 'acf' ),
52 5 => false, // Post type does not support revisions.
53 6 => $this->post_type_created_message( true ), // Created.
54 7 => __( 'Post type saved.', 'acf' ),
55 8 => __( 'Post type submitted.', 'acf' ),
56 9 => __( 'Post type scheduled for.', 'acf' ),
57 10 => __( 'Post type draft updated.', 'acf' ),
58 );
59
60 return $messages;
61 }
62
63 /**
64 * Renders the post type created message.
65 *
66 * @since 6.1
67 *
68 * @param boolean $created True if the post was just created.
69 * @return string
70 */
71 public function post_type_created_message( $created = false ) {
72 global $post_id;
73
74 $title = get_the_title( $post_id );
75
76 /* translators: %s post type name */
77 $item_saved_text = sprintf( __( '%s post type updated', 'acf' ), $title );
78
79 if ( $created ) {
80 /* translators: %s post type name */
81 $item_saved_text = sprintf( __( '%s post type created', 'acf' ), $title );
82 }
83
84 $add_fields_link = wp_nonce_url(
85 admin_url( 'post-new.php?post_type=acf-field-group&use_post_type=' . $post_id ),
86 'add-fields-' . $post_id
87 );
88
89 $create_post_type_link = admin_url( 'post-new.php?post_type=acf-post-type' );
90 $duplicate_post_type_link = wp_nonce_url(
91 admin_url( 'post-new.php?post_type=acf-post-type&use_post_type=' . $post_id ),
92 'acfduplicate-' . $post_id
93 );
94
95 $create_taxonomy_link = wp_nonce_url(
96 admin_url( 'post-new.php?post_type=acf-taxonomy&use_post_type=' . $post_id ),
97 'create-taxonomy-' . $post_id
98 );
99
100 ob_start(); ?>
101 <p class="acf-item-saved-text"><?php echo esc_html( $item_saved_text ); ?></p>
102 <div class="acf-item-saved-links">
103 <a href="<?php echo esc_url( $add_fields_link ); ?>"><?php esc_html_e( 'Add fields', 'acf' ); ?></a>
104 <a class="acf-link-field-groups" href="#"><?php esc_html_e( 'Link field groups', 'acf' ); ?></a>
105 <a href="<?php echo esc_url( $create_post_type_link ); ?>"><?php esc_html_e( 'Create post type', 'acf' ); ?></a>
106 <a href="<?php echo esc_url( $duplicate_post_type_link ); ?>"><?php esc_html_e( 'Duplicate post type', 'acf' ); ?></a>
107 <a href="<?php echo esc_url( $create_taxonomy_link ); ?>"><?php esc_html_e( 'Create taxonomy', 'acf' ); ?></a>
108 </div>
109 <?php
110 return ob_get_clean();
111 }
112
113 /**
114 * Enqueues any scripts necessary for internal post type.
115 *
116 * @since 5.0.0
117 */
118 public function admin_enqueue_scripts() {
119
120 wp_enqueue_style( 'acf-field-group' );
121
122 acf_localize_text(
123 array(
124 'Post' => __( 'Post', 'acf' ),
125 'Posts' => __( 'Posts', 'acf' ),
126 'Page' => __( 'Page', 'acf' ),
127 'Pages' => __( 'Pages', 'acf' ),
128 'Default' => __( 'Default', 'acf' ),
129 )
130 );
131
132 parent::admin_enqueue_scripts();
133
134 do_action( 'acf/post_type/admin_enqueue_scripts' );
135 }
136
137 /**
138 * Sets up all functionality for the post type edit page to work.
139 *
140 * @since 3.1.8
141 */
142 public function admin_head() {
143
144 // global.
145 global $post, $acf_post_type;
146
147 // set global var.
148 $acf_post_type = acf_get_internal_post_type( $post->ID, $this->post_type );
149
150 if ( ! empty( $acf_post_type['not_registered'] ) ) {
151 acf_add_admin_notice(
152 __( 'This post type could not be registered because its key is in use by another post type registered by another plugin or theme.', 'acf' ),
153 'error'
154 );
155 }
156
157 // metaboxes.
158 add_meta_box( 'acf-basic-settings', __( 'Basic Settings', 'acf' ), array( $this, 'mb_basic_settings' ), 'acf-post-type', 'normal', 'high' );
159 add_meta_box( 'acf-advanced-settings', __( 'Advanced Settings', 'acf' ), array( $this, 'mb_advanced_settings' ), 'acf-post-type', 'normal', 'high' );
160
161 // actions.
162 add_action( 'post_submitbox_misc_actions', array( $this, 'post_submitbox_misc_actions' ), 10, 0 );
163 add_action( 'edit_form_after_title', array( $this, 'edit_form_after_title' ), 10, 0 );
164
165 // filters.
166 add_filter( 'screen_settings', array( $this, 'screen_settings' ), 10, 1 );
167 add_filter( 'get_user_option_screen_layout_acf-post-type', array( $this, 'screen_layout' ), 10, 1 );
168 add_filter( 'get_user_option_metaboxhidden_acf-post-type', array( $this, 'force_basic_settings' ), 10, 1 );
169 add_filter( 'get_user_option_closedpostboxes_acf-post-type', array( $this, 'force_basic_settings' ), 10, 1 );
170 add_filter( 'get_user_option_closedpostboxes_acf-post-type', array( $this, 'force_advanced_settings' ), 10, 1 );
171
172 // 3rd party hook.
173 do_action( 'acf/post_type/admin_head' );
174 }
175
176 /**
177 * This action will allow ACF to render metaboxes after the title.
178 */
179 public function edit_form_after_title() {
180
181 // globals.
182 global $post;
183
184 // render post data.
185 acf_form_data(
186 array(
187 'screen' => 'post_type',
188 'post_id' => $post->ID,
189 'delete_fields' => 0,
190 'validation' => 1,
191 )
192 );
193 }
194
195 /**
196 * This function will add extra HTML to the acf form data element
197 *
198 * @since 5.3.8
199 *
200 * @param array $args Arguments array to pass through to action.
201 * @return void
202 */
203 public function form_data( $args ) {
204 do_action( 'acf/post_type/form_data', $args );
205 }
206
207 /**
208 * This function will append extra l10n strings to the acf JS object
209 *
210 * @since 5.3.8
211 *
212 * @param array $l10n The array of translated strings.
213 * @return array $l10n
214 */
215 public function admin_l10n( $l10n ) {
216 return apply_filters( 'acf/post_type/admin_l10n', $l10n );
217 }
218
219 /**
220 * Admin footer third party hook support
221 *
222 * @since 5.3.2
223 */
224 public function admin_footer() {
225 do_action( 'acf/post_type/admin_footer' );
226 }
227
228 /**
229 * Screen settings html output
230 *
231 * @since 3.6.0
232 *
233 * @param string $html Current screen settings HTML.
234 * @return string $html
235 */
236 public function screen_settings( $html ) {
237 return $html;
238 }
239
240 /**
241 * Sets the "Edit Post Type" screen to use a one-column layout.
242 *
243 * @param integer $columns Number of columns for layout.
244 * @return integer
245 */
246 public function screen_layout( $columns = 0 ) {
247 return 1;
248 }
249
250 /**
251 * Force basic settings to always be visible
252 *
253 * @param array $hidden_metaboxes The metaboxes hidden on this page.
254 * @return array
255 */
256 public function force_basic_settings( $hidden_metaboxes ) {
257 if ( ! is_array( $hidden_metaboxes ) ) {
258 return $hidden_metaboxes;
259 }
260 return array_diff( $hidden_metaboxes, array( 'acf-basic-settings' ) );
261 }
262
263 /**
264 * Force advanced settings to be visible
265 *
266 * @param array $hidden_metaboxes The metaboxes hidden on this page.
267 * @return array
268 */
269 public function force_advanced_settings( $hidden_metaboxes ) {
270 if ( ! is_array( $hidden_metaboxes ) ) {
271 return $hidden_metaboxes;
272 }
273 return array_diff( $hidden_metaboxes, array( 'acf-advanced-settings' ) );
274 }
275
276 /**
277 * This function will customize the publish metabox
278 *
279 * @since 5.2.9
280 */
281 public function post_submitbox_misc_actions() {
282 global $acf_post_type;
283 $status_label = $acf_post_type['active'] ? _x( 'Active', 'post status', 'acf' ) : _x( 'Inactive', 'post status', 'acf' );
284
285 ?>
286 <script type="text/javascript">
287 (function($) {
288 $('#post-status-display').html( '<?php echo esc_html( $status_label ); ?>' );
289 })(jQuery);
290 </script>
291 <?php
292 }
293
294 /**
295 * Saves post type data.
296 *
297 * @since 1.0.0
298 *
299 * @param integer $post_id The post ID.
300 * @param WP_Post $post The post object.
301 * @return integer $post_id
302 */
303 public function save_post( $post_id, $post ) {
304 if ( ! $this->verify_save_post( $post_id, $post ) ) {
305 return $post_id;
306 }
307
308 // Disable filters to ensure ACF loads raw data from DB.
309 acf_disable_filters();
310
311 // phpcs:disable WordPress.Security.NonceVerification.Missing -- Validated in $this->verify_save_post() above.
312 // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized when saved.
313 $_POST['acf_post_type']['ID'] = $post_id;
314 $_POST['acf_post_type']['title'] = isset( $_POST['acf_post_type']['labels']['name'] ) ? $_POST['acf_post_type']['labels']['name'] : '';
315
316 if ( ! acf_get_setting( 'enable_meta_box_cb_edit' ) ) {
317 $_POST['acf_post_type']['register_meta_box_cb'] = '';
318
319 $existing_post = acf_maybe_unserialize( $post->post_content );
320 if ( ! empty( $existing_post['register_meta_box_cb'] ) ) {
321 $_POST['acf_post_type']['register_meta_box_cb'] = $existing_post['register_meta_box_cb'];
322 }
323 }
324
325 // Save the post type.
326 acf_update_internal_post_type( $_POST['acf_post_type'], $this->post_type ); // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Validated in verify_save_post
327 // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
328 // phpcs:enable WordPress.Security.NonceVerification.Missing
329
330 return $post_id;
331 }
332
333 /**
334 * Renders HTML for the basic settings metabox.
335 *
336 * @since 5.0.0
337 */
338 public function mb_basic_settings() {
339 global $acf_post_type;
340
341 if ( ! acf_is_internal_post_type_key( $acf_post_type['key'], 'acf-post-type' ) ) {
342 $acf_post_type['key'] = uniqid( 'post_type_' );
343 }
344
345 acf_get_view( $this->post_type . '/basic-settings' );
346 }
347
348
349 /**
350 * Renders the HTML for the advanced settings metabox.
351 *
352 * @since 5.0.0
353 */
354 public function mb_advanced_settings() {
355 acf_get_view( $this->post_type . '/advanced-settings' );
356 }
357 }
358
359 new ACF_Admin_Post_Type();
360 endif; // Class exists check.
361
362 ?>
363