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