PluginProbe ʕ •ᴥ•ʔ
Secure Custom Fields / 6.5.7
Secure Custom Fields v6.5.7
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 10 months ago class-acf-field-accordion.php 1 year ago class-acf-field-button-group.php 1 year ago class-acf-field-checkbox.php 10 months ago class-acf-field-clone.php 10 months ago class-acf-field-color_picker.php 1 year ago class-acf-field-date_picker.php 10 months ago class-acf-field-date_time_picker.php 10 months ago class-acf-field-email.php 1 year ago class-acf-field-file.php 1 year ago class-acf-field-flexible-content.php 10 months ago class-acf-field-gallery.php 1 year ago class-acf-field-google-map.php 10 months ago class-acf-field-group.php 10 months ago class-acf-field-icon_picker.php 10 months 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-nav-menu.php 1 year ago class-acf-field-number.php 1 year ago class-acf-field-oembed.php 10 months ago class-acf-field-output.php 1 year ago class-acf-field-page_link.php 10 months ago class-acf-field-password.php 1 year ago class-acf-field-post_object.php 10 months ago class-acf-field-radio.php 1 year ago class-acf-field-range.php 1 year ago class-acf-field-relationship.php 10 months 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 10 months ago class-acf-repeater-table.php 1 year ago index.php 1 year ago
class-acf-field.php
400 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 * Return the schema array for the REST API.
263 *
264 * @param array $field
265 * @return array
266 */
267 public function get_rest_schema( array $field ) {
268 $schema = array(
269 'type' => array( 'string', 'null' ),
270 'required' => ! empty( $field['required'] ),
271 );
272
273 if ( isset( $field['default_value'] ) && '' !== $field['default_value'] ) {
274 $schema['default'] = $field['default_value'];
275 }
276
277 return $schema;
278 }
279
280 /**
281 * Return an array of links for addition to the REST API response. Each link is an array and must have both `rel` and
282 * `href` keys. The `href` key must be a REST API resource URL. If a link is marked as `embeddable`, the `_embed` URL
283 * parameter will trigger WordPress to dispatch an internal sub request and load the object within the same request
284 * under the `_embedded` response property.
285 *
286 * e.g;
287 * [
288 * [
289 * 'rel' => 'acf:post',
290 * 'href' => 'https://example.com/wp-json/wp/v2/posts/497',
291 * 'embeddable' => true,
292 * ],
293 * [
294 * 'rel' => 'acf:user',
295 * 'href' => 'https://example.com/wp-json/wp/v2/users/2',
296 * 'embeddable' => true,
297 * ],
298 * ]
299 *
300 * @param mixed $value The raw (unformatted) field value.
301 * @param string|integer $post_id
302 * @param array $field
303 * @return array
304 */
305 public function get_rest_links( $value, $post_id, array $field ) {
306 return array();
307 }
308
309 /**
310 * Apply basic formatting to prepare the value for default REST output.
311 *
312 * @param mixed $value
313 * @param string|integer $post_id
314 * @param array $field
315 * @return mixed
316 */
317 public function format_value_for_rest( $value, $post_id, array $field ) {
318 return $value;
319 }
320
321 /**
322 * Renders the "Required" setting on the field type "Validation" settings tab.
323 *
324 * @since ACF 6.2.5
325 *
326 * @param array $field The field type being rendered.
327 * @return void
328 */
329 public function render_required_setting( $field ) {
330 $supports_required = acf_field_type_supports( $field['type'], 'required', true );
331
332 // Only prevent rendering if explicitly disabled.
333 if ( ! $supports_required ) {
334 return;
335 }
336
337 acf_render_field_setting(
338 $field,
339 array(
340 'label' => __( 'Required', 'secure-custom-fields' ),
341 'instructions' => '',
342 'type' => 'true_false',
343 'name' => 'required',
344 'ui' => 1,
345 'class' => 'field-required',
346 ),
347 true
348 );
349 }
350
351 /**
352 * Renders the "Allow in Bindings" setting on the field type "Presentation" settings tab.
353 *
354 * @since ACF 6.3.6
355 *
356 * @param array $field The field type being rendered.
357 * @return void
358 */
359 public function render_bindings_setting( $field ) {
360 $supports_bindings = acf_field_type_supports( $field['type'], 'bindings', true );
361
362 // Only prevent rendering if explicitly disabled.
363 if ( ! $supports_bindings ) {
364 return;
365 }
366
367 /* translators: %s A "Learn More" link to documentation explaining the setting further. */
368 $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' );
369 $binding_url = '<a target="_blank" href="' . 'https://www.advancedcustomfields.com/resources/bindings-security/' . '">' . esc_html__( 'Learn more.', 'secure-custom-fields' ) . '</a>';
370 $binding_instructions = sprintf(
371 $binding_string,
372 $binding_url
373 );
374
375 // 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.
376 if ( ! isset( $field['allow_in_bindings'] ) ) {
377 if ( empty( $field['ID'] ) || doing_action( 'wp_ajax_acf/field_group/render_field_settings' ) ) {
378 $field['allow_in_bindings'] = false;
379 } else {
380 $field['allow_in_bindings'] = true;
381 }
382 }
383
384 acf_render_field_setting(
385 $field,
386 array(
387 'label' => __( 'Allow Access to Value in Editor UI', 'secure-custom-fields' ),
388 'instructions' => $binding_instructions,
389 'type' => 'true_false',
390 'name' => 'allow_in_bindings',
391 'ui' => 1,
392 'class' => 'field-show-in-bindings',
393 ),
394 true
395 );
396 }
397 }
398
399 endif; // class_exists check
400