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