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-oembed.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 6 months ago class-acf-field-image.php 1 month ago class-acf-field-link.php 5 months ago class-acf-field-message.php 6 months ago class-acf-field-number.php 5 months ago class-acf-field-oembed.php 2 months ago class-acf-field-output.php 6 months ago class-acf-field-page_link.php 1 month ago class-acf-field-password.php 5 months ago class-acf-field-post_object.php 1 month ago class-acf-field-radio.php 2 months ago class-acf-field-range.php 5 months ago class-acf-field-relationship.php 1 month ago class-acf-field-select.php 2 months ago class-acf-field-separator.php 6 months ago class-acf-field-tab.php 6 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-oembed.php
443 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_oembed' ) ) :
13 class acf_field_oembed extends acf_field {
14
15
16 /**
17 * This function will setup the field type data
18 *
19 * @type function
20 * @date 5/03/2014
21 * @since 5.0.0
22 *
23 * @param n/a
24 * @return n/a
25 */
26 function initialize() {
27
28 // vars
29 $this->name = 'oembed';
30 $this->label = __( 'oEmbed', 'acf' );
31 $this->category = 'content';
32 $this->description = __( 'An interactive component for embedding videos, images, tweets, audio and other content by making use of the native WordPress oEmbed functionality.', 'acf' );
33 $this->preview_image = acf_get_url() . '/assets/images/field-type-previews/field-preview-oembed.png';
34 $this->doc_url = acf_add_url_utm_tags( 'https://www.advancedcustomfields.com/resources/oembed/', 'docs', 'field-type-selection' );
35 $this->defaults = array(
36 'width' => '',
37 'height' => '',
38 );
39 $this->width = 640;
40 $this->height = 390;
41 $this->supports = array(
42 'escaping_html' => true, // The OEmbed field only produces html safe content from format_value.
43 );
44
45 // extra
46 add_action( 'wp_ajax_acf/fields/oembed/search', array( $this, 'ajax_query' ) );
47 add_action( 'wp_ajax_nopriv_acf/fields/oembed/search', array( $this, 'ajax_query' ) );
48 }
49
50
51 /**
52 * This function will prepare the field for input
53 *
54 * @type function
55 * @date 14/2/17
56 * @since 5.5.8
57 *
58 * @param $field (array)
59 * @return (int)
60 */
61 function prepare_field( $field ) {
62
63 // defaults
64 if ( ! $field['width'] ) {
65 $field['width'] = $this->width;
66 }
67 if ( ! $field['height'] ) {
68 $field['height'] = $this->height;
69 }
70
71 // return
72 return $field;
73 }
74
75 /**
76 * Attempts to fetch the HTML for the provided URL using oEmbed.
77 *
78 * @date 24/01/2014
79 * @since 5.0.0
80 *
81 * @param string $url The URL that should be embedded.
82 * @param integer|string $width Optional maxwidth value passed to the provider URL.
83 * @param integer|string $height Optional maxheight value passed to the provider URL.
84 * @param array $args Optional. Additional arguments merged into the oEmbed request (e.g. 'discover').
85 * @return string|false The embedded HTML on success, false on failure.
86 */
87 function wp_oembed_get( $url = '', $width = 0, $height = 0, $args = array() ) {
88 $embed = false;
89 $res = array_merge(
90 array(
91 'width' => $width,
92 'height' => $height,
93 ),
94 $args
95 );
96
97 if ( function_exists( 'wp_oembed_get' ) ) {
98 $embed = wp_oembed_get( $url, $res );
99 }
100
101 // try shortcode
102 if ( ! $embed ) {
103 global $wp_embed;
104
105 /**
106 * Mirror our discover restriction onto WP_Embed::shortcode(),
107 * which otherwise forces discover=true via embed_oembed_discover.
108 */
109 $force_discover_off = isset( $args['discover'] ) && false === $args['discover'];
110 if ( $force_discover_off ) {
111 add_filter( 'embed_oembed_discover', '__return_false', PHP_INT_MAX );
112 }
113
114 $embed = $wp_embed->shortcode( $res, $url );
115
116 if ( $force_discover_off ) {
117 remove_filter( 'embed_oembed_discover', '__return_false', PHP_INT_MAX );
118 }
119 }
120
121 return $embed;
122 }
123
124 /**
125 * Returns AJAX results for the oEmbed field.
126 *
127 * @since 5.0.0
128 *
129 * @return void
130 */
131 public function ajax_query() {
132 $args = acf_request_args(
133 array(
134 'nonce' => '',
135 'field_key' => '',
136 )
137 );
138
139 if ( ! acf_verify_ajax( $args['nonce'], $args['field_key'], true, 'oembed' ) ) {
140 die();
141 }
142
143 wp_send_json( $this->get_ajax_query( $_POST ) );
144 }
145
146 /**
147 * This function will return an array of data formatted for use in a select2 AJAX response
148 *
149 * @type function
150 * @date 15/10/2014
151 * @since 5.0.9
152 *
153 * @param $options (array)
154 * @return (array)
155 */
156 function get_ajax_query( $args = array() ) {
157
158 // defaults
159 $args = acf_parse_args(
160 $args,
161 array(
162 's' => '',
163 'field_key' => '',
164 )
165 );
166
167 // load field
168 $field = acf_get_field( $args['field_key'] );
169 if ( ! $field ) {
170 return false;
171 }
172
173 // prepare field to correct width and height
174 $field = $this->prepare_field( $field );
175
176 /**
177 * Filters whether URL discovery is permitted on the AJAX oEmbed preview path.
178 *
179 * Discovery is restricted by default to users with the edit_posts capability,
180 * limiting unauthenticated and subscriber-tier callers to WordPress's
181 * registered oEmbed provider allowlist. Saved values and admin save-time
182 * rendering are unaffected.
183 *
184 * @since 6.8.3
185 *
186 * @param bool $allow_discovery Whether discovery is permitted. Default: true for users with edit_posts, false otherwise.
187 * @param array $field The oEmbed field array.
188 */
189 $allow_discovery = (bool) apply_filters( 'acf/fields/oembed/allow_discovery', current_user_can( 'edit_posts' ), $field );
190
191 // vars
192 $response = array(
193 'url' => $args['s'],
194 'html' => $this->wp_oembed_get( $args['s'], $field['width'], $field['height'], array( 'discover' => $allow_discovery ) ),
195 );
196
197 // return
198 return $response;
199 }
200
201
202 /**
203 * Renders the oEmbed field.
204 *
205 * @since 3.6
206 *
207 * @param array $field The field settings array.
208 * @return void
209 */
210 public function render_field( $field ) {
211 $atts = array(
212 'class' => 'acf-oembed',
213 'data-nonce' => wp_create_nonce( 'acf_field_' . $this->name . '_' . $field['key'] ),
214 );
215
216 if ( $field['value'] ) {
217 $atts['class'] .= ' has-value';
218 }
219
220 ?>
221 <div <?php echo acf_esc_attrs( $atts ); ?>>
222
223 <?php
224 acf_hidden_input(
225 array(
226 'class' => 'input-value',
227 'name' => $field['name'],
228 'value' => $field['value'],
229 )
230 );
231 ?>
232
233 <div class="title">
234 <?php
235 acf_text_input(
236 array(
237 'class' => 'input-search',
238 'value' => $field['value'],
239 'placeholder' => __( 'Enter URL', 'acf' ),
240 'autocomplete' => 'off',
241 )
242 );
243 ?>
244 <div class="acf-actions -hover">
245 <a data-name="clear-button" href="#" class="acf-icon -cancel grey"></a>
246 </div>
247 </div>
248
249 <div class="canvas">
250 <div class="canvas-media">
251 <?php
252 if ( $field['value'] ) {
253 echo $this->wp_oembed_get( $field['value'], $field['width'], $field['height'] ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- wp_ombed_get generates HTML safe output.
254 }
255 ?>
256 </div>
257 <i class="acf-icon -picture hide-if-value"></i>
258 </div>
259
260 </div>
261 <?php
262 }
263
264
265 /**
266 * Create extra options for your field. This is rendered when editing a field.
267 * The value of $field['name'] can be used (like bellow) to save extra data to the $field
268 *
269 * @param $field - an array holding all the field's data
270 *
271 * @type action
272 * @since 3.6
273 * @date 23/01/13
274 */
275 function render_field_settings( $field ) {
276 acf_render_field_setting(
277 $field,
278 array(
279 'label' => __( 'Embed Size', 'acf' ),
280 'type' => 'text',
281 'name' => 'width',
282 'prepend' => __( 'Width', 'acf' ),
283 'append' => 'px',
284 'placeholder' => $this->width,
285 )
286 );
287
288 acf_render_field_setting(
289 $field,
290 array(
291 'label' => __( 'Embed Size', 'acf' ),
292 'type' => 'text',
293 'name' => 'height',
294 'prepend' => __( 'Height', 'acf' ),
295 'append' => 'px',
296 'placeholder' => $this->height,
297 '_append' => 'width',
298 )
299 );
300 }
301
302 /**
303 * This filter is appied to the $value after it is loaded from the db and before it is returned to the template.
304 *
305 * @type filter
306 * @since 3.6
307 *
308 * @param mixed $value The value which was loaded from the database.
309 * @param mixed $post_id The $post_id from which the value was loaded.
310 * @param array $field The field array holding all the field options.
311 * @return mixed the modified value
312 */
313 public function format_value( $value, $post_id, $field ) {
314 // bail early if no value
315 if ( empty( $value ) ) {
316 return $value;
317 }
318
319 // prepare field to correct width and height
320 $field = $this->prepare_field( $field );
321
322 // get oembed
323 $value = $this->wp_oembed_get( $value, $field['width'], $field['height'] );
324
325 // return
326 return $value;
327 }
328
329 /**
330 * Return the schema array for the REST API.
331 *
332 * @param array $field
333 * @return array
334 */
335 public function get_rest_schema( array $field ) {
336 $schema = parent::get_rest_schema( $field );
337 $schema['format'] = 'uri';
338
339 return $schema;
340 }
341
342 /**
343 * Returns an array of JSON-LD Property output types that are supported by this field type.
344 *
345 * @since 6.8
346 *
347 * @return string[]
348 */
349 public function get_jsonld_output_types(): array {
350 return array( 'VideoObject', 'AudioObject', 'MediaObject' );
351 }
352
353 /**
354 * Formats the field value for JSON-LD output.
355 *
356 * @since 6.8.0
357 *
358 * @param mixed $value The value of the field (URL).
359 * @param integer|string $post_id The ID of the post.
360 * @param array $field The field array.
361 * @return mixed
362 */
363 public function format_value_for_jsonld( $value, $post_id, $field ) {
364 if ( empty( $value ) ) {
365 return null;
366 }
367
368 // Get output format with fallback.
369 $output_format = $field['schema_output_format'] ?? '';
370 if ( empty( $output_format ) ) {
371 $property = $field['schema_property'] ?? '';
372 $output_format = \ACF\AI\GEO\Schema::get_default_output_format( $this->name, $property );
373 }
374
375 // Default to VideoObject if no format determined.
376 if ( empty( $output_format ) ) {
377 $output_format = 'VideoObject';
378 }
379
380 // Get oEmbed data for richer output.
381 $oembed_data = _wp_oembed_get_object()->get_data( $value, array() );
382
383 $result = array(
384 '@type' => $output_format,
385 'url' => $value,
386 );
387
388 if ( $oembed_data ) {
389 // Add name/title.
390 if ( ! empty( $oembed_data->title ) ) {
391 $result['name'] = $oembed_data->title;
392 }
393
394 // Add thumbnail.
395 if ( ! empty( $oembed_data->thumbnail_url ) ) {
396 $result['thumbnailUrl'] = $oembed_data->thumbnail_url;
397 }
398
399 // Add provider information.
400 if ( ! empty( $oembed_data->provider_name ) ) {
401 $result['publisher'] = array(
402 '@type' => 'Organization',
403 'name' => $oembed_data->provider_name,
404 );
405 if ( ! empty( $oembed_data->provider_url ) ) {
406 $result['publisher']['url'] = $oembed_data->provider_url;
407 }
408 }
409
410 // Add dimensions for video.
411 if ( 'VideoObject' === $output_format || 'video' === ( $oembed_data->type ?? '' ) ) {
412 if ( ! empty( $oembed_data->width ) ) {
413 $result['width'] = (int) $oembed_data->width;
414 }
415 if ( ! empty( $oembed_data->height ) ) {
416 $result['height'] = (int) $oembed_data->height;
417 }
418 }
419
420 // Add author if available.
421 if ( ! empty( $oembed_data->author_name ) ) {
422 $author = array(
423 '@type' => 'Person',
424 'name' => $oembed_data->author_name,
425 );
426 if ( ! empty( $oembed_data->author_url ) ) {
427 $author['url'] = $oembed_data->author_url;
428 }
429 $result['author'] = $author;
430 }
431 }
432
433 return $result;
434 }
435 }
436
437
438 // initialize
439 acf_register_field_type( 'acf_field_oembed' );
440 endif; // class_exists check
441
442 ?>
443