PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.8.5
Secure Custom Fields v6.8.5
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 / fields / class-acf-field-post_object.php
secure-custom-fields / includes / fields Last commit date
FlexibleContent 2 months ago class-acf-field-accordion.php 1 month ago class-acf-field-button-group.php 1 month ago class-acf-field-checkbox.php 1 month ago class-acf-field-clone.php 2 months ago class-acf-field-color_picker.php 1 month ago class-acf-field-date_picker.php 1 month ago class-acf-field-date_time_picker.php 1 month ago class-acf-field-email.php 1 month ago class-acf-field-file.php 1 month ago class-acf-field-flexible-content.php 1 month ago class-acf-field-gallery.php 1 month ago class-acf-field-google-map.php 1 month ago class-acf-field-group.php 1 month ago class-acf-field-icon_picker.php 7 months ago class-acf-field-image.php 1 month ago class-acf-field-link.php 1 month ago class-acf-field-message.php 1 year ago class-acf-field-nav-menu.php 1 year ago class-acf-field-number.php 1 month ago class-acf-field-oembed.php 1 month ago class-acf-field-output.php 1 year ago class-acf-field-page_link.php 1 month ago class-acf-field-password.php 1 month ago class-acf-field-post_object.php 1 month ago class-acf-field-radio.php 1 month ago class-acf-field-range.php 1 month ago class-acf-field-relationship.php 1 month ago class-acf-field-repeater.php 1 month ago class-acf-field-select.php 1 month ago class-acf-field-separator.php 1 year ago class-acf-field-tab.php 1 year ago class-acf-field-taxonomy.php 1 month ago class-acf-field-text.php 1 month ago class-acf-field-textarea.php 1 month ago class-acf-field-time_picker.php 1 month ago class-acf-field-true_false.php 1 month ago class-acf-field-url.php 1 month ago class-acf-field-user.php 1 month ago class-acf-field-wysiwyg.php 1 month ago class-acf-field.php 1 month ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field-post_object.php
805 lines
1 <?php
2
3 if ( ! class_exists( 'acf_field_post_object' ) ) :
4
5 class acf_field_post_object extends acf_field {
6
7
8
9 /**
10 * This function will setup the field type data
11 *
12 * @since ACF 5.0.0
13 */
14 public function initialize() {
15 $this->name = 'post_object';
16 $this->label = __( 'Post Object', 'secure-custom-fields' );
17 $this->category = 'relational';
18 $this->description = __( 'An interactive and customizable UI for picking one or many posts, pages or post type items with the option to search. ', 'secure-custom-fields' );
19 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-post-object.png';
20 $this->doc_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/post-object/';
21 $this->tutorial_url = 'https://developer.wordpress.org/secure-custom-fields/features/fields/post-object/post-object-tutorial/';
22 $this->defaults = array(
23 'post_type' => array(),
24 'taxonomy' => array(),
25 'allow_null' => 0,
26 'multiple' => 0,
27 'return_format' => 'object',
28 'ui' => 1,
29 'bidirectional_target' => array(),
30 );
31
32 // extra
33 add_action( 'wp_ajax_acf/fields/post_object/query', array( $this, 'ajax_query' ) );
34 add_action( 'wp_ajax_nopriv_acf/fields/post_object/query', array( $this, 'ajax_query' ) );
35 add_filter( 'acf/conditional_logic/choices', array( $this, 'render_field_post_object_conditional_choices' ), 10, 3 );
36 }
37
38 /**
39 * Filters choices in post object conditions.
40 *
41 * @since ACF 6.3
42 *
43 * @param array $choices The selected choice.
44 * @param array $conditional_field The conditional field settings object.
45 * @param string $rule_value The rule value.
46 * @return array
47 */
48 public function render_field_post_object_conditional_choices( $choices, $conditional_field, $rule_value ) {
49 if ( ! is_array( $conditional_field ) || $conditional_field['type'] !== 'post_object' ) {
50 return $choices;
51 }
52 if ( ! empty( $rule_value ) ) {
53 $post_title = esc_html( get_the_title( $rule_value ) );
54 $choices = array( $rule_value => $post_title );
55 }
56 return $choices;
57 }
58
59 /**
60 * AJAX query handler for post object fields.
61 *
62 * @since ACF 5.0.0
63 *
64 * @return void
65 */
66 public function ajax_query() {
67 $nonce = acf_request_arg( 'nonce', '' );
68 $key = acf_request_arg( 'field_key', '' );
69 $conditional_logic = (bool) acf_request_arg( 'conditional_logic', false );
70
71 if ( $conditional_logic ) {
72 if ( ! acf_current_user_can_admin() ) {
73 die();
74 }
75
76 // Use the standard ACF admin nonce.
77 $nonce = '';
78 $key = '';
79 }
80
81 if ( ! acf_verify_ajax( $nonce, $key, ! $conditional_logic ) ) {
82 die();
83 }
84
85 acf_send_ajax_results( $this->get_ajax_query( $_POST ) );
86 }
87
88 /**
89 * Returns an array of data formatted for use in a select2 AJAX response.
90 *
91 * @since ACF 5.0.9
92 *
93 * @param array $options The options being queried for the ajax request.
94 * @return array|boolean The AJAX response array, or false on failure.
95 */
96 public function get_ajax_query( $options = array() ) {
97 // defaults
98 $options = acf_parse_args(
99 $options,
100 array(
101 'post_id' => 0,
102 's' => '',
103 'field_key' => '',
104 'paged' => 1,
105 'include' => '',
106 )
107 );
108
109 // load field
110 $field = acf_get_field( $options['field_key'] );
111 if ( ! $field ) {
112 return false;
113 }
114
115 // vars
116 $results = array();
117 $args = array();
118 $s = false;
119 $is_search = false;
120
121 // paged
122 $args['posts_per_page'] = 20;
123 $args['paged'] = (int) $options['paged'];
124
125 // search
126 if ( $options['s'] !== '' ) {
127
128 // strip slashes (search may be integer)
129 $s = wp_unslash( strval( $options['s'] ) );
130
131 // update vars
132 $args['s'] = $s;
133 $is_search = true;
134 }
135
136 if ( ! empty( $options['include'] ) ) {
137 $args['include'] = (int) $options['include'];
138 }
139
140 // post_type
141 if ( ! empty( $field['post_type'] ) ) {
142 $args['post_type'] = acf_get_array( $field['post_type'] );
143 } else {
144 $args['post_type'] = acf_get_post_types();
145 }
146
147 // Post status - use field config only, don't accept from user input.
148 if ( ! empty( $field['post_status'] ) ) {
149 $args['post_status'] = acf_get_array( $field['post_status'] );
150 }
151
152 // If there is an include set, we will unset search to avoid attempting to further filter by the search term.
153 if ( isset( $args['include'] ) ) {
154 unset( $args['s'] );
155 }
156
157 // taxonomy
158 if ( ! empty( $field['taxonomy'] ) ) {
159
160 // vars
161 $terms = acf_decode_taxonomy_terms( $field['taxonomy'] );
162
163 // append to $args
164 $args['tax_query'] = array();
165
166 // now create the tax queries
167 foreach ( $terms as $k => $v ) {
168 $args['tax_query'][] = array(
169 'taxonomy' => $k,
170 'field' => 'slug',
171 'terms' => $v,
172 );
173 }
174 }
175
176 // filters
177 $args = apply_filters( 'acf/fields/post_object/query', $args, $field, $options['post_id'] );
178 $args = apply_filters( 'acf/fields/post_object/query/name=' . $field['name'], $args, $field, $options['post_id'] );
179 $args = apply_filters( 'acf/fields/post_object/query/key=' . $field['key'], $args, $field, $options['post_id'] );
180
181 // get posts grouped by post type
182 $groups = acf_get_grouped_posts( $args );
183
184 // bail early if no posts
185 if ( empty( $groups ) ) {
186 return false;
187 }
188
189 // loop
190 foreach ( array_keys( $groups ) as $group_title ) {
191
192 // vars
193 $posts = acf_extract_var( $groups, $group_title );
194
195 // data
196 $data = array(
197 'text' => $group_title,
198 'children' => array(),
199 );
200
201 // convert post objects to post titles
202 foreach ( array_keys( $posts ) as $post_id ) {
203 $posts[ $post_id ] = $this->get_post_title( $posts[ $post_id ], $field, $options['post_id'], $is_search, true );
204 }
205
206 // order posts by search
207 if ( $is_search && empty( $args['orderby'] ) && isset( $args['s'] ) ) {
208 $posts = acf_order_by_search( $posts, $args['s'] );
209 }
210
211 // append to $data
212 foreach ( array_keys( $posts ) as $post_id ) {
213 $data['children'][] = $this->get_post_result( $post_id, $posts[ $post_id ] );
214 }
215
216 // append to $results
217 $results[] = $data;
218 }
219
220 // optgroup or single
221 $post_type = acf_get_array( $args['post_type'] );
222 if ( count( $post_type ) == 1 ) {
223 $results = $results[0]['children'];
224 }
225
226 // vars
227 $response = array(
228 'results' => $results,
229 'limit' => $args['posts_per_page'],
230 );
231
232 // return
233 return $response;
234 }
235
236 /**
237 * This function will return an array containing id, text and maybe description data
238 *
239 * @since ACF 5.4.0
240 *
241 * @param mixed $id The ID of the post result.
242 * @param string $text The text for the response item.
243 * @return array The combined result array.
244 */
245 public function get_post_result( $id, $text ) {
246
247 // vars
248 $result = array(
249 'id' => $id,
250 'text' => $text,
251 );
252
253 // look for parent
254 $search = '| ' . __( 'Parent', 'secure-custom-fields' ) . ':';
255 $pos = strpos( $text, $search );
256
257 if ( $pos !== false ) {
258 $result['description'] = substr( $text, $pos + 2 );
259 $result['text'] = substr( $text, 0, $pos );
260 }
261
262 // return
263 return $result;
264 }
265
266
267 /**
268 * This function post object's filtered output post title
269 *
270 * @since ACF 5.0.0
271 *
272 * @param WP_Post $post The WordPress post.
273 * @param array $field The field being output.
274 * @param integer $post_id The post_id to which this value is saved to.
275 * @param integer $is_search An int-as-boolean value for whether we're performing a search.
276 * @param boolean $unescape Should we return an unescaped post title.
277 * @return string A potentially user filtered post title for the post, which may contain unsafe HTML.
278 */
279 public function get_post_title( $post, $field, $post_id = 0, $is_search = 0, $unescape = false ) {
280
281 // get post_id
282 if ( ! $post_id ) {
283 $post_id = acf_get_form_data( 'post_id' );
284 }
285
286 // vars
287 $title = acf_get_post_title( $post, $is_search );
288
289 // unescape for select2 output which handles the escaping.
290 if ( $unescape ) {
291 $title = html_entity_decode( $title );
292 }
293
294 // filters
295 $title = apply_filters( 'acf/fields/post_object/result', $title, $post, $field, $post_id );
296 $title = apply_filters( 'acf/fields/post_object/result/name=' . $field['_name'], $title, $post, $field, $post_id );
297 $title = apply_filters( 'acf/fields/post_object/result/key=' . $field['key'], $title, $post, $field, $post_id );
298
299 // return untrusted output.
300 return $title;
301 }
302
303
304 /**
305 * Create the HTML interface for the post object field.
306 *
307 * @since ACF 3.6
308 *
309 * @param array $field An array holding all the field's data.
310 * @return void
311 */
312 public function render_field( $field ) {
313 // Change Field into a select
314 $field['type'] = 'select';
315 $field['ui'] = 1;
316 $field['ajax'] = 1;
317 $field['nonce'] = wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] );
318 $field['choices'] = array();
319
320 // load posts
321 $posts = $this->get_posts( $field['value'], $field );
322
323 if ( $posts ) {
324 foreach ( array_keys( $posts ) as $i ) {
325
326 // vars
327 $post = acf_extract_var( $posts, $i );
328
329 // append to choices
330 $field['choices'][ $post->ID ] = $this->get_post_title( $post, $field );
331 }
332 }
333
334 // render
335 acf_render_field( $field );
336 }
337
338
339 /**
340 * Create extra options for post object field. This is rendered when editing.
341 * The value of $field['name'] can be used (like below) to save extra data to the $field.
342 *
343 * @since ACF 3.6
344 *
345 * @param array $field An array holding all the field's data.
346 */
347 public function render_field_settings( $field ) {
348 acf_render_field_setting(
349 $field,
350 array(
351 'label' => __( 'Filter by Post Type', 'secure-custom-fields' ),
352 'instructions' => '',
353 'type' => 'select',
354 'name' => 'post_type',
355 'choices' => acf_get_pretty_post_types(),
356 'multiple' => 1,
357 'ui' => 1,
358 'allow_null' => 1,
359 'placeholder' => __( 'All post types', 'secure-custom-fields' ),
360 )
361 );
362
363 acf_render_field_setting(
364 $field,
365 array(
366 'label' => __( 'Filter by Post Status', 'secure-custom-fields' ),
367 'instructions' => '',
368 'type' => 'select',
369 'name' => 'post_status',
370 'choices' => acf_get_pretty_post_statuses(),
371 'multiple' => 1,
372 'ui' => 1,
373 'allow_null' => 1,
374 'placeholder' => __( 'Any post status', 'secure-custom-fields' ),
375 )
376 );
377
378 acf_render_field_setting(
379 $field,
380 array(
381 'label' => __( 'Filter by Taxonomy', 'secure-custom-fields' ),
382 'instructions' => '',
383 'type' => 'select',
384 'name' => 'taxonomy',
385 'choices' => acf_get_taxonomy_terms(),
386 'multiple' => 1,
387 'ui' => 1,
388 'allow_null' => 1,
389 'placeholder' => __( 'All taxonomies', 'secure-custom-fields' ),
390 )
391 );
392
393 acf_render_field_setting(
394 $field,
395 array(
396 'label' => __( 'Return Format', 'secure-custom-fields' ),
397 'instructions' => '',
398 'type' => 'radio',
399 'name' => 'return_format',
400 'choices' => array(
401 'object' => __( 'Post Object', 'secure-custom-fields' ),
402 'id' => __( 'Post ID', 'secure-custom-fields' ),
403 ),
404 'layout' => 'horizontal',
405 )
406 );
407
408 acf_render_field_setting(
409 $field,
410 array(
411 'label' => __( 'Select Multiple', 'secure-custom-fields' ),
412 'instructions' => 'Allow content editors to select multiple values',
413 'name' => 'multiple',
414 'type' => 'true_false',
415 'ui' => 1,
416 )
417 );
418 }
419
420 /**
421 * Renders the field settings used in the "Validation" tab.
422 *
423 * @since ACF 6.0
424 *
425 * @param array $field The field settings array.
426 * @return void
427 */
428 public function render_field_validation_settings( $field ) {
429 acf_render_field_setting(
430 $field,
431 array(
432 'label' => __( 'Allow Null', 'secure-custom-fields' ),
433 'instructions' => '',
434 'name' => 'allow_null',
435 'type' => 'true_false',
436 'ui' => 1,
437 )
438 );
439 }
440
441 /**
442 * Renders the field settings used in the "Advanced" tab.
443 *
444 * @since ACF 6.2
445 *
446 * @param array $field The field settings array.
447 * @return void
448 */
449 public function render_field_advanced_settings( $field ) {
450 acf_render_bidirectional_field_settings( $field );
451 }
452
453 /**
454 * This filter is applied to the $value after it is loaded from the db
455 *
456 * @since ACF 3.6
457 *
458 * @param mixed $value The value found in the database
459 * @param mixed $post_id The post_id from which the value was loaded
460 * @param array $field The field array holding all the field options
461 * @return mixed $value
462 */
463 public function load_value( $value, $post_id, $field ) {
464
465 // ACF4 null
466 if ( $value === 'null' ) {
467 return false;
468 }
469
470 // return
471 return $value;
472 }
473
474
475 /**
476 * This filter is applied to the $value after it is loaded from the db and before it is returned to the template
477 *
478 * @since ACF 3.6
479 *
480 * @param mixed $value The value found in the database
481 * @param mixed $post_id The post_id from which the value was loaded
482 * @param array $field The field array holding all the field options
483 * @return mixed $value
484 */
485 public function format_value( $value, $post_id, $field ) {
486 $value = acf_get_numeric( $value );
487
488 // bail early if no value
489 if ( empty( $value ) ) {
490 return false;
491 }
492
493 // load posts if needed
494 if ( $field['return_format'] == 'object' ) {
495 $value = $this->get_posts( $value, $field );
496 }
497
498 // convert back from array if necessary
499 if ( ! $field['multiple'] && is_array( $value ) ) {
500 $value = current( $value );
501 }
502
503 // return value
504 return $value;
505 }
506
507
508 /**
509 * Filters the field value before it is saved into the database.
510 *
511 * @since ACF 3.6
512 *
513 * @param mixed $value The value which will be saved in the database.
514 * @param integer $post_id The post_id of which the value will be saved.
515 * @param array $field The field array holding all the field options.
516 * @return mixed $value The modified value.
517 */
518 public function update_value( $value, $post_id, $field ) {
519
520 // Bail early if no value.
521 if ( empty( $value ) ) {
522 acf_update_bidirectional_values( array(), $post_id, $field );
523 return $value;
524 }
525
526 // Format array of values.
527 // - ensure each value is an id.
528 // - Parse each id as string for SQL LIKE queries.
529 if ( acf_is_sequential_array( $value ) ) {
530 $value = array_map( 'acf_idval', $value );
531 $value = array_map( 'strval', $value );
532
533 // Parse single value for id.
534 } else {
535 $value = acf_idval( $value );
536 }
537
538 acf_update_bidirectional_values( acf_get_array( $value ), $post_id, $field );
539
540 return $value;
541 }
542
543
544 /**
545 * This function will return an array of posts for a given field value
546 *
547 * @since ACF 5.0
548 *
549 * @param mixed $value The value of the field.
550 * @param array $field The field array holding all the field options.
551 * @return array $value An array of post objects.
552 */
553 public function get_posts( $value, $field ) {
554
555 // numeric
556 $value = acf_get_numeric( $value );
557
558 // bail early if no value
559 if ( empty( $value ) ) {
560 return false;
561 }
562
563 // get posts
564 $posts = acf_get_posts(
565 array(
566 'post__in' => $value,
567 'post_type' => $field['post_type'],
568 )
569 );
570
571 // return
572 return $posts;
573 }
574
575 /**
576 * Validates post object fields updated via the REST API.
577 *
578 * @since ACF 5.11
579 *
580 * @param boolean $valid The current validity boolean.
581 * @param integer $value The value of the field.
582 * @param array $field The field array.
583 * @return boolean|WP_Error
584 */
585 public function validate_rest_value( $valid, $value, $field ) {
586 if ( is_null( $value ) ) {
587 return $valid;
588 }
589
590 $param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
591 $data = array( 'param' => $param );
592 $value = is_array( $value ) ? $value : array( $value );
593
594 $invalid_posts = array();
595 $post_type_errors = array();
596 $taxonomy_errors = array();
597
598 foreach ( $value as $post_id ) {
599 if ( is_string( $post_id ) ) {
600 continue;
601 }
602
603 $post_type = get_post_type( $post_id );
604 if ( ! $post_type ) {
605 $invalid_posts[] = $post_id;
606 continue;
607 }
608
609 if (
610 is_array( $field['post_type'] ) &&
611 ! empty( $field['post_type'] ) &&
612 ! in_array( $post_type, $field['post_type'] )
613 ) {
614 $post_type_errors[] = $post_id;
615 }
616
617 if ( is_array( $field['taxonomy'] ) && ! empty( $field['taxonomy'] ) ) {
618 $found = false;
619 foreach ( $field['taxonomy'] as $taxonomy_term ) {
620 $decoded = acf_decode_taxonomy_term( $taxonomy_term );
621 if ( $decoded && is_object_in_term( $post_id, $decoded['taxonomy'], $decoded['term'] ) ) {
622 $found = true;
623 break;
624 }
625 }
626
627 if ( ! $found ) {
628 $taxonomy_errors[] = $post_id;
629 }
630 }
631 }
632
633 if ( count( $invalid_posts ) ) {
634 $error = sprintf(
635 /* translators: %s: field name */
636 __( '%1$s must have a valid post ID.', 'secure-custom-fields' ),
637 $param
638 );
639 $data['value'] = $invalid_posts;
640 return new WP_Error( 'rest_invalid_param', $error, $data );
641 }
642
643 if ( count( $post_type_errors ) ) {
644 $error = sprintf(
645 /* translators: 1: field name, 2: post type */
646 _n(
647 '%1$s must be of post type %2$s.',
648 '%1$s must be of one of the following post types: %2$s',
649 count( $field['post_type'] ),
650 'secure-custom-fields'
651 ),
652 $param,
653 count( $field['post_type'] ) > 1 ? implode( ', ', $field['post_type'] ) : $field['post_type'][0]
654 );
655 $data['value'] = $post_type_errors;
656
657 return new WP_Error( 'rest_invalid_param', $error, $data );
658 }
659
660 if ( count( $taxonomy_errors ) ) {
661 $error = sprintf(
662 /* translators: 1: field name, 2: taxonomy term */
663 _n(
664 '%1$s must have term %2$s.',
665 '%1$s must have one of the following terms: %2$s',
666 count( $field['taxonomy'] ),
667 'secure-custom-fields'
668 ),
669 $param,
670 count( $field['taxonomy'] ) > 1 ? implode( ', ', $field['taxonomy'] ) : $field['taxonomy'][0]
671 );
672 $data['value'] = $taxonomy_errors;
673
674 return new WP_Error( 'rest_invalid_param', $error, $data );
675 }
676
677 return $valid;
678 }
679
680 /**
681 * Return the schema array for the REST API.
682 *
683 * @since ACF 5.11
684 *
685 * @param array $field The field array.
686 * @return array
687 */
688 public function get_rest_schema( array $field ) {
689 $schema = array(
690 'type' => array( 'integer', 'array', 'null' ),
691 'required' => ! empty( $field['required'] ),
692 'items' => array(
693 'type' => 'integer',
694 ),
695 );
696
697 if ( empty( $field['allow_null'] ) ) {
698 $schema['minItems'] = 1;
699 }
700
701 if ( empty( $field['multiple'] ) ) {
702 $schema['maxItems'] = 1;
703 }
704
705 return $schema;
706 }
707
708 /**
709 * REST link attributes generator for this field.
710 *
711 * @since ACF 5.11
712 * @see \acf_field::get_rest_links()
713 *
714 * @param mixed $value The raw (unformatted) field value.
715 * @param integer|string $post_id The post ID being queried.
716 * @param array $field The field array.
717 * @return array
718 */
719 public function get_rest_links( $value, $post_id, array $field ) {
720 $links = array();
721
722 if ( empty( $value ) ) {
723 return $links;
724 }
725
726 foreach ( (array) $value as $object_id ) {
727 if ( ! $post_type = get_post_type( $object_id ) ) {
728 continue;
729 }
730
731 if ( ! $post_type_object = get_post_type_object( $post_type ) ) {
732 continue;
733 }
734
735 $rest_base = acf_get_object_type_rest_base( $post_type_object );
736 $links[] = array(
737 'rel' => $post_type_object->name === 'attachment' ? 'acf:attachment' : 'acf:post',
738 'href' => rest_url( sprintf( '/wp/v2/%s/%s', $rest_base, $object_id ) ),
739 'embeddable' => true,
740 );
741 }
742
743 return $links;
744 }
745
746 /**
747 * Apply basic formatting to prepare the value for default REST output.
748 *
749 * @since ACF 5.11
750 *
751 * @param mixed $value The raw (unformatted) field value.
752 * @param integer|string $post_id The post ID being queried.
753 * @param array $field The field array.
754 * @return mixed
755 */
756 public function format_value_for_rest( $value, $post_id, array $field ) {
757 return acf_format_numerics( $value );
758 }
759
760 /**
761 * Formats the field value for JSON-LD output.
762 *
763 * @since 6.8.0
764 *
765 * @param mixed $value The value of the field.
766 * @param integer|string $post_id The ID of the post.
767 * @param array $field The field array.
768 * @return mixed
769 */
770 public function format_value_for_jsonld( $value, $post_id, $field ) {
771 $value = acf_format_numerics( $value );
772
773 if ( ! $value ) {
774 return $value;
775 }
776
777 if ( is_array( $value ) ) {
778 return array_map(
779 function ( $post_id ) {
780 return get_permalink( $post_id );
781 },
782 $value
783 );
784 }
785
786 return get_permalink( $value );
787 }
788
789 /**
790 * Returns an array of JSON-LD Property output types that are supported by this field type.
791 *
792 * @since 6.8
793 *
794 * @return string[]
795 */
796 public function get_jsonld_output_types(): array {
797 return array( 'Thing', 'URL' );
798 }
799 }
800
801
802 // initialize
803 acf_register_field_type( 'acf_field_post_object' );
804 endif; // class_exists check
805