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