PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.4.0-beta2
Secure Custom Fields v6.4.0-beta2
6.9.5 6.9.4 6.9.3 6.9.2 6.9.1 6.9.0 6.8.9 6.8.7 6.8.8 6.8.6 6.8.4 6.8.5 trunk 6.4.0-beta1 6.4.0-beta2 6.4.1 6.4.1-beta3 6.4.1-beta4 6.4.1-beta5 6.4.1-beta6 6.4.1-beta7 6.4.2 6.5.0 6.5.1 6.5.2 6.5.3 6.5.4 6.5.5 6.5.6 6.5.7 6.6.0 6.7.0 6.7.1 6.8.0 6.8.1 6.8.2 6.8.3
secure-custom-fields / includes / admin / post-types / admin-field-groups.php
secure-custom-fields / includes / admin / post-types Last commit date
admin-field-group.php 1 year ago admin-field-groups.php 1 year ago admin-post-type.php 1 year ago admin-post-types.php 1 year ago admin-taxonomies.php 1 year ago admin-taxonomy.php 1 year ago index.php 1 year ago
admin-field-groups.php
387 lines
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 if ( ! class_exists( 'ACF_Admin_Field_Groups' ) ) :
8 #[AllowDynamicProperties]
9 class ACF_Admin_Field_Groups extends ACF_Admin_Internal_Post_Type_List {
10
11 /**
12 * The slug for the internal post type.
13 *
14 * @since 6.1
15 * @var string
16 */
17 public $post_type = 'acf-field-group';
18
19 /**
20 * The admin body class used for the post type.
21 *
22 * @since 6.1
23 * @var string
24 */
25 public $admin_body_class = 'acf-admin-field-groups';
26
27 /**
28 * The name of the store used for the post type.
29 *
30 * @var string
31 */
32 public $store = 'field-groups';
33
34 /**
35 * Constructor.
36 *
37 * @since 5.0.0
38 */
39 public function __construct() {
40 add_action( 'admin_menu', array( $this, 'admin_menu' ), 7 );
41 add_action( 'load-edit.php', array( $this, 'handle_redirection' ) );
42 add_action( 'post_class', array( $this, 'get_admin_table_post_classes' ), 10, 3 );
43
44 parent::__construct();
45 }
46
47 /**
48 * Add any menu items required for field groups.
49 *
50 * @since 6.1
51 */
52 public function admin_menu() {
53 $parent_slug = 'edit.php?post_type=acf-field-group';
54 $cap = acf_get_setting( 'capability' );
55 add_submenu_page( $parent_slug, __( 'Field Groups', 'acf' ), __( 'Field Groups', 'acf' ), $cap, $parent_slug );
56 }
57
58 /**
59 * Redirects users from ACF 4.0 admin page.
60 *
61 * @since 5.7.6
62 */
63 public function handle_redirection() {
64 if ( isset( $_GET['post_type'] ) && $_GET['post_type'] === 'acf' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
65 wp_safe_redirect( $this->get_admin_url() );
66 exit;
67 }
68 }
69
70 /**
71 * Customizes the admin table columns.
72 *
73 * @date 1/4/20
74 * @since 5.9.0
75 *
76 * @param array $_columns The columns array.
77 * @return array
78 */
79 public function admin_table_columns( $_columns ) {
80 // Set the "no found" label to be our custom HTML for no results.
81 if ( empty( acf_request_arg( 's' ) ) ) {
82 global $wp_post_types;
83 $this->not_found_label = $wp_post_types['acf-field-group']->labels->not_found;
84 $wp_post_types['acf-field-group']->labels->not_found = $this->get_not_found_html();
85 }
86
87 $columns = array(
88 'cb' => $_columns['cb'],
89 'title' => $_columns['title'],
90 'acf-description' => __( 'Description', 'acf' ),
91 'acf-key' => __( 'Key', 'acf' ),
92 'acf-location' => __( 'Location', 'acf' ),
93 'acf-count' => __( 'Fields', 'acf' ),
94 );
95
96 if ( acf_get_local_json_files( $this->post_type ) ) {
97 $columns['acf-json'] = __( 'Local JSON', 'acf' );
98 }
99
100 return $columns;
101 }
102
103 /**
104 * Renders a specific admin table column.
105 *
106 * @date 17/4/20
107 * @since 5.9.0
108 *
109 * @param string $column_name The name of the column to display.
110 * @param array $post The main ACF post array.
111 * @return void
112 */
113 public function render_admin_table_column( $column_name, $post ) {
114 switch ( $column_name ) {
115
116 // Key.
117 case 'acf-key':
118 echo '<i class="acf-icon acf-icon-key-solid"></i>';
119 echo esc_html( $post['key'] );
120 break;
121
122 // Description.
123 case 'acf-description':
124 if ( ( is_string( $post['description'] ) || is_numeric( $post['description'] ) ) && ! empty( $post['description'] ) ) {
125 echo '<span class="acf-description">' . acf_esc_html( $post['description'] ) . '</span>';
126 } else {
127 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
128 echo '<span class="screen-reader-text">' . esc_html__( 'No description', 'acf' ) . '</span>';
129 }
130 break;
131
132 // Location.
133 case 'acf-location':
134 $this->render_admin_table_column_locations( $post );
135 break;
136
137 // Count.
138 case 'acf-count':
139 $this->render_admin_table_column_num_fields( $post );
140 break;
141
142 // Local JSON.
143 case 'acf-json':
144 $this->render_admin_table_column_local_status( $post );
145 break;
146 }
147 }
148
149 /**
150 * Displays a visual representation of the field group's locations.
151 *
152 * @date 1/4/20
153 * @since 5.9.0
154 *
155 * @param array $field_group The field group.
156 * @return void
157 */
158 public function render_admin_table_column_locations( $field_group ) {
159 $objects = array();
160
161 // Loop over location rules and determine connected object types.
162 if ( $field_group['location'] ) {
163 foreach ( $field_group['location'] as $i => $rules ) {
164
165 // Determine object types for each rule.
166 foreach ( $rules as $j => $rule ) {
167
168 // Get location type and subtype for the current rule.
169 $location = acf_get_location_rule( $rule['param'] );
170 $location_object_type = '';
171 $location_object_subtype = '';
172 if ( $location ) {
173 $location_object_type = $location->get_object_type( $rule );
174 $location_object_subtype = $location->get_object_subtype( $rule );
175 }
176 $rules[ $j ]['object_type'] = $location_object_type;
177 $rules[ $j ]['object_subtype'] = $location_object_subtype;
178 }
179
180 // Now that each $rule conains object type data...
181 $object_types = array_column( $rules, 'object_type' );
182 $object_types = array_filter( $object_types );
183 $object_types = array_values( $object_types );
184 if ( $object_types ) {
185 $object_type = $object_types[0];
186 } else {
187 continue;
188 }
189
190 $object_subtypes = array_column( $rules, 'object_subtype' );
191 $object_subtypes = array_filter( $object_subtypes );
192 $object_subtypes = array_values( $object_subtypes );
193 $object_subtypes = array_map( 'acf_array', $object_subtypes );
194 if ( count( $object_subtypes ) > 1 ) {
195 $object_subtypes = call_user_func_array( 'array_intersect', $object_subtypes );
196 $object_subtypes = array_values( $object_subtypes );
197 } elseif ( $object_subtypes ) {
198 $object_subtypes = $object_subtypes[0];
199 } else {
200 $object_subtypes = array( '' );
201 }
202
203 // Append to objects.
204 foreach ( $object_subtypes as $object_subtype ) {
205 $object = acf_get_object_type( $object_type, $object_subtype );
206 if ( $object ) {
207 $objects[ $object->name ] = $object;
208 }
209 }
210 }
211 }
212
213 // Reset keys.
214 $objects = array_values( $objects );
215
216 // Display.
217 $html = '';
218 if ( $objects ) {
219 $limit = 3;
220 $total = count( $objects );
221
222 // Icon.
223 $html .= '<span class="dashicons ' . $objects[0]->icon . ( $total > 1 ? ' acf-multi-dashicon' : '' ) . '"></span>';
224
225 // Labels.
226 $labels = array_column( $objects, 'label' );
227 $labels = array_slice( $labels, 0, 3 );
228 $html .= implode( ', ', $labels );
229
230 // More.
231 if ( $total > $limit ) {
232 $html .= ', ...';
233 }
234 } else {
235 $html = '<span class="dashicons dashicons-businesswoman"></span> ' . __( 'Various', 'acf' );
236 }
237
238 // Filter.
239 echo acf_esc_html( $html );
240 }
241
242 /**
243 * Renders the number of fields created for the field group in the list table.
244 *
245 * @since 6.1.5
246 *
247 * @param array $field_group The main field group array.
248 * @return void
249 */
250 public function render_admin_table_column_num_fields( $field_group ) {
251 $field_count = acf_get_field_count( $field_group );
252
253 if ( ! $field_count || ! is_numeric( $field_count ) ) {
254 echo '<span class="acf-emdash" aria-hidden="true">—</span>';
255 echo '<span class="screen-reader-text">' . esc_html__( 'No fields', 'acf' ) . '</span>';
256 return;
257 }
258
259 // If in JSON but not synced or in trash, the link won't work.
260 if ( empty( $field_group['ID'] ) || 'trash' === get_post_status( $field_group['ID'] ) ) {
261 echo esc_html( number_format_i18n( $field_count ) );
262 return;
263 }
264
265 printf(
266 '<a href="%s">%s</a>',
267 esc_url( admin_url( 'post.php?action=edit&post=' . $field_group['ID'] ) ),
268 esc_html( number_format_i18n( $field_count ) )
269 );
270 }
271
272 /**
273 * Gets the class(es) to be used by field groups in the list table.
274 *
275 * @since 6.2.8
276 *
277 * @param array $classes An array of the classes used by the field group.
278 * @param array $css_class An array of additional classes added to the field group.
279 * @param integer $post_id The ID of the field group.
280 * @return array
281 */
282 public function get_admin_table_post_classes( $classes, $css_class, $post_id ) {
283 // Bail early if not in the field group list table.
284 if ( ! is_admin() || $this->post_type !== get_post_type( $post_id ) ) {
285 return $classes;
286 }
287
288 return apply_filters( 'acf/field_group/list_table_classes', $classes, $css_class, $post_id );
289 }
290
291 /**
292 * Fires when trashing a field group.
293 *
294 * @date 8/01/2014
295 * @since 5.0.0
296 *
297 * @param integer $post_id The post ID.
298 * @return void
299 */
300 public function trashed_post( $post_id ) {
301 if ( get_post_type( $post_id ) === $this->post_type ) {
302 acf_trash_field_group( $post_id );
303 }
304 }
305
306 /**
307 * Fires when untrashing a field group.
308 *
309 * @date 8/01/2014
310 * @since 5.0.0
311 *
312 * @param integer $post_id The post ID.
313 * @return void
314 */
315 public function untrashed_post( $post_id ) {
316 if ( get_post_type( $post_id ) === $this->post_type ) {
317 acf_untrash_field_group( $post_id );
318 }
319 }
320
321 /**
322 * Fires when deleting a field group.
323 *
324 * @date 8/01/2014
325 * @since 5.0.0
326 *
327 * @param integer $post_id The post ID.
328 * @return void
329 */
330 public function deleted_post( $post_id ) {
331 if ( get_post_type( $post_id ) === $this->post_type ) {
332 acf_delete_field_group( $post_id );
333 }
334 }
335
336 /**
337 * Gets the translated action notice text for list table actions (activate, deactivate, sync, etc.).
338 *
339 * @since 6.1
340 *
341 * @param string $action The action being performed.
342 * @param integer $count The number of items the action was performed on.
343 * @return string
344 */
345 public function get_action_notice_text( $action, $count = 1 ) {
346 $text = '';
347 $count = (int) $count;
348
349 switch ( $action ) {
350 case 'acfactivatecomplete':
351 $text = sprintf(
352 /* translators: %s number of field groups activated */
353 _n( 'Field group activated.', '%s field groups activated.', $count, 'acf' ),
354 $count
355 );
356 break;
357 case 'acfdeactivatecomplete':
358 $text = sprintf(
359 /* translators: %s number of field groups deactivated */
360 _n( 'Field group deactivated.', '%s field groups deactivated.', $count, 'acf' ),
361 $count
362 );
363 break;
364 case 'acfduplicatecomplete':
365 $text = sprintf(
366 /* translators: %s number of field groups duplicated */
367 _n( 'Field group duplicated.', '%s field groups duplicated.', $count, 'acf' ),
368 $count
369 );
370 break;
371 case 'acfsynccomplete':
372 $text = sprintf(
373 /* translators: %s number of field groups synchronized */
374 _n( 'Field group synchronized.', '%s field groups synchronized.', $count, 'acf' ),
375 $count
376 );
377 break;
378 }
379
380 return $text;
381 }
382 }
383
384 // Instantiate.
385 acf_new_instance( 'ACF_Admin_Field_Groups' );
386 endif; // Class exists check.
387