PluginProbe ʕ •ᴥ•ʔ
Presto Player / 4.3.1
Presto Player v4.3.1
4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / inc / Services / Shortcodes.php
presto-player / inc / Services Last commit date
API 1 month ago Blocks 10 months ago License 1 month ago AdminNotice.php 3 weeks ago AdminNotices.php 3 weeks ago AjaxActions.php 3 weeks ago Blocks.php 1 year ago Compatibility.php 10 months ago Learn.php 1 month ago Menu.php 1 month ago Migrations.php 1 year ago NpsSurvey.php 5 months ago Onboarding.php 3 weeks ago Player.php 4 days ago PluginInstaller.php 1 month ago PreloadService.php 1 year ago ProCompatibility.php 1 month ago ReusableVideos.php 2 weeks ago RewriteRulesManager.php 1 year ago Scripts.php 2 weeks ago Settings.php 1 month ago Shortcodes.php 1 month ago Streamer.php 3 weeks ago Translation.php 3 weeks ago Usage.php 3 weeks ago VideoPostType.php 2 weeks ago
Shortcodes.php
632 lines
1 <?php
2 /**
3 * Shortcodes service file.
4 *
5 * @package PrestoPlayer\Services
6 */
7
8 namespace PrestoPlayer\Services;
9
10 use PrestoPlayer\Blocks\AudioBlock;
11 use PrestoPlayer\Pro\Blocks\PlaylistBlock;
12 use PrestoPlayer\Models\Video;
13 use PrestoPlayer\Blocks\VimeoBlock;
14 use PrestoPlayer\Blocks\YouTubeBlock;
15 use PrestoPlayer\Blocks\SelfHostedBlock;
16 use PrestoPlayer\Models\ReusableVideo;
17 use PrestoPlayer\Services\ReusableVideos;
18 use PrestoPlayer\Support\Block;
19 use PrestoPlayer\Pro\Blocks\BunnyCDNBlock;
20 use PrestoPlayer\Plugin;
21
22 /**
23 * Shortcodes service.
24 *
25 * @package PrestoPlayer\Services
26 */
27 class Shortcodes {
28
29 /**
30 * Register shortcodes.
31 *
32 * @return void
33 */
34 public function register() {
35 add_shortcode( 'presto_player_chapter', '__return_false' );
36 add_shortcode( 'presto_playlist_item', '__return_false' );
37 add_shortcode( 'presto_player_overlay', '__return_false' );
38 add_shortcode( 'presto_player_track', '__return_false' );
39 add_shortcode( 'presto_player', array( $this, 'playerShortcode' ), 10, 2 );
40 add_shortcode( 'presto_timestamp', array( $this, 'timestampShortcode' ), 10, 2 );
41 add_shortcode( 'pptime', array( $this, 'timestampShortcode' ), 10, 2 );
42 add_shortcode( 'presto_playlist', array( $this, 'playlistShortcode' ), 10, 2 );
43 add_shortcode( 'presto_popup', array( $this, 'popupShortcode' ), 10, 2 );
44 }
45
46 /**
47 * Do the shortcode
48 *
49 * @param array $atts Array of shortcode attributes.
50 * @param string $content String of content.
51 * @return void|string
52 */
53 public function playerShortcode( $atts, $content ) {
54 if ( ! is_admin() ) {
55 // global is the most reliable between page builders.
56 global $load_presto_js;
57 $load_presto_js = true;
58 ( new Scripts() )->blockAssets(); // Enqueue block assets.
59 }
60
61 $atts = shortcode_atts(
62 array(
63 'id' => '',
64 'src' => '',
65 'title' => '',
66 'provider' => '',
67 'class' => '',
68 'custom_field' => '',
69 'poster' => '',
70 'preload' => 'auto',
71 'preset' => 0,
72 'autoplay' => false,
73 'plays_inline' => false,
74 'chapters' => array(),
75 'overlays' => array(),
76 'muted_autoplay_preview' => false,
77 'muted_autoplay_caption_preview' => false,
78 'ratio' => 'original',
79 ),
80 $atts
81 );
82
83 // could not find source but ID is present.
84 if ( ! $atts['src'] && ! $atts['custom_field'] && $atts['id'] ) {
85 $fallback = $this->maybeUnauthorizedFallback( $atts['id'] );
86 if ( false !== $fallback ) {
87 return $fallback;
88 }
89 return ReusableVideos::getBlock( $atts['id'] );
90 }
91
92 $atts = $this->parseAttributes( $atts, $content );
93 return $this->renderBlock( $atts );
94 }
95
96 /**
97 * Do the shortcode
98 *
99 * @param array $atts Array of shortcode attributes.
100 * @param string $content String of content.
101 * @return void|string
102 */
103 public function playlistShortcode( $atts, $content ) {
104 if ( ! is_admin() ) {
105 // global is the most reliable between page builders.
106 global $load_presto_js;
107 $load_presto_js = true;
108 ( new Scripts() )->blockAssets(); // enqueue block assets.
109 }
110
111 $atts = $this->parsePlaylistAttributes( $atts, $content );
112
113 return ( new PlaylistBlock() )->html( $atts );
114 }
115
116 /**
117 * Timestamp shortcode.
118 *
119 * @param array $atts Shortcode attributes.
120 * @param string $content Content inside shortcode.
121 * @return string
122 */
123 public function timestampShortcode( $atts, $content ) {
124 $atts = shortcode_atts(
125 array(
126 'time' => '',
127 ),
128 $atts
129 );
130 return '<presto-timestamp time="' . esc_attr( $atts['time'] ) . '">' . $content . '</presto-timestamp>';
131 }
132
133 /**
134 * Popup shortcode.
135 *
136 * @param array $atts Shortcode attributes.
137 * @param string $content Content inside shortcode.
138 * @return string
139 */
140 public function popupShortcode( $atts, $content ) {
141 $atts = shortcode_atts(
142 array(
143 'media_id' => '',
144 'image_url' => '',
145 'button_text' => '',
146 ),
147 $atts
148 );
149
150 if ( empty( $atts['media_id'] ) ) {
151 return '';
152 }
153
154 // Get the popup block content.
155 $popup_block_content = $this->popupBlockContent( $atts, $content );
156
157 // Return the processed block markup.
158 return $this->getProcessedBlockHtml( $popup_block_content );
159 }
160
161 /**
162 * Generate complete popup block content including trigger.
163 *
164 * @param array $atts Shortcode attributes.
165 * @param string $content Content between shortcode tags.
166 * @return string
167 */
168 private function popupBlockContent( $atts, $content ) {
169 $trigger_content = '';
170
171 // Image trigger.
172 if ( ! empty( $atts['image_url'] ) ) {
173 // Use core/image for non-premium users, core/cover for premium users.
174 if ( ! Plugin::hasRequiredProVersion( 'popups' ) ) {
175 // For non-premium users, use the popup-image-trigger variation of core/image.
176 $trigger_content .= '<!-- wp:image {"url":"' . esc_url( $atts['image_url'] ) . '","className":"presto-popup-image-trigger","style":{"aspectRatio":"16/9","border":{"radius":"5px"}},"width":"100%","height":"auto","sizeSlug":"large"} -->
177 <figure class="wp-block-image size-large presto-popup-image-trigger" style="aspect-ratio:16/9;border-radius:5px;width:100%"><img src="' . esc_url( $atts['image_url'] ) . '" alt="" style="width:100%;height:auto"/></figure>
178 <!-- /wp:image -->';
179 } else {
180 // For premium users, use core/cover block with overlay and play button.
181 $play_button_url = PRESTO_PLAYER_PLUGIN_URL . 'img/play-button.svg';
182 $trigger_content .= '<!-- wp:cover {"url":"' . esc_url( $atts['image_url'] ) . '","className":"presto-popup-cover-trigger","customOverlayColor":"#131313","isUserOverlayColor":true,"dimRatio":50,"minHeight":336,"minHeightUnit":"px","contentPosition":"center center","layout":{"type":"constrained"},"style":{"aspectRatio":"16/9","border":{"radius":"5px"}}} -->
183 <div class="wp-block-cover presto-popup-cover-trigger" style="border-radius:5px;aspect-ratio:16/9;min-height:336px"><span aria-hidden="true" class="wp-block-cover__background has-background-dim has-background-dim-50" style="background-color:#131313"></span><div class="wp-block-cover__image-background" style="background-image:url(' . esc_url( $atts['image_url'] ) . ');background-position:50% 50%"></div><div class="wp-block-cover__inner-container"><!-- wp:group {"layout":{"type":"flex","flexWrap":"nowrap","justifyContent":"center"}} -->
184 <div class="wp-block-group"><!-- wp:image {"url":"' . $play_button_url . '","alt":"","width":"48px","height":"auto","sizeSlug":"large","align":"center","className":"is-style-default","style":{"color":{"duotone":"unset"}}} -->
185 <figure class="wp-block-image aligncenter size-large is-style-default" style="width:48px"><img src="' . esc_url( $play_button_url ) . '" alt="" style="width:48px;height:auto"/></figure>
186 <!-- /wp:image --></div>
187 <!-- /wp:group --></div></div>
188 <!-- /wp:cover -->';
189 }
190 }
191
192 // Button trigger.
193 if ( ! empty( $atts['button_text'] ) ) {
194 $trigger_content .= '<!-- wp:buttons -->
195 <div class="wp-block-buttons"><!-- wp:button -->
196 <div class="wp-block-button"><a class="wp-block-button__link wp-element-button">' . esc_html( $atts['button_text'] ) . '</a></div>
197 <!-- /wp:button --></div>
198 <!-- /wp:buttons -->';
199 }
200
201 // Custom content.
202 if ( ! empty( $content ) ) {
203 $trigger_content .= $content;
204 }
205
206 // Return complete popup block with trigger and media.
207 return '<!-- wp:presto-player/popup {"popupId":"' . (int) $atts['media_id'] . '"} -->
208 <div class="wp-block-presto-player-popup"><!-- wp:presto-player/popup-trigger -->
209 <div class="wp-block-presto-player-popup-trigger">' . $trigger_content . '</div>
210 <!-- /wp:presto-player/popup-trigger -->
211
212 <!-- wp:presto-player/popup-media -->
213 <div class="wp-block-presto-player-popup-media"><!-- wp:presto-player/reusable-display {"id":' . (int) $atts['media_id'] . '} -->
214 <div class="wp-block-presto-player-reusable-display"></div>
215 <!-- /wp:presto-player/reusable-display --></div>
216 <!-- /wp:presto-player/popup-media --></div>
217 <!-- /wp:presto-player/popup -->';
218 }
219
220 /**
221 * Parse playlist attributes.
222 *
223 * @param array $atts Shortcode attributes.
224 * @param string $content Content inside shortcode.
225 * @return array
226 */
227 public function parsePlaylistAttributes( $atts, $content = '' ) {
228
229 // backwards compat.
230 $atts['listTextPlural'] = $atts['listtextplural'] ?? null;
231 $atts['listTextSingular'] = $atts['listtextplural'] ?? null;
232 $atts['transitionDuration'] = $atts['transitionduration'] ?? null;
233
234 $atts = shortcode_atts(
235 array(
236 'heading' => __( 'Playlist', 'presto-player' ),
237 'listTextPlural' => __( 'Videos', 'presto-player' ),
238 'listTextSingular' => __( 'Video', 'presto-player' ),
239 'transitionDuration' => 5,
240 'styles' => '',
241 ),
242 $atts
243 );
244
245 $atts['items'] = $this->getPlaylistItems( $content );
246
247 return $atts;
248 }
249
250 /**
251 * Parse attributes.
252 *
253 * @param array $atts Shortcode attributes.
254 * @param string $content Content inside shortcode.
255 * @return array
256 */
257 public function parseAttributes( $atts, $content = '' ) {
258 $atts = shortcode_atts(
259 array(
260 'id' => '',
261 'src' => '',
262 'title' => '',
263 'provider' => '',
264 'class' => '',
265 'custom_field' => '',
266 'poster' => '',
267 'preload' => 'auto',
268 'preset' => 0,
269 'autoplay' => false,
270 'plays_inline' => false,
271 'chapters' => array(),
272 'overlays' => array(),
273 'muted_autoplay_preview' => false,
274 'muted_autoplay_caption_preview' => false,
275 'ratio' => 'original',
276 ),
277 $atts
278 );
279
280 if ( ! $atts['id'] && ! $atts['src'] && ! $atts['custom_field'] ) {
281 return array();
282 }
283
284 // custom field as a src.
285 if ( $atts['custom_field'] ) {
286 $atts['src'] = get_post_meta( get_the_ID(), $atts['custom_field'], true );
287
288 // Compatibility for file input field type from Advanced custom field plugin.
289 if ( function_exists( 'get_field' ) ) {
290 // phpcs:disable-next-line Generic.Functions.CallTimePassByReference.NotAllowed
291 $custom_field = \get_field( $atts['custom_field'] );
292 if ( $custom_field ) {
293 switch ( gettype( $custom_field ?? null ) ) {
294 case 'array':
295 $atts['src'] = $custom_field['url'] ?? '';
296 break;
297 case 'integer':
298 $atts['src'] = wp_get_attachment_url( $custom_field ) ?? '';
299 break;
300 case 'string':
301 $atts['src'] = $custom_field;
302 break;
303 }
304 }
305 }
306 }
307
308 // get provider based on src, if not provided.
309 $atts['provider'] = ! $atts['provider'] ? $this->getProvider( $atts['src'] ) : $atts['provider'];
310
311 $atts['id'] = $this->getOrCreateVideoId( $atts );
312 $atts['chapters'] = $this->getChapters( $content );
313 $atts['overlays'] = $this->getOverlays( $content );
314 $atts['tracks'] = $this->getTracks( $content );
315 $atts['playsInline'] = (bool) $atts['plays_inline'];
316 $atts['mutedPreview'] = array(
317 'enabled' => (bool) $atts['muted_autoplay_preview'],
318 'captions' => (bool) $atts['muted_autoplay_caption_preview'],
319 );
320 $atts['className'] = sanitize_html_class( $atts['class'] );
321
322 unset( $atts['plays_inline'] );
323 unset( $atts['muted_autoplay_preview'] );
324 unset( $atts['muted_autoplay_caption_preview'] );
325 unset( $atts['class'] );
326
327 return $atts;
328 }
329
330 /**
331 * Renders the block with attributes.
332 *
333 * @param array $atts Block attributes.
334 * @return void|string
335 */
336 public function renderBlock( $atts ) {
337 switch ( $atts['provider'] ?? '' ) {
338 case 'self-hosted':
339 return ( new SelfHostedBlock() )->html( $atts, '' );
340
341 case 'youtube':
342 return ( new YouTubeBlock() )->html( $atts, '' );
343
344 case 'vimeo':
345 return ( new VimeoBlock() )->html( $atts, '' );
346
347 case 'bunny':
348 return ( new BunnyCDNBlock() )->html( $atts, '' );
349
350 case 'audio':
351 return ( new AudioBlock() )->html( $atts, '' );
352 }
353 }
354
355 /**
356 * Get or create video id for analytics.
357 *
358 * @param array $atts Block attributes.
359 * @return int
360 */
361 public function getOrCreateVideoId( $atts ) {
362 $create = array(
363 'src' => $atts['src'],
364 'type' => $atts['provider'],
365 );
366 if ( ! empty( $atts['title'] ) ) {
367 $create['title'] = $atts['title'];
368 }
369
370 $video = new Video();
371 $model = $video->getOrCreate(
372 array( 'src' => $atts['src'] ),
373 $create
374 );
375
376 $model = $model->toObject();
377 return ! empty( $model->id ) ? $model->id : 0;
378 }
379
380 /**
381 * Get chapters from shortcodes.
382 *
383 * @param string $content Content inside shortcode.
384 * @return array
385 */
386 public function getChapters( $content ) {
387 $chapters = $this->getShortcodesAtts(
388 'presto_player_chapter',
389 $content,
390 array(
391 'time' => '00:00',
392 'title' => '',
393 )
394 );
395 foreach ( (array) $chapters as $key => $chapter ) {
396 if ( ! strpos( $chapter['time'], ':' ) ) {
397 $chapters[ $key ]['time'] = '00:' . $chapter['time'];
398 }
399 }
400
401 return $chapters;
402 }
403
404 /**
405 * Get playlist items from shortcodes.
406 *
407 * @param string $content Content inside shortcode.
408 * @return array
409 */
410 public function getPlaylistItems( $content ) {
411 $items = $this->getShortcodesAtts(
412 'presto_playlist_item',
413 $content,
414 array(
415 'duration' => '00:00',
416 'title' => '',
417 'id' => 0,
418 )
419 );
420 foreach ( $items as $key => $item ) {
421 $video_details = ( new ReusableVideo( $item['id'] ) )->getAttributes();
422 $items[ $key ] = array(
423 'id' => $items[ $key ]['id'],
424 'config' => $video_details,
425 'duration' => $items[ $key ]['duration'],
426 'title' => $items[ $key ]['title'],
427 );
428 }
429 return $items;
430 }
431
432 /**
433 * Get overlays from shortcodes.
434 *
435 * @param string $content Content inside shortcode.
436 * @return array
437 */
438 public function getOverlays( $content ) {
439
440 $overlays = $this->getShortcodesAtts(
441 'presto_player_overlay',
442 $content,
443 array(
444 'start_time' => '00:00',
445 'end_time' => '',
446 'text' => '',
447 'link' => array(),
448 'position' => '',
449 )
450 );
451 foreach ( (array) $overlays as $key => $overlay ) {
452 if ( ! strpos( $overlay['start_time'], ':' ) ) {
453 $overlays[ $key ]['startTime'] = '00:' . $overlay['start_time'];
454 } else {
455 $overlays[ $key ]['startTime'] = $overlay['start_time'];
456 }
457
458 if ( ! strpos( $overlay['end_time'], ':' ) ) {
459 $overlays[ $key ]['endTime'] = '00:' . $overlay['end_time'];
460 } else {
461 $overlays[ $key ]['endTime'] = $overlay['end_time'];
462 }
463
464 $overlays[ $key ]['link']['url'] = esc_url_raw( $overlay['link_url'] );
465 $overlays[ $key ]['link']['opensInNewTab'] = (bool) $overlay['link_new_tab'];
466
467 unset( $overlays[ $key ]['link_url'] );
468 unset( $overlays[ $key ]['link_new_tab'] );
469 unset( $overlays[ $key ]['start_time'] );
470 unset( $overlays[ $key ]['end_time'] );
471 }
472 return $overlays;
473 }
474
475 /**
476 * Get tracks from shortcodes.
477 *
478 * @param string $content Content inside shortcode.
479 * @return array
480 */
481 public function getTracks( $content ) {
482 return $this->getShortcodesAtts(
483 'presto_player_track',
484 $content,
485 array(
486 'label' => '',
487 'src' => '',
488 'srclang' => '',
489 )
490 );
491 }
492
493 /**
494 * Get specific shortcode atts from content.
495 *
496 * @param string $name Name of shortcode.
497 * @param string $content Page content.
498 * @param array $defaults Defaults for each shortcode.
499 * @return array
500 */
501 public function getShortcodesAtts( $name, $content, $defaults = array() ) {
502 $items = array();
503
504 // if shortcode exists.
505 if (
506 preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches )
507 && array_key_exists( 2, $matches )
508 && in_array( $name, $matches[2], true )
509 ) {
510 foreach ( (array) $matches[0] as $key => $value ) {
511 if ( strpos( $value, $name ) !== false ) {
512 $items[] = wp_parse_args(
513 shortcode_parse_atts( $matches[3][ $key ] ),
514 $defaults
515 );
516 }
517 }
518 }
519
520 return $items;
521 }
522
523 /**
524 * Pre-render gate for the player shortcode.
525 *
526 * The shortcode `[presto_player id=X]` renders the underlying Media Hub
527 * post directly via ReusableVideos::getBlock(). That bypasses the
528 * normal singular-post visibility check WordPress applies when you
529 * visit the Media Hub permalink — so a Media Hub item set to Private
530 * was leaking through the shortcode.
531 *
532 * This method short-circuits the shortcode with the standard
533 * "Please login for access" curtain whenever the referenced
534 * pp_video_block post is non-public AND the current user cannot read
535 * it. We defer to current_user_can( 'read_post', $id ) so WP's
536 * map_meta_cap chain stays in charge — site owners and capability
537 * plugins (membership, LMS) keep full control without us inventing
538 * a parallel filter.
539 *
540 * @param int|string $id Media Hub post ID supplied to the shortcode.
541 * @return string|false Curtain HTML to short-circuit, or false to continue.
542 */
543 public function maybeUnauthorizedFallback( $id ) {
544 $reusable = new ReusableVideo( (int) $id );
545 $visibility = $reusable->getMediaHubPostVisibility();
546
547 // Not a Media Hub post — let the normal flow handle it.
548 if ( null === $visibility ) {
549 return false;
550 }
551
552 // Public statuses (publish) are viewable by anyone — fast path.
553 $status_obj = get_post_status_object( $visibility );
554 if ( $status_obj && $status_obj->public ) {
555 return false;
556 }
557
558 // Non-public status — defer to WP's standard post-visibility check
559 // so admins/editors and capability plugins still pass through.
560 if ( current_user_can( 'read_post', $reusable->post->ID ) ) {
561 return false;
562 }
563
564 return ( new Block() )->getFallbackHTMLForUnauthorizeAccess();
565 }
566
567 /**
568 * Maybe switch provider if the url is overridden.
569 *
570 * @param string $src Source URL.
571 * @return string
572 */
573 protected function getProvider( $src ) {
574 $provider = 'self-hosted';
575
576 if ( ! empty( $src ) ) {
577 $filetype = wp_check_filetype( $src );
578 if ( isset( $filetype['type'] ) && false !== strpos( $filetype['type'], 'audio' ) ) {
579 return 'audio';
580 }
581
582 $yt_rx = '/^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/';
583 $has_match_youtube = preg_match( $yt_rx, $src, $yt_matches );
584
585 if ( $has_match_youtube ) {
586 return 'youtube';
587 }
588
589 $vm_rx = '/(https?:\/\/)?(www\.)?(player\.)?vimeo\.com\/([a-z]*\/)*([‌​0-9]{6,11})[?]?.*/';
590 $has_match_vimeo = preg_match( $vm_rx, $src, $vm_matches );
591
592 if ( $has_match_vimeo ) {
593 return 'vimeo';
594 }
595
596 if ( strpos( $src, 'https://vz-' ) !== false && strpos( $src, 'b-cdn.net' ) !== false ) {
597 return 'bunny';
598 }
599 }
600
601 return $provider;
602 }
603
604 /**
605 * Returns the markup for the current block.
606 *
607 * @param string $content Block content.
608 * @global WP_Embed $wp_embed
609 *
610 * @return string Block markup.
611 */
612 public function getProcessedBlockHtml( $content ) {
613 global $wp_embed;
614
615 if ( ! $content ) {
616 return;
617 }
618
619 $content = $wp_embed->run_shortcode( $content );
620 $content = $wp_embed->autoembed( $content );
621 $content = do_blocks( $content );
622 $content = wptexturize( $content );
623 $content = convert_smilies( $content );
624 $content = shortcode_unautop( $content );
625 $content = wp_filter_content_tags( $content, 'template' );
626 $content = do_shortcode( $content );
627 $content = str_replace( ']]>', ']]&gt;', $content );
628
629 return $content;
630 }
631 }
632