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 / post-types / admin-post-types.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-types.php
358 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_Post_Types' ) ) :
17
18 /**
19 * The ACF Post Types admin controller class
20 */
21 class ACF_Admin_Post_Types extends ACF_Admin_Internal_Post_Type_List {
22
23 /**
24 * The slug for the internal post type.
25 *
26 * @var string
27 */
28 public $post_type = 'acf-post-type';
29
30 /**
31 * The admin body class used for the post type.
32 *
33 * @var string
34 */
35 public $admin_body_class = 'acf-admin-post-types';
36
37 /**
38 * The name of the store used for the post type.
39 *
40 * @var string
41 */
42 public $store = 'post-types';
43
44 /**
45 * Constructor.
46 *
47 * @since 6.2
48 */
49 public function __construct() {
50 add_action( 'admin_menu', array( $this, 'admin_menu' ), 8 );
51 parent::__construct();
52 }
53
54 /**
55 * Current screen actions for the post types list admin page.
56 *
57 * @since 6.1
58 */
59 public function current_screen() {
60 // Bail early if not post types admin page.
61 if ( ! acf_is_screen( "edit-{$this->post_type}" ) ) {
62 return;
63 }
64
65 parent::current_screen();
66
67 // Run a first-run routine to set some defaults which are stored in user preferences.
68 if ( ! acf_get_user_setting( 'post-type-first-run', false ) ) {
69 $option_key = 'manageedit-' . $this->post_type . 'columnshidden';
70 $hidden_items = get_user_option( $option_key );
71
72 if ( ! is_array( $hidden_items ) ) {
73 $hidden_items = array();
74 }
75
76 if ( ! in_array( 'acf-key', $hidden_items ) ) {
77 $hidden_items[] = 'acf-key';
78 }
79 update_user_option( get_current_user_id(), $option_key, $hidden_items, true );
80
81 acf_update_user_setting( 'post-type-first-run', true );
82 }
83 }
84
85 /**
86 * Add any menu items required for post types.
87 *
88 * @since 6.1
89 */
90 public function admin_menu() {
91 $parent_slug = 'edit.php?post_type=acf-field-group';
92 $cap = acf_get_setting( 'capability' );
93 add_submenu_page( $parent_slug, __( 'Post Types', 'acf' ), __( 'Post Types', 'acf' ), $cap, 'edit.php?post_type=acf-post-type' );
94 }
95
96 /**
97 * Customizes the admin table columns.
98 *
99 * @date 1/4/20
100 * @since 5.9.0
101 *
102 * @param array $_columns The columns array.
103 * @return array
104 */
105 public function admin_table_columns( $_columns ) {
106 // Set the "no found" label to be our custom HTML for no results.
107 if ( empty( acf_request_arg( 's' ) ) ) {
108 global $wp_post_types;
109 $wp_post_types[ $this->post_type ]->labels->not_found = $this->get_not_found_html();
110 }
111
112 $columns = array(
113 'cb' => $_columns['cb'],
114 'title' => $_columns['title'],
115 'acf-description' => __( 'Description', 'acf' ),
116 'acf-key' => __( 'Key', 'acf' ),
117 'acf-taxonomies' => __( 'Taxonomies', 'acf' ),
118 'acf-field-groups' => __( 'Field Groups', 'acf' ),
119 'acf-count' => __( 'Posts', 'acf' ),
120 );
121
122 if ( acf_get_local_json_files( $this->post_type ) ) {
123 $columns['acf-json'] = __( 'Local JSON', 'acf' );
124 }
125
126 return $columns;
127 }
128
129 /**
130 * Renders a specific admin table column.
131 *
132 * @date 17/4/20
133 * @since 5.9.0
134 *
135 * @param string $column_name The name of the column to display.
136 * @param array $post The main ACF post array.
137 * @return void
138 */
139 public function render_admin_table_column( $column_name, $post ) {
140 switch ( $column_name ) {
141 case 'acf-key':
142 echo '<i class="acf-icon acf-icon-key-solid"></i>';
143 echo esc_html( $post['key'] );
144 break;
145
146 // Description.
147 case 'acf-description':
148 if ( ( is_string( $post['description'] ) || is_numeric( $post['description'] ) ) && ! empty( $post['description'] ) ) {
149 echo '<span class="acf-description">' . acf_esc_html( $post['description'] ) . '</span>';
150 } else {
151 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
152 echo '<span class="screen-reader-text">' . esc_html__( 'No description', 'acf' ) . '</span>';
153 }
154 break;
155
156 case 'acf-taxonomies':
157 $this->render_admin_table_column_taxonomies( $post );
158 break;
159
160 case 'acf-field-groups':
161 $this->render_admin_table_column_field_groups( $post );
162 break;
163
164 case 'acf-count':
165 $this->render_admin_table_column_num_posts( $post );
166 break;
167
168 // Local JSON.
169 case 'acf-json':
170 $this->render_admin_table_column_local_status( $post );
171 break;
172 }
173 }
174
175 /**
176 * Renders the field groups attached to the post type in the list table.
177 *
178 * @since 6.1
179 *
180 * @param array $post_type The main post type array.
181 * @return void
182 */
183 public function render_admin_table_column_field_groups( $post_type ) {
184 $field_groups = acf_get_field_groups( array( 'post_type' => $post_type['post_type'] ) );
185
186 if ( empty( $field_groups ) ) {
187 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
188 echo '<span class="screen-reader-text">' . esc_html__( 'No field groups', 'acf' ) . '</span>';
189 return;
190 }
191
192 $labels = wp_list_pluck( $field_groups, 'title' );
193 $limit = 3;
194 $shown_labels = array_slice( $labels, 0, $limit );
195 $hidden_labels = array_slice( $labels, $limit );
196 $text = implode( ', ', $shown_labels );
197
198 if ( ! empty( $hidden_labels ) ) {
199 $text .= ', <span class="acf-more-items acf-js-tooltip" title="' . implode( ', ', $hidden_labels ) . '">+' . count( $hidden_labels ) . '</span>';
200 }
201
202 echo acf_esc_html( $text );
203 }
204
205 /**
206 * Renders the taxonomies attached to the post type in the list table.
207 *
208 * @since 6.1
209 *
210 * @param array $post_type The main post type array.
211 * @return void
212 */
213 public function render_admin_table_column_taxonomies( $post_type ) {
214 $taxonomies = array();
215 $labels = array();
216
217 if ( is_array( $post_type['taxonomies'] ) ) {
218 $taxonomies = $post_type['taxonomies'];
219 }
220
221 $acf_taxonomies = acf_get_internal_post_type_posts( 'acf-taxonomy' );
222
223 foreach ( $acf_taxonomies as $acf_taxonomy ) {
224 if ( is_array( $acf_taxonomy['object_type'] ) && in_array( $post_type['post_type'], $acf_taxonomy['object_type'], true ) ) {
225 $taxonomies[] = $acf_taxonomy['taxonomy'];
226 }
227 }
228
229 $taxonomies = array_unique( $taxonomies );
230
231 foreach ( $taxonomies as $tax_slug ) {
232 $taxonomy = get_taxonomy( $tax_slug );
233
234 if ( ! is_object( $taxonomy ) || empty( $taxonomy->label ) ) {
235 continue;
236 }
237
238 $labels[] = $taxonomy->label;
239 }
240
241 if ( empty( $labels ) ) {
242 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
243 echo '<span class="screen-reader-text">' . esc_html__( 'No taxonomies', 'acf' ) . '</span>';
244 return;
245 }
246
247 $limit = 3;
248 $shown_labels = array_slice( $labels, 0, $limit );
249 $hidden_labels = array_slice( $labels, $limit );
250 $text = implode( ', ', $shown_labels );
251
252 if ( ! empty( $hidden_labels ) ) {
253 $text .= ', <span class="acf-more-items acf-js-tooltip" title="' . implode( ', ', $hidden_labels ) . '">+' . count( $hidden_labels ) . '</span>';
254 }
255
256 echo acf_esc_html( $text );
257 }
258
259 /**
260 * Renders the number of posts created for the post type in the list table.
261 *
262 * @since 6.1
263 *
264 * @param array $post_type The main post type array.
265 * @return void
266 */
267 public function render_admin_table_column_num_posts( $post_type ) {
268 $no_posts = '<span class="acf-emdash" aria-hidden="true">—</span>';
269 $no_posts .= '<span class="screen-reader-text">' . esc_html__( 'No posts', 'acf' ) . '</span>';
270
271 // WP doesn't count posts for post types that don't exist.
272 if ( empty( $post_type['active'] ) || 'trash' === get_post_status( $post_type['ID'] ) ) {
273 echo acf_esc_html( $no_posts );
274 return;
275 }
276
277 $num_posts = wp_count_posts( $post_type['post_type'] );
278 if ( is_object( $num_posts ) && property_exists( $num_posts, 'publish' ) ) {
279 $num_posts = $num_posts->publish;
280 }
281
282 if ( ! $num_posts || ! is_numeric( $num_posts ) ) {
283 echo acf_esc_html( $no_posts );
284 return;
285 }
286
287 printf(
288 '<a href="%s">%s</a>',
289 esc_url( admin_url( 'edit.php?post_type=' . $post_type['post_type'] ) ),
290 esc_html( number_format_i18n( $num_posts ) )
291 );
292 }
293
294 /**
295 * Gets the translated action notice text for list table actions (activate, deactivate, sync, etc.).
296 *
297 * @since 6.1
298 *
299 * @param string $action The action being performed.
300 * @param integer $count The number of items the action was performed on.
301 * @return string
302 */
303 public function get_action_notice_text( $action, $count = 1 ) {
304 $text = '';
305 $count = (int) $count;
306
307 switch ( $action ) {
308 case 'acfactivatecomplete':
309 $text = sprintf(
310 /* translators: %s number of post types activated */
311 _n( 'Post type activated.', '%s post types activated.', $count, 'acf' ),
312 $count
313 );
314 break;
315 case 'acfdeactivatecomplete':
316 $text = sprintf(
317 /* translators: %s number of post types deactivated */
318 _n( 'Post type deactivated.', '%s post types deactivated.', $count, 'acf' ),
319 $count
320 );
321 break;
322 case 'acfduplicatecomplete':
323 $text = sprintf(
324 /* translators: %s number of post types duplicated */
325 _n( 'Post type duplicated.', '%s post types duplicated.', $count, 'acf' ),
326 $count
327 );
328 break;
329 case 'acfsynccomplete':
330 $text = sprintf(
331 /* translators: %s number of post types synchronized */
332 _n( 'Post type synchronized.', '%s post types synchronized.', $count, 'acf' ),
333 $count
334 );
335 break;
336 }
337
338 return $text;
339 }
340
341 /**
342 * Returns the registration error state.
343 *
344 * @since 6.1
345 *
346 * @return string
347 */
348 public function get_registration_error_state() {
349 return '<span class="acf-js-tooltip dashicons dashicons-warning" title="' .
350 __( 'This post type could not be registered because its key is in use by another post type registered by another plugin or theme.', 'acf' ) .
351 '"></span> ' . _x( 'Registration Failed', 'post status', 'acf' );
352 }
353 }
354
355 // Instantiate.
356 acf_new_instance( 'ACF_Admin_Post_Types' );
357 endif; // Class exists check.
358