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