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.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 5 months ago class-acf-field-image.php 4 weeks ago class-acf-field-link.php 5 months ago class-acf-field-message.php 5 months ago class-acf-field-number.php 5 months ago class-acf-field-oembed.php 2 months ago class-acf-field-output.php 5 months ago class-acf-field-page_link.php 4 weeks ago class-acf-field-password.php 5 months ago class-acf-field-post_object.php 4 weeks ago class-acf-field-radio.php 2 months ago class-acf-field-range.php 5 months ago class-acf-field-relationship.php 4 weeks ago class-acf-field-select.php 2 months ago class-acf-field-separator.php 5 months ago class-acf-field-tab.php 5 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.php
433 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' ) ) :
13 class acf_field {
14
15 // field information properties.
16 public $name = '';
17 public $label = '';
18 public $category = 'basic';
19 public $description = '';
20 public $doc_url = false;
21 public $tutorial_url = false;
22 public $preview_image = false;
23 public $pro = false;
24 public $defaults = array();
25 public $l10n = array();
26 public $public = true;
27 public $show_in_rest = true;
28 public $supports = array(
29 'escaping_html' => false, // Set true when a field handles its own HTML escaping in format_value
30 'required' => true,
31 );
32
33 // Additional properties used by field types
34 public $default_values = array();
35 public $have_rows = '';
36 public $width = '';
37 public $height = '';
38
39 /**
40 * Initializes the `acf_field` class. To initialize a field type that is
41 * extending this class, use the `initialize()` method in the child class instead.
42 *
43 * @since 5.0.0
44 */
45 public function __construct() {
46 // Initialize the field type.
47 $this->initialize();
48
49 // Register info about the field type.
50 acf_register_field_type_info(
51 array(
52 'label' => $this->label,
53 'name' => $this->name,
54 'category' => $this->category,
55 'description' => $this->description,
56 'doc_url' => $this->doc_url,
57 'tutorial_url' => $this->tutorial_url,
58 'preview_image' => $this->preview_image,
59 'pro' => $this->pro,
60 'public' => $this->public,
61 )
62 );
63
64 // value
65 $this->add_field_filter( 'acf/load_value', array( $this, 'load_value' ), 10, 3 );
66 $this->add_field_filter( 'acf/update_value', array( $this, 'update_value' ), 10, 3 );
67 $this->add_field_filter( 'acf/format_value', array( $this, 'format_value' ), 10, 4 );
68 $this->add_field_filter( 'acf/validate_value', array( $this, 'validate_value' ), 10, 4 );
69 $this->add_field_action( 'acf/delete_value', array( $this, 'delete_value' ), 10, 3 );
70
71 // field
72 $this->add_field_filter( 'acf/validate_rest_value', array( $this, 'validate_rest_value' ), 10, 3 );
73 $this->add_field_filter( 'acf/validate_field', array( $this, 'validate_field' ), 10, 1 );
74 $this->add_field_filter( 'acf/load_field', array( $this, 'load_field' ), 10, 1 );
75 $this->add_field_filter( 'acf/update_field', array( $this, 'update_field' ), 10, 1 );
76 $this->add_field_filter( 'acf/duplicate_field', array( $this, 'duplicate_field' ), 10, 1 );
77 $this->add_field_action( 'acf/delete_field', array( $this, 'delete_field' ), 10, 1 );
78 $this->add_field_action( 'acf/render_field', array( $this, 'render_field' ), 9, 1 );
79 $this->add_field_action( 'acf/render_field_settings', array( $this, 'render_field_settings' ), 9, 1 );
80 $this->add_field_filter( 'acf/prepare_field', array( $this, 'prepare_field' ), 10, 1 );
81 $this->add_field_filter( 'acf/translate_field', array( $this, 'translate_field' ), 10, 1 );
82
83 // input actions
84 $this->add_action( 'acf/input/admin_enqueue_scripts', array( $this, 'input_admin_enqueue_scripts' ), 10, 0 );
85 $this->add_action( 'acf/input/admin_head', array( $this, 'input_admin_head' ), 10, 0 );
86 $this->add_action( 'acf/input/form_data', array( $this, 'input_form_data' ), 10, 1 );
87 $this->add_filter( 'acf/input/admin_l10n', array( $this, 'input_admin_l10n' ), 10, 1 );
88 $this->add_action( 'acf/input/admin_footer', array( $this, 'input_admin_footer' ), 10, 1 );
89
90 // field group actions
91 $this->add_action( 'acf/field_group/admin_enqueue_scripts', array( $this, 'field_group_admin_enqueue_scripts' ), 10, 0 );
92 $this->add_action( 'acf/field_group/admin_head', array( $this, 'field_group_admin_head' ), 10, 0 );
93 $this->add_action( 'acf/field_group/admin_footer', array( $this, 'field_group_admin_footer' ), 10, 0 );
94
95 // Add field global settings configurable by supports on specific field types.
96 $this->add_field_action( 'acf/field_group/render_field_settings_tab/validation', array( $this, 'render_required_setting' ), 5 );
97 $this->add_field_action( 'acf/field_group/render_field_settings_tab/presentation', array( $this, 'render_bindings_setting' ), 5 );
98
99 foreach ( acf_get_combined_field_type_settings_tabs() as $tab_key => $tab_label ) {
100 $this->add_field_action( "acf/field_group/render_field_settings_tab/{$tab_key}", array( $this, "render_field_{$tab_key}_settings" ), 9, 1 );
101 }
102 }
103
104 /**
105 * Initializes the field type. Overridden in child classes.
106 *
107 * @since 5.6.0
108 */
109 public function initialize() {
110 /* do nothing */
111 }
112
113 /**
114 * Checks a function `is_callable()` before adding the filter, since
115 * classes that extend `acf_field` might not implement all filters.
116 *
117 * @since 5.0.0
118 *
119 * @param string $tag The name of the filter to add the callback to.
120 * @param string $function_to_add The callback to be run when the filter is applied.
121 * @param integer $priority The priority to add the filter on.
122 * @param integer $accepted_args The number of args to pass to the function.
123 * @return void
124 */
125 public function add_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
126 // Bail early if not callable.
127 if ( ! is_callable( $function_to_add ) ) {
128 return;
129 }
130
131 add_filter( $tag, $function_to_add, $priority, $accepted_args );
132 }
133
134 /**
135 * Adds a filter specific to the current field type.
136 *
137 * @since 5.4.0
138 *
139 * @param string $tag The name of the filter to add the callback to.
140 * @param string $function_to_add The callback to be run when the filter is applied.
141 * @param integer $priority The priority to add the filter on.
142 * @param integer $accepted_args The number of args to pass to the function.
143 * @return void
144 */
145 public function add_field_filter( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
146 // Append the field type name to the tag before adding the filter.
147 $tag .= '/type=' . $this->name;
148 $this->add_filter( $tag, $function_to_add, $priority, $accepted_args );
149 }
150
151 /**
152 * Checks a function `is_callable()` before adding the action, since
153 * classes that extend `acf_field` might not implement all actions.
154 *
155 * @since 5.0.0
156 *
157 * @param string $tag The name of the action to add the callback to.
158 * @param string $function_to_add The callback to be run when the action is ran.
159 * @param integer $priority The priority to add the action on.
160 * @param integer $accepted_args The number of args to pass to the function.
161 * @return void
162 */
163 public function add_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
164 // Bail early if not callable
165 if ( ! is_callable( $function_to_add ) ) {
166 return;
167 }
168
169 add_action( $tag, $function_to_add, $priority, $accepted_args );
170 }
171
172 /**
173 * Adds an action specific to the current field type.
174 *
175 * @since 5.4.0
176 *
177 * @param string $tag The name of the action to add the callback to.
178 * @param string $function_to_add The callback to be run when the action is ran.
179 * @param integer $priority The priority to add the action on.
180 * @param integer $accepted_args The number of args to pass to the function.
181 * @return void
182 */
183 public function add_field_action( $tag = '', $function_to_add = '', $priority = 10, $accepted_args = 1 ) {
184 // Append the field type name to the tag before adding the action.
185 $tag .= '/type=' . $this->name;
186 $this->add_action( $tag, $function_to_add, $priority, $accepted_args );
187 }
188
189 /**
190 * Appends default settings to a field.
191 * Runs on `acf/validate_field/type={$this->name}`.
192 *
193 * @since 3.6
194 *
195 * @param array $field The field array.
196 * @return array $field
197 */
198 public function validate_field( $field ) {
199 // Bail early if no defaults.
200 if ( ! is_array( $this->defaults ) ) {
201 return $field;
202 }
203
204 // Merge in defaults but keep order of $field keys.
205 foreach ( $this->defaults as $k => $v ) {
206 if ( ! isset( $field[ $k ] ) ) {
207 $field[ $k ] = $v;
208 }
209 }
210
211 return $field;
212 }
213
214 /**
215 * Append l10n text translations to an array which is later passed to JS.
216 * Runs on `acf/input/admin_l10n`.
217 *
218 * @since 3.6
219 *
220 * @param array $l10n
221 * @return array $l10n
222 */
223 public function input_admin_l10n( $l10n ) {
224 // Bail early if no defaults.
225 if ( empty( $this->l10n ) ) {
226 return $l10n;
227 }
228
229 // Append.
230 $l10n[ $this->name ] = $this->l10n;
231
232 return $l10n;
233 }
234
235 /**
236 * Add additional validation for fields being updated via the REST API.
237 *
238 * @param boolean $valid The current validity booleean
239 * @param integer $value The value of the field
240 * @param array $field The field array
241 * @return boolean|WP_Error
242 */
243 public function validate_rest_value( $valid, $value, $field ) {
244 return $valid;
245 }
246
247 /**
248 * Returns the JSON schema for creating this field type.
249 *
250 * @since 6.8.0
251 *
252 * @return array JSON Schema definition for this field type, or an empty array if none exists.
253 */
254 public function get_field_creation_schema(): array {
255 $schema = acf_get_field_json_schema( $this->name );
256
257 if ( empty( $schema ) ) {
258 $schema = array(
259 'type' => 'object',
260 'properties' => array(
261 'label' => array(
262 'type' => 'string',
263 'description' => 'The label for the field',
264 'minLength' => 1,
265 'required' => true,
266 ),
267 'type' => array(
268 'type' => 'string',
269 'enum' => array( $this->name ),
270 'description' => 'The field type',
271 'required' => true,
272 ),
273 ),
274 );
275 }
276
277 return $schema;
278 }
279
280 /**
281 * Return the schema array for the REST API.
282 *
283 * @param array $field
284 * @return array
285 */
286 public function get_rest_schema( array $field ) {
287 $schema = array(
288 'type' => array( 'string', 'null' ),
289 'required' => ! empty( $field['required'] ),
290 );
291
292 if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
293 $schema['default'] = $field['default_value'];
294 }
295
296 return $schema;
297 }
298
299 /**
300 * Return an array of links for addition to the REST API response. Each link is an array and must have both `rel` and
301 * `href` keys. The `href` key must be a REST API resource URL. If a link is marked as `embeddable`, the `_embed` URL
302 * parameter will trigger WordPress to dispatch an internal sub request and load the object within the same request
303 * under the `_embedded` response property.
304 *
305 * e.g;
306 * [
307 * [
308 * 'rel' => 'acf:post',
309 * 'href' => 'https://example.com/wp-json/wp/v2/posts/497',
310 * 'embeddable' => true,
311 * ],
312 * [
313 * 'rel' => 'acf:user',
314 * 'href' => 'https://example.com/wp-json/wp/v2/users/2',
315 * 'embeddable' => true,
316 * ],
317 * ]
318 *
319 * @param mixed $value The raw (unformatted) field value.
320 * @param string|integer $post_id
321 * @param array $field
322 * @return array
323 */
324 public function get_rest_links( $value, $post_id, array $field ) {
325 return array();
326 }
327
328 /**
329 * Apply basic formatting to prepare the value for default REST output.
330 *
331 * @param mixed $value
332 * @param string|integer $post_id
333 * @param array $field
334 * @return mixed
335 */
336 public function format_value_for_rest( $value, $post_id, array $field ) {
337 return $value;
338 }
339
340 /**
341 * Returns an array of JSON-LD Property output types that are supported by this field type.
342 *
343 * Override in field type classes to declare supported ranges.
344 * Used to determine valid properties and output formats.
345 *
346 * @since 6.8
347 *
348 * @return string[]
349 */
350 public function get_jsonld_output_types(): array {
351 return array();
352 }
353
354 /**
355 * Renders the "Required" setting on the field type "Validation" settings tab.
356 *
357 * @since 6.2.5
358 *
359 * @param array $field The field type being rendered.
360 * @return void
361 */
362 public function render_required_setting( $field ) {
363 $supports_required = acf_field_type_supports( $field['type'], 'required', true );
364
365 // Only prevent rendering if explicitly disabled.
366 if ( ! $supports_required ) {
367 return;
368 }
369
370 acf_render_field_setting(
371 $field,
372 array(
373 'label' => __( 'Required', 'acf' ),
374 'instructions' => '',
375 'type' => 'true_false',
376 'name' => 'required',
377 'ui' => 1,
378 'class' => 'field-required',
379 ),
380 true
381 );
382 }
383
384 /**
385 * Renders the "Allow in Bindings" setting on the field type "Presentation" settings tab.
386 *
387 * @since 6.3.6
388 *
389 * @param array $field The field type being rendered.
390 * @return void
391 */
392 public function render_bindings_setting( $field ) {
393 $supports_bindings = acf_field_type_supports( $field['type'], 'bindings', true );
394
395 // Only prevent rendering if explicitly disabled.
396 if ( ! $supports_bindings ) {
397 return;
398 }
399
400 /* translators: %s A "Learn More" link to documentation explaining the setting further. */
401 $binding_string = esc_html__( 'Allow content editors to access and display the field value in the editor UI using Block Bindings or the ACF Shortcode. %s', 'acf' );
402 $binding_url = '<a target="_blank" href="' . acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/bindings-security/', 'docs', 'field-settings' ) . '">' . esc_html__( 'Learn more.', 'acf' ) . '</a>';
403 $binding_instructions = sprintf(
404 $binding_string,
405 $binding_url
406 );
407
408 // This field setting has unique behavior. If the value isn't defined on the field object, it defaults to true, but for new fields or when changing field types, it defaults to off.
409 if ( ! isset( $field['allow_in_bindings'] ) ) {
410 if ( empty( $field['ID'] ) || doing_action( 'wp_ajax_acf/field_group/render_field_settings' ) ) {
411 $field['allow_in_bindings'] = false;
412 } else {
413 $field['allow_in_bindings'] = true;
414 }
415 }
416
417 acf_render_field_setting(
418 $field,
419 array(
420 'label' => __( 'Allow Access to Value in Editor UI', 'acf' ),
421 'instructions' => $binding_instructions,
422 'type' => 'true_false',
423 'name' => 'allow_in_bindings',
424 'ui' => 1,
425 'class' => 'field-show-in-bindings',
426 ),
427 true
428 );
429 }
430 }
431
432 endif; // class_exists check
433