PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / trunk
Secure Custom Fields vtrunk
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 / admin-internal-post-type.php
secure-custom-fields / includes / admin Last commit date
beta-features 7 months ago post-types 2 months ago tools 7 months ago views 1 week ago admin-commands.php 2 months ago admin-internal-post-type-list.php 10 months ago admin-internal-post-type.php 1 year ago admin-notices.php 1 year ago admin-tools.php 10 months ago admin-upgrade.php 1 year ago admin.php 10 months ago beta-features.php 7 months ago class-acf-admin-options-page.php 2 months ago index.php 1 year ago
admin-internal-post-type.php
355 lines
1 <?php
2 /**
3 * ACF Internal Post Type class
4 *
5 * Base class to add functionality to ACF internal post types.
6 *
7 * @package wordpress/secure-custom-fields
8 * @subpackage Admin
9 * @since ACF 6.1
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 ACF 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 ACF 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 ACF 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 ACF 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 ACF 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_filter( '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 ACF 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 ACF 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 ACF 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 ACF 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 ACF 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 ACF 5.3.8
165 *
166 * @param array $l10n The array of translated strings.
167 * @return mixed
168 */
169 public function admin_l10n( $l10n ) {
170 // Override as necessary.
171 return $l10n;
172 }
173
174 /**
175 * Ran during the `save_post` hook to verify that the post should be saved.
176 *
177 * @since ACF 6.1
178 *
179 * @param integer $post_id The ID of the post being saved.
180 * @param WP_Post $post The post object.
181 * @return boolean
182 */
183 public function verify_save_post( $post_id, $post ) {
184 // Do not save if this is an auto save routine.
185 if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
186 return false;
187 }
188
189 // Bail early if not an ACF internal post type.
190 if ( $post->post_type !== $this->post_type ) {
191 return false;
192 }
193
194 // Only save once! WordPress saves a revision as well.
195 if ( wp_is_post_revision( $post_id ) ) {
196 return false;
197 }
198
199 // Verify nonce.
200 $nonce_name = str_replace(
201 array( 'acf-', '-' ),
202 array( '', '_' ),
203 $this->post_type
204 );
205
206 if ( ! acf_verify_nonce( $nonce_name ) ) {
207 return false;
208 }
209
210 // Bail early if request came from an unauthorised user.
211 if ( ! current_user_can( acf_get_setting( 'capability' ) ) ) {
212 return false;
213 }
214
215 return true;
216 }
217
218 /**
219 * Powers the modal for linking field groups to newly-created CPTs/taxonomies.
220 *
221 * @since ACF 6.1
222 */
223 public function ajax_link_field_groups() {
224 // Disable filters to ensure ACF loads raw data from DB.
225 acf_disable_filters();
226
227 // phpcs:disable WordPress.Security.NonceVerification.Missing
228 $args = acf_parse_args(
229 $_POST,
230 array(
231 'nonce' => '',
232 'post_id' => 0,
233 'field_groups' => array(),
234 )
235 );
236 // phpcs:enable WordPress.Security.NonceVerification.Missing
237
238 // Verify nonce and user capability.
239 if ( ! wp_verify_nonce( $args['nonce'], 'acf_nonce' ) || ! acf_current_user_can_admin() || ! $args['post_id'] ) {
240 die();
241 }
242
243 $post_type = get_post_type( $args['post_id'] );
244 $saved_post = acf_get_internal_post_type( $args['post_id'], $post_type );
245
246 // Link the selected field groups.
247 if ( is_array( $args['field_groups'] ) && ! empty( $args['field_groups'] ) && $saved_post ) {
248 foreach ( $args['field_groups'] as $field_group_id ) {
249 $field_group = acf_get_field_group( $field_group_id );
250
251 if ( ! is_array( $field_group ) ) {
252 continue;
253 }
254
255 if ( 'acf-post-type' === $post_type ) {
256 $param = 'post_type';
257 $value = $saved_post['post_type'];
258 } elseif ( 'acf-taxonomy' === $post_type ) {
259 $param = 'taxonomy';
260 $value = $saved_post['taxonomy'];
261 } else {
262 $param = 'options_page';
263 $value = $saved_post['menu_slug'];
264 }
265
266 $field_group['location'][] = array(
267 array(
268 'param' => $param,
269 'operator' => '==',
270 'value' => $value,
271 ),
272 );
273
274 acf_update_field_group( $field_group );
275 }
276
277 ob_start();
278 ?>
279 <p class="acf-link-successful">
280 <?php
281 $link_successful_text = _n(
282 'Field group linked successfully.',
283 'Field groups linked successfully.',
284 count( $args['field_groups'] ),
285 'secure-custom-fields'
286 );
287 echo esc_html( $link_successful_text );
288 ?>
289 </p>
290 <div class="acf-actions">
291 <button type="button" class="acf-btn acf-btn-secondary acf-close-popup"><?php esc_html_e( 'Close Modal', 'secure-custom-fields' ); ?></button>
292 </div>
293 <?php
294 $content = ob_get_clean();
295 wp_send_json_success( array( 'content' => $content ) );
296 }
297
298 // Render the field group select.
299 $field_groups = acf_get_field_groups();
300 $choices = array();
301
302 if ( ! empty( $field_groups ) ) {
303 foreach ( $field_groups as $field_group ) {
304 if ( ! $field_group['ID'] ) {
305 continue;
306 }
307
308 $choices[ $field_group['ID'] ] = $field_group['title'];
309 }
310 }
311
312 $instructions = sprintf(
313 /* translators: %s - either "post type" or "taxonomy" */
314 __( 'Add this %s to the location rules of the selected field groups.', 'secure-custom-fields' ),
315 'acf-post-type' === $post_type ? __( 'post type', 'secure-custom-fields' ) : __( 'taxonomy', 'secure-custom-fields' )
316 );
317
318 $field = acf_get_valid_field(
319 array(
320 'type' => 'select',
321 'name' => 'acf_field_groups',
322 'choices' => $choices,
323 'aria-label' => __( 'Please select the field groups to link.', 'secure-custom-fields' ),
324 'placeholder' => __( 'Select one or many field groups...', 'secure-custom-fields' ),
325 'label' => __( 'Field Group(s)', 'secure-custom-fields' ),
326 'instructions' => $instructions,
327 'ui' => true,
328 'multiple' => true,
329 'allow_null' => true,
330 )
331 );
332
333 ob_start();
334 ?>
335 <form id="acf-link-field-groups-form">
336 <?php acf_render_field_wrap( $field, 'div', 'field' ); ?>
337 <div class="acf-actions">
338 <button type="button" class="acf-btn acf-btn-secondary acf-close-popup"><?php esc_html_e( 'Cancel', 'secure-custom-fields' ); ?></button>
339 <button type="submit" class="acf-btn acf-btn-primary"><?php esc_html_e( 'Done', 'secure-custom-fields' ); ?></button>
340 </div>
341 </form>
342 <?php
343 $content = ob_get_clean();
344
345 wp_send_json_success(
346 array(
347 'content' => $content,
348 'title' => esc_html__( 'Link Existing Field Groups', 'secure-custom-fields' ),
349 )
350 );
351 }
352 }
353
354 endif; // Class exists check.
355