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 / pro / fields / class-acf-field-gallery.php
secure-custom-fields / pro / fields Last commit date
class-acf-field-clone.php 1 year ago class-acf-field-flexible-content.php 1 year ago class-acf-field-gallery.php 1 year ago class-acf-field-repeater.php 1 year ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field-gallery.php
922 lines
1 <?php
2
3 if ( ! class_exists( 'acf_field_gallery' ) ) :
4
5 class acf_field_gallery extends acf_field {
6
7
8 /**
9 * This function will setup the field type data
10 *
11 * @type function
12 * @date 5/03/2014
13 * @since 5.0.0
14 *
15 * @param n/a
16 * @return n/a
17 */
18 function initialize() {
19
20 // vars
21 $this->name = 'gallery';
22 $this->label = __( 'Gallery', 'acf' );
23 $this->category = 'content';
24 $this->description = __( 'An interactive interface for managing a collection of attachments, such as images.', 'acf' );
25 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-gallery.png';
26 $this->doc_url = 'https://www.advancedcustomfields.com/resources/gallery/';
27 $this->tutorial_url = 'https://www.advancedcustomfields.com/resources/how-to-use-the-gallery-field/';
28 $this->pro = true;
29 $this->supports = array( 'bindings' => false );
30 $this->defaults = array(
31 'return_format' => 'array',
32 'preview_size' => 'medium',
33 'insert' => 'append',
34 'library' => 'all',
35 'min' => 0,
36 'max' => 0,
37 'min_width' => 0,
38 'min_height' => 0,
39 'min_size' => 0,
40 'max_width' => 0,
41 'max_height' => 0,
42 'max_size' => 0,
43 'mime_types' => '',
44 );
45
46 // actions
47 add_action( 'wp_ajax_acf/fields/gallery/get_attachment', array( $this, 'ajax_get_attachment' ) );
48 add_action( 'wp_ajax_nopriv_acf/fields/gallery/get_attachment', array( $this, 'ajax_get_attachment' ) );
49
50 add_action( 'wp_ajax_acf/fields/gallery/update_attachment', array( $this, 'ajax_update_attachment' ) );
51 add_action( 'wp_ajax_nopriv_acf/fields/gallery/update_attachment', array( $this, 'ajax_update_attachment' ) );
52
53 add_action( 'wp_ajax_acf/fields/gallery/get_sort_order', array( $this, 'ajax_get_sort_order' ) );
54 add_action( 'wp_ajax_nopriv_acf/fields/gallery/get_sort_order', array( $this, 'ajax_get_sort_order' ) );
55 }
56
57 /**
58 * description
59 *
60 * @type function
61 * @date 16/12/2015
62 * @since 5.3.2
63 *
64 * @param $post_id (int)
65 * @return $post_id (int)
66 */
67 function input_admin_enqueue_scripts() {
68
69 // localize
70 acf_localize_text(
71 array(
72 'Add Image to Gallery' => __( 'Add Image to Gallery', 'acf' ),
73 'Maximum selection reached' => __( 'Maximum selection reached', 'acf' ),
74 )
75 );
76 }
77
78 /**
79 * AJAX handler for retrieving and rendering an attachment.
80 *
81 * @since 5.0.0
82 *
83 * @return void
84 */
85 public function ajax_get_attachment() {
86 // Get args.
87 $args = acf_request_args(
88 array(
89 'id' => 0,
90 'field_key' => '',
91 'nonce' => '',
92 )
93 );
94
95 // Validate request.
96 if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) {
97 die();
98 }
99
100 // Cast args.
101 $args['id'] = (int) $args['id'];
102
103 // Bail early if no id.
104 if ( ! $args['id'] ) {
105 die();
106 }
107
108 // Load field.
109 $field = acf_get_field( $args['field_key'] );
110 if ( ! $field ) {
111 die();
112 }
113
114 // Render.
115 $this->render_attachment( $args['id'], $field );
116 die;
117 }
118
119 /**
120 * AJAX handler for updating an attachment.
121 *
122 * @since 5.0.0
123 *
124 * @return void
125 */
126 public function ajax_update_attachment() {
127 $args = acf_request_args(
128 array(
129 'nonce' => '',
130 'field_key' => '',
131 )
132 );
133
134 if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) {
135 wp_send_json_error();
136 }
137
138 // bail early if no attachments
139 if ( empty( $_POST['attachments'] ) ) {
140 wp_send_json_error();
141 }
142
143 // loop over attachments
144 foreach ( $_POST['attachments'] as $id => $changes ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized by WP core when saved.
145
146 if ( ! current_user_can( 'edit_post', $id ) ) {
147 wp_send_json_error();
148 }
149
150 $post = get_post( $id, ARRAY_A );
151
152 if ( 'attachment' != $post['post_type'] ) {
153 wp_send_json_error();
154 }
155
156 if ( isset( $changes['title'] ) ) {
157 $post['post_title'] = $changes['title'];
158 }
159
160 if ( isset( $changes['caption'] ) ) {
161 $post['post_excerpt'] = $changes['caption'];
162 }
163
164 if ( isset( $changes['description'] ) ) {
165 $post['post_content'] = $changes['description'];
166 }
167
168 if ( isset( $changes['alt'] ) ) {
169 $alt = wp_unslash( $changes['alt'] );
170 if ( $alt != get_post_meta( $id, '_wp_attachment_image_alt', true ) ) {
171 $alt = wp_strip_all_tags( $alt, true );
172 update_post_meta( $id, '_wp_attachment_image_alt', wp_slash( $alt ) );
173 }
174 }
175
176 // save post
177 wp_update_post( $post );
178
179 /** This filter is documented in wp-admin/includes/media.php */
180 // - seems off to run this filter AFTER the update_post function, but there is a reason
181 // - when placed BEFORE, an empty post_title will be populated by WP
182 // - this filter will still allow 3rd party to save extra image data!
183 $post = apply_filters( 'attachment_fields_to_save', $post, $changes );
184
185 // save meta
186 acf_save_post( $id );
187 }
188
189 // return
190 wp_send_json_success();
191 }
192
193 /**
194 * AJAX handler for getting the attachment sort order.
195 *
196 * @since 5.0.0
197 *
198 * @return void
199 */
200 public function ajax_get_sort_order() {
201 $order = 'DESC';
202 $args = acf_parse_args(
203 $_POST, // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Verified below.
204 array(
205 'ids' => 0,
206 'sort' => 'date',
207 'field_key' => '',
208 'nonce' => '',
209 )
210 );
211
212 if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'] ) ) {
213 wp_send_json_error();
214 }
215
216 // Reverse order.
217 if ( $args['sort'] === 'reverse' ) {
218 $ids = array_reverse( $args['ids'] );
219 wp_send_json_success( $ids );
220 }
221
222 // Ascending order.
223 if ( $args['sort'] === 'title' ) {
224 $order = 'ASC';
225 }
226
227 // Find attachments (DISTINCT POSTS).
228 $ids = get_posts(
229 array(
230 'post_type' => 'attachment',
231 'numberposts' => -1,
232 'post_status' => 'any',
233 'post__in' => $args['ids'],
234 'order' => $order,
235 'orderby' => $args['sort'],
236 'fields' => 'ids',
237 )
238 );
239
240 if ( ! empty( $ids ) ) {
241 wp_send_json_success( $ids );
242 }
243
244 wp_send_json_error();
245 }
246
247 /**
248 * Renders the sidebar HTML shown when selecting an attachmemnt.
249 *
250 * @date 13/12/2013
251 * @since 5.0.0
252 *
253 * @param integer $id The attachment ID.
254 * @param array $field The field array.
255 * @return void
256 */
257 function render_attachment( $id, $field ) {
258 // Load attachmenet data.
259 $attachment = wp_prepare_attachment_for_js( $id );
260 $compat = get_compat_media_markup( $id );
261
262 // Get attachment thumbnail (video).
263 if ( isset( $attachment['thumb']['src'] ) ) {
264 $thumb = $attachment['thumb']['src'];
265
266 // Look for thumbnail size (image).
267 } elseif ( isset( $attachment['sizes']['thumbnail']['url'] ) ) {
268 $thumb = $attachment['sizes']['thumbnail']['url'];
269
270 // Use url for svg.
271 } elseif ( $attachment['type'] === 'image' ) {
272 $thumb = $attachment['url'];
273
274 // Default to icon.
275 } else {
276 $thumb = wp_mime_type_icon( $id );
277 }
278
279 // Get attachment dimensions / time / size.
280 $dimensions = '';
281 if ( $attachment['type'] === 'audio' ) {
282 $dimensions = __( 'Length', 'acf' ) . ': ' . $attachment['fileLength'];
283 } elseif ( ! empty( $attachment['width'] ) ) {
284 $dimensions = $attachment['width'] . ' x ' . $attachment['height'];
285 }
286 if ( ! empty( $attachment['filesizeHumanReadable'] ) ) {
287 $dimensions .= ' (' . $attachment['filesizeHumanReadable'] . ')';
288 }
289
290 ?>
291 <div class="acf-gallery-side-info">
292 <img src="<?php echo esc_url( $thumb ); ?>" alt="<?php echo esc_attr( $attachment['alt'] ); ?>" />
293 <p class="filename"><strong><?php echo esc_html( $attachment['filename'] ); ?></strong></p>
294 <p class="uploaded"><?php echo esc_html( $attachment['dateFormatted'] ); ?></p>
295 <p class="dimensions"><?php echo esc_html( $dimensions ); ?></p>
296 <p class="actions">
297 <a href="#" class="acf-gallery-edit" data-id="<?php echo esc_attr( $id ); ?>"><?php esc_html_e( 'Edit', 'acf' ); ?></a>
298 <a href="#" class="acf-gallery-remove" data-id="<?php echo esc_attr( $id ); ?>"><?php esc_html_e( 'Remove', 'acf' ); ?></a>
299 </p>
300 </div>
301 <table class="form-table">
302 <tbody>
303 <?php
304
305 // Render fields.
306 $prefix = 'attachments[' . $id . ']';
307
308 acf_render_field_wrap(
309 array(
310 // 'key' => "{$field['key']}-title",
311 'name' => 'title',
312 'prefix' => $prefix,
313 'type' => 'text',
314 'label' => __( 'Title', 'acf' ),
315 'value' => $attachment['title'],
316 ),
317 'tr'
318 );
319
320 acf_render_field_wrap(
321 array(
322 // 'key' => "{$field['key']}-caption",
323 'name' => 'caption',
324 'prefix' => $prefix,
325 'type' => 'textarea',
326 'label' => __( 'Caption', 'acf' ),
327 'value' => $attachment['caption'],
328 ),
329 'tr'
330 );
331
332 acf_render_field_wrap(
333 array(
334 // 'key' => "{$field['key']}-alt",
335 'name' => 'alt',
336 'prefix' => $prefix,
337 'type' => 'text',
338 'label' => __( 'Alt Text', 'acf' ),
339 'value' => $attachment['alt'],
340 ),
341 'tr'
342 );
343
344 acf_render_field_wrap(
345 array(
346 // 'key' => "{$field['key']}-description",
347 'name' => 'description',
348 'prefix' => $prefix,
349 'type' => 'textarea',
350 'label' => __( 'Description', 'acf' ),
351 'value' => $attachment['description'],
352 ),
353 'tr'
354 );
355
356 ?>
357 </tbody>
358 </table>
359 <?php
360
361 // Display compat fields.
362 echo $compat['item']; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- escaped inside get_compat_media_markup().
363 }
364
365 /**
366 * Create the HTML interface for your field
367 *
368 * @param $field - an array holding all the field's data
369 *
370 * @type action
371 * @since 3.6
372 * @date 23/01/13
373 */
374 function render_field( $field ) {
375
376 // Enqueue uploader assets.
377 acf_enqueue_uploader();
378
379 // Control attributes.
380 $attrs = array(
381 'id' => $field['id'],
382 'class' => "acf-gallery {$field['class']}",
383 'data-library' => $field['library'],
384 'data-preview_size' => $field['preview_size'],
385 'data-min' => $field['min'],
386 'data-max' => $field['max'],
387 'data-mime_types' => $field['mime_types'],
388 'data-insert' => $field['insert'],
389 'data-columns' => 4,
390 'data-nonce' => wp_create_nonce( $field['key'] ),
391 );
392
393 // Set gallery height with deafult of 400px and minimum of 200px.
394 $height = acf_get_user_setting( 'gallery_height', 400 );
395 $height = max( $height, 200 );
396 $attrs['style'] = "height:{$height}px";
397
398 // Load attachments.
399 $attachments = array();
400 if ( $field['value'] ) {
401
402 // Clean value into an array of IDs.
403 $attachment_ids = array_map( 'intval', acf_array( $field['value'] ) );
404
405 // Find posts in database (ensures all results are real).
406 $posts = acf_get_posts(
407 array(
408 'post_type' => 'attachment',
409 'post__in' => $attachment_ids,
410 'update_post_meta_cache' => true,
411 'update_post_term_cache' => false,
412 )
413 );
414
415 // Load attatchment data for each post.
416 $attachments = array_map( 'acf_get_attachment', $posts );
417 }
418
419 ?>
420 <div <?php echo acf_esc_attrs( $attrs ); ?>>
421 <input type="hidden" name="<?php echo esc_attr( $field['name'] ); ?>" value="" />
422 <div class="acf-gallery-main">
423 <div class="acf-gallery-attachments">
424 <?php if ( $attachments ) : ?>
425 <?php
426 foreach ( $attachments as $i => $attachment ) :
427
428 // Vars
429 $a_id = $attachment['ID'];
430 $a_title = $attachment['title'];
431 $a_type = $attachment['type'];
432 $a_filename = $attachment['filename'];
433 $a_class = "acf-gallery-attachment -{$a_type}";
434
435 // Get thumbnail.
436 $a_thumbnail = acf_get_post_thumbnail( $a_id, $field['preview_size'] );
437 $a_class .= ( $a_thumbnail['type'] === 'icon' ) ? ' -icon' : '';
438
439 ?>
440 <div class="<?php echo esc_attr( $a_class ); ?>" data-id="<?php echo esc_attr( $a_id ); ?>">
441 <input type="hidden" name="<?php echo esc_attr( $field['name'] ); ?>[]" value="<?php echo esc_attr( $a_id ); ?>" />
442 <div class="margin">
443 <div class="thumbnail">
444 <img src="<?php echo esc_url( $a_thumbnail['url'] ); ?>" alt="" />
445 </div>
446 <?php if ( $a_type !== 'image' ) : ?>
447 <div class="filename"><?php echo acf_esc_html( acf_get_truncated( $a_filename, 30 ) ); ?></div>
448 <?php endif; ?>
449 </div>
450 <div class="actions">
451 <a class="acf-icon -cancel dark acf-gallery-remove" href="#" data-id="<?php echo esc_attr( $a_id ); ?>" title="<?php esc_html_e( 'Remove', 'acf' ); ?>"></a>
452 </div>
453 </div>
454 <?php endforeach; ?>
455 <?php endif; ?>
456 </div>
457 <div class="acf-gallery-toolbar">
458 <ul class="acf-hl">
459 <li>
460 <a href="#" class="acf-button button button-primary acf-gallery-add"><?php esc_html_e( 'Add to gallery', 'acf' ); ?></a>
461 </li>
462 <li class="acf-fr">
463 <select class="acf-gallery-sort">
464 <option value=""><?php esc_html_e( 'Bulk actions', 'acf' ); ?></option>
465 <option value="date"><?php esc_html_e( 'Sort by date uploaded', 'acf' ); ?></option>
466 <option value="modified"><?php esc_html_e( 'Sort by date modified', 'acf' ); ?></option>
467 <option value="title"><?php esc_html_e( 'Sort by title', 'acf' ); ?></option>
468 <option value="reverse"><?php esc_html_e( 'Reverse current order', 'acf' ); ?></option>
469 </select>
470 </li>
471 </ul>
472 </div>
473 </div>
474 <div class="acf-gallery-side">
475 <div class="acf-gallery-side-inner">
476 <div class="acf-gallery-side-data"></div>
477 <div class="acf-gallery-toolbar">
478 <ul class="acf-hl">
479 <li>
480 <a href="#" class="acf-button button acf-gallery-close"><?php esc_html_e( 'Close', 'acf' ); ?></a>
481 </li>
482 <li class="acf-fr">
483 <a class="acf-button button button-primary acf-gallery-update" href="#"><?php esc_html_e( 'Update', 'acf' ); ?></a>
484 </li>
485 </ul>
486 </div>
487 </div>
488 </div>
489 </div>
490 <?php
491 }
492
493
494 /**
495 * Create extra options for your field. This is rendered when editing a field.
496 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
497 *
498 * @type action
499 * @since 3.6
500 * @date 23/01/13
501 *
502 * @param $field - an array holding all the field's data
503 */
504 function render_field_settings( $field ) {
505 acf_render_field_setting(
506 $field,
507 array(
508 'label' => __( 'Return Format', 'acf' ),
509 'instructions' => '',
510 'type' => 'radio',
511 'name' => 'return_format',
512 'layout' => 'horizontal',
513 'choices' => array(
514 'array' => __( 'Image Array', 'acf' ),
515 'url' => __( 'Image URL', 'acf' ),
516 'id' => __( 'Image ID', 'acf' ),
517 ),
518 )
519 );
520
521 acf_render_field_setting(
522 $field,
523 array(
524 'label' => __( 'Library', 'acf' ),
525 'instructions' => __( 'Limit the media library choice', 'acf' ),
526 'type' => 'radio',
527 'name' => 'library',
528 'layout' => 'horizontal',
529 'choices' => array(
530 'all' => __( 'All', 'acf' ),
531 'uploadedTo' => __( 'Uploaded to post', 'acf' ),
532 ),
533 )
534 );
535 }
536
537 /**
538 * Renders the field settings used in the "Validation" tab.
539 *
540 * @since 6.0
541 *
542 * @param array $field The field settings array.
543 * @return void
544 */
545 function render_field_validation_settings( $field ) {
546 // Clear numeric settings.
547 $clear = array(
548 'min',
549 'max',
550 'min_width',
551 'min_height',
552 'min_size',
553 'max_width',
554 'max_height',
555 'max_size',
556 );
557
558 foreach ( $clear as $k ) {
559 if ( empty( $field[ $k ] ) ) {
560 $field[ $k ] = '';
561 }
562 }
563
564 acf_render_field_setting(
565 $field,
566 array(
567 'label' => __( 'Minimum Selection', 'acf' ),
568 'instructions' => '',
569 'type' => 'number',
570 'name' => 'min',
571 )
572 );
573
574 acf_render_field_setting(
575 $field,
576 array(
577 'label' => __( 'Maximum Selection', 'acf' ),
578 'instructions' => '',
579 'type' => 'number',
580 'name' => 'max',
581 )
582 );
583
584 acf_render_field_setting(
585 $field,
586 array(
587 'label' => __( 'Minimum', 'acf' ),
588 'hint' => __( 'Restrict which images can be uploaded', 'acf' ),
589 'type' => 'text',
590 'name' => 'min_width',
591 'prepend' => __( 'Width', 'acf' ),
592 'append' => 'px',
593 )
594 );
595
596 acf_render_field_setting(
597 $field,
598 array(
599 'label' => '',
600 'type' => 'text',
601 'name' => 'min_height',
602 'prepend' => __( 'Height', 'acf' ),
603 'append' => 'px',
604 '_append' => 'min_width',
605 )
606 );
607
608 acf_render_field_setting(
609 $field,
610 array(
611 'label' => '',
612 'type' => 'text',
613 'name' => 'min_size',
614 'prepend' => __( 'File size', 'acf' ),
615 'append' => 'MB',
616 '_append' => 'min_width',
617 )
618 );
619
620 acf_render_field_setting(
621 $field,
622 array(
623 'label' => __( 'Maximum', 'acf' ),
624 'hint' => __( 'Restrict which images can be uploaded', 'acf' ),
625 'type' => 'text',
626 'name' => 'max_width',
627 'prepend' => __( 'Width', 'acf' ),
628 'append' => 'px',
629 )
630 );
631
632 acf_render_field_setting(
633 $field,
634 array(
635 'label' => '',
636 'type' => 'text',
637 'name' => 'max_height',
638 'prepend' => __( 'Height', 'acf' ),
639 'append' => 'px',
640 '_append' => 'max_width',
641 )
642 );
643
644 acf_render_field_setting(
645 $field,
646 array(
647 'label' => '',
648 'type' => 'text',
649 'name' => 'max_size',
650 'prepend' => __( 'File size', 'acf' ),
651 'append' => 'MB',
652 '_append' => 'max_width',
653 )
654 );
655
656 acf_render_field_setting(
657 $field,
658 array(
659 'label' => __( 'Allowed File Types', 'acf' ),
660 'hint' => __( 'Comma separated list. Leave blank for all types', 'acf' ),
661 'type' => 'text',
662 'name' => 'mime_types',
663 )
664 );
665 }
666
667 /**
668 * Renders the field settings used in the "Presentation" tab.
669 *
670 * @since 6.0
671 *
672 * @param array $field The field settings array.
673 * @return void
674 */
675 function render_field_presentation_settings( $field ) {
676 acf_render_field_setting(
677 $field,
678 array(
679 'label' => __( 'Insert', 'acf' ),
680 'instructions' => __( 'Specify where new attachments are added', 'acf' ),
681 'type' => 'select',
682 'name' => 'insert',
683 'choices' => array(
684 'append' => __( 'Append to the end', 'acf' ),
685 'prepend' => __( 'Prepend to the beginning', 'acf' ),
686 ),
687 )
688 );
689
690 acf_render_field_setting(
691 $field,
692 array(
693 'label' => __( 'Preview Size', 'acf' ),
694 'instructions' => '',
695 'type' => 'select',
696 'name' => 'preview_size',
697 'choices' => acf_get_image_sizes(),
698 )
699 );
700 }
701
702 /**
703 * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
704 *
705 * @type filter
706 * @since 3.6
707 * @date 23/01/13
708 *
709 * @param $value (mixed) the value which was loaded from the database
710 * @param $post_id (mixed) the post_id from which the value was loaded
711 * @param $field (array) the field array holding all the field options
712 *
713 * @return $value (mixed) the modified value
714 */
715 function format_value( $value, $post_id, $field ) {
716
717 // Bail early if no value.
718 if ( ! $value ) {
719 return false;
720 }
721
722 // Clean value into an array of IDs.
723 $attachment_ids = array_map( 'intval', acf_array( $value ) );
724
725 // Find posts in database (ensures all results are real).
726 $posts = acf_get_posts(
727 array(
728 'post_type' => 'attachment',
729 'post__in' => $attachment_ids,
730 'update_post_meta_cache' => true,
731 'update_post_term_cache' => false,
732 )
733 );
734
735 // Bail early if no posts found.
736 if ( ! $posts ) {
737 return false;
738 }
739
740 // Format values using field settings.
741 $value = array();
742 foreach ( $posts as $post ) {
743
744 // Return object.
745 if ( $field['return_format'] == 'object' ) {
746 $item = $post;
747
748 // Return array.
749 } elseif ( $field['return_format'] == 'array' ) {
750 $item = acf_get_attachment( $post );
751
752 // Return URL.
753 } elseif ( $field['return_format'] == 'url' ) {
754 $item = wp_get_attachment_url( $post->ID );
755
756 // Return ID.
757 } else {
758 $item = $post->ID;
759 }
760
761 // Append item.
762 $value[] = $item;
763 }
764
765 // Return.
766 return $value;
767 }
768
769
770 /**
771 * description
772 *
773 * @type function
774 * @date 11/02/2014
775 * @since 5.0.0
776 *
777 * @param $post_id (int)
778 * @return $post_id (int)
779 */
780 function validate_value( $valid, $value, $field, $input ) {
781
782 if ( empty( $value ) || ! is_array( $value ) ) {
783 $value = array();
784 }
785
786 if ( count( $value ) < $field['min'] ) {
787 $valid = _n( '%1$s requires at least %2$s selection', '%1$s requires at least %2$s selections', $field['min'], 'acf' );
788 $valid = sprintf( $valid, $field['label'], $field['min'] );
789 }
790
791 return $valid;
792 }
793
794
795 /**
796 * This filter is appied to the $value before it is updated in the db
797 *
798 * @type filter
799 * @since 3.6
800 * @date 23/01/13
801 *
802 * @param $value - the value which will be saved in the database
803 * @param $post_id - the post_id of which the value will be saved
804 * @param $field - the field array holding all the field options
805 *
806 * @return $value - the modified value
807 */
808 function update_value( $value, $post_id, $field ) {
809
810 // Bail early if no value.
811 if ( empty( $value ) ) {
812 return $value;
813 }
814
815 // Convert to array.
816 $value = acf_array( $value );
817
818 // Format array of values.
819 // - ensure each value is an id.
820 // - Parse each id as string for SQL LIKE queries.
821 $value = array_map( 'acf_idval', $value );
822 $value = array_map( 'strval', $value );
823
824 // Return value.
825 return $value;
826 }
827
828 /**
829 * Validates file fields updated via the REST API.
830 *
831 * @param boolean $valid The current validity booleean
832 * @param integer $value The value of the field
833 * @param array $field The field array
834 * @return boolean|WP
835 */
836 public function validate_rest_value( $valid, $value, $field ) {
837 if ( ! $valid || ! is_array( $value ) ) {
838 return $valid;
839 }
840
841 foreach ( $value as $attachment_id ) {
842 $file_valid = acf_get_field_type( 'file' )->validate_rest_value( $valid, $attachment_id, $field );
843
844 if ( is_wp_error( $file_valid ) ) {
845 return $file_valid;
846 }
847 }
848
849 return $valid;
850 }
851
852 /**
853 * Return the schema array for the REST API.
854 *
855 * @param array $field
856 * @return array
857 */
858 public function get_rest_schema( array $field ) {
859 $schema = array(
860 'type' => array( 'array', 'null' ),
861 'required' => ! empty( $field['required'] ),
862 'items' => array(
863 'type' => 'number',
864 ),
865 );
866
867 if ( ! empty( $field['min'] ) ) {
868 $schema['minItems'] = (int) $field['min'];
869 }
870
871 if ( ! empty( $field['max'] ) ) {
872 $schema['maxItems'] = (int) $field['max'];
873 }
874
875 return $schema;
876 }
877
878 /**
879 * @see \acf_field::get_rest_links()
880 * @param mixed $value The raw (unformatted) field value.
881 * @param integer|string $post_id
882 * @param array $field
883 * @return array
884 */
885 public function get_rest_links( $value, $post_id, array $field ) {
886 $links = array();
887
888 if ( empty( $value ) ) {
889 return $links;
890 }
891
892 foreach ( (array) $value as $object_id ) {
893 $links[] = array(
894 'rel' => 'acf:attachment',
895 'href' => rest_url( '/wp/v2/media/' . $object_id ),
896 'embeddable' => true,
897 );
898 }
899
900 return $links;
901 }
902
903 /**
904 * Apply basic formatting to prepare the value for default REST output.
905 *
906 * @param mixed $value
907 * @param string|integer $post_id
908 * @param array $field
909 * @return mixed
910 */
911 public function format_value_for_rest( $value, $post_id, array $field ) {
912 return acf_format_numerics( $value );
913 }
914 }
915
916
917 // initialize
918 acf_register_field_type( 'acf_field_gallery' );
919 endif; // class_exists check
920
921 ?>
922