PluginProbe ʕ •ᴥ•ʔ
Advanced Custom Fields (ACF®) / 6.8.8
Advanced Custom Fields (ACF®) v6.8.8
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 6.0.1 6.0.2 6.0.3 6.0.4 6.0.5 6.0.6 6.0.7 6.1.0 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.1.6 6.1.7 6.1.8 6.2.0 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.2.6 6.2.6.1 6.2.7 6.2.8 6.2.9 6.3.0 6.3.1 6.3.10.2 6.3.11 6.3.12 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.6.1 6.4.0 6.4.0.1 6.4.1 6.4.2 6.4.3 6.5.0 6.5.1 6.6.0 6.6.1 6.6.2 6.7.0 6.7.1 6.7.2 6.8.0 trunk 1.0.0 1.0.2 1.0.3 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.1.1 2.1.3 2.1.4 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.0.6 3.0.7 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.8 4.2.0 4.2.1 4.2.2 4.3.0 4.3.1 4.3.2 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.3.8 4.3.9 4.4.0 4.4.1 4.4.10 4.4.11 4.4.12 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 5.10 5.10.1 5.10.2 5.11 5.11.1 5.11.2 5.11.3 5.11.4 5.12 5.12.1 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.6.10 5.6.2 5.6.3 5.6.4 5.6.5 5.6.6 5.6.7 5.6.8 5.6.9 5.7.0 5.7.1 5.7.10 5.7.12 5.7.13 5.7.2 5.7.3 5.7.4 5.7.5 5.7.6 5.7.7 5.7.8 5.7.9 5.8.0 5.8.1 5.8.10 5.8.11 5.8.12 5.8.13 5.8.14 5.8.2 5.8.3 5.8.4
advanced-custom-fields / includes / fields / class-acf-field-file.php
advanced-custom-fields / includes / fields Last commit date
class-acf-field-accordion.php 5 months ago class-acf-field-button-group.php 5 months ago class-acf-field-checkbox.php 2 months ago class-acf-field-color_picker.php 5 months ago class-acf-field-date_picker.php 5 months ago class-acf-field-date_time_picker.php 5 months ago class-acf-field-email.php 5 months ago class-acf-field-file.php 5 months ago class-acf-field-google-map.php 5 months ago class-acf-field-group.php 5 months ago class-acf-field-icon_picker.php 6 months ago class-acf-field-image.php 1 month ago class-acf-field-link.php 5 months ago class-acf-field-message.php 6 months ago class-acf-field-number.php 5 months ago class-acf-field-oembed.php 2 months ago class-acf-field-output.php 6 months ago class-acf-field-page_link.php 1 month ago class-acf-field-password.php 5 months ago class-acf-field-post_object.php 1 month ago class-acf-field-radio.php 2 months ago class-acf-field-range.php 5 months ago class-acf-field-relationship.php 1 month ago class-acf-field-select.php 2 months ago class-acf-field-separator.php 6 months ago class-acf-field-tab.php 6 months ago class-acf-field-taxonomy.php 2 months ago class-acf-field-text.php 5 months ago class-acf-field-textarea.php 5 months ago class-acf-field-time_picker.php 5 months ago class-acf-field-true_false.php 5 months ago class-acf-field-url.php 5 months ago class-acf-field-user.php 2 months ago class-acf-field-wysiwyg.php 5 months ago class-acf-field.php 5 months ago index.php 2 years ago
class-acf-field-file.php
617 lines
1 <?php
2 /**
3 * @package ACF
4 * @author WP Engine
5 *
6 * © 2026 Advanced Custom Fields (ACF®). All rights reserved.
7 * "ACF" is a trademark of WP Engine.
8 * Licensed under the GNU General Public License v2 or later.
9 * https://www.gnu.org/licenses/gpl-2.0.html
10 */
11
12 if ( ! class_exists( 'acf_field_file' ) ) :
13
14 class acf_field_file extends acf_field {
15
16
17 /**
18 * This function will setup the field type data
19 *
20 * @type function
21 * @date 5/03/2014
22 * @since 5.0.0
23 *
24 * @param n/a
25 * @return n/a
26 */
27 function initialize() {
28
29 // vars
30 $this->name = 'file';
31 $this->label = __( 'File', 'acf' );
32 $this->category = 'content';
33 $this->description = __( 'Uses the native WordPress media picker to upload, or choose files.', 'acf' );
34 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-file.png';
35 $this->doc_url = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/file/', 'docs', 'field-type-selection' );
36 $this->defaults = array(
37 'return_format' => 'array',
38 'library' => 'all',
39 'min_size' => 0,
40 'max_size' => 0,
41 'mime_types' => '',
42 );
43
44 // filters
45 add_filter( 'get_media_item_args', array( $this, 'get_media_item_args' ) );
46 }
47
48
49 /**
50 * description
51 *
52 * @type function
53 * @date 16/12/2015
54 * @since 5.3.2
55 *
56 * @param $post_id (int)
57 * @return $post_id (int)
58 */
59 function input_admin_enqueue_scripts() {
60
61 // localize
62 acf_localize_text(
63 array(
64 'Select File' => __( 'Select File', 'acf' ),
65 'Edit File' => __( 'Edit File', 'acf' ),
66 'Update File' => __( 'Update File', 'acf' ),
67 )
68 );
69 }
70
71
72 /**
73 * Create the HTML interface for your field
74 *
75 * @param $field - an array holding all the field's data
76 *
77 * @type action
78 * @since 3.6
79 * @date 23/01/13
80 */
81 function render_field( $field ) {
82
83 // vars
84 $uploader = acf_get_setting( 'uploader' );
85
86 // allow custom uploader
87 $uploader = acf_maybe_get( $field, 'uploader', $uploader );
88
89 // enqueue
90 if ( $uploader == 'wp' ) {
91 acf_enqueue_uploader();
92 }
93
94 // vars
95 $o = array(
96 'icon' => '',
97 'title' => '',
98 'url' => '',
99 'filename' => '',
100 'filesize' => '',
101 );
102
103 $div = array(
104 'class' => 'acf-file-uploader',
105 'data-library' => $field['library'],
106 'data-mime_types' => $field['mime_types'],
107 'data-uploader' => $uploader,
108 );
109
110 // has value?
111 if ( $field['value'] ) {
112 $attachment = acf_get_attachment( $field['value'] );
113 if ( $attachment ) {
114
115 // has value
116 $div['class'] .= ' has-value';
117
118 // update
119 $o['icon'] = $attachment['icon'];
120 $o['title'] = $attachment['title'];
121 $o['url'] = $attachment['url'];
122 $o['filename'] = $attachment['filename'];
123 if ( $attachment['filesize'] ) {
124 $o['filesize'] = size_format( $attachment['filesize'] );
125 }
126 }
127 }
128
129 ?>
130 <div <?php echo acf_esc_attrs( $div ); ?>>
131 <?php
132 acf_hidden_input(
133 array(
134 'name' => $field['name'],
135 'value' => $field['value'],
136 'data-name' => 'id',
137 )
138 );
139 ?>
140 <div class="show-if-value file-wrap" tabindex="0" role="button" aria-label="<?php esc_attr_e( 'Selected file. Press tab to access file options.', 'acf' ); ?>">
141 <div class="file-icon">
142 <img data-name="icon" src="<?php echo esc_url( $o['icon'] ); ?>" alt=""/>
143 </div>
144 <div class="file-info">
145 <p>
146 <strong data-name="title"><?php echo esc_html( $o['title'] ); ?></strong>
147 </p>
148 <p>
149 <strong><?php esc_html_e( 'File name', 'acf' ); ?>:</strong>
150 <a data-name="filename" href="<?php echo esc_url( $o['url'] ); ?>" target="_blank"><?php echo esc_html( $o['filename'] ); ?></a>
151 </p>
152 <p>
153 <strong><?php esc_html_e( 'File size', 'acf' ); ?>:</strong>
154 <span data-name="filesize"><?php echo esc_html( $o['filesize'] ); ?></span>
155 </p>
156 </div>
157 <div class="acf-actions -hover">
158 <?php if ( $uploader != 'basic' ) : ?>
159 <a class="acf-icon -pencil dark" data-name="edit" href="#" title="<?php esc_attr_e( 'Edit', 'acf' ); ?>" aria-label="<?php esc_attr_e( 'Edit file', 'acf' ); ?>"></a>
160 <?php endif; ?>
161 <a class="acf-icon -cancel dark" data-name="remove" href="#" title="<?php esc_attr_e( 'Remove', 'acf' ); ?>" aria-label="<?php esc_attr_e( 'Remove file', 'acf' ); ?>"></a>
162 </div>
163 </div>
164 <div class="hide-if-value">
165 <?php if ( $uploader == 'basic' ) : ?>
166
167 <?php if ( $field['value'] && ! is_numeric( $field['value'] ) ) : ?>
168 <div class="acf-error-message"><p><?php echo acf_esc_html( $field['value'] ); ?></p></div>
169 <?php endif; ?>
170
171 <label class="acf-basic-uploader">
172 <?php
173 $args = array(
174 'name' => $field['name'],
175 'id' => $field['id'],
176 'key' => $field['key'],
177 );
178
179 if ( ! empty( $field['mime_types'] ) ) {
180 $args['accept'] = $field['mime_types'];
181 }
182
183 acf_file_input( $args );
184 ?>
185 </label>
186
187 <?php else : ?>
188
189 <p><?php esc_html_e( 'No file selected', 'acf' ); ?> <a data-name="add" class="acf-button button" href="#"><?php esc_html_e( 'Add File', 'acf' ); ?></a></p>
190
191 <?php endif; ?>
192
193 </div>
194 </div>
195 <?php
196 }
197
198 /**
199 * Create extra options for your field. This is rendered when editing a field.
200 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
201 *
202 * @type action
203 * @since 3.6
204 * @date 23/01/13
205 *
206 * @param $field - an array holding all the field's data
207 */
208 function render_field_settings( $field ) {
209 acf_render_field_setting(
210 $field,
211 array(
212 'label' => __( 'Return Value', 'acf' ),
213 'instructions' => __( 'Specify the returned value on front end', 'acf' ),
214 'type' => 'radio',
215 'name' => 'return_format',
216 'layout' => 'horizontal',
217 'choices' => array(
218 'array' => __( 'File Array', 'acf' ),
219 'url' => __( 'File URL', 'acf' ),
220 'id' => __( 'File ID', 'acf' ),
221 ),
222 )
223 );
224
225 acf_render_field_setting(
226 $field,
227 array(
228 'label' => __( 'Library', 'acf' ),
229 'instructions' => __( 'Limit the media library choice', 'acf' ),
230 'type' => 'radio',
231 'name' => 'library',
232 'layout' => 'horizontal',
233 'choices' => array(
234 'all' => __( 'All', 'acf' ),
235 'uploadedTo' => __( 'Uploaded to post', 'acf' ),
236 ),
237 )
238 );
239 }
240
241 /**
242 * Renders the field settings used in the "Validation" tab.
243 *
244 * @since 6.0
245 *
246 * @param array $field The field settings array.
247 * @return void
248 */
249 function render_field_validation_settings( $field ) {
250 // Clear numeric settings.
251 $clear = array(
252 'min_size',
253 'max_size',
254 );
255
256 foreach ( $clear as $k ) {
257 if ( empty( $field[ $k ] ) ) {
258 $field[ $k ] = '';
259 }
260 }
261
262 acf_render_field_setting(
263 $field,
264 array(
265 'label' => __( 'Minimum', 'acf' ),
266 'instructions' => __( 'Restrict which files can be uploaded', 'acf' ),
267 'type' => 'text',
268 'name' => 'min_size',
269 'prepend' => __( 'File size', 'acf' ),
270 'append' => 'MB',
271 )
272 );
273
274 acf_render_field_setting(
275 $field,
276 array(
277 'label' => __( 'Maximum', 'acf' ),
278 'instructions' => __( 'Restrict which files can be uploaded', 'acf' ),
279 'type' => 'text',
280 'name' => 'max_size',
281 'prepend' => __( 'File size', 'acf' ),
282 'append' => 'MB',
283 )
284 );
285
286 acf_render_field_setting(
287 $field,
288 array(
289 'label' => __( 'Allowed File Types', 'acf' ),
290 'hint' => __( 'Comma separated list. Leave blank for all types', 'acf' ),
291 'type' => 'text',
292 'name' => 'mime_types',
293 )
294 );
295 }
296
297 /**
298 * This filter is appied to the $value after it is loaded from the db and before it is returned to the template
299 *
300 * @type filter
301 * @since 3.6
302 * @date 23/01/13
303 *
304 * @param $value (mixed) the value which was loaded from the database
305 * @param $post_id (mixed) the post_id from which the value was loaded
306 * @param $field (array) the field array holding all the field options
307 *
308 * @return $value (mixed) the modified value
309 */
310 function format_value( $value, $post_id, $field ) {
311
312 // bail early if no value
313 if ( empty( $value ) ) {
314 return false;
315 }
316
317 // bail early if not numeric (error message)
318 if ( ! is_numeric( $value ) ) {
319 return false;
320 }
321
322 // convert to int
323 $value = intval( $value );
324
325 // format
326 if ( $field['return_format'] == 'url' ) {
327 return wp_get_attachment_url( $value );
328 } elseif ( $field['return_format'] == 'array' ) {
329 return acf_get_attachment( $value );
330 }
331
332 // return
333 return $value;
334 }
335
336
337 /**
338 * description
339 *
340 * @type function
341 * @date 27/01/13
342 * @since 3.6.0
343 *
344 * @param $vars (array)
345 * @return $vars
346 */
347 function get_media_item_args( $vars ) {
348
349 $vars['send'] = true;
350 return( $vars );
351 }
352
353
354 /**
355 * This filter is appied to the $value before it is updated in the db
356 *
357 * @type filter
358 * @since 3.6
359 * @date 23/01/13
360 *
361 * @param $value - the value which will be saved in the database
362 * @param $post_id - the post_id of which the value will be saved
363 * @param $field - the field array holding all the field options
364 *
365 * @return $value - the modified value
366 */
367 function update_value( $value, $post_id, $field ) {
368
369 // Bail early if no value.
370 if ( empty( $value ) ) {
371 return $value;
372 }
373
374 // Parse value for id.
375 $attachment_id = acf_idval( $value );
376
377 // Connect attacment to post.
378 acf_connect_attachment_to_post( $attachment_id, $post_id );
379
380 // Return id.
381 return $attachment_id;
382 }
383
384 /**
385 * validate_value
386 *
387 * This function will validate a basic file input
388 *
389 * @type function
390 * @date 11/02/2014
391 * @since 5.0.0
392 *
393 * @param $post_id (int)
394 * @return $post_id (int)
395 */
396 function validate_value( $valid, $value, $field, $input ) {
397
398 // bail early if empty
399 if ( empty( $value ) ) {
400 return $valid;
401 }
402
403 // bail early if is numeric
404 if ( is_numeric( $value ) ) {
405 return $valid;
406 }
407
408 // bail early if not basic string
409 if ( ! is_string( $value ) ) {
410 return $valid;
411 }
412
413 // decode value
414 $file = null;
415 parse_str( $value, $file );
416
417 // bail early if no attachment
418 if ( empty( $file ) ) {
419 return $valid;
420 }
421
422 // get errors
423 $errors = acf_validate_attachment( $file, $field, 'basic_upload' );
424
425 // append error
426 if ( ! empty( $errors ) ) {
427 $valid = implode( "\n", $errors );
428 }
429
430 // return
431 return $valid;
432 }
433
434 /**
435 * Validates file fields updated via the REST API.
436 *
437 * @param boolean $valid The current validity booleean
438 * @param integer $value The value of the field
439 * @param array $field The field array
440 * @return boolean|WP_Error
441 */
442 public function validate_rest_value( $valid, $value, $field ) {
443 if ( is_null( $value ) && empty( $field['required'] ) ) {
444 return $valid;
445 }
446
447 /**
448 * A bit of a hack, but we use `wp_prepare_attachment_for_js()` here
449 * since it returns all the data we need to validate the file, and we use this anyways
450 * to validate fields updated via UI.
451 */
452 $attachment = wp_prepare_attachment_for_js( $value );
453 $param = sprintf( '%s[%s]', $field['prefix'], $field['name'] );
454 $data = array(
455 'param' => $param,
456 'value' => (int) $value,
457 );
458
459 if ( ! $attachment ) {
460 $error = sprintf( __( '%s requires a valid attachment ID.', 'acf' ), $param );
461 return new WP_Error( 'rest_invalid_param', $error, $data );
462 }
463
464 $errors = acf_validate_attachment( $attachment, $field, 'prepare' );
465
466 if ( ! empty( $errors ) ) {
467 $error = $param . ' - ' . implode( ' ', $errors );
468 return new WP_Error( 'rest_invalid_param', $error, $data );
469 }
470
471 return $valid;
472 }
473
474 /**
475 * Return the schema array for the REST API.
476 *
477 * @param array $field
478 * @return array
479 */
480 public function get_rest_schema( array $field ) {
481 $schema = array(
482 'type' => array( 'integer', 'null' ),
483 'required' => isset( $field['required'] ) && $field['required'],
484 );
485
486 if ( ! empty( $field['min_width'] ) ) {
487 $schema['minWidth'] = (int) $field['min_width'];
488 }
489
490 if ( ! empty( $field['min_height'] ) ) {
491 $schema['minHeight'] = (int) $field['min_height'];
492 }
493
494 if ( ! empty( $field['min_size'] ) ) {
495 $schema['minSize'] = $field['min_size'];
496 }
497
498 if ( ! empty( $field['max_width'] ) ) {
499 $schema['maxWidth'] = (int) $field['max_width'];
500 }
501
502 if ( ! empty( $field['max_height'] ) ) {
503 $schema['maxHeight'] = (int) $field['max_height'];
504 }
505
506 if ( ! empty( $field['max_size'] ) ) {
507 $schema['maxSize'] = $field['max_size'];
508 }
509
510 if ( ! empty( $field['mime_types'] ) ) {
511 $schema['mimeTypes'] = $field['mime_types'];
512 }
513
514 return $schema;
515 }
516
517 /**
518 * Apply basic formatting to prepare the value for default REST output.
519 *
520 * @param mixed $value
521 * @param string|integer $post_id
522 * @param array $field
523 * @return mixed
524 */
525 public function format_value_for_rest( $value, $post_id, array $field ) {
526 return acf_format_numerics( $value );
527 }
528
529 /**
530 * Formats the field value for JSON-LD output.
531 *
532 * @since 6.8.0
533 *
534 * @param mixed $value The value of the field.
535 * @param integer|string $post_id The ID of the post.
536 * @param array $field The field array.
537 * @return mixed
538 */
539 public function format_value_for_jsonld( $value, $post_id, $field ) {
540 if ( empty( $value ) ) {
541 return null;
542 }
543
544 // Get output format with fallback.
545 $output_format = $field['schema_output_format'] ?? '';
546 if ( empty( $output_format ) ) {
547 $property = $field['schema_property'] ?? '';
548 $output_format = \ACF\AI\GEO\Schema::get_default_output_format( $this->name, $property );
549 }
550
551 // Get attachment ID.
552 $attachment_id = is_array( $value ) ? ( $value['ID'] ?? 0 ) : (int) $value;
553 if ( ! $attachment_id ) {
554 return null;
555 }
556
557 $url = wp_get_attachment_url( $attachment_id );
558 if ( ! $url ) {
559 return null;
560 }
561
562 // URL format - just return the URL string.
563 if ( 'URL' === $output_format ) {
564 return $url;
565 }
566
567 // MediaObject or DataDownload format.
568 $file_object = array(
569 '@type' => $output_format ?: 'MediaObject',
570 'contentUrl' => $url,
571 );
572
573 // Add name from attachment title.
574 $attachment = get_post( $attachment_id );
575 if ( $attachment && $attachment->post_title ) {
576 $file_object['name'] = $attachment->post_title;
577 }
578
579 // Add description if available.
580 if ( $attachment && $attachment->post_content ) {
581 $file_object['description'] = $attachment->post_content;
582 }
583
584 // Add file metadata.
585 $file_path = get_attached_file( $attachment_id );
586 if ( $file_path && file_exists( $file_path ) ) {
587 $file_object['contentSize'] = size_format( filesize( $file_path ) );
588 }
589
590 // Add MIME type.
591 $mime_type = get_post_mime_type( $attachment_id );
592 if ( $mime_type ) {
593 $file_object['encodingFormat'] = $mime_type;
594 }
595
596 return $file_object;
597 }
598
599 /**
600 * Returns an array of JSON-LD Property output types that are supported by this field type.
601 *
602 * @since 6.8
603 *
604 * @return string[]
605 */
606 public function get_jsonld_output_types(): array {
607 return array( 'MediaObject', 'DataDownload', 'URL' );
608 }
609 }
610
611
612 // initialize
613 acf_register_field_type( 'acf_field_file' );
614 endif; // class_exists check
615
616 ?>
617