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