index of
/
home
/
thefkyzp
/
hulmvisaadvisor.com
/
wp-content
/
plugins
/
presto-player
/
inc
/
Support
/
File: /home/thefkyzp/hulmvisaadvisor.com/wp-content/plugins/presto-player/inc/Support/Block.php
<?php /** * Block support for Presto Player. * * @package PrestoPlayer */ namespace PrestoPlayer\Support; use PrestoPlayer\Models\Video; use PrestoPlayer\Models\Player; use PrestoPlayer\Models\Preset; use PrestoPlayer\Models\AudioPreset; use PrestoPlayer\Models\Setting; use PrestoPlayer\Support\DynamicData; use PrestoPlayer\Integrations\LearnDash\LearnDash; use PrestoPlayer\Services\PreloadService; /** * Base block class */ class Block { /** * The block name (slug) * * @var string */ protected $name = ''; /** * The translated block title * * @var string */ protected $title = 'Video'; /** * The template name * * @var string */ protected $template_name = 'video'; /** * Attributes * * @var array */ protected $attributes = array( 'color' => array( 'type' => 'string', 'default' => '#00b3ff', ), 'blockAlignment' => array( 'type' => 'string', ), 'autoplay' => array( 'type' => 'boolean', ), 'id' => array( 'type' => 'number', ), 'src' => array( 'type' => 'string', ), 'imageID' => array( 'type' => 'number', ), 'poster' => array( 'type' => 'string', ), 'content' => array( 'type' => 'boolean', ), 'pip' => array( 'type' => 'boolean', 'default' => true, ), 'fullscreen' => array( 'type' => 'boolean', 'default' => true, ), 'captions' => array( 'type' => 'boolean', 'default' => false, ), 'hideControls' => array( 'type' => 'boolean', 'default' => true, ), 'playLarge' => array( 'type' => 'boolean', 'default' => true, ), 'chapters' => array( 'type' => 'array', 'default' => array(), ), 'overlays' => array( 'type' => 'array', 'default' => array(), ), 'speed' => array( 'type' => 'boolean', 'default' => true, ), ); /** * Attributes to pass to web component * * @var array */ protected $component_attributes = array( 'preset', 'chapters', 'overlays', 'tracks', 'branding', 'blockAttributes', 'config', 'skin', 'analytics', 'automations', 'provider', 'video_id', 'videoAttributes', 'audioAttributes', 'provider_video_id', 'youtube', ); /** * Default attributes for the block. * * @var array */ protected $default_attributes = array( 'playsInline' => true, ); /** * Constructor. * * @param bool $is_premium Whether the plugin is premium. * @param int $version Plugin version. */ public function __construct( bool $is_premium = false, $version = 1 ) { do_action( 'presto_player_before_block_output', array( $this, 'middleware' ) ); } /** * Register the block type * * @return void */ public function register() { $this->registerBlockType(); } /** * Get additional attributes for the block. * * @return array */ public function additionalAttributes() { return array(); } /** * Register dynamic block type. * * @return void */ public function registerBlockType() { register_block_type( "presto-player/$this->name", array( 'attributes' => wp_parse_args( $this->additionalAttributes(), $this->attributes ), 'render_callback' => array( $this, 'html' ), ) ); } /** * Middleware to run before outputting template. * * @param array $attributes Block attributes. * @param string $content Block content. * @return boolean Whether the block should load. */ public function middleware( $attributes, $content ) { return true; } /** * Sanitize attributes function. * * @param array $attributes Block attributes. * @param array $default_config Default configuration. * @return array Sanitized attributes. */ public function sanitizeAttributes( $attributes, $default_config ) { return array(); } /** * Allow overriding attributes. * * @param array $attributes Block attributes. * @return array */ public function overrideAttributes( $attributes ) { return apply_filters( 'presto_video_block_attributes_override', $attributes, $this ); } /** * Must sanitize attributes. * * @param array $attributes Block attributes. * @return array Sanitized attributes. */ private function _sanitizeAttibutes( $attributes ) { // attribute overrides. $attributes = $this->overrideAttributes( $attributes ); // Apply default attributes if not set. $attributes = $this->applyAttributeDefaults( $attributes ); // video id. $id = ! empty( $attributes['id'] ) ? $attributes['id'] : 0; if ( 'audio' === $this->name ) { $preset = $this->getAudioPreset( ! empty( $attributes['preset'] ) ? $attributes['preset'] : 0 ); $preset->type = 'audio'; } else { $preset = $this->getPreset( ! empty( $attributes['preset'] ) ? $attributes['preset'] : 0 ); } $branding = $this->getBranding( $preset ); $class = $this->getClasses( $attributes ); $player_class = $this->getPlayerClasses( $id, $preset ); $styles = $this->getPlayerStyles( $preset, $branding ); $css = $this->getCSS( $id ); $src = ! empty( $attributes['src'] ) ? $attributes['src'] : ''; // use title or source. if ( empty( $attributes['title'] ) ) { $video = $id ? ( new Video( $id ) ) : false; $attributes['title'] = $video ? $video->title : $src; } // Default config. $default_config = apply_filters( 'presto_player/block/default_attributes', array( 'type' => $this->name, 'name' => $this->title, 'css' => wp_kses_post( $css ), 'class' => $class, 'is_hls' => $this->isHls( $src ), 'styles' => $styles, 'skin' => $preset->skin, 'playerClass' => $player_class, 'id' => $id, 'src' => $src, 'autoplay' => ! empty( $attributes['autoplay'] ), 'playsInline' => ! empty( $attributes['playsInline'] ), 'poster' => ! empty( $attributes['poster'] ) ? $attributes['poster'] : '', 'branding' => $branding, 'youtube' => array( 'noCookie' => (bool) Setting::get( 'youtube', 'nocookie' ), 'channelId' => sanitize_text_field( Setting::get( 'youtube', 'channel_id' ) ), 'show_count' => ! empty( $preset->action_bar['show_count'] ), ), 'preload' => ! empty( $attributes['preload'] ) ? $attributes['preload'] : '', 'tracks' => ! empty( $attributes['tracks'] ) ? (array) $attributes['tracks'] : array(), 'preset' => $preset ? $preset->toArray() : array(), 'chapters' => ! empty( $attributes['chapters'] ) ? $attributes['chapters'] : array(), 'overlays' => DynamicData::replaceItems( ! empty( $attributes['overlays'] ) ? $attributes['overlays'] : array(), 'text' ), 'blockAttributes' => $attributes, 'provider' => $this->name, 'analytics' => Setting::get( 'analytics', 'enable', false ), 'automations' => Setting::get( 'performance', 'automations', true ), 'title' => ! empty( $attributes['title'] ) ? html_entity_decode( $attributes['title'] ) : '', ), $attributes ); return wp_parse_args( $this->sanitizeAttributes( $attributes, $default_config ), $default_config ); } /** * Get CSS from settings. * Is it an HLS playlist. * * @param string $src src parameter. * @return boolean */ public function isHls( $src ) { $src = ! empty( $src ) ? $src : ''; return \strpos( $src, '.m3u8' ) !== false; } /** * Get CSS from settings. * Validates before output. * * @param integer $id the video id. * @return string */ public function getCSS( $id ) { return apply_filters( 'presto_player/player/css', Utility::sanitizeCSS( Setting::get( 'branding', 'player_css' ), $id ) ); } /** * Gets the preset. * * @param integer $id Preset ID. * @return \PrestoPlayer\Models\Preset */ public function getPreset( $id ) { $preset = new Preset( ! empty( $id ) ? $id : 0 ); $preset_id = $preset->id; if ( empty( $preset_id ) ) { $preset = $preset->findWhere( array( 'slug' => 'default' ) ); } // replace watermark text. if ( ! empty( $preset->watermark['enabled'] ) ) { $watermark_text = array( 'text' => DynamicData::replaceText( $preset->watermark['text'] ), ); $preset->watermark = wp_parse_args( $watermark_text, $preset->watermark ); } return apply_filters( 'presto_player/presto_player_presets/data', $preset, 'video' ); } /** * Gets the audio preset. * * @param integer $id Preset ID. * @return \PrestoPlayer\Models\AudioPreset */ public function getAudioPreset( $id ) { $preset = new AudioPreset( ! empty( $id ) ? $id : 0 ); $preset_id = $preset->id; if ( empty( $preset_id ) ) { $preset = $preset->findWhere( array( 'slug' => 'default' ) ); } return apply_filters( 'presto_player/presto_player_presets/data', $preset, 'audio' ); } /** * Get player branding. * * @param \PrestoPlayer\Models\Preset $preset the preset. * @return array */ public function getBranding( $preset ) { $branding = Player::getBranding(); // sanitize with sensible defaults. $branding['color'] = ! empty( $branding['color'] ) ? sanitize_hex_color( $branding['color'] ) : 'rgba(43,51,63,.7)'; $branding['logo_width'] = ! empty( $branding['logo_width'] ) ? $branding['logo_width'] : 150; if ( isset( $branding['logo'] ) ) { $branding['logo'] = ! empty( $branding['logo'] && ! $preset->hide_logo ) ? $branding['logo'] : ''; } return $branding; } /** * Get block classes. * * @param array $attributes the block attributes. * @return string */ public function getClasses( $attributes ) { $block_alignment = isset( $attributes['align'] ) ? sanitize_text_field( $attributes['align'] ) : ''; return ! empty( $block_alignment ) ? 'align' . $block_alignment : ''; } /** * Get player classes. * * @param integer $id the video id. * @param \PrestoPlayer\Models\Preset $preset the preset. * @return string */ public function getPlayerClasses( $id, $preset ) { $skin = $preset->skin; $player_class = 'presto-video-id-' . (int) $id; $player_class .= ' presto-preset-id-' . (int) $preset->id; if ( ! empty( $skin ) ) { $player_class .= ' skin-' . sanitize_text_field( $skin ); } $caption_style = $preset->caption_style; if ( ! empty( $caption_style ) ) { $player_class .= ' caption-style-' . sanitize_html_class( $caption_style ); } if ( ! empty( $attributes['className'] ) ) { $player_class .= ' ' . (string) $attributes['className']; } return $player_class; } /** * Get player styles. * * @param \PrestoPlayer\Models\Preset $preset the preset. * @param array $branding the branding object. * @return string */ public function getPlayerStyles( $preset, $branding ) { // Set brand color. $background_color = ( ! empty( $preset->background_color ) ? sanitize_hex_color( $preset->background_color ) : 'var(--presto-player-highlight-color, ' . sanitize_hex_color( $branding['color'] ) . ')' ); $styles = '--plyr-color-main: ' . $background_color . '; '; // video. if ( $preset->caption_background ) { $styles .= '--plyr-captions-background: ' . sanitize_hex_color( $preset->caption_background ) . '; '; } if ( $preset->border_radius ) { $styles .= '--presto-player-border-radius: ' . (int) $preset->border_radius . 'px; '; } if ( $branding['logo_width'] ) { $styles .= '--presto-player-logo-width: ' . (int) $branding['logo_width'] . 'px; '; } if ( ! empty( $preset->email_collection['border_radius'] ) ) { $styles .= '--presto-player-email-border-radius: ' . (int) $preset->email_collection['border_radius'] . 'px; '; } // audio. if ( 'audio' === $preset->type ) { if ( $preset->background_color ) { $styles .= '--plyr-audio-controls-background: ' . sanitize_hex_color( $preset->background_color ) . ';'; } else { $styles .= '--plyr-audio-controls-background: ' . sanitize_hex_color( $branding['color'] ) . ';'; } if ( $preset->control_color ) { $styles .= '--plyr-audio-control-color: ' . sanitize_hex_color( $preset->control_color ) . ';'; $styles .= '--plyr-range-thumb-background: ' . sanitize_hex_color( $preset->control_color ) . ';'; $styles .= '--plyr-range-fill-background: ' . sanitize_hex_color( $preset->control_color ) . ';'; $styles .= '--plyr-audio-progress-buffered-background: ' . Utility::hex2rgba( sanitize_hex_color( $preset->control_color ), 0.35 ) . ';'; $styles .= '--plyr-range-thumb-shadow: 0 1px 1px ' . Utility::hex2rgba( sanitize_hex_color( $preset->control_color ), 0.15 ) . ', 0 0 0 1px ' . Utility::hex2rgba( sanitize_hex_color( $preset->control_color ), 0.2 ) . ';'; } else { $styles .= '--plyr-audio-control-color: #ffffff;'; $styles .= '--plyr-range-thumb-background: #ffffff;'; $styles .= '--plyr-range-fill-background: #ffffff;'; $styles .= '--plyr-audio-progress-buffered-background: ' . Utility::hex2rgba( sanitize_hex_color( sanitize_hex_color( '#dcdcdc' ) ), 0.35 ) . ';'; } } return $styles; } /** * Get block attributes. * * @param array $attributes the block attributes. * @return array */ public function getAttributes( $attributes ) { return $this->_sanitizeAttibutes( $attributes ); } /** * Dynamic block output. * * @param array $attributes the block attributes. * @param string $content the post content. * @return string */ public function html( $attributes, $content ) { global $presto_player_instance; if ( null === $presto_player_instance ) { $presto_player_instance = 0; } ++$presto_player_instance; // html middleware. $load = $this->middleware( $attributes, $content ); if ( is_feed() ) { return $this->getFeedHtml( $attributes ); } if ( LearnDash::isEnabled() ) { if ( ! LearnDash::shouldVideoLoad() ) { return false; } } // let integrations filter loading capabilities. if ( ! apply_filters( 'presto_player_load_video', $load, $attributes, $content, $this->name ) ) { // allow a custom fallback. $fallback = apply_filters( 'presto_player_load_video_fallback', false, $attributes, $content, $this ); if ( $fallback ) { return wp_kses_post( $fallback ); } return $this->getFallbackHTMLForUnauthorizeAccess(); } // get template data. $data = apply_filters( 'presto_player_block_data', $this->getAttributes( $attributes ), $this ); // need and id and src. if ( empty( $data['id'] ) && empty( $data['src'] ) ) { return false; } // Preload component resources. $preload_service = new PreloadService(); $preload_service->add( array( 'presto-player' ) ); switch ( $this->name ) { case 'bunny': $preload_service->add( array( 'presto-bunny' ) ); break; case 'youtube': $preload_service->add( array( 'presto-youtube' ) ); break; case 'self-hosted': $preload_service->add( array( 'presto-video' ) ); break; case 'vimeo': $preload_service->add( array( 'presto-vimeo' ) ); break; case 'audio': $preload_service->add( array( 'presto-audio' ) ); break; default: break; } $preload_service->bootstrap(); // TODO: child template system. ob_start(); if ( ! empty( $data['id'] ) ) { echo '<!--presto-player:video_id=' . (int) $data['id'] . '-->'; } if ( file_exists( PRESTO_PLAYER_PLUGIN_DIR . "templates/{$this->template_name}.php" ) ) { include PRESTO_PLAYER_PLUGIN_DIR . "templates/{$this->template_name}.php"; } $this->initComponentScript( $data['id'], $data, $presto_player_instance ); $this->iframeFallback( $data ); // output schema markup for optimized seo. $this->outputVideoSchemaMarkup( $this->getSchema( $data ) ); $template = ob_get_contents(); ob_end_clean(); return $template; } /** * Get json data for video schema. * https://developers.google.com/search/docs/appearance/structured-data/video#video-object. * * @param array $data the block data. * * @return array|bool */ public function getSchema( $data ) { if ( isset( $data ) && empty( $data['id'] ) ) { return false; } if ( 'audio' === $data['type'] ) { return false; } $visibility = $data['blockAttributes']['visibility'] ?? false; if ( $visibility && 'private' === $visibility ) { return false; } $title = $data['title'] ?? get_the_title(); if ( empty( $title ) ) { return false; } $poster = $data['poster'] ?? ''; if ( empty( $poster ) ) { return false; } $video = new Video( (int) $data['id'] ); return array( // required. '@context' => 'https://schema.org', '@type' => 'VideoObject', 'name' => wp_kses_post( $title ), 'thumbnailUrl' => esc_url( $poster ), 'uploadDate' => wp_date( 'c', strtotime( $video->getCreatedAt() ) ), // recommended. 'contentUrl' => esc_url( $data['src'] ?? '' ), ); } /** * Output video schema markup. * * @param array $data the block data. * * @return void|bool */ public function outputVideoSchemaMarkup( $data ) { if ( empty( $data ) ) { return false; } ?> <script type="application/ld+json"> <?php echo wp_json_encode( $data ); ?> </script> <?php } /** * Dynamically initialize component via script tag. * * We have to do this because we cannot send arrays or objects in plain HTML. * This function generates a script tag that sets up the player attributes. * * @param int $id The video ID. Default is 0. * @param array $data An array of data to be passed to the component. Default is an empty array. * @param int $instance The instance number of the player on the page. Default is 1. * * @return void This function outputs HTML directly and doesn't return a value. */ public function initComponentScript( $id = 0, $data = array(), $instance = 1 ) { if ( ! $id ) { return; } ?> <script> var player = document.querySelector('presto-player#presto-player-<?php echo (int) $instance; ?>'); player.video_id = <?php echo (int) $id; ?>; <?php $attributes = apply_filters( 'presto_player/component/attributes', $this->component_attributes, $data ); foreach ( $attributes as $attribute ) { ?> <?php if ( isset( $data[ $attribute ] ) ) { ?> player.<?php echo esc_js( sanitize_text_field( $attribute ) ); ?> = <?php echo wp_json_encode( $data[ $attribute ] ); ?>; <?php } ?> <?php } ?> </script> <?php } /** * Adds an iframe fallback script to the page in case js loading fails. * * This function checks if the video provider is YouTube or Vimeo and adds * a filter to load an iframe fallback script if necessary. This ensures * that the video can still be displayed even if JavaScript fails to load. * * @param array $data An array containing video data, including the 'provider' key. * * @return void This function doesn't return a value, but may add a filter. */ public function iframeFallback( $data ) { // must be vimeo or youtube. if ( in_array( $data['provider'], array( 'youtube', 'vimeo' ) ) ) { add_filter( 'presto_player/scripts/load_iframe_fallback', '__return_true' ); } } /** * This function return HTML for unauthorized access or curtain. * * @return string. */ public function getFallbackHTMLForUnauthorizeAccess() { // Get the branding CSS variable. $data = $this->getAttributes( array() ); ob_start(); if ( file_exists( PRESTO_PLAYER_PLUGIN_DIR . 'templates/unauthorized.php' ) ) { include PRESTO_PLAYER_PLUGIN_DIR . 'templates/unauthorized.php'; } $template = ob_get_contents(); ob_end_clean(); return $template; } /** * Return fallback html for feeds. * * @param array $atts array of attributes. */ public function getFeedHtml( $atts ) { if ( is_feed() ) { ob_start(); ?> <?php if ( in_array( $this->name, array( 'self-hosted', 'bunny' ) ) && ! empty( $atts['src'] ) ) { ?> <video controls preload="none"> <source src="<?php echo esc_url( $atts['src'] ); ?>" /> </video> <?php } ?> <?php if ( 'audio' === $this->name && ! empty( $atts['src'] ) ) { ?> <audio controls preload="none"> <source src="<?php echo esc_url( $atts['src'] ); ?>" /> </audio> <?php } ?> <?php if ( 'youtube' === $this->name && ! empty( $atts['video_id'] ) ) { ?> <?php echo wp_kses_post( wp_oembed_get( 'https://www.youtube.com/watch?v=' . esc_attr( $atts['video_id'] ) ) ); ?> <?php } ?> <?php if ( 'vimeo' === $this->name && ! empty( $atts['video_id'] ) ) { ?> <?php echo wp_kses_post( wp_oembed_get( 'https://vimeo.com/' . esc_attr( $atts['video_id'] ) ) ); ?> <?php } ?> <?php return ob_get_clean(); } } /** * Applies a default value to the attribute if attribute is not set. * * @param array $attributes array of attributes. * @return array The merged attributes after applying defaults. */ public function applyAttributeDefaults( $attributes ) { return wp_parse_args( $attributes, $this->default_attributes ); } }