| @@ -1,310 +1,219 @@ | ||
| 1 | 1 | <?php |
| 2 | 2 | |
| 3 | +/* | |
| 4 | + * To change this license header, choose License Headers in Project Properties. | |
| 5 | + * To change this template file, choose Tools | Templates | |
| 6 | + * and open the template in the editor. | |
| 7 | + */ | |
| 8 | + | |
| 9 | + | |
| 3 | 10 | /** |
| 4 | - * Front-end video player for WpStream live channels and video-on-demand. | |
| 11 | + * Description of class-wpstream-player | |
| 5 | 12 | * |
| 6 | - * This class is the WordPress and backwards-compatibility facade: it hooks | |
| 7 | - * the_content, decides whether the current user is entitled to watch, preserves | |
| 8 | - * the established public renderer methods, and exposes the status-poll AJAX | |
| 9 | - * endpoint. Wpstream_Playback_Presentation owns source resolution, engine | |
| 10 | - * selection, assets, and viewer-facing player markup. | |
| 11 | - * | |
| 12 | - * Live status is fetched from the WpStream cloud API and cached in a 45-second | |
| 13 | - * transient so repeated polls do not hammer the remote service. | |
| 14 | - * | |
| 15 | - * @package Wpstream | |
| 16 | - * @subpackage Wpstream/includes | |
| 17 | - * @author cretu | |
| 13 | + * @author cretu | |
| 18 | 14 | */ |
| 19 | - | |
| 20 | -// Exit if accessed directly. | |
| 21 | -if ( ! defined( 'ABSPATH' ) ) { | |
| 22 | - exit; | |
| 23 | -} | |
| 24 | - | |
| 25 | 15 | class Wpstream_Player{ |
| 26 | - /** @var object Main plugin instance; exposes shared services (live connection, quota manager). */ | |
| 27 | - public $main; | |
| 28 | - | |
| 29 | - /** | |
| 30 | - * @var Wpstream_Playback_Session Helper that issues/validates playback sessions for encrypted streams. | |
| 31 | - */ | |
| 32 | - public $playback_session; | |
| 33 | - | |
| 34 | - /** | |
| 35 | - * Wire up the player: keep a handle on the plugin, load the playback-session | |
| 36 | - * helper, and register the content filter, purchase check, and status-poll | |
| 37 | - * AJAX endpoints (both logged-in and nopriv). | |
| 38 | - * | |
| 39 | - * @param object $plugin_main Main plugin instance passed in by the loader. | |
| 40 | - */ | |
| 41 | 16 | public function __construct($plugin_main) { |
| 42 | - // Keep a reference to the main plugin so we can reach its services later. | |
| 43 | 17 | $this->main = $plugin_main; |
| 44 | - | |
| 45 | - // Instantiate the playback-session helper (used for encrypted streams). | |
| 46 | - $this->playback_session = new Wpstream_Playback_Session(); | |
| 47 | - | |
| 48 | - // Inject the player markup into single wpstream product/VOD pages. | |
| 18 | + | |
| 49 | 19 | add_filter( 'the_content',array($this, 'wpstream_filter_the_title') ); |
| 50 | - // On a WooCommerce single product, render the player only if the visitor already bought it. | |
| 51 | 20 | add_action( 'woocommerce_before_single_product', array($this,'wpstream_user_logged_in_product_already_bought') ); |
| 52 | - | |
| 53 | - // Front-end status poll endpoint for logged-in users. | |
| 54 | - add_action( 'wp_ajax_wpstream_player_check_status', array($this,'wpstream_player_check_status') ); | |
| 55 | - // Same endpoint for logged-out visitors (nopriv) so public streams can poll too. | |
| 21 | + | |
| 22 | + add_action( 'wp_ajax_wpstream_player_check_status', array($this,'wpstream_player_check_status') ); | |
| 56 | 23 | add_action('wp_ajax_nopriv_wpstream_player_check_status', array($this,'wpstream_player_check_status')); |
| 57 | - | |
| 24 | + | |
| 25 | + | |
| 26 | + add_action( 'wp_ajax_wpstream_force_clear_transient', array($this,'wpstream_force_clear_transient') ); | |
| 27 | + add_action('wp_ajax_nopriv_wpstream_force_clear_transient', array($this,'wpstream_force_clear_transient')); | |
| 28 | + | |
| 29 | + | |
| 58 | 30 | } |
| 59 | 31 | |
| 60 | 32 | |
| 61 | 33 | |
| 62 | - | |
| 34 | + /** | |
| 35 | + * clear status transients | |
| 36 | + * | |
| 37 | + * @author cretu | |
| 38 | + */ | |
| 63 | 39 | |
| 40 | + | |
| 41 | + public function wpstream_force_clear_transient($event_id){ | |
| 42 | + | |
| 43 | + $transient_name = 'event_data_to_return_'.$event_id; | |
| 44 | + delete_transient($transient_name); | |
| 45 | + update_post_meta($event_id,'statsUrl',''); | |
| 46 | + update_post_meta($event_id,'chatUrl',''); | |
| 64 | 47 | |
| 48 | + } | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 65 | 52 | /** |
| 66 | - * AJAX endpoint: report whether a channel is currently live and, if so, its | |
| 67 | - * playback/stats/chat URLs. Called repeatedly by the front-end player JS. | |
| 68 | - * | |
| 69 | - * The posted id must be a published streaming channel or it is rejected | |
| 70 | - * before any work. Reads the channel status from a 45-second transient; on | |
| 71 | - * a cache miss it calls the WpStream cloud API and refreshes the transient. | |
| 72 | - * Liveness is public, but the playback/stats/chat URLs are returned only to | |
| 73 | - * callers who pass the player-render entitlement check; the response always | |
| 74 | - * carries exactly the five keys the player JS reads. Echoes a JSON payload | |
| 75 | - * and dies. No nonce check on purpose (see inline note) because the hosting | |
| 76 | - * page may be cached, which would invalidate the nonce. | |
| 77 | - * | |
| 78 | - * edited 4.0 | |
| 79 | - * | |
| 80 | - * @return void Outputs JSON and terminates the request. | |
| 81 | - * @author cretu | |
| 82 | - */ | |
| 53 | + * check player status | |
| 54 | + * | |
| 55 | + * @author cretu | |
| 56 | + */ | |
| 57 | + | |
| 83 | 58 | public function wpstream_player_check_status(){ |
| 84 | - // did not add a nonce check here because this is a call done from the frontend | |
| 85 | - // and the page might be cached, so the nonce would not be valid | |
| 86 | - // Which channel/post the caller is asking about. | |
| 87 | - $channel_id = intval($_POST['channel_id']); | |
| 59 | + $event_id = intval($_POST['event_id']); | |
| 60 | + $show_id=$event_id; | |
| 61 | + $transient_name = 'event_data_to_return_'.$event_id; | |
| 62 | + $event_data_for_transient = get_transient( $transient_name ); | |
| 63 | + | |
| 88 | 64 | |
| 89 | - // Reject anything that is not a published streaming channel BEFORE any | |
| 90 | - // cache read, remote API call or meta write: the id must be a wpstream | |
| 91 | - // live/VOD post, or a WooCommerce product carrying one of the wpstream | |
| 92 | - // product types. This stops arbitrary-id probing from reaching the API | |
| 93 | - // or touching unrelated posts' meta. | |
| 94 | - $channel_post = get_post( $channel_id ); | |
| 95 | - $is_valid_channel = false; | |
| 96 | - if ( $channel_post instanceof WP_Post && 'publish' === $channel_post->post_status ) { | |
| 97 | - if ( in_array( $channel_post->post_type, array( 'wpstream_product', 'wpstream_product_vod' ), true ) ) { | |
| 98 | - $is_valid_channel = true; | |
| 99 | - } elseif ( 'product' === $channel_post->post_type | |
| 100 | - && has_term( array( 'live_stream', 'video_on_demand', 'subscription' ), 'product_type', $channel_post ) ) { | |
| 101 | - $is_valid_channel = true; | |
| 65 | + | |
| 66 | + if ( false === $event_data_for_transient || $event_data_for_transient=='' ) { //ws || $hls_to_return=='' | |
| 67 | + | |
| 68 | + $server_id = ''; // server id IS blank - need to retrive it | |
| 69 | + $token = $this->main->wpstream_live_connection->wpstream_get_token(); | |
| 70 | + | |
| 71 | + if($server_id==''){ | |
| 72 | + update_post_meta($show_id,'server_id', '' ); | |
| 73 | + | |
| 74 | + $server_id =$this->main->wpstream_live_connection->retrive_server_id_based_on_show_id($show_id); | |
| 75 | + | |
| 102 | 76 | } |
| 103 | - } | |
| 104 | - if ( ! $is_valid_channel ) { | |
| 105 | - ob_end_clean(); | |
| 106 | - wp_send_json_error( array( 'message' => esc_html__( 'Invalid channel.', 'wpstream' ) ), 400 ); | |
| 107 | - } | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + update_post_meta($show_id,'server_id', $server_id ); | |
| 81 | + $values_array=array( | |
| 82 | + "server_id" => esc_html($server_id), | |
| 83 | + 'from_where' => 'wpstream_check_event_status_front_player' | |
| 84 | + ); | |
| 85 | + | |
| 86 | + if($server_id==''){ | |
| 87 | + $this->main->wpstream_live_connection->wpstream_reset_event_data($show_id); | |
| 88 | + //print 'failed connection'; | |
| 89 | + return; | |
| 90 | + } | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + $url=WPSTREAM_CLUBLINKSSL."://www.".WPSTREAM_CLUBLINK."/wp-json/rcapi/v1/api20-livestrem/event_status/?access_token=".$token; | |
| 95 | + $arguments = array( | |
| 96 | + 'method' => 'GET', | |
| 97 | + 'timeout' => 45, | |
| 98 | + 'redirection' => 5, | |
| 99 | + 'httpversion' => '1.0', | |
| 100 | + 'blocking' => true, | |
| 101 | + 'headers' => array(), | |
| 102 | + 'body' => $values_array, | |
| 103 | + 'cookies' => array() | |
| 104 | + ); | |
| 108 | 105 | |
| 109 | - // Channel state (cache, Baker fetch on miss, fresh-data meta sync) is | |
| 110 | - // owned by Wpstream_Channel_State — the poll only asks questions of it. | |
| 111 | - $state = Wpstream_Channel_State::for_channel( $channel_id, 'wpstream_player_check_status_note_from_js' ); | |
| 106 | + $response = wp_remote_post($url,$arguments); | |
| 107 | + $received_data = wp_remote_retrieve_body($response); | |
| 112 | 108 | |
| 113 | - // Live means playable: upstream status active AND a playback URL present. | |
| 114 | - if ( $state->is_live() ) { | |
| 109 | + if( isset($response['response']['code']) && $response['response']['code']=='200'){ | |
| 110 | + $received_data_encoded=json_decode($received_data,true); | |
| 111 | + | |
| 112 | + if( isset($received_data_encoded['success']) && intval( $received_data_encoded['success'] ) ==1 ){ | |
| 113 | + | |
| 114 | + /* | |
| 115 | + * we set transient and return the array saved | |
| 116 | + * false if no data | |
| 117 | + * | |
| 118 | + * */ | |
| 119 | + $event_data_for_transient= $this->main->wpstream_live_connection->api20_wpstream_update_event($received_data_encoded,$show_id,$server_id); | |
| 120 | + }else{ | |
| 121 | + $this->main->wpstream_live_connection->wpstream_reset_event_data($show_id); | |
| 122 | + } | |
| 123 | + | |
| 124 | + }else{ | |
| 125 | + $this->main->wpstream_live_connection->wpstream_reset_event_data($show_id); | |
| 126 | + } | |
| 127 | + | |
| 128 | + | |
| 115 | 129 | |
| 116 | - // Entitlement gate: playback/stats/chat URLs go only to | |
| 117 | - // callers who pass the same check that decides whether the player | |
| 118 | - // renders at all (free wpstream post types for anyone; WooCommerce | |
| 119 | - // products only for buyers / active subscribers / bundle owners). | |
| 120 | - // Liveness itself stays visible so a paywall page can reflect it. | |
| 121 | - $viewer_is_entitled = wpstream_user_entitled_for_product( $channel_id ); | |
| 122 | - | |
| 123 | - // cleanup any previous echo before sending json | |
| 124 | - ob_end_clean(); | |
| 125 | - // Both branches return exactly the keys the player JS reads — | |
| 126 | - // never the raw upstream payload or any debug field. | |
| 127 | - if ( $viewer_is_entitled ) { | |
| 128 | - echo json_encode( array( | |
| 129 | - 'started' => 'yes', | |
| 130 | - 'channel_id' => $channel_id, | |
| 131 | - 'event_uri' => $state->playback_url(), | |
| 132 | - 'live_conect_views' => $state->stats_url(), | |
| 133 | - 'chat_url' => $state->chat_url(), | |
| 134 | - )); | |
| 135 | - } else { | |
| 136 | - // Unentitled caller: same JSON shape, real liveness, but every | |
| 137 | - // URL field empty. | |
| 138 | - echo json_encode( array( | |
| 139 | - 'started' => 'yes', | |
| 140 | - 'channel_id' => $channel_id, | |
| 141 | - 'event_uri' => '', | |
| 142 | - 'live_conect_views' => '', | |
| 143 | - 'chat_url' => '', | |
| 144 | - )); | |
| 130 | + | |
| 131 | + if ( false === $event_data_for_transient || $event_data_for_transient=='' ){ | |
| 132 | + //we are not live | |
| 133 | + $event_data_for_transient=array(); | |
| 134 | + $event_data_for_transient['hlsPlaybackUrl']=''; | |
| 135 | + | |
| 145 | 136 | } |
| 146 | - | |
| 137 | + } | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + // 1==2 && | |
| 142 | + | |
| 143 | + if( $event_data_for_transient['hlsPlaybackUrl']!=''){ | |
| 144 | + echo json_encode( array( | |
| 145 | + | |
| 146 | + 'started' => 'yes', | |
| 147 | + 'server_id' => $event_data_for_transient['server_id'], | |
| 148 | + 'event_id' => $event_id, | |
| 149 | + 'event_uri' => $event_data_for_transient['hlsPlaybackUrl'], | |
| 150 | + 'live_conect_views' => $event_data_for_transient['statsUrl'], | |
| 151 | + 'chat_url' => $event_data_for_transient['chatUrl'], | |
| 152 | + | |
| 153 | + )); | |
| 147 | 154 | }else{ |
| 148 | - // Channel is not live: return a "started: no" payload with empty | |
| 149 | - // URLs, in the same five-key shape as the live branch. | |
| 150 | - // cleanup any previous echo before sending json | |
| 151 | - ob_end_clean(); | |
| 152 | 155 | echo json_encode( array( |
| 153 | 156 | 'started' => 'no', |
| 154 | - 'channel_id' => $channel_id, | |
| 157 | + 'server_id' => $server_id, | |
| 158 | + 'event_id' => $event_id, | |
| 155 | 159 | 'event_uri' => '', |
| 156 | 160 | 'live_conect_views' => '', |
| 157 | 161 | 'chat_url' => '', |
| 162 | + | |
| 158 | 163 | )); |
| 159 | - | |
| 164 | + $this->wpstream_force_clear_transient($event_id); | |
| 160 | 165 | } |
| 161 | - | |
| 162 | - // AJAX response is complete; stop execution so nothing else is appended. | |
| 163 | 166 | die(); |
| 164 | 167 | } |
| 165 | - | |
| 166 | - | |
| 167 | - | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 168 | 171 | /** |
| 169 | - * the_content filter: prepend the player markup to single live/VOD product pages. | |
| 172 | + * Insert player in page | |
| 170 | 173 | * |
| 171 | - * @param string $content The post content WordPress is about to render. | |
| 172 | - * @return string Content with the player div prepended, or unchanged. | |
| 173 | 174 | * @author cretu |
| 174 | 175 | */ |
| 175 | 176 | public function wpstream_filter_the_title( $content ) { |
| 176 | - // Only inject on single WpStream live-product or VOD-product pages. | |
| 177 | - if( is_singular('wpstream_product') || is_singular('wpstream_product_vod') ){ | |
| 177 | + if( is_singular('wpstream_product')){ | |
| 178 | 178 | global $post; |
| 179 | - // The theme may own the player placement and switch the injection off. | |
| 180 | - if ( ! $this->auto_insert_enabled( intval( $post->ID ), 'the_content' ) ) { | |
| 181 | - return $content; | |
| 182 | - } | |
| 183 | - // Build the player HTML for the current post and prepend it to the content. | |
| 184 | 179 | $args=array('id'=>$post->ID); |
| 185 | 180 | $custom_content = $this->wpstream_insert_player_inpage($args); |
| 186 | 181 | $content = '<div class="wpestream_inserted_player">'.$custom_content.'</div>'.$content; |
| 187 | 182 | return $content; |
| 188 | 183 | }else{ |
| 189 | - // Not a player page: return content untouched. | |
| 190 | 184 | return $content; |
| 191 | 185 | } |
| 192 | 186 | } |
| 193 | 187 | |
| 194 | 188 | /** |
| 195 | - * Decide whether the plugin injects its player automatically into a page. | |
| 196 | - * | |
| 197 | - * Themes that render the player in their own templates switch this off. | |
| 198 | - * Replaces the `wpstream_remove_wpstream_filter()` function-name sniff, | |
| 199 | - * which is honoured as the default for one more release. | |
| 200 | - * | |
| 201 | - * @param int $post_id Post the page is about. | |
| 202 | - * @param string $context `the_content` or `woocommerce_before_single_product`. | |
| 203 | - * @return bool | |
| 204 | - */ | |
| 205 | - private function auto_insert_enabled( $post_id, $context ) { | |
| 206 | - // One-release shim: a theme defining the legacy opt-out function still opts out. | |
| 207 | - $enabled = ! function_exists( 'wpstream_remove_wpstream_filter' ); | |
| 208 | - | |
| 209 | - /** | |
| 210 | - * Filter whether the plugin inserts its player into the page automatically. | |
| 211 | - * | |
| 212 | - * Only the automatic placements (post content, WooCommerce single product) | |
| 213 | - * are affected; shortcodes and builder widgets always render. | |
| 214 | - * | |
| 215 | - * @since 4.14.0 | |
| 216 | - * | |
| 217 | - * @param bool $enabled Whether to insert the player. | |
| 218 | - * @param int $post_id Post the page is about. | |
| 219 | - * @param string $context `the_content` or `woocommerce_before_single_product`. | |
| 220 | - */ | |
| 221 | - return (bool) apply_filters( 'wpstream_player_auto_insert', $enabled, $post_id, $context ); | |
| 222 | - } | |
| 223 | - | |
| 224 | - /** | |
| 225 | - * Build the access notice shown in place of the player. | |
| 226 | - * | |
| 227 | - * @param string $reason `nobuy`, `nolog` or `sub_active`. | |
| 228 | - * @param int $product_id Product the notice is about. | |
| 229 | - * @param string $message Configured wording for the reason. | |
| 230 | - * @param string $wrapper_class Extra class on the outer wrapper (shortcode placement). | |
| 231 | - * @param string $notice_style Inline style kept by the shortcode placement. | |
| 232 | - * @return string Notice markup. | |
| 233 | - */ | |
| 234 | - private function not_entitled_notice( $reason, $product_id, $message, $wrapper_class = '', $notice_style = '' ) { | |
| 235 | - /** | |
| 236 | - * Filter the wording of the access notice shown in place of the player. | |
| 237 | - * | |
| 238 | - * @since 4.14.0 | |
| 239 | - * | |
| 240 | - * @param string $message Plain-text message (not yet escaped). | |
| 241 | - * @param int $product_id Product the notice is about. | |
| 242 | - * @param string $reason `nobuy`, `nolog` or `sub_active` — the entitlement path, | |
| 243 | - * not the wording (global-subscription sites show the | |
| 244 | - * "not subscribed" text under `nobuy`). | |
| 245 | - */ | |
| 246 | - $message = (string) apply_filters( 'wpstream_player_not_entitled_message', $message, $product_id, $reason ); | |
| 247 | - | |
| 248 | - // Assemble the block with the message escaped; the style is a plugin constant. | |
| 249 | - $style = '' !== $notice_style ? ' style="' . esc_attr( $notice_style ) . '"' : ''; | |
| 250 | - $html = '<div class="wpstream_player_wrapper ' . esc_attr( trim( $wrapper_class . ' no_buy' ) ) . '"><div class="wpstream_player_container">' | |
| 251 | - . '<div class="wpstream_notice"' . $style . '>' . esc_html( $message ) . '</div>' | |
| 252 | - . '</div></div>'; | |
| 253 | - | |
| 254 | - /** | |
| 255 | - * Filter the whole access notice block shown in place of the player. | |
| 256 | - * | |
| 257 | - * The default markup is already escaped; callbacks own the escaping of | |
| 258 | - * anything they add. This decides presentation only — entitlement was | |
| 259 | - * refused before this point and is not revisited. | |
| 260 | - * | |
| 261 | - * @since 4.14.0 | |
| 262 | - * | |
| 263 | - * @param string $html Notice markup. | |
| 264 | - * @param int $product_id Product the notice is about. | |
| 265 | - * @param string $reason `nobuy`, `nolog` or `sub_active` (the entitlement path). | |
| 266 | - */ | |
| 267 | - return (string) apply_filters( 'wpstream_player_not_entitled_html', $html, $product_id, $reason ); | |
| 268 | - } | |
| 269 | - | |
| 270 | - /** | |
| 271 | - * Build the player HTML for a shortcode/embed and return it as a string. | |
| 189 | + * Insert player in page | |
| 272 | 190 | * |
| 273 | - * Buffers the echoed player markup so it can be returned instead of printed. | |
| 274 | - * | |
| 275 | - * @param array $attributes Shortcode attributes; 'id' selects the product. | |
| 276 | - * @param string|null $content Unused enclosed shortcode content. | |
| 277 | - * @return string The captured player markup. | |
| 278 | 191 | * @author cretu |
| 279 | 192 | */ |
| 193 | + | |
| 280 | 194 | public function wpstream_insert_player_inpage($attributes, $content = null){ |
| 281 | 195 | $product_id = ''; |
| 282 | 196 | $return_string = ''; |
| 283 | - // Normalise the incoming attributes against the supported defaults. | |
| 284 | - $attributes = shortcode_atts( | |
| 197 | + $attributes = shortcode_atts( | |
| 285 | 198 | array( |
| 286 | 199 | 'id' => 0, |
| 287 | 200 | ), $attributes) ; |
| 288 | 201 | |
| 289 | 202 | |
| 290 | - // Take the product id from the attributes when present. | |
| 291 | 203 | if ( isset($attributes['id']) ){ |
| 292 | 204 | $product_id=$attributes['id']; |
| 293 | 205 | } |
| 294 | - | |
| 295 | - // No explicit id: fall back to the first available product id. The | |
| 296 | - // lookup lives on the main plugin class, not on this player service. | |
| 206 | + | |
| 297 | 207 | if(intval($product_id)==0){ |
| 298 | - $product_id= $this->main->wpstream_player_retrieve_first_id(); | |
| 208 | + $product_id= $this->wpstream_player_retrive_first_id(); | |
| 299 | 209 | } |
| 300 | 210 | |
| 301 | - // Capture everything the shortcode renderer echoes into a string. | |
| 302 | 211 | ob_start(); |
| 303 | - | |
| 212 | + | |
| 304 | 213 | $this->wpstream_video_player_shortcode($product_id); |
| 305 | 214 | $return_string= ob_get_contents(); |
| 306 | - ob_end_clean(); | |
| 215 | + ob_end_clean(); | |
| 307 | 216 | |
| 308 | 217 | return $return_string; |
| 309 | 218 | } |
| 310 | 219 | |
| @@ -311,71 +220,70 @@ | ||
| 311 | 220 | |
| 312 | 221 | |
| 313 | 222 | |
| 314 | 223 | /** |
| 315 | - * Render the player for a product, gated by login and purchase entitlement. | |
| 224 | + * Video Player shortcode | |
| 316 | 225 | * |
| 317 | - * Picks the live or VOD renderer based on product type / taxonomy term, and | |
| 318 | - * shows a "not purchased" / "must log in" notice when the visitor is not | |
| 319 | - * entitled to watch. | |
| 320 | - * | |
| 321 | - * @param string|int $from_sh_id Product/post id to render. | |
| 322 | - * @return void Echoes the player markup or an access notice. | |
| 323 | 226 | * @author cretu |
| 324 | 227 | */ |
| 228 | + | |
| 325 | 229 | public function wpstream_video_player_shortcode($from_sh_id='') { |
| 326 | - // disable cache in order to be able to check the nonce | |
| 327 | - if ( !defined( 'DONOTCACHEPAGE' ) ) { | |
| 328 | - define( 'DONOTCACHEPAGE', true ); | |
| 329 | - } | |
| 330 | 230 | |
| 331 | - $product_id = intval( $from_sh_id ); | |
| 332 | - $product_post = get_post( $product_id ); | |
| 333 | - if ( ! $product_post instanceof WP_Post | |
| 334 | - || ( 'publish' !== $product_post->post_status && ! current_user_can( 'read_post', $product_id ) ) ) { | |
| 335 | - return; | |
| 336 | - } | |
| 231 | + if ( is_user_logged_in() ) { | |
| 232 | + global $product; | |
| 233 | + $current_user = wp_get_current_user(); | |
| 234 | + $product_id = intval($from_sh_id); | |
| 337 | 235 | |
| 338 | - // Player depends on Video.js plus the WpStream player glue script (+styles). | |
| 339 | - wpstream_enqueue_player_assets(); | |
| 340 | 236 | |
| 341 | - if ( is_user_logged_in() ) { | |
| 342 | - // Logged-in branch: gather the identifier needed to check entitlement. | |
| 343 | - // Entitlement gate: the single shared rule (free type / purchase / | |
| 344 | - // active subscription / bundle / Netflix mode). | |
| 345 | - if ( wpstream_user_entitled_for_product( $product_id ) ){ | |
| 346 | - // Open the player wrapper markup. | |
| 237 | + if ( ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) && wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id) ) || get_post_type($product_id)=='wpstream_product' ){ | |
| 238 | + global $product; | |
| 347 | 239 | echo '<div class="wpstream_player_wrapper wpstream_player_shortcode"><div class="wpstream_player_container">'; |
| 348 | - echo $this->main->playback_presentation->render( $product_id, 'auto' ); | |
| 349 | - // Close the player wrapper markup. | |
| 240 | + | |
| 241 | + | |
| 242 | + if( get_post_type($product_id) == 'wpstream_product' ){ | |
| 243 | + | |
| 244 | + $wpstream_product_type = esc_html(get_post_meta($product_id, 'wpstream_product_type', true)); | |
| 245 | + if($wpstream_product_type==1){ | |
| 246 | + $this->wpstream_live_event_player($product_id); | |
| 247 | + } else if($wpstream_product_type==2 || $wpstream_product_type==3){ | |
| 248 | + $this->wpstream_video_on_demand_player($product_id); | |
| 249 | + } | |
| 250 | + | |
| 251 | + }else{ | |
| 252 | + $term_list = wp_get_post_terms($product_id, 'product_type'); | |
| 253 | + $is_subscription_live_event = esc_html(get_post_meta($product_id,'_subscript_live_event',true)); | |
| 254 | + | |
| 255 | + if( $term_list[0]->name=='live_stream' || ( $term_list[0]->name=='subscription' && $is_subscription_live_event=='yes' ) ){ | |
| 256 | + $this->wpstream_live_event_player($product_id); | |
| 257 | + }else if( $term_list[0]->name=='video_on_demand' || ($term_list[0]->name=='subscription' && $is_subscription_live_event=='no' ) ){ | |
| 258 | + $this->wpstream_video_on_demand_player($product_id); | |
| 259 | + } | |
| 260 | + } | |
| 261 | + | |
| 262 | + | |
| 350 | 263 | echo '</div></div>'; |
| 351 | 264 | }else{ |
| 352 | - // Logged in but not entitled: show a "not purchased" notice for paid products. | |
| 265 | + | |
| 353 | 266 | if( get_post_type($product_id) == 'product' ){ |
| 354 | - $message = (string) get_option( 'wpstream_product_not_bought', 'You did not yet purchase this item.' ); | |
| 355 | - echo $this->not_entitled_notice( 'nobuy', $product_id, $message, 'wpstream_player_shortcode', 'background:#e16767;' ); | |
| 267 | + echo '<div class="wpstream_player_wrapper wpstream_player_shortcode no_buy"><div class="wpstream_player_container">'; | |
| 268 | + echo '<div class="wpstream_notice" style="background:#e16767;">'.esc_html__('You did not buy this product!','wpstream').'</div>'; | |
| 269 | + echo '</div></div>'; | |
| 356 | 270 | } |
| 357 | 271 | } |
| 358 | 272 | |
| 273 | + | |
| 274 | + }else{ | |
| 275 | + | |
| 276 | + $product_id = intval($from_sh_id); | |
| 277 | + if( get_post_type($product_id) == 'wpstream_product' ){ | |
| 359 | 278 | |
| 360 | - }else{ | |
| 361 | - // Logged-out branch. Stable type slug is '' when the product has no term. | |
| 362 | - $product_type_slug = wpstream_get_product_type_slug($product_id); | |
| 279 | + $wpstream_product_type = esc_html(get_post_meta($product_id, 'wpstream_product_type', true)); | |
| 280 | + if($wpstream_product_type==1){ | |
| 281 | + $this->wpstream_live_event_player($product_id); | |
| 282 | + } else if($wpstream_product_type==2 || $wpstream_product_type==3){ | |
| 283 | + $this->wpstream_video_on_demand_player($product_id); | |
| 284 | + } | |
| 363 | 285 | |
| 364 | - if( get_post_type($product_id) == 'product' && ($product_type_slug=='live_stream' || $product_type_slug=='video_on_demand') ){ | |
| 365 | - // Paid live/VOD product requires login: show a "must log in" notice. | |
| 366 | - $message = (string) get_option( 'wpstream_product_not_login', 'You must be logged in to watch this video.' ); | |
| 367 | - echo $this->not_entitled_notice( 'nolog', $product_id, $message, 'wpstream_player_shortcode', 'background:#e16767;' ); | |
| 368 | - }elseif( get_post_type($product_id) == 'wpstream_product' ){ | |
| 369 | - // Free live product is watchable without login. | |
| 370 | - echo '<div class="wpstream_player_wrapper wpstream_player_shortcode"><div class="wpstream_player_container">'; | |
| 371 | - echo $this->main->playback_presentation->render( $product_id, 'auto' ); | |
| 372 | - echo '</div></div>'; | |
| 373 | - } else if( get_post_type($product_id) == 'wpstream_product_vod' ){ | |
| 374 | - // Free VOD product is watchable without login. | |
| 375 | - echo '<div class="wpstream_player_wrapper wpstream_player_shortcode"><div class="wpstream_player_container">'; | |
| 376 | - echo $this->main->playback_presentation->render( $product_id, 'auto' ); | |
| 377 | - echo '</div></div>'; | |
| 378 | 286 | } |
| 379 | 287 | } |
| 380 | 288 | } |
| 381 | 289 | |
| @@ -381,107 +289,439 @@ | ||
| 381 | 289 | |
| 382 | 290 | |
| 383 | 291 | |
| 384 | 292 | /** |
| 385 | - * Strip a leading http:// or https:// scheme from a URL. | |
| 293 | + * Video Player shortcode - low latency | |
| 386 | 294 | * |
| 387 | - * @param string $url URL to normalise. | |
| 388 | - * @return string URL without its leading scheme, or unchanged if none matched. | |
| 389 | 295 | * @author cretu |
| 390 | 296 | */ |
| 391 | - function remove_http($url) { return $this->main->playback_presentation->remove_http( $url ); } | |
| 392 | 297 | |
| 298 | + public function wpstream_video_player_shortcode_low_latency($from_sh_id='') { | |
| 299 | + | |
| 300 | + if ( is_user_logged_in() ) { | |
| 301 | + global $product; | |
| 302 | + $current_user = wp_get_current_user(); | |
| 303 | + $product_id = intval($from_sh_id); | |
| 304 | + | |
| 305 | + | |
| 306 | + if ( ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) && wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id) ) || get_post_type($product_id)=='wpstream_product' ){ | |
| 307 | + global $product; | |
| 308 | + echo '<div class="wpstream_player_wrapper wpstream_player_shortcode"><div class="wpstream_player_container">'; | |
| 309 | + | |
| 310 | + | |
| 311 | + if( get_post_type($product_id) == 'wpstream_product' ){ | |
| 312 | + | |
| 313 | + $wpstream_product_type = esc_html(get_post_meta($product_id, 'wpstream_product_type', true)); | |
| 314 | + if($wpstream_product_type==1){ | |
| 315 | + $this->wpstream_live_event_player_low_latency($product_id); | |
| 316 | + } | |
| 317 | + | |
| 318 | + }else{ | |
| 319 | + $term_list = wp_get_post_terms($product_id, 'product_type'); | |
| 320 | + $is_subscription_live_event = esc_html(get_post_meta($product_id,'_subscript_live_event',true)); | |
| 321 | + | |
| 322 | + if( $term_list[0]->name=='live_stream' || ( $term_list[0]->name=='subscription' && $is_subscription_live_event=='yes' ) ){ | |
| 323 | + $this->wpstream_live_event_player_low_latency($product_id); | |
| 324 | + } | |
| 325 | + } | |
| 326 | + | |
| 327 | + | |
| 328 | + echo '</div></div>'; | |
| 329 | + }else{ | |
| 330 | + | |
| 331 | + if( get_post_type($product_id) == 'product' ){ | |
| 332 | + echo '<div class="wpstream_player_wrapper wpstream_player_shortcode no_buy"><div class="wpstream_player_container">'; | |
| 333 | + echo '<div class="wpstream_notice" style="background:#e16767;">'.esc_html__('You did not buy this product!','wpstream').'</div>'; | |
| 334 | + echo '</div></div>'; | |
| 335 | + } | |
| 336 | + } | |
| 337 | + | |
| 338 | + | |
| 339 | + }else{ | |
| 340 | + $product_id = intval($from_sh_id); | |
| 341 | + if( get_post_type($product_id) == 'wpstream_product' ){ | |
| 342 | + | |
| 343 | + $wpstream_product_type = esc_html(get_post_meta($product_id, 'wpstream_product_type', true)); | |
| 344 | + if($wpstream_product_type==1){ | |
| 345 | + $this->wpstream_live_event_player_low_latency($product_id); | |
| 346 | + } | |
| 347 | + } | |
| 348 | + } | |
| 349 | + } | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 393 | 355 | /** |
| 394 | - * Derive the "live connect" stats URI from an event-status payload. | |
| 356 | + * Live Event Player | |
| 395 | 357 | * |
| 396 | - * @deprecated Kept because separately-installed themes may call it; the | |
| 397 | - * derivation now lives in Wpstream_Channel_State. | |
| 398 | - * @param array $event_status Status data from the cloud API. | |
| 399 | - * @return string The stats URL, a host derived from the playback URL, or ''. | |
| 358 | + * @author cretu | |
| 400 | 359 | */ |
| 401 | - function wpstream_get_live_connect_uri($event_status) { | |
| 402 | - return Wpstream_Channel_State::derive_stats_url( $event_status ); | |
| 360 | + function remove_http($url) { | |
| 361 | + $disallowed = array('http://', 'https://'); | |
| 362 | + foreach($disallowed as $d) { | |
| 363 | + if(strpos($url, $d) === 0) { | |
| 364 | + return str_replace($d, '', $url); | |
| 365 | + } | |
| 366 | + } | |
| 367 | + return $url; | |
| 403 | 368 | } |
| 404 | - | |
| 369 | + | |
| 370 | + | |
| 405 | 371 | /** |
| 406 | - * Resolve the effective event settings for a product: per-event options when | |
| 407 | - * enabled, otherwise the site-wide global channel options. | |
| 372 | + * Live Event Player | |
| 408 | 373 | * |
| 409 | - * @param int $product_id Product/channel id. | |
| 410 | - * @return mixed The per-event options array, or the global options. | |
| 411 | 374 | * @author cretu |
| 412 | 375 | */ |
| 413 | - function wpstream_return_event_settings($product_id){ return $this->main->playback_presentation->wpstream_return_event_settings( $product_id ); } | |
| 376 | + | |
| 377 | + function wpstream_live_event_player($product_id,$poster_show='',$use_chat=''){ | |
| 378 | + $live_event_uri = get_post_meta($product_id,'live_event_uri',true); | |
| 379 | + $api20_event_id = get_post_meta($product_id,'server_id',true); | |
| 380 | + | |
| 381 | + $thumb_id = get_post_thumbnail_id($product_id); | |
| 382 | + $thumb = wp_get_attachment_image_src($thumb_id,'small'); | |
| 414 | 383 | |
| 415 | - /** | |
| 416 | - * Deprecated misspelled alias of wpstream_return_event_settings(). | |
| 417 | - * | |
| 418 | - * Kept because the method is public and may be called by external code. | |
| 419 | - * | |
| 420 | - * @deprecated 4.13.4 Use wpstream_return_event_settings() instead. | |
| 421 | - */ | |
| 422 | - function wpestream_return_event_settings($product_id){ return $this->wpstream_return_event_settings( $product_id ); } | |
| 384 | + $chatUrl= get_post_meta($product_id,'statsUrl',true); | |
| 385 | + | |
| 386 | + | |
| 387 | + $live_event_uri_final = $this->wpstream_request_hls_player_dynamic('',$product_id);// buleala lu Gabi | |
| 388 | + $now = time().rand(0,10); | |
| 389 | + $live_conect_array = explode('live.streamer.wpstream.net',$live_event_uri_final); | |
| 390 | + $live_conect_views = $live_conect_array[0].'live.streamer.wpstream.net'; | |
| 391 | + $live_conect_views = $this->remove_http($live_conect_views); | |
| 392 | + $usernamestream = esc_html ( get_option('wpstream_api_username','') ); | |
| 393 | + | |
| 394 | + echo '<div class="wpstream_live_player_wrapper" data-now="'.$now.'" data-me="'.esc_attr($usernamestream).'" data-product-id="'.$product_id.'" id="wpstream_live_player_wrapper'.$now.'" > ' | |
| 395 | + . '<div id="wpestream_live_counting" class="wpestream_live_counting"></div>'; | |
| 396 | + | |
| 397 | + $show_wpstream_not_live_mess=' style="display:none;" '; | |
| 398 | + if(trim($live_event_uri_final) ==''){ | |
| 399 | + $show_wpstream_not_live_mess=''; | |
| 400 | + } | |
| 401 | + | |
| 402 | + | |
| 403 | + print '<div class="wpstream_not_live_mess " '.$show_wpstream_not_live_mess.' ><div class="wpstream_not_live_mess_back"></div><div class="wpstream_not_live_mess_mess">'.esc_html__('We are not live at this moment. Please check back later.','wpstream').'</div></div>'; | |
| 404 | + | |
| 405 | + | |
| 406 | + $poster_data=' poster="'.$thumb[0].'" '; | |
| 407 | + if($poster_show=='no'){ | |
| 408 | + $poster_data=''; | |
| 409 | + } | |
| 410 | + | |
| 411 | + echo' | |
| 412 | + <video id="wpstream-video'.$now.'" '.$poster_data.' class="video-js vjs-default-skin vjs-16-9" playsinline="true" controls> | |
| 413 | + <source | |
| 414 | + src="'.$live_event_uri_final.'" | |
| 415 | + type="application/x-mpegURL"> | |
| 416 | + </video>'; | |
| 423 | 417 | |
| 418 | + print '<script type="text/javascript"> | |
| 419 | + //<![CDATA[ | |
| 420 | + jQuery(document).ready(function(){ | |
| 421 | + wpstream_player_initialize("'.$now.'","'.$live_event_uri_final.'","'.$live_conect_views.'");'; | |
| 422 | + print'}); | |
| 423 | + //]]> | |
| 424 | + </script>'; | |
| 425 | + print '</div>'; | |
| 426 | + | |
| 427 | + | |
| 428 | + if(trim($live_event_uri_final) ==''){ | |
| 429 | + // $show_wpstream_not_live_mess=''; | |
| 430 | + }else{ | |
| 431 | + print '<script type="text/javascript"> | |
| 432 | + //<![CDATA[ | |
| 433 | + jQuery(document).ready(function(){ | |
| 434 | + var player_wrapper = jQuery(".wpstream_live_player_wrapper"); | |
| 435 | + wpstream_read_websocket_info("'.$product_id.'","wpstream_live_player_wrapper'.$now.'", player_wrapper ,"'.$chatUrl.'", "'.$live_event_uri_final.'"); | |
| 436 | + }); | |
| 437 | + //]]> | |
| 438 | + </script>'; | |
| 439 | + } | |
| 440 | + | |
| 441 | + | |
| 442 | + if($use_chat=="yes"){ | |
| 443 | + $this->wpstream_connect_to_chat($product_id); | |
| 444 | + } | |
| 445 | + | |
| 446 | + usleep (10000); | |
| 447 | + | |
| 448 | + } | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 424 | 452 | /** |
| 425 | - * Render the live event player for a channel. | |
| 453 | + * Live Event Player | |
| 426 | 454 | * |
| 427 | - * Fetches channel status from the cloud API (cached 45s in a transient), | |
| 428 | - * then renders either the legacy Video.js markup or, when the channel has an | |
| 429 | - * embedUrl, the newer iframe-based player with a minted embed key. | |
| 430 | - * | |
| 431 | - * edited in 4.0 | |
| 432 | - * | |
| 433 | - * @param int $channel_id Channel/post id. | |
| 434 | - * @param string $poster_show Pass 'no' to suppress the poster image. | |
| 435 | - * @return void Echoes the player markup. | |
| 436 | 455 | * @author cretu |
| 437 | 456 | */ |
| 438 | - function wpstream_live_event_player($channel_id,$poster_show=''){ $this->main->playback_presentation->wpstream_live_event_player( $channel_id, $poster_show ); } | |
| 457 | + | |
| 458 | + function wpstream_live_event_player_low_latency($product_id,$poster_show='',$use_chat=''){ | |
| 459 | + $live_event_uri = get_post_meta($product_id,'live_event_uri',true); | |
| 460 | + $api20_event_id = get_post_meta($product_id,'server_id',true); | |
| 461 | + | |
| 462 | + $thumb_id = get_post_thumbnail_id($product_id); | |
| 463 | + $thumb = wp_get_attachment_image_src($thumb_id,'small'); | |
| 439 | 464 | |
| 465 | + $chatUrl= get_post_meta($product_id,'statsUrl',true); | |
| 466 | + | |
| 467 | + | |
| 468 | + //$live_event_uri_final = $this->wpstream_request_hls_player_dynamic('',$product_id);// buleala lu Gabi | |
| 469 | + | |
| 470 | + | |
| 471 | + $live_event_uri_final= get_post_meta($product_id,'sldpPlaybackUrl',true); | |
| 472 | + $now = time().rand(0,10); | |
| 473 | + | |
| 474 | + $usernamestream = esc_html ( get_option('wpstream_api_username','') ); | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + echo '<div class="wpstream_live_player_wrapper wpstream_low_latency" data-now="'.$now.'" data-me="'.esc_attr($usernamestream).'" data-product-id="'.$product_id.'" id="wpstream_live_player_wrapper'.$now.'" > ' | |
| 480 | + . '<div id="wpestream_live_counting" class="wpestream_live_counting"></div>'; | |
| 481 | + | |
| 482 | + $show_wpstream_not_live_mess=' style="display:none;" '; | |
| 483 | + if(trim($live_event_uri_final) ==''){ | |
| 484 | + $show_wpstream_not_live_mess=''; | |
| 485 | + } | |
| 486 | + | |
| 487 | + | |
| 488 | + print '<div class="wpstream_not_live_mess " '.$show_wpstream_not_live_mess.' ><div class="wpstream_not_live_mess_back"></div><div class="wpstream_not_live_mess_mess">'.esc_html__('We are not live at this moment. Please check back later.','wpstream').'</div></div>'; | |
| 489 | + | |
| 490 | + | |
| 491 | + $poster_data=' poster="'.$thumb[0].'" '; | |
| 492 | + if($poster_show=='no'){ | |
| 493 | + $poster_data=''; | |
| 494 | + } | |
| 495 | + | |
| 496 | + | |
| 497 | + echo' | |
| 498 | + <div iccd="player" id="wpstream-video'.$now.'" '.$poster_data.' class="" > | |
| 499 | + </div>'; | |
| 500 | + | |
| 501 | + print '<script type="text/javascript"> | |
| 502 | + //<![CDATA[ | |
| 503 | + jQuery(document).ready(function(){ | |
| 504 | + var low_latencyid="wpstream-video'.$now.'"; | |
| 505 | + document.addEventListener("DOMContentLoaded", initPlayer(low_latencyid,"'.$live_event_uri_final.'") ); '; | |
| 506 | + print'}); | |
| 507 | + //]]> | |
| 508 | + </script>'; | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + if(trim($live_event_uri_final) ==''){ | |
| 513 | + // $show_wpstream_not_live_mess=''; | |
| 514 | + }else{ | |
| 515 | + print '<script type="text/javascript"> | |
| 516 | + //<![CDATA[ | |
| 517 | + jQuery(document).ready(function(){ | |
| 518 | + var player_wrapper = jQuery(".wpstream_live_player_wrapper"); | |
| 519 | + wpstream_read_websocket_info("'.$product_id.'","wpstream_live_player_wrapper'.$now.'", player_wrapper ,"'.$chatUrl.'", "'.$live_event_uri_final.'"); | |
| 520 | + }); | |
| 521 | + //]]> | |
| 522 | + </script>'; | |
| 523 | + } | |
| 524 | + | |
| 525 | + | |
| 526 | + if($use_chat=="yes"){ | |
| 527 | + $this->wpstream_connect_to_chat($product_id); | |
| 528 | + } | |
| 529 | + | |
| 530 | + usleep (10000); | |
| 531 | + | |
| 532 | + } | |
| 533 | + | |
| 534 | + | |
| 440 | 535 | |
| 441 | - /* | |
| 442 | - * Ask the cloud API for a VOD's HLS manifest URL (and DRM keys/embed data). | |
| 536 | + /** | |
| 537 | + * HLS PLAYER | |
| 443 | 538 | * |
| 444 | - * Persists a 5-minute transient of the HLS URL and stores decryption keys / | |
| 445 | - * embed metadata as post meta. Note: the transient read is immediately | |
| 446 | - * overwritten with false below, so the API is currently queried every call. | |
| 447 | - * | |
| 448 | - * @param string $video_name Remote video name/identifier. | |
| 449 | - * @param int $product_id Product/post to store the resulting meta on. | |
| 450 | - * @return string HLS URL on success, '' on failure. | |
| 539 | + * @author cretu | |
| 451 | 540 | */ |
| 452 | - public function wpstream_request_video_on_demand_hls_player($video_name,$product_id){ return $this->main->playback_presentation->wpstream_request_video_on_demand_hls_player( $video_name, $product_id ); } | |
| 541 | + public function wpstream_request_hls_player_dynamic($server_id,$product_id){ | |
| 542 | + | |
| 543 | + $transient_name = 'hls_to_return_'.$product_id; | |
| 544 | + $hls_to_return = get_transient( $transient_name ); | |
| 453 | 545 | |
| 546 | + if ( false === $hls_to_return || $hls_to_return=='' ) { //ws || $hls_to_return=='' | |
| 547 | + | |
| 548 | + $token = $this->main->wpstream_live_connection->wpstream_get_token(); | |
| 549 | + $values_array = array(); | |
| 550 | + $values_array['server_id'] = $server_id; | |
| 551 | + | |
| 552 | + if($server_id==''){ | |
| 553 | + $this->main->wpstream_live_connection->wpstream_check_event_status_front_player($product_id,$server_id); | |
| 554 | + $server_id = get_post_meta($product_id,'server_id', true ); | |
| 555 | + $values_array['server_id'] = $server_id; | |
| 556 | + } | |
| 557 | + | |
| 558 | + | |
| 559 | + if($server_id==''){ | |
| 560 | + delete_transient($transient_name); | |
| 561 | + return '';exit(); | |
| 562 | + } | |
| 563 | + | |
| 564 | + $url = WPSTREAM_CLUBLINKSSL."://www.".WPSTREAM_CLUBLINK."/wp-json/rcapi/v1/api20-livestrem/ap20_get_player_hls_dynamic/?access_token=".$token; | |
| 565 | + | |
| 566 | + | |
| 567 | + $arguments = array( | |
| 568 | + 'method' => 'GET', | |
| 569 | + 'timeout' => 45, | |
| 570 | + 'redirection' => 5, | |
| 571 | + 'httpversion' => '1.0', | |
| 572 | + 'blocking' => true, | |
| 573 | + 'headers' => array(), | |
| 574 | + 'body' => $values_array, | |
| 575 | + 'cookies' => array() | |
| 576 | + ); | |
| 577 | + $response = wp_remote_post($url,$arguments); | |
| 578 | + | |
| 579 | + $received_data = json_decode( wp_remote_retrieve_body($response) ,true); | |
| 580 | + | |
| 581 | + | |
| 582 | + | |
| 583 | + | |
| 584 | + if( isset($response['response']['code']) && $response['response']['code']=='200'){ | |
| 585 | + $hls_to_return = trim($received_data); | |
| 586 | + | |
| 587 | + | |
| 588 | + set_transient( $transient_name, $hls_to_return, 60 ); | |
| 589 | + return $hls_to_return; | |
| 590 | + }else{ | |
| 591 | + return 'failed connection'; | |
| 592 | + } | |
| 593 | + exit(); | |
| 594 | + }else{ | |
| 595 | + return $hls_to_return; | |
| 596 | + } | |
| 597 | + | |
| 598 | + } | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 454 | 602 | /** |
| 455 | - * Resolve the CSS class for the configured Video.js theme/skin. | |
| 603 | + * HLS PLAYER | |
| 456 | 604 | * |
| 457 | - * Enqueues the theme stylesheet as a side effect. Streamify users get no theme. | |
| 458 | - * | |
| 459 | - * @param int|null $channel_id Channel/product id (used for the streamify check). | |
| 460 | - * @return string A 'vjs-theme-*' class, or '' when no theme applies. | |
| 605 | + * @author cretu | |
| 461 | 606 | */ |
| 462 | - function wpstream_get_player_theme( $channel_id = null ) { return $this->main->playback_presentation->wpstream_get_player_theme( $channel_id ); } | |
| 607 | + | |
| 463 | 608 | |
| 464 | - /** | |
| 465 | - * Enqueue the bundled Video.js theme stylesheet for the selected skin. | |
| 466 | - * | |
| 467 | - * @param string $player_theme Theme slug (skips the built-in 'default'). | |
| 468 | - * @return void | |
| 469 | - */ | |
| 470 | - function wpstream_enqueue_player_theme_style( $player_theme ) { $this->main->playback_presentation->wpstream_enqueue_player_theme_style( $player_theme ); } | |
| 609 | + public function wpstream_request_hls_player($product_id){ | |
| 610 | + | |
| 611 | + $transient_name = 'hls_to_return_'.$product_id; | |
| 612 | + $hls_to_return = get_transient( $transient_name ); | |
| 471 | 613 | |
| 614 | + if ( false === $hls_to_return || $hls_to_return=='' ) { | |
| 615 | + | |
| 616 | + $show_id = intval($product_id); | |
| 617 | + $token = $this->main->wpstream_live_connection->wpstream_get_token(); | |
| 618 | + $values_array = array(); | |
| 619 | + $values_array['show_id'] = $show_id; | |
| 620 | + | |
| 621 | + $url = WPSTREAM_CLUBLINKSSL."://www.".WPSTREAM_CLUBLINK."/wp-json/rcapi/v1/videos/ap20_get_player_hls/?access_token=".$token; | |
| 622 | + | |
| 623 | + | |
| 624 | + $arguments = array( | |
| 625 | + 'method' => 'GET', | |
| 626 | + 'timeout' => 45, | |
| 627 | + 'redirection' => 5, | |
| 628 | + 'httpversion' => '1.0', | |
| 629 | + 'blocking' => true, | |
| 630 | + 'headers' => array(), | |
| 631 | + 'body' => $values_array, | |
| 632 | + 'cookies' => array() | |
| 633 | + ); | |
| 634 | + $response = wp_remote_post($url,$arguments); | |
| 635 | + | |
| 636 | + $received_data = json_decode( wp_remote_retrieve_body($response) ,true); | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + if( isset($response['response']['code']) && $response['response']['code']=='200'){ | |
| 641 | + $hls_to_return = trim($received_data); | |
| 642 | + set_transient( $transient_name, $hls_to_return, 60 ); | |
| 643 | + return $hls_to_return = trim($received_data); | |
| 644 | + }else{ | |
| 645 | + return 'failed connection'; | |
| 646 | + } | |
| 647 | + exit(); | |
| 648 | + }else{ | |
| 649 | + return $hls_to_return; | |
| 650 | + } | |
| 651 | + | |
| 652 | + } | |
| 653 | + | |
| 654 | + | |
| 655 | + | |
| 472 | 656 | /** |
| 473 | - * Resolve the VOD source URL and type for a product. | |
| 657 | + * VODPlayer uri details | |
| 474 | 658 | * |
| 475 | - * Encrypted VODs (and WooCommerce products) get an HLS manifest fetched | |
| 476 | - * from the cloud API; unencrypted VODs use the stored external/local URL. | |
| 477 | - * | |
| 478 | - * @param int $product_id Product/post id. | |
| 479 | - * @return array Keys: video_path_final, wpstream_data_setup, video_type, | |
| 480 | - * free_video_type, post_type. | |
| 481 | 659 | * @author cretu |
| 482 | 660 | */ |
| 483 | - public function wpstream_video_on_demand_player_uri_request($product_id){ return $this->main->playback_presentation->resolve_vod_source( $product_id ); } | |
| 661 | + public function wpstream_video_on_demand_player_uri_request($product_id){ | |
| 662 | + | |
| 663 | + $wpstream_data_setup = ' data-setup="{}" '; | |
| 664 | + | |
| 665 | + /* free_video_type | |
| 666 | + * 1 - free live channel | |
| 667 | + * 2 - free video encrypted | |
| 668 | + * 3 - free video -not encrypted | |
| 669 | + */ | |
| 670 | + $free_video_type = intval( get_post_meta($product_id, 'wpstream_product_type', true)); | |
| 671 | + | |
| 672 | + | |
| 673 | + if($free_video_type==2 || get_post_type($product_id)=='product' ){ | |
| 674 | + | |
| 675 | + /* IF vide is encrypted- readed from vod,streaner | |
| 676 | + */ | |
| 677 | + | |
| 678 | + $video_type = 'application/x-mpegURL'; | |
| 679 | + $video_path = get_post_meta($product_id,'_movie_url',true); | |
| 680 | + if(get_post_type($product_id)=='wpstream_product'){ | |
| 681 | + $video_path = esc_html(get_post_meta($product_id, 'wpstream_free_video', true)); | |
| 682 | + } | |
| 683 | + | |
| 684 | + $username = esc_html ( get_option('wpstream_api_username','') ); | |
| 685 | + if (filter_var($username, FILTER_VALIDATE_EMAIL)) { | |
| 686 | + $username = $this->wpstream_retrive_username(); | |
| 687 | + } | |
| 688 | + | |
| 689 | + if(strpos($username,'@')!=false){ | |
| 690 | + $username_array= explode('@', $username); | |
| 691 | + $username=$username_array[0]; | |
| 692 | + } | |
| 693 | + | |
| 694 | + $video_path_final = 'https://vod.streamer.wpstream.net/'.$username.'/'.$video_path.'/index.m3u8?'.get_site_url(); | |
| 695 | + if(!is_ssl()){ | |
| 696 | + $video_path_final = 'http://vod.streamer.wpstream.net/'.$username.'/'.$video_path.'/index.m3u8?'.get_site_url(); | |
| 697 | + } | |
| 698 | + | |
| 699 | + }else if($free_video_type==3){ | |
| 700 | + | |
| 701 | + /* Video is unecrypted - read from local or youtube / vimeo | |
| 702 | + */ | |
| 703 | + | |
| 704 | + $video_type = 'video/mp4'; | |
| 705 | + $video_path_final=esc_html(get_post_meta($product_id, 'wpstream_free_video_external', true)); | |
| 706 | + | |
| 707 | + if (strpos($video_path_final, 'www.youtube') !== false) { | |
| 708 | + $wpstream_data_setup= ' data-setup=\'{ "techOrder": ["youtube"], "sources": [{ "type": "video/youtube", "src": "'.$video_path_final.'"}] }\' '; | |
| 709 | + $video_path_final=''; | |
| 710 | + } | |
| 711 | + if (strpos($video_path_final, 'vimeo.com') !== false) { | |
| 712 | + $wpstream_data_setup= ' data-setup=\'{"techOrder": ["vimeo"], "sources": [{ "type": "video/vimeo", "src": "'.$video_path_final.'"}], "vimeo": { "color": "#fbc51b"} }\' '; | |
| 713 | + $video_path_final=''; | |
| 714 | + } | |
| 715 | + | |
| 716 | + } | |
| 717 | + | |
| 718 | + $return_array=array(); | |
| 719 | + $return_array['video_path_final'] = $video_path_final; | |
| 720 | + $return_array['wpstream_data_setup']= $wpstream_data_setup; | |
| 721 | + $return_array['video_type'] = $video_type; | |
| 722 | + return $return_array; | |
| 723 | + } | |
| 484 | 724 | |
| 485 | 725 | |
| 486 | 726 | |
| 487 | 727 | /** |
| @@ -489,219 +729,169 @@ | ||
| 489 | 729 | * |
| 490 | 730 | * @author cretu |
| 491 | 731 | */ |
| 492 | 732 | |
| 493 | - public function wpstream_video_on_demand_player($product_id){ $this->main->playback_presentation->wpstream_video_on_demand_player( $product_id ); } | |
| 733 | + public function wpstream_video_on_demand_player($product_id){ | |
| 734 | + | |
| 735 | + $uri_details = $this->wpstream_video_on_demand_player_uri_request($product_id); | |
| 736 | + $video_path_final = $uri_details['video_path_final']; | |
| 737 | + $wpstream_data_setup = $uri_details['wpstream_data_setup']; | |
| 738 | + $video_type = $uri_details['video_type']; | |
| 739 | + | |
| 740 | + $thumb_id = get_post_thumbnail_id($product_id); | |
| 741 | + $thumb = wp_get_attachment_image_src($thumb_id,'small'); | |
| 742 | + $usernamestream = esc_html ( get_option('wpstream_api_username','') ); | |
| 743 | + | |
| 744 | + $pack = $this->main->wpstream_live_connection->wpstream_request_pack_data_per_user(); | |
| 745 | + | |
| 746 | + if($pack['band']>0){ | |
| 747 | + echo '<video id="wpstream-video'.time().'" class="video-js vjs-default-skin vjs-16-9 kuk wpstream_video_on_demand" data-me="'.esc_attr($usernamestream).'" data-product-id="'.$product_id.'" controls preload="auto" | |
| 748 | + poster="'.$thumb[0].'" '.$wpstream_data_setup.'> | |
| 494 | 749 | |
| 750 | + <source src="'.trim($video_path_final).'" type="'.$video_type.'"> | |
| 751 | + <p class="vjs-no-js"> | |
| 752 | + To view this video please enable JavaScript, and consider upgrading to a web browser that | |
| 753 | + <a href="http://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a> | |
| 754 | + </p> | |
| 755 | + </video>'; | |
| 756 | + }else{ | |
| 757 | + print esc_html_e('Insufficient resources to stream this title','wpstream'); | |
| 758 | + } | |
| 495 | 759 | |
| 760 | + } | |
| 761 | + | |
| 762 | + | |
| 496 | 763 | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 497 | 767 | /** |
| 498 | - * Render a VOD player that shows only the trailer (used by the theme). | |
| 768 | + * Retreive username for vod path | |
| 499 | 769 | * |
| 500 | - * No main video source is set; playback is limited to the trailer plus | |
| 501 | - * its play/mute/unmute controls. | |
| 502 | - * | |
| 503 | - * @param int $product_id Product/post id. | |
| 504 | - * @return void Echoes the trailer-only player markup. | |
| 505 | 770 | * @author cretu |
| 506 | 771 | */ |
| 507 | - public function wpstream_video_on_demand_player_only_trailer($product_id){ $this->main->playback_presentation->wpstream_video_on_demand_player_only_trailer( $product_id ); } | |
| 772 | + private function wpstream_retrive_username(){ | |
| 773 | + $token = $this->main->wpstream_live_connection->wpstream_get_token(); | |
| 508 | 774 | |
| 509 | - /** | |
| 510 | - * Decide whether the current user may watch the given product. | |
| 511 | - * | |
| 512 | - * @deprecated Kept as a compatibility shim for separately-installed themes | |
| 513 | - * that call it; the rule itself lives in wpstream_user_entitled_for_product() | |
| 514 | - * (includes/Helpers/wpstream-entitlement.php). New code calls the helper. | |
| 515 | - * | |
| 516 | - * @param int $product_id Product id. | |
| 517 | - * @return bool True when the user is entitled to watch. | |
| 518 | - * @since 3.12 | |
| 519 | - */ | |
| 520 | - public function wpstream_check_if_player_can_dsplay($product_id){ | |
| 521 | - // Delegate to the single entitlement rule. | |
| 522 | - return wpstream_user_entitled_for_product( $product_id ); | |
| 523 | - } | |
| 524 | - | |
| 525 | - | |
| 526 | - | |
| 527 | - /** | |
| 528 | - * Theme variant of the entitlement check. | |
| 529 | - * | |
| 530 | - * @deprecated Kept as a compatibility shim for separately-installed themes | |
| 531 | - * that call it; the rule itself lives in wpstream_user_entitled_for_product() | |
| 532 | - * (includes/Helpers/wpstream-entitlement.php). New code calls the helper. | |
| 533 | - * | |
| 534 | - * @param int $product_id Product/post id. | |
| 535 | - * @return bool True when the player may be displayed. | |
| 536 | - * @since 3.12 | |
| 537 | - */ | |
| 538 | - public function wpstream_check_if_player_can_dsplay_theme($product_id){ | |
| 539 | - // Delegate to the single entitlement rule. | |
| 540 | - return wpstream_user_entitled_for_product( $product_id ); | |
| 775 | + $url=WPSTREAM_CLUBLINKSSL."://www.".WPSTREAM_CLUBLINK."/wp-json/rcapi/v1/return_login/?access_token=".$token; | |
| 776 | + $arguments = array( | |
| 777 | + 'method' => 'GET', | |
| 778 | + 'timeout' => 45, | |
| 779 | + 'redirection' => 5, | |
| 780 | + 'httpversion' => '1.0', | |
| 781 | + 'blocking' => true, | |
| 782 | + 'headers' => array(), | |
| 783 | + 'cookies' => array() | |
| 784 | + ); | |
| 785 | + $response = wp_remote_post($url,$arguments); | |
| 786 | + $received_data = json_decode( wp_remote_retrieve_body($response) ,true); | |
| 787 | + if( isset($response['response']['code']) && $response['response']['code']=='200'){ | |
| 788 | + return ($received_data); die(); | |
| 789 | + }else{ | |
| 790 | + print 'Failed to conbect media server'; | |
| 791 | + die(); | |
| 792 | + } | |
| 541 | 793 | } |
| 542 | - | |
| 543 | - | |
| 544 | - /** | |
| 545 | - * Check the global-subscription entitlement for a product (Netflix mode). | |
| 546 | - * | |
| 547 | - * @deprecated Logic moved to wpstream_user_has_qualifying_global_subscription() | |
| 548 | - * (includes/Helpers/wpstream-entitlement.php); kept as a compatibility shim | |
| 549 | - * for external callers. | |
| 550 | - * | |
| 551 | - * @param int $product_id Product id. | |
| 552 | - * @return bool True when the user has a qualifying active subscription. | |
| 553 | - * @since 3.12 | |
| 554 | - */ | |
| 555 | - public function wpstream_in_plugin_check_global_subscription_model($product_id) { | |
| 556 | - // Delegate to the moved Netflix-mode leg of the entitlement rule. | |
| 557 | - return wpstream_user_has_qualifying_global_subscription( $product_id ); | |
| 558 | - } | |
| 559 | 794 | |
| 560 | 795 | |
| 561 | 796 | |
| 562 | 797 | |
| 563 | 798 | |
| 564 | - | |
| 565 | - | |
| 566 | - | |
| 567 | - | |
| 568 | 799 | /** |
| 569 | - * | |
| 570 | - * | |
| 571 | - * | |
| 572 | - * | |
| 573 | - * check if the user bought the product and display the player - TO REDo | |
| 574 | - * | |
| 575 | - * @since 3.0.1 | |
| 800 | + * check if the user bought the product and display the player - TO REDo | |
| 801 | + * | |
| 802 | + * @since 3.0.1 | |
| 576 | 803 | * returns html of the player |
| 577 | - * | |
| 578 | - * | |
| 579 | - * | |
| 580 | - * | |
| 581 | - * | |
| 582 | - */ | |
| 583 | - public function wpstream_user_logged_in_product_already_bought($from_sh_id='') { | |
| 584 | - // Work against the current WooCommerce product on the page. | |
| 585 | - global $product; | |
| 586 | - if ( ! $product instanceof WC_Product ) { | |
| 587 | - return; | |
| 588 | - } | |
| 589 | - $product_id = $product->get_id(); | |
| 590 | - $current_user = wp_get_current_user(); | |
| 591 | - // The theme may own the player placement and switch the injection off. | |
| 592 | - if ( ! $this->auto_insert_enabled( intval( $product_id ), 'woocommerce_before_single_product' ) ) { | |
| 593 | - return; | |
| 594 | - } | |
| 595 | - // Stable type slug is '' when the product has no term (never a crash). | |
| 596 | - $product_type_slug = wpstream_get_product_type_slug($product_id); | |
| 804 | + */ | |
| 805 | + public function wpstream_user_logged_in_product_already_bought($from_sh_id='') { | |
| 597 | 806 | |
| 598 | - // A "simple subscription" (neither live nor VOD) has no player here. | |
| 599 | - $is_simple_subscription = get_post_meta($product_id, '_subscript_live_event'); | |
| 600 | - if ( $product_type_slug == 'subscription' && ! empty( $is_simple_subscription ) && $is_simple_subscription[0] == 'none' ) { | |
| 601 | - return; | |
| 602 | - } | |
| 807 | + if ( is_user_logged_in() ) { | |
| 808 | + global $product; | |
| 809 | + $current_user = wp_get_current_user(); | |
| 810 | + $product_id = $product->get_id(); | |
| 603 | 811 | |
| 604 | - if ( is_user_logged_in() ) { | |
| 605 | - if( wpstream_user_entitled_for_product($product_id) ){ | |
| 606 | - // Entitled: the presentation module classifies live vs VOD | |
| 607 | - // (product term or subscription flag) and renders. | |
| 608 | - echo '<div class="wpstream_player_wrapper "><div class="wpstream_player_container">'; | |
| 609 | - echo $this->main->playback_presentation->render( $product_id, 'auto' ); | |
| 610 | - echo '</div></div>'; | |
| 611 | - } else { | |
| 612 | - // Not entitled: show the appropriate "no buy" message. | |
| 613 | - if( $product_type_slug=='subscription' ){ | |
| 614 | - // For subscriptions, only prompt when there is no active subscription. | |
| 615 | - if( !wcs_user_has_subscription( $current_user->ID, $product_id ,'active') ) { | |
| 616 | - $this->wpstream_display_no_buy_message('nobuy',$product_id); | |
| 617 | - } | |
| 618 | 812 | |
| 619 | - }else{ | |
| 620 | - $this->wpstream_display_no_buy_message('nobuy',$product_id); | |
| 621 | - } | |
| 813 | + if ( wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product_id) || ( function_exists('wcs_user_has_subscription') && wcs_user_has_subscription( $current_user->ID, $product_id ,'active') ) ){ | |
| 622 | 814 | |
| 623 | 815 | |
| 816 | + echo '<div class="wpstream_player_wrapper"><div class="wpstream_player_container">'; | |
| 817 | + | |
| 818 | + $is_subscription_live_event = esc_html(get_post_meta($product_id,'_subscript_live_event',true)); | |
| 819 | + $term_list = wp_get_post_terms($product_id, 'product_type'); | |
| 820 | + | |
| 821 | + | |
| 822 | + if( $term_list[0]->name=='live_stream' || ($term_list[0]->name=='subscription' && $is_subscription_live_event=='yes' ) ){ | |
| 823 | + $this->wpstream_live_event_player($product_id); | |
| 824 | + }else if( $term_list[0]->name=='video_on_demand' || ($term_list[0]->name=='subscription' && $is_subscription_live_event=='no' ) ){ | |
| 825 | + $this->wpstream_video_on_demand_player($product_id); | |
| 826 | + } | |
| 827 | + echo '</div></div>'; | |
| 828 | + }else{ | |
| 829 | + if( get_post_type($product_id) == 'wpstream_product' ){ | |
| 830 | + echo '<div class="wpstream_player_wrapper no_buy"><div class="wpstream_player_container">'; | |
| 831 | + echo '<div class="wpstream_notice">'.__('You did not buy this product!','wpstream').'</div>'; | |
| 832 | + echo '</div></div>'; | |
| 833 | + } | |
| 624 | 834 | } |
| 625 | 835 | |
| 626 | - | |
| 627 | - }else{ | |
| 628 | - // Logged out: prompt the visitor to log in. | |
| 629 | - $this->wpstream_display_no_buy_message('nolog',$product_id); | |
| 836 | + | |
| 630 | 837 | } |
| 631 | 838 | } |
| 632 | 839 | |
| 840 | + /** | |
| 841 | + * check if the user bought the product and display the player - TO REDo | |
| 842 | + * | |
| 843 | + * @since 3.0.1 | |
| 844 | + * returns html of the player | |
| 845 | + */ | |
| 633 | 846 | |
| 847 | + public function wpstream_chat_wrapper($product_id){ | |
| 848 | + require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/templates/wpstream_chat_template.php'; | |
| 849 | + } | |
| 850 | + | |
| 634 | 851 | |
| 635 | 852 | |
| 636 | - | |
| 637 | - /** | |
| 638 | - * display no buy Message | |
| 639 | - * Render the appropriate access notice ("must log in" / "not purchased" / | |
| 640 | - * "not subscribed" / "subscription active") for a product. | |
| 641 | - * | |
| 642 | - * @param string $log Which case to show: 'sub_active', 'nolog', or other (nobuy). | |
| 643 | - * @param int $product_id Product/post id. | |
| 644 | - * @return void Echoes the notice markup. | |
| 645 | - * @since 3.12.2 | |
| 646 | - */ | |
| 647 | - public function wpstream_display_no_buy_message($log,$product_id) { | |
| 648 | - // Special case: subscription already active -> confirmation notice and return early. | |
| 649 | - if($log=='sub_active'){ | |
| 650 | - $message = (string) get_option( 'wpstream_subscription_active', 'Your Subscription is Active.' ); | |
| 651 | - echo $this->not_entitled_notice( 'sub_active', $product_id, $message ); | |
| 652 | - return; | |
| 853 | + public function wpstream_connect_to_chat($product_id){ | |
| 854 | + $current_user = wp_get_current_user(); | |
| 855 | + $userID = $current_user->ID; | |
| 856 | + $user_login = $current_user->user_login; | |
| 653 | 857 | |
| 654 | - }else if($log=='nolog'){ | |
| 655 | - // Visitor is logged out. | |
| 656 | - $reason = 'nolog'; | |
| 657 | - $message = (string) get_option( 'wpstream_product_not_login', 'You must be logged in to watch this video.' ); | |
| 658 | - }else{ | |
| 659 | - // Default: logged in but has not purchased. | |
| 660 | - $reason = 'nobuy'; | |
| 661 | - $message = (string) get_option( 'wpstream_product_not_bought', 'You did not yet purchase this item.' ); | |
| 662 | - } | |
| 663 | - // In subscription mode, swap in the "not subscribed" wording. | |
| 664 | - $subscription_model = intval( get_option('wpstream_global_sub','')) ; | |
| 665 | - if($subscription_model==1){ | |
| 666 | - $message = (string) get_option( 'wpstream_product_not_subscribe', 'You did not yet subscribe to this item.' ); | |
| 667 | - } | |
| 858 | + $key=''; | |
| 668 | 859 | |
| 860 | + $chatUrl = get_post_meta($product_id,'chatUrl',true); | |
| 861 | + | |
| 669 | 862 | |
| 670 | - if( get_post_type($product_id) == 'product' && $subscription_model==0 ){ | |
| 671 | - // PPV mode: only show the notice for live/VOD/subscription product types. | |
| 672 | - $product = wc_get_product($product_id); | |
| 673 | - $product_type_slug = wpstream_get_product_type_slug($product_id); | |
| 674 | - $product_type = $product->get_type(); | |
| 675 | - $is_subscription_live_event = esc_html(get_post_meta($product_id,'_subscript_live_event',true)); | |
| 863 | + wp_enqueue_script( 'sockjs-0.3.min' ); | |
| 864 | + wp_enqueue_script( 'emojione.min.js' ); | |
| 865 | + wp_enqueue_script( "jquery-effects-core"); | |
| 866 | + wp_enqueue_script( 'jquery.linkify.min.js'); | |
| 867 | + wp_enqueue_script( 'ripples.min.js'); | |
| 868 | + wp_enqueue_script( 'material.min.js'); | |
| 869 | + wp_enqueue_script( 'chat.js'); | |
| 676 | 870 | |
| 677 | 871 | |
| 678 | 872 | |
| 679 | - if( $product_type_slug=='video_on_demand' || $product_type_slug=='live_stream' || $product_type=='subscription'){ | |
| 680 | - echo $this->not_entitled_notice( $reason, $product_id, $message ); | |
| 681 | - } | |
| 873 | + wp_enqueue_style( 'chat.css'); | |
| 874 | + wp_enqueue_style( 'ripples.css'); | |
| 875 | + wp_enqueue_style( 'emojione.min.css'); | |
| 682 | 876 | |
| 683 | - }else if( get_post_type($product_id) == 'product' && $subscription_model==1 ){ | |
| 684 | - // Subscription mode: show the notice for any non-simple product. | |
| 685 | - // '' (no term) counts as non-simple, matching the pre-guard intent. | |
| 686 | - if( wpstream_get_product_type_slug($product_id)!=='simple'){ | |
| 687 | - echo $this->not_entitled_notice( $reason, $product_id, $message ); | |
| 688 | - } | |
| 689 | - } | |
| 690 | - } | |
| 691 | 877 | |
| 692 | - /** | |
| 693 | - * Get the video player logo URL. | |
| 694 | - * | |
| 695 | - * @param int $product_id Product ID. | |
| 696 | - * @return mixed|string Logo URL, the WpStream symbol for streamify users, or ''. | |
| 697 | - */ | |
| 698 | - public function wpstream_get_video_player_logo( $product_id ) { return $this->main->playback_presentation->wpstream_get_video_player_logo( $product_id ); } | |
| 878 | + | |
| 879 | + | |
| 880 | + if(!is_user_logged_in()){ | |
| 881 | + $user_login=''; | |
| 882 | + $chatUrl=''; | |
| 883 | + } | |
| 699 | 884 | |
| 700 | - /* | |
| 701 | - * Check whether a channel/product is on a basic (streamify) subscription. | |
| 702 | - * | |
| 703 | - * @param int $channel_id Channel ID | |
| 704 | - * @return bool True when the 'basicStreaming' meta equals '1'. | |
| 705 | - */ | |
| 706 | - public function wpstream_is_streamify_user( $channel_id ) { return $this->main->playback_presentation->wpstream_is_streamify_user( $channel_id ); } | |
| 885 | + | |
| 886 | + print '<script type="text/javascript"> | |
| 887 | + //<![CDATA[ | |
| 888 | + jQuery(document).ready(function(){ | |
| 889 | + username = "'.$user_login.'"; | |
| 890 | + key="'.$key.'"; | |
| 891 | + | |
| 892 | + }); | |
| 893 | + //]]> | |
| 894 | + </script>'; | |
| 895 | + | |
| 896 | + } | |
| 707 | 897 | } |