PluginProbe ʕ •ᴥ•ʔ
Pods – Custom Content Types and Fields / 3.2.2
Pods – Custom Content Types and Fields v3.2.2
trunk 1.14.8 2.7.31.3 2.8.23.3 2.9.19.3 3.0.10.3 3.1.4.1 3.2.0 3.2.1 3.2.1.1 3.2.2 3.2.4 3.2.5 3.2.6 3.2.7 3.2.7.1 3.2.8 3.2.8.1 3.2.8.2 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
pods / classes / fields / oembed.php
pods / classes / fields Last commit date
avatar.php 3 years ago boolean.php 3 years ago code.php 2 years ago color.php 3 years ago comment.php 4 years ago currency.php 3 years ago date.php 2 years ago datetime.php 2 years ago email.php 3 years ago file.php 2 years ago heading.php 2 years ago html.php 2 years ago link.php 3 years ago number.php 2 years ago oembed.php 2 years ago paragraph.php 2 years ago password.php 3 years ago phone.php 3 years ago pick.php 2 years ago slug.php 3 years ago taxonomy.php 4 years ago text.php 2 years ago time.php 2 years ago website.php 3 years ago wysiwyg.php 2 years ago
oembed.php
522 lines
1 <?php
2
3 /**
4 * @package Pods\Fields
5 */
6 class PodsField_OEmbed extends PodsField {
7
8 /**
9 * {@inheritdoc}
10 */
11 public static $group = 'Relationships / Media';
12
13 /**
14 * {@inheritdoc}
15 */
16 public static $type = 'oembed';
17
18 /**
19 * {@inheritdoc}
20 */
21 public static $label = 'oEmbed';
22
23 /**
24 * {@inheritdoc}
25 */
26 public static $prepare = '%s';
27
28 /**
29 * Available oEmbed providers
30 *
31 * @var array
32 * @since 2.7.0
33 */
34 private $providers = array();
35
36 /**
37 * Current embed width
38 *
39 * @var int
40 * @since 2.7.0
41 */
42 private $width = 0;
43
44 /**
45 * Current embed height
46 *
47 * @var int
48 * @since 2.7.0
49 */
50 private $height = 0;
51
52 /**
53 * {@inheritdoc}
54 */
55 public function setup() {
56
57 static::$group = __( 'Relationships / Media', 'pods' );
58 static::$label = __( 'oEmbed', 'pods' );
59 }
60
61 /**
62 * {@inheritdoc}
63 */
64 public function admin_init() {
65
66 // AJAX for Uploads
67 add_action( 'wp_ajax_oembed_update_preview', array( $this, 'admin_ajax_oembed_update_preview' ) );
68 }
69
70 /**
71 * {@inheritdoc}
72 */
73 public function options() {
74
75 $options = array(
76 static::$type . '_width' => array(
77 'label' => __( 'Embed Width', 'pods' ),
78 'default' => 0,
79 'type' => 'number',
80 'help' => __( 'Optional width to use for this oEmbed. Leave as 0 (zero) to default to none.', 'pods' ),
81 ),
82 static::$type . '_height' => array(
83 'label' => __( 'Embed Height', 'pods' ),
84 'default' => 0,
85 'type' => 'number',
86 'help' => __( 'Optional height to use for this oEmbed. Leave as 0 (zero) to default to none.', 'pods' ),
87 ),
88 static::$type . '_show_preview' => array(
89 'label' => __( 'Show preview', 'pods' ),
90 'default' => 0,
91 'type' => 'boolean',
92 ),
93 );
94
95 // Get all unique provider host names
96 $unique_providers = array();
97 foreach ( $this->get_providers() as $provider ) {
98 if ( ! in_array( $provider['host'], $unique_providers, true ) ) {
99 $unique_providers[] = $provider['host'];
100 }
101 }
102 sort( $unique_providers );
103
104 // Only add the options if we have data
105 if ( ! empty( $unique_providers ) ) {
106 $options[ static::$type . '_restrict_providers' ] = array(
107 'label' => __( 'Restrict to providers', 'pods' ),
108 'help' => __( 'Restrict input to specific WordPress oEmbed compatible providers.', 'pods' ),
109 'type' => 'boolean',
110 'default' => 0,
111 'dependency' => true,
112 );
113 $options[ static::$type . '_enable_providers' ] = array(
114 'label' => __( 'Select enabled providers', 'pods' ),
115 'type' => 'boolean_group',
116 'depends-on' => array( static::$type . '_restrict_providers' => true ),
117 'boolean_group' => array(),
118 );
119 // Add all the oEmbed providers
120 foreach ( $unique_providers as $provider ) {
121 $options[ static::$type . '_enable_providers' ]['boolean_group'][ static::$type . '_enabled_providers_' . tag_escape( $provider ) ] = array(
122 'label' => $provider,
123 'type' => 'boolean',
124 'default' => 0,
125 );
126 }
127 }//end if
128
129 return $options;
130 }
131
132 /**
133 * {@inheritdoc}
134 */
135 public function schema( $options = null ) {
136
137 $schema = 'LONGTEXT';
138
139 return $schema;
140 }
141
142 /**
143 * {@inheritdoc}
144 */
145 public function display( $value = null, $name = null, $options = null, $pod = null, $id = null ) {
146 $value = $this->pre_save( $value, $id, $name, $options, null, $pod );
147
148 $width = (int) pods_v( static::$type . '_width', $options );
149 $height = (int) pods_v( static::$type . '_height', $options );
150 $args = array();
151 if ( $width > 0 ) {
152 $args['width'] = $width;
153 }
154 if ( $height > 0 ) {
155 $args['height'] = $height;
156 }
157
158 return wp_oembed_get( $value, $args );
159 }
160
161 /**
162 * {@inheritdoc}
163 */
164 public function input( $name, $value = null, $options = null, $pod = null, $id = null ) {
165
166 $options = ( is_array( $options ) || is_object( $options ) ) ? $options : (array) $options;
167 $form_field_type = PodsForm::$field_type;
168
169 $value = $this->normalize_value_for_input( $value, $options );
170
171 if ( isset( $options['name'] ) && ! pods_permission( $options ) ) {
172 if ( pods_v( 'read_only', $options, false ) ) {
173 $options['readonly'] = true;
174 } else {
175 return;
176 }
177 } elseif ( ! pods_has_permissions( $options ) && pods_v( 'read_only', $options, false ) ) {
178 $options['readonly'] = true;
179 }
180
181 if ( ! empty( $options['disable_dfv'] ) ) {
182 return pods_view( PODS_DIR . 'ui/fields/oembed.php', compact( array_keys( get_defined_vars() ) ) );
183 }
184
185 $type = pods_v( 'type', $options, static::$type );
186
187 $args = compact( array_keys( get_defined_vars() ) );
188 $args = (object) $args;
189
190 $this->render_input_script( $args );
191 }
192
193 /**
194 * {@inheritdoc}
195 */
196 public function validate( $value, $name = null, $options = null, $fields = null, $pod = null, $id = null, $params = null ) {
197 $validate = parent::validate( $value, $name, $options, $fields, $pod, $id, $params );
198
199 $errors = array();
200
201 if ( is_array( $validate ) ) {
202 $errors = $validate;
203 }
204
205 $check = $this->pre_save( $value, $id, $name, $options, $fields, $pod, $params );
206
207 if ( is_array( $check ) ) {
208 $errors = $check;
209 } else {
210 if ( 0 < strlen( $value ) && '' === $check ) {
211 if ( $this->is_required( $options ) ) {
212 $errors[] = __( 'This field is required.', 'pods' );
213 }
214 }
215 }
216
217 if ( ! empty( $errors ) ) {
218 return $errors;
219 }
220
221 return $validate;
222 }
223
224 /**
225 * {@inheritdoc}
226 */
227 public function pre_save( $value, $id = null, $name = null, $options = null, $fields = null, $pod = null, $params = null ) {
228 $value = $this->strip_html( $value, $options );
229 $value = $this->strip_shortcodes( $value, $options );
230 $value = $this->trim_whitespace( $value, $options );
231
232 // Only allow ONE URL
233 if ( ! empty( $value ) ) {
234 $value = explode( ' ', $value );
235 $value = esc_url( $value[0] );
236 }
237
238 if ( $this->validate_provider( $value, $options ) ) {
239 return $value;
240 } else {
241 return false;
242 }
243
244 }
245
246 /**
247 * {@inheritdoc}
248 */
249 public function ui( $id, $value, $name = null, $options = null, $fields = null, $pod = null ) {
250
251 $value = $this->pre_save( $value, $id, $name, $options, $fields, $pod );
252
253 return $value;
254 }
255
256 /**
257 * {@inheritdoc}
258 */
259 public function strip_html( $value, $options = null ) {
260
261 if ( is_array( $value ) ) {
262 // @codingStandardsIgnoreLine
263 $value = @implode( ' ', $value );
264 }
265
266 $value = trim( $value );
267
268 if ( empty( $value ) ) {
269 return $value;
270 }
271
272 // Strip HTML
273 $value = wp_strip_all_tags( $value );
274
275 // Strip shortcodes
276 $value = strip_shortcodes( $value );
277
278 return $value;
279 }
280
281 /**
282 * Passes any unlinked URLs that are on their own line to {@link WP_Embed::shortcode()} for potential embedding.
283 *
284 * @see WP_Embed::autoembed()
285 * @see WP_Embed::autoembed_callback()
286 *
287 * @uses PodsField_OEmbed::autoembed_callback()
288 *
289 * @param string $content The content to be searched.
290 *
291 * @return string Potentially modified $content.
292 *
293 * @since 2.7.0
294 */
295 public function autoembed( $content ) {
296
297 // Replace line breaks from all HTML elements with placeholders.
298 $content = wp_replace_in_html_tags( $content, array( "\n" => '<!-- wp-line-break -->' ) );
299
300 // Find URLs that are on their own line.
301 $content = preg_replace_callback(
302 '|^(\s*)(https?://[^\s"]+)(\s*)$|im', array(
303 $this,
304 'autoembed_callback',
305 ), $content
306 );
307
308 // Put the line breaks back.
309 return str_replace( '<!-- wp-line-break -->', "\n", $content );
310
311 }
312
313 /**
314 * Callback function for {@link WP_Embed::autoembed()}.
315 *
316 * @param array $match A regex match array.
317 *
318 * @return string The embed shortcode
319 *
320 * @since 2.7.0
321 */
322 public function autoembed_callback( $match ) {
323
324 $shortcode = '[embed width="' . $this->width . '" height="' . $this->height . '"]' . $match[2] . '[/embed]';
325
326 return $shortcode;
327
328 }
329
330 /**
331 * Get a list of available providers from the WP_oEmbed class
332 *
333 * @see wp-includes/class-oembed.php
334 * @return array $providers {
335 * Array of provider data with regex as key
336 *
337 * @type string URL for this provider
338 * @type int
339 * @type string Hostname for this provider
340 * }
341 *
342 * @since 2.7.0
343 */
344 public function get_providers() {
345
346 // Return class property if already set
347 if ( ! empty( $this->providers ) ) {
348 return $this->providers;
349 }
350
351 if ( ! class_exists( 'WP_oEmbed' ) && file_exists( ABSPATH . WPINC . '/class-oembed.php' ) ) {
352 require_once ABSPATH . WPINC . '/class-oembed.php';
353 }
354
355 // Return an empty array if no providers could be found
356 $providers = array();
357
358 if ( function_exists( '_wp_oembed_get_object' ) ) {
359 $wp_oembed = _wp_oembed_get_object();
360 $providers = $wp_oembed->providers;
361
362 foreach ( $providers as $key => $provider ) {
363 $url = wp_parse_url( $provider[0] );
364 $host = $url['host'];
365 $tmp = explode( '.', $host );
366
367 if ( count( $tmp ) === 3 ) {
368 // Take domain names like .co.uk in consideration
369 if ( ! in_array( 'co', $tmp, true ) ) {
370 unset( $tmp[0] );
371 }
372 } elseif ( count( $tmp ) === 4 ) {
373 // Take domain names like .co.uk in consideration
374 unset( $tmp[0] );
375 }
376
377 $host = implode( '.', $tmp );
378
379 $providers[ $key ]['host'] = $host;
380 }
381
382 $this->providers = $providers;
383 }//end if
384
385 return $providers;
386
387 }
388
389 /**
390 * Takes a URL and returns the corresponding oEmbed provider's URL, if there is one.
391 *
392 * @since 2.7.0
393 * @access public
394 *
395 * @see WP_oEmbed::get_provider()
396 *
397 * @param string $url The URL to the content.
398 * @param string|array $args Optional provider arguments.
399 *
400 * @return false|string False on failure, otherwise the oEmbed provider URL.
401 */
402 public function get_provider( $url, $args = array() ) {
403
404 if ( ! class_exists( 'WP_oEmbed' ) && file_exists( ABSPATH . WPINC . '/class-oembed.php' ) ) {
405 require_once ABSPATH . WPINC . '/class-oembed.php';
406 }
407
408 if ( function_exists( '_wp_oembed_get_object' ) ) {
409 $wp_oembed = _wp_oembed_get_object();
410
411 if ( is_callable( array( $wp_oembed, 'get_provider' ) ) ) {
412 return $wp_oembed->get_provider( $url, $args );
413 }
414 }
415
416 return false;
417 }
418
419 /**
420 * Validate a value with the enabled oEmbed providers (if required).
421 *
422 * @since 2.7.0
423 *
424 * @param string $value Field value.
425 * @param array $options Field options.
426 *
427 * @return bool
428 */
429 public function validate_provider( $value, $options ) {
430
431 // Check if we need to validate.
432 if ( 0 === (int) pods_v( static::$type . '_restrict_providers', $options ) ) {
433 return true;
434 }
435
436 $providers = $this->get_providers();
437
438 // Filter existing providers.
439 foreach ( $providers as $key => $provider ) {
440 $fieldname = static::$type . '_enabled_providers_' . tag_escape( $provider['host'] );
441
442 /**
443 * @todo Future compat to enable serialised strings as field options
444 */
445
446 /**
447 * Current solution: all separate field options.
448 */
449 if ( empty( $options[ $fieldname ] ) ) {
450 unset( $providers[ $key ] );
451 }
452 }
453
454 // Value validation.
455 $provider_match = $this->get_provider( $value );
456
457 foreach ( $providers as $match => $provider ) {
458 if ( $provider_match === $match ) {
459 return true;
460 }
461 }
462
463 return false;
464 }
465
466 /**
467 * Handle update preview AJAX.
468 *
469 * @since 2.7.0
470 */
471 public function admin_ajax_oembed_update_preview() {
472
473 // Sanitize input.
474 // @codingStandardsIgnoreLine
475 $params = pods_unslash( (array) $_POST );
476
477 if ( ! empty( $params['_nonce_pods_oembed'] ) && ! empty( $params['pods_field_oembed_value'] ) && wp_verify_nonce( $params['_nonce_pods_oembed'], 'pods_field_oembed_preview' ) ) {
478 $name = '';
479 $value = '';
480 $options = array();
481
482 if ( ! empty( $params['pods_field_oembed_name'] ) ) {
483 $name = $params['pods_field_oembed_name'];
484 }
485
486 if ( ! empty( $params['pods_field_oembed_value'] ) ) {
487 $value = $params['pods_field_oembed_value'];
488 $value = $this->strip_html( $value );
489 $value = $this->strip_shortcodes( $value );
490 $value = $this->trim_whitespace( $value );
491 }
492
493 if ( ! empty( $params['pods_field_oembed_options'] ) ) {
494 $options = $params['pods_field_oembed_options'];
495 }
496
497 // Load the field to get it's options.
498 $options = pods_api()->load_field( $options );
499
500 // Field options are stored here, if not, just stay with the full options array.
501 if ( ! empty( $options['options'] ) ) {
502 $options = $options['options'];
503 }
504
505 // Run display function to run oEmbed.
506 $value = $this->display( $value, $name, $options );
507
508 if ( empty( $value ) ) {
509 $value = __( 'Please choose a valid oEmbed URL.', 'pods' );
510 wp_send_json_error( $value );
511 } else {
512 wp_send_json_success( $value );
513 }
514 }//end if
515 wp_send_json_error( __( 'Unauthorized request', 'pods' ) );
516
517 die();
518 // Kill it!
519 }
520
521 }
522