*/ class Wpstream_Admin { /** * Store plugin main class to allow public access. * * @since 20180622 * @var object The main class. */ public $main; /** * The ID of this plugin. * * @since 3.0.1 * @access private * @var string $plugin_name The ID of this plugin. */ private $plugin_name; /** * The version of this plugin. * * @since 3.0.1 * @access private * @var string $version The current version of this plugin. */ private $version; /** * Initialize the class and set its properties. * * @since 3.0.1 * @param string $plugin_name The name of this plugin. * @param string $version The version of this plugin. */ public $global_event_options ; public function __construct( $plugin_name, $version,$plugin_main ) { $this->plugin_name = $plugin_name; $this->version = $version; $this->main = $plugin_main; add_action('init', array($this, 'load_global_event_options')); } public function load_global_event_options() { $this->global_event_options = array( 'record' => array( 'name' => esc_html__('Record Live Stream','wpstream'), 'details' => esc_html__('If enabled, live streams will be recorded and saved to your library.','wpstream'), 'defaults' => 'no', ), 'view_count' => array( 'name' => esc_html__('Display Viewer Count','wpstream'), 'details' => esc_html__('If enabled, the live viewer count will show up in the player.','wpstream'), 'defaults' => 'yes', ), 'domain_lock' => array( 'name' => esc_html__('Lock To Website','wpstream'), 'details' => sprintf ( esc_html__('If enabled, live video will only display on %1$s, otherwise it can show up on any website.','wpstream'),get_bloginfo('wpurl') ), 'defaults' => 'no', ), 'autoplay' => array( 'name' => esc_html__('Autoplay','wpstream'), 'details' => esc_html__('If enabled, live video will attempt to start playing automatically. This is only achievable in some browsers.','wpstream'), 'defaults' => 'yes', ), 'mute' => array( 'name' => esc_html__('Start Muted','wpstream'), 'details' => esc_html__('If enabled, live video will start muted. This may increase the rate of autoplay in some browsers. ','wpstream'), 'defaults' => 'no', ), 'low_latency' => array( 'name' => esc_html__('Low Latency (beta)','wpstream'), 'details' => esc_html__('Shortens the live delay between streamer and viewers. Useful for interactive applications like gaming, auctions, trading etc. Low latency may worsen the viewer experience on some devices.','wpstream'), 'defaults' => 'no', ), 'adaptive_bitrate' => array( 'name' => esc_html__('Adaptive Bitrate (beta)','wpstream'), 'details' => esc_html__('Ensures a smooth and uninterrupted viewing experience by adjusting video quality for viewers with reduced network speed or device capabilities.','wpstream'), 'defaults' => 'no', ), 'encrypt' =>array( 'name' => esc_html__('Encrypt Live Stream','wpstream'), 'details' => esc_html__('If enabled, video data will be encrypted. Enabling encryption may lead to reduced website performance under certain configurations. Encrypted video may not display in all browsers.','wpstream'), 'defaults' => 'no', ), 'ses_encrypt'=>array( 'name' => esc_html__('Use Sessions with Encryption','wpstream'), 'details' => esc_html__('If enabled, encryption key distribution will be checked against valid user sessions. Setting may malfunction or lead to reduced website performance under certain configurations. ','wpstream'), 'defaults' => 'no', ), 'autostart' =>array( 'name' => esc_html__('Auto TURN ON','wpstream'), 'details' => esc_html__('If enabled, channel will TURN ON automatically when broadcasting with an External Streaming App (RTMP Encoder/Broadcaster)','wpstream'), 'defaults' => 'no', ), ); } /** * Register the stylesheets for the admin area. * * @since 3.0.1 */ public function enqueue_styles() { /** * This function is provided for demonstration purposes only. * * An instance of this class should be passed to the run() function * defined in Wpstream_Loader as all of the hooks are defined * in that particular class. * * The Wpstream_Loader will then create the relationship * between the defined hooks and the functions defined in this * class. */ wp_enqueue_style( 'wpstream-roboto', "https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700,900&display=swap&subset=latin-ext" ); wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wpstream-admin.css', array(), filemtime(plugin_dir_path(__FILE__) . 'css/wpstream-admin.css' ), 'all' ); wp_enqueue_style( 'wpstream-on-boarding-css', plugin_dir_url( __FILE__ ) . 'css/wpstream-admin-onboarding.css', array(), filemtime(plugin_dir_path(__FILE__) . 'css/wpstream-admin-onboarding.css'), ); if (!did_action('wp_enqueue_media')) { wp_enqueue_media(); } } /** * Register the JavaScript for the admin area. * * @since 3.0.1 */ public function enqueue_scripts() { wp_enqueue_script("jquery-ui-slider"); wp_enqueue_script("jquery-ui-datepicker"); wp_enqueue_script('jquery.fileupload', plugin_dir_url( __FILE__ ) .'js/jquery.fileupload.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true); wp_enqueue_script( 'wpstream-admin-utils', plugin_dir_url( __FILE__ ) .'js/utils/admin_utils.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true); wp_enqueue_script('wpstream-admin-control', plugin_dir_url( __FILE__ ) .'js/admin_control.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true); wp_localize_script('wpstream-admin-control', 'wpstream_admin_control_vars', array( 'admin_url' => get_admin_url(), 'multipart_upload_nonce' => wp_create_nonce( 'wpstream_multipart_upload_nonce' ), 'loading_url' => WPSTREAM_PLUGIN_DIR_URL.'/img/loading.gif', 'download_mess' => esc_html__('Click to download!','wpstream'), 'uploading' => esc_html__('We are uploading your file. Do not close this window!','wpstream'), 'upload_complete2' => esc_html__('Upload Complete! You can upload another file!','wpstream'), 'not_accepted' => esc_html__('The file is not an accepted video format','wpstream'), 'upload_complete' => esc_html__('Upload Complete!','wpstream'), 'no_band' => esc_html__('Not enough streaming data.','wpsteam'), 'no_band_no_store' => esc_html__('Not enough streaming data or storage.','wpsteam'), 'no_streaming_hours' => esc_html__('Not enough streaming hours.','wpstream'), 'exceeding_limit' => esc_html__('File size exceeds 5GB. Initiating multipart upload...','wpsteam'), 'upload_failed' => esc_html__('Upload Failed!','wpstream'), 'upload_failed2' => esc_html__('Upload Failed! Please Try again!','wpstream'), 'choose_a_file' => esc_html__('Choose a file…','wpstream'), 'preparing_multipart' => esc_html__('Preparing multipart upload...','wpstream'), 'uploading_part' => esc_html__('Uploading part {part} of {total}...','wpstream'), 'upload_failed_part' => esc_html__('Failed to upload part {part}. Please try again.','wpstream'), 'completing_upload' => esc_html__('Completing upload. Please wait...','wpstream'), 'upload_failed_part_retry' => esc_html__('Failed to upload part {part}. Retrying...','wpstream'), 'choose_recording' => esc_html__( 'Choose Recording', 'wpstream' ), 'select_recording' => esc_html__( 'Please select a recording from the list', 'wpstream' ), 'invalid_response' => esc_html__('Invalid response from server. Missing required upload data.', 'wpstream'), 'video_processing' => esc_html__( 'The video is still processing', 'wpstream' ), 'file_name_text' => esc_html__('File Name:','wpstream'), 'channel_create_error' => esc_html__('Something did not work. Please try again.', 'wpstream'), 'select_caption_file' => esc_html__('Select .vtt Captions File', 'wpstream'), 'select_button' => esc_html__('Select', 'wpstream'), 'remove_button' => esc_html__('Remove', 'wpstream'), 'use_streaming_hours' => $this->wpstream_is_use_streaming_hours(), )); wp_enqueue_script('wpstream-recordings-videos-list', plugin_dir_url( __FILE__ ) .'js/recordings_videos_list.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true); wp_localize_script( 'wpstream-recordings-videos-list', 'wpstream_recordings_videos_list_vars', array( 'delete_file' => esc_html__('Delete file', 'wpstream'), 'download' => esc_html__( 'Download', 'wpstream'), 'download_available' => esc_html__( 'Click to download! The url will work for the next 20 minutes!', 'wpstream'), 'add_free_video_url' => esc_url( admin_url( 'post-new.php?post_type=wpstream_product_vod') . '&new_video_name=' ), 'create_ftv_vod' => esc_html__( 'Create new Free-To-View VOD from this recording' , 'wpstream' ), 'woocommerce_exists' => class_exists( 'WooCommerce' ), 'add_paid_video_url' => esc_url( admin_url( 'post-new.php?post_type=product').'&new_video_name=' ), 'create_ptv_vod' => esc_html__( 'Create new Pay-Per-View VOD from this recording' , 'wpstream' ), ) ); $modified_start_streaming_file_time = gmdate( 'YmdHi', filemtime( WPSTREAM_PLUGIN_PATH . 'public/js/start_streaming.js' ) ); wp_enqueue_script('wpstream-start-streaming_admin', plugin_dir_url( __DIR__ ) .'public/js/start_streaming.js', array(), $modified_start_streaming_file_time, true); wp_localize_script('wpstream-start-streaming_admin', 'wpstream_start_streaming_vars', array( 'admin_url' => get_admin_url(), 'loading_url' => WPSTREAM_PLUGIN_DIR_URL.'/img/loading.gif', 'download_mess' => esc_html__('Click to download!','wpstream'), 'uploading' => esc_html('We are uploading your file.Do not close this window!','wpstream'), 'upload_complete2' => esc_html('Upload Complete! You can upload another file!','wpstream'), 'not_accepted' => esc_html('The file is not an accepted video format','wpstream'), 'upload_complete' => esc_html('Upload Complete!','wpstream'), 'no_band' => esc_html('Not enough streaming data.','wpsteam'), 'no_band_no_store' => esc_html('Not enough streaming data or storage.','wpsteam'), 'start_streaming_action'=> esc_html__('TURNING ON','wpstream'), 'stop_streaming_action' => esc_html__('TURNING OFF','wpstream'), 'start_streaming' => esc_html__('TURN ON','wpstream'), 'stop_streaming' => esc_html__('TURN OFF','wpstream'), 'failed_fetching' => esc_html__('Failed to get channel info. Please try again.','wpstream'), 'turned_on_tooltip' => esc_html__('Channel is now OFF. Click to turn ON.','wpstream'), 'turned_off_tooltip' => esc_html__('Click to turn channel off. This will interrupt any ongoing broadcast.','wpstream'), 'turning_on_tooltip' => esc_html__('Turning a channel on may take 1-2 minutes or more. Please be patient.','wpstream'), 'turning_off_tooltip' => esc_html__('This may take a few minutes.','wpstream'), 'error1' => esc_html__('You don\'t have enough data to start a new event!','wpstream'), 'failed_event_creation' => esc_html__('Failed to start the channel. Please try again in a few minutes.','wpstream'), 'channel_turning_on' => esc_html__('Channel is turning on','wpstream'), 'channel_turning_off' => esc_html__('Channel is turning off','wpstream'), 'channel_on' => esc_html__('Channel is ON','wpstream'), 'channel_off' => esc_html__('Channel is OFF','wpstream'), 'turn_off_confirm' => esc_html__( 'ARE YOU SURE you\'d like to TURN OFF the channel now? ' . PHP_EOL . PHP_EOL . '- Channels TURN OFF automatically after 1 hour of inactivity (no active broadcast).' . PHP_EOL . '- Manual TURN OFF is only useful if you require to change the channel settings immediately.' . PHP_EOL . '- If your channel is configured with Auto TURN ON, it will turn back on as soon as there is a broadcast.', 'wpstream' ), 'is_basic_streaming' => $this->wpstream_is_basic_streaming_mode(), 'use_streaming_hours' => $this->wpstream_is_use_streaming_hours(), 'basic_streaming_warning' => esc_html__( 'You’ve used all available broadcast or viewer hours.' . PHP_EOL . PHP_EOL . 'Some live channel features will be limited, including recording, viewer count, browser broadcasting, and content protection.' . PHP_EOL . PHP_EOL . 'Top up your resources or upgrade your plan to use all features, or choose OK to start anyway.', 'wpstream' ), 'basic_streaming_warning_traffic' => esc_html__( 'Your account is now in BASIC STREAMING mode.' . PHP_EOL . PHP_EOL . 'Instead of offloading to the WpStream Cloud, this mode relies on WordPress and hosting resources to process and deliver video. In some WP environments, streaming may be unreliable.' . PHP_EOL . 'Certain features, such as recording, viewer count, browser broadcasting, and content protection are unavailable.' . PHP_EOL . PHP_EOL . '- To take advantage of all features, please choose Cancel and upgrade your plan.' . PHP_EOL . '- Otherwise, choose OK to start your channel with these limitations.' . PHP_EOL . PHP_EOL . 'ARE YOU SURE you want to continue with Basic Streaming?', 'wpstream' ), 'broadcaster_url' => esc_url( esc_url(home_url('/broadcaster-page/') ) ), 'is_onboarding' => isset($_GET['onboard']) && $_GET['onboard'] === 'yes' ? 'yes' : 'no', )); wp_enqueue_script('wpstream-settings', plugin_dir_url( __DIR__ ) .'/admin/js/wpstream_settings.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true); wp_localize_script('wpstream-settings', 'wpstream_settings_vars', array( 'error_message' => esc_html__( 'Failed to save settings. Please try again.', 'wpstream'), 'choose_image_text' => esc_html__( 'Choose Logo Image', 'wpstream'), 'select_image_text' => esc_html__( 'Select Image', 'wpstream'), 'update_successful' => esc_html__( 'Update Successful.', 'wpstream'), 'update_failed' => esc_html__( 'Something went wrong. Try again.', 'wpstream'), 'broadcaster_url' => esc_url( esc_url(home_url('/broadcaster-page/') ) ), )); $branch = isset($_GET['branch']) ? sanitize_text_field( wp_unslash( $_GET['branch'] ) ) : ''; wp_enqueue_script('wpstream-on-boarding-js',plugin_dir_url( __DIR__ ) .'/admin/js/wpstream-onboarding2.js',array(), WPSTREAM_PLUGIN_VERSION, true); wp_localize_script('wpstream-on-boarding-js', 'wpstreamonboarding_js_vars', array( 'admin_url' => get_admin_url(), 'plugin_url' => get_dashboard_url().'/plugins.php', 'upload_url' => get_dashboard_url().'admin.php?page=wpstream_recordings', 'branch' => $branch )); $current_screen=get_current_screen(); // enqueue the file only on the on-boarding page and wpstream_product post type $is_wpstream_onboarding_page = $current_screen->base ==='wpstream_page_wpstream_onboard'; $is_wpstream_onboarding_post_type_page = isset($_GET['onboard']) && $_GET['onboard'] === 'yes'; $onboarding_visible = $is_wpstream_onboarding_page || $is_wpstream_onboarding_post_type_page; if( $onboarding_visible) { wp_enqueue_script('wpstream-on-boarding-page-js', plugin_dir_url( __DIR__ ) .'admin/js/wpstream-onboarding-page.js',array(), WPSTREAM_PLUGIN_VERSION, true); wp_localize_script( 'wpstream-on-boarding-page-js', 'wpstream_onboarding_page_vars', array( 'admin_url' => get_admin_url(), 'request_url' => WPSTREAM_CLICK, 'wps_user' => get_option('wpstream_api_username_from_token'), 'current_page' => $is_wpstream_onboarding_post_type_page ? 'post_edit' : 'onboarding', 'plugin_version' => WPSTREAM_PLUGIN_VERSION, 'branch' => $branch, ) ); } if ( in_array( $current_screen->base, ['toplevel_page_wpstream_credentials', 'wpstream_page_wpstream_live_channels', 'wpstream_page_wpstream_recordings', 'wpstream_page_wpstream_onboard'] ) ) { wp_enqueue_script( 'wpstream-user-quota-update', plugin_dir_url( __DIR__ ) . 'admin/js/wpstream-user-quota.js', array(), WPSTREAM_PLUGIN_VERSION, true ); wp_localize_script( 'wpstream-user-quota-update', 'wpstream_user_quota_vars', array( 'admin_url' => get_admin_url() )); } // Add localized variables for broadcaster wp_localize_script('wpstream-broadcaster', 'wpstream_broadcaster_vars', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('wpstream_broadcaster_nonce'), 'plugin_url' => plugin_dir_url(__FILE__), )); } /** * Add Plugin Administation menu * * @since 3.0.1 */ public function wpstream_manage_admin_menu() { add_menu_page( __('WpStream','wpestream'), __('WpStream ','wpstream'), 'administrator', 'wpstream_credentials', array($this,'wpstream_set_wpstream_credentials'), WPSTREAM_PLUGIN_DIR_URL.'img/wpstream-icon-menu_2.png',20 ); add_submenu_page( 'wpstream_credentials', __('WpStream Credentials','wpestream'), __('Credentials','wpestream'), 'administrator', 'wpstream_credentials', array($this,'wpstream_set_wpstream_credentials') ); add_submenu_page( 'wpstream_credentials', __('WpStream Live Channels','wpestream'), __('All Channels','wpestream'), 'administrator', 'wpstream_live_channels', array( $this,'wpstream_new_general_set')); add_submenu_page( 'wpstream_credentials', __('WpStream Recordings','wpestream'), __('Recordings','wpestream'), 'administrator', 'wpstream_recordings', array($this,'wpstream_media_management')); add_submenu_page( 'wpstream_credentials', __('WpStream Settings','wpestream'), __('Settings','wpestream'), 'administrator', 'wpstream_settings', array($this,'wpstream_settings')); add_submenu_page( 'wpstream_credentials', __('WpStream Quick Start','wpestream'), __('WpStream Quick Start','wpestream'), 'administrator', 'wpstream_onboard', array($this,'wpstream_pre_onboard_display')); } /** * Shows events wpstream * * @since 3.0.1 */ public function wpstream_new_general_set() { $no_channel=1; if(class_exists ('WC_Subscription')){ } //event_passed $args = array( 'posts_per_page' => -1, 'post_type' => 'product', 'post_status' => 'publish', 'meta_query' => array( array( 'key' => 'event_passed', 'value' => 1, 'compare' => '!=', ) ), 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => array('live_stream','subscription') ) ), ); $event_list = new WP_Query($args); global $live_event_for_user; $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user(); $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_new_general_set' ); $this->main->show_user_data($pack_details); if( $event_list->have_posts()){ print '

'.__('Your Pay-Per-View Channel List','wpstream').'

'; $link_new = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new'); print ''.esc_html__('Create new Pay-Per-View channel.','wpstream').''; print '
'; print '
'; while ($event_list->have_posts()): $event_list->the_post(); $the_id = get_the_ID(); $is_subscription_live_event = esc_html(get_post_meta($the_id,'_subscript_live_event',true)); $term_list = wp_get_post_terms($the_id, 'product_type'); if( $term_list[0]->name=='subscription' && $is_subscription_live_event=='no'){ continue; } $this->wpstream_live_stream_unit($the_id); endwhile; print'
'; $no_channel=1; }else{ $no_channel=0; } $ajax_nonce = wp_create_nonce( "wpstream_start_event_nonce" ); print ''; $current_user = wp_get_current_user(); $allowded_html = array(); $userID = $current_user->ID; $user_live_streams = get_user_meta($userID,'live_shows'); wp_reset_postdata(); // free $args_free = array( 'posts_per_page' => -1, 'post_type' => 'wpstream_product', 'post_status' => 'publish', ); $event_list_free = new WP_Query($args_free); if( $event_list_free->have_posts()){ print '

'.__('Free-To-View Channels','wpstream').'

'; $link_new = admin_url('post-new.php?post_type=wpstream_product'); print ''.esc_html__('Create new Free-To-View channel.','wpstream').''; print '
'; print '
'; while ($event_list_free->have_posts()): $event_list_free->the_post(); $the_id = get_the_ID(); if( get_post_meta ($the_id,'event_passed',true)!=1){ $this->wpstream_live_stream_unit($the_id); } endwhile; print'
'; print '
er2
'.esc_html__('Close','wpstream').'
'; $no_channel=1; }else{ $no_channel=0; } $link_new_paid = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new'); $link_new_free = admin_url('post-new.php?post_type=wpstream_product'); print '
'; if($event_list->found_posts==0){ print '
'.__('* You do not have any Pay-Per-View channels!','wpstream').'
'; } if($event_list_free->found_posts==0){ print '
'. __('* You do not have any free channels!','wpstream').'
'; } print ''.esc_html__('Add new Free-To-View channel ','wpstream').''; print ''.esc_html__('Add new Pay-Per-View channel ','wpstream').''; print '
'; } // end wpstream_new_general_set /** * Social share * * @since 3.0.1 */ public function wpstream_social_share($the_id){ $protocol = is_ssl() ? 'https' : 'http'; $pinterest = wp_get_attachment_image_src(get_post_thumbnail_id($the_id), 'full'); $link = esc_url ( get_permalink($the_id) ); $title = get_the_title($the_id); $twiter_status = urlencode( $title.' '.$link); $email_link = 'subject='.urlencode ( $title ) .'&body='. urlencode( esc_url($link)); $facebook_link = esc_html($protocol).'://www.facebook.com/sharer.php?u='. esc_url($link) .'&t='. urlencode(get_the_title()); ?>
'; } /** * Shows event unit card in admin * * @since 3.0.1 */ public function wpstream_live_stream_unit($the_id,$is_front=''){ global $live_event_for_user; global $wpstream_plugin; $current_user = wp_get_current_user(); if( !current_user_can('administrator')){ if($is_front=='' ){ print '
'; esc_html_e('You are not allowed to broadcast.','wpstream'); print '
'; return; } } if( !$this->main->wpstream_check_user_can_stream() ){ print '
'; esc_html_e('You are not allowed to broadcast','wpstream'); print '
'; return; } $live_class=''; if(isset($live_event_for_user[$the_id])) { $live_class=" wpstream_show_started"; } if(has_post_thumbnail($the_id)){ $thumb = get_the_post_thumbnail_url($the_id,'thumbnail'); }else{ $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/plugin-logo.png'; } $pending_streaming_class = 'hide_stream_data'; $external_software_streaming_class = ''; $obs_uri = ''; $obs_stream = ''; $live_data_url = ''; if( $live_event_for_user=='' && $is_front=='front' ){ $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user(); } $channel_status = '
'; $button_status = '
'; if(is_array($live_event_for_user) && isset($live_event_for_user[$the_id])) { $pending_streaming_class = 'pending_trigger'; $live_data_url = get_post_meta($the_id,'qos_url',true); // $channel_status = esc_html__('Channel is on','wpstream'); } else { $channel_status = esc_html__('Channel is OFF','wpstream'); $button_status = esc_html__('TURN ON','wpstream'); } $server_id = get_post_meta($the_id,'server_id',true); $obs_uri = get_post_meta($the_id,'obs_uri',true); $obs_stream = get_post_meta($the_id,'obs_stream',true); $webcaster_url = get_post_meta($the_id,'webcaster_url',true); $rtmp_ip_uri = ''; $ajax_nonce = wp_create_nonce( 'wpstream_start_event_nonce' ); print ''; print '
'; print '
'.$channel_status.'
'; print '
'; print '
'; print '
'.wp_trim_words(get_the_title($the_id),10); /* print '***
'.get_post_meta($the_id,'obs_uri',true) .'***
'. get_post_meta($the_id,'obs_stream',true).'***
'. get_post_meta($the_id,'broadcast_url',true); */ print '
'.esc_html( '#ID' ).' '.$the_id.'
'; print '
'; print '
' . $button_status; print '
'.esc_html__('Channel is now OFF. Click to turn ON.','wpestream').'
'; print '
'; print '
'; print '
'; print '
'.esc_html__('Turn ON the channel to go live.','wpestream').'
'; print '
'.esc_html__('Go live with your webcam','wpestream').'
'; print ' '; print '
'; print '
'; print '
'.esc_html__('Turn ON the channel to go live.','wpestream').'
'; print '
'.esc_html__('Go Live with external streaming app','wpestream').'
'; print ' '; print '
'; print ''; print '
'.esc_html__('Turn ON the channel to see live stats.','wpestream').'
'; print '
'.esc_html__('Live Statistics','wpestream').'
'; print' '; print '
'; print '
'; print '
'; if($is_front==''){ print '
'; print '
'.esc_html__(' Turn OFF the channel to change its settings.','wpestream').'
'; print '
'.esc_html__('Channel Settings','wpestream').'
'; print '
'; print ''; print '
'.esc_html__('Edit Channel','wpestream').'
'; print ' '; print '
'; } print ''; print '
'.esc_html__('View Channel','wpestream').'
'; print ' '; print '
'; print '
'; print '
'.esc_html__('Share Channel','wpestream').'
'; print ' '; print '
'; print '
'; $this->wpstream_display_modal_seetings($the_id); $this->wpstream_display_modal_share($the_id); $this->wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream); print '
'; } /** * Shows event unit card in admin - theme version * * @since 3.0.1 */ public function wpstream_live_stream_unit_for_theme($the_id,$is_front=''){ global $live_event_for_user; global $wpstream_plugin; $current_user = wp_get_current_user(); if( !current_user_can('administrator')){ if($is_front=='' ){ print '
'; esc_html_e('You are not allowed to broadcast.','wpstream'); print '
'; return; } } if( !$this->main->wpstream_check_user_can_stream() ){ print '
'; esc_html_e('You are not allowed to broadcast','wpstream'); print '
'; return; } $live_class=''; if(isset($live_event_for_user[$the_id])) { $live_class=" wpstream_show_started"; } if(has_post_thumbnail($the_id)){ $thumb = get_the_post_thumbnail_url($the_id,'thumbnail'); }else{ $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/plugin-logo.png'; } $pending_streaming_class = 'hide_stream_data'; $external_software_streaming_class = ''; $obs_uri = ''; $obs_stream = ''; $live_data_url = ''; if( $live_event_for_user=='' && $is_front=='front' ){ $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user(); } $spinner_url = admin_url('images/spinner-2x.gif'); $button_status = '
'; $channel_status = ''; if(is_array($live_event_for_user) && isset($live_event_for_user[$the_id])) { $pending_streaming_class = 'pending_trigger'; $live_data_url = get_post_meta($the_id,'qos_url',true); // $channel_status = esc_html__('Channel is on','wpstream'); } else { $channel_status = esc_html__('Channel is OFF','wpstream'); $button_status = esc_html__('TURN ON', 'wpstream'); } $server_id = get_post_meta($the_id,'server_id',true); $obs_uri = get_post_meta($the_id,'obs_uri',true); $obs_stream = get_post_meta($the_id,'obs_stream',true); $webcaster_url = get_post_meta($the_id,'webcaster_url',true); $rtmp_ip_uri = ''; print '
'; print '
'.$channel_status.'
'; print '
'; print '
'; print '
'; print '
'.wp_trim_words(get_the_title($the_id),10); print '
'.esc_html('#ID','wpstream').' '.$the_id.'
'; print '
'; print '
'; print '
'; print '
'; print '
'; print '
'.esc_html__('Turn ON the channel to go live.','wpestream').'
'; print '
'.esc_html__('Go live with your webcam','wpestream').'
'; print ' '; esc_html_e('Webcam','wpstream'); print '
'; print '
'; print '
'.esc_html__('Turn ON the channel to go live.','wpestream').'
'; print '
'.esc_html__('Go Live with external streaming app','wpestream').'
'; print ' '; esc_html_e('External App','wpstream'); print '
'; print ''; print '
'.esc_html__('Turn ON the channel to see live stats.','wpestream').'
'; print '
'.esc_html__('Live Statistics','wpestream').'
'; print' '; esc_html_e('Statistics','wpstream'); print '
'; print '
'; print '
'; if($is_front==''){ print '
'; print '
'.esc_html__('Turn OFF the channel to change its settings.','wpestream').'
'; print '
'.esc_html__('Channel Settings','wpestream').'
'; print '
'; print ''; print '
'.esc_html__('Edit Channel','wpestream').'
'; print ' '; print '
'; } print ''; print '
'.esc_html__('View Channel','wpestream').'
'; print ' '; esc_html_e('View','wpstream'); print '
'; print '
'; print '
'.esc_html__('Share Channel','wpestream').'
'; print ' '; esc_html_e('Share','wpstream'); print '
'; print '
'; print '
'. $button_status; print '
'.esc_html__('Channel is now OFF. Click to turn ON.','wpestream').'
'; print '
'; print '
'; $this->wpstream_display_modal_seetings($the_id); $this->wpstream_display_modal_share($the_id); $this->wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream); print '
'; } /* * * Close modal button * */ public function wpstream_close_modal_button(){ print '
'; } public function wpstream_local_event_options_toggle( $is_basic_stream_mode = false ) { $use_global_event_options = get_post_meta(get_the_ID(), 'use_global_event_options', true ); $local_event_options = get_post_meta( get_the_ID(), 'local_event_options', true ); $use_local_event_options_enabled = ( is_array( $local_event_options ) && empty( $use_global_event_options ) ) || ( !empty($use_global_event_options) && intval( $use_global_event_options ) === 0 ); if ( $is_basic_stream_mode ) { $this->wpstream_basic_stream_mode_message(); } print '
'; print '
'; print ''; print ''.sprintf(esc_html__('When is OFF, the settings from %s will be applied','wpstream'), ''.esc_html__('Default Channel Settings','wpstream').'').''; print '
'; print ''; print '
'; } public function wpstream_basic_stream_mode_message() { print '
'; if ( $this->wpstream_is_use_streaming_hours() ) { print sprintf( wp_kses( __( 'You’ve used all available broadcast or viewer hours. Default channel settings will be used for now. To edit channel settings, top up your resources or upgrade your plan.', 'wpstream' ), array( 'a' => array( 'href' => array(), 'target' => array() ) ) ), esc_url( 'https://wpstream.net/pricing/' ), esc_url( 'https://wpstream.net/pricing/' ) ); } else { print sprintf( wp_kses( __( 'You are currently in Basic Streaming Mode. The default channel settings will be used instead. Please upgrade your plan to edit the channel settings.', 'wpstream' ), array( 'a' => array( 'href' => array() ) ) ), esc_url( 'https://wpstream.net/pricing/' ) ); } print '
'; } /* * * Display modal settings * */ public function wpstream_display_modal_seetings($the_id){ $is_basic_stream_mode = $this->wpstream_is_basic_streaming_mode(); print '
'; $this->wpstream_close_modal_button(); print '

'; printf( esc_html__('Channel Settings (#ID %s)','wpstream'),$the_id); print '

'; $this->wpstream_local_event_options_toggle( $is_basic_stream_mode ); $local_event_options = get_post_meta($the_id,'local_event_options',true); $use_global_event_options = get_post_meta($the_id, 'use_global_event_options',true); $is_local_event_options_enabled = ( is_array( $local_event_options ) && empty( $use_global_event_options ) ) || ( !empty($use_global_event_options) && intval( $use_global_event_options ) === 0 ); $local_array_exclude=array('ses_encrypt','vod_domain_lock','vod_encrypt'); print '
'; $this->user_streaming_global_channel_options( '', $local_event_options, $local_array_exclude, !$is_local_event_options_enabled, $is_basic_stream_mode ); print '
'; print '
'; } /* * * Display share settings * */ public function wpstream_display_modal_share($the_id){ print '
'; $this->wpstream_close_modal_button(); print '

'.esc_html__('Share your Channel','wpstream').'

'; $this->wpstream_social_share($the_id); print '
'; } /* * * Display broadcast modal * */ public function wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream){ print '
'; $this->wpstream_close_modal_button(); print '

'.esc_html__('Go Live with External Streaming App','wpstream').'

'; print '
'.esc_html__('Please choose your RTMP encoder/broadcaster','wpstream').'
'; print ''; $this->wpstream_obs_settings($obs_uri,$obs_stream); $this->wpstream_streamyard_settings($obs_uri,$obs_stream); $this->wpstream_restream_settings($obs_uri,$obs_stream); $this->wpstream_wmix_settings($obs_uri,$obs_stream); $this->wpstream_wirecast_settings($obs_uri,$obs_stream); $this->wpstream_xplit_settings($obs_uri,$obs_stream); $this->wpstream_larix_settings($obs_uri,$obs_stream); print '
'; } /* * * Display OBS settings * */ public function wpstream_obs_settings($obs_uri,$obs_stream){ print '
'; print '
'; print '
'.esc_html__('Server:').' '; print '
' . $obs_uri.'
'.__('copy','wpstream').'
'; print '
'.__('Stream Key:').'
'. $obs_stream.'
'.__('copy','wpstream').'
'; print '
'; print'
'; print '
'; print '
  • 1. Click Settings in the OBS Window and then Select Stream.
  • 2. Choose Custom Streaming Server in the Stream Type dropdown menu.
  • 3. In the URL box, type/paste your Server.
  • 4. In the Stream key, type/paste your Stream key.
  • 5. Save changes.Close the Settings window and click on the "Start Streaming" button in the main window of OBS.
'; print '
'; print'
'; } /* * * Display StreamYard settings * */ public function wpstream_streamyard_settings($obs_uri,$obs_stream){ print '
'; print '
'; print '
'.esc_html__('RTMP server URL:').' '; print '
' . $obs_uri.'
'.__('copy','wpstream').'
'; print '
'.__('Stream key:').'
'. $obs_stream.'
'.__('copy','wpstream').'
'; print '
'; print'
'; print '
'; print '
  • 1. Set up your destination by going to your StreamYard account.
  • 2. Choose "Custom RTMP" and add the RTMP server URL and Stream key from WpStream.
  • 3. Go to "Broadcasts" then "create a broadcast".
  • 4. Enter Live Studio.
  • 5. Adjust all your preferred settings and Click on "Go Live".
'; print '
'; print'
'; } /* * * Display StreamYard settings * */ public function wpstream_restream_settings($obs_uri,$obs_stream){ print '
'; print '
'; print '
'.esc_html__('RTMP URL:').' '; print '
' . $obs_uri.'
'.__('copy','wpstream').'
'; print '
'.__('Stream key:').'
'. $obs_stream.'
'.__('copy','wpstream').'
'; print '
'; print'
'; print '
'; print '
  • 1. Go to your Restream account and set up a destination or channel.
  • 2. Choose "Custom RTMP" and add the RTMP URL and Stream Key from WpStream.
  • 3. Click on "Add Channel".
  • 4. Enter Live Studio.
  • 5. Adjust your preferred settings and Go Live.
'; print '
'; print'
'; } /* * * Display Xplit settings * */ public function wpstream_xplit_settings($obs_uri,$obs_stream){ print ''; } /* * * Display WireCast settings * */ public function wpstream_wirecast_settings($obs_uri,$obs_stream){ print ''; } /* * * Display Larix settings * */ public function wpstream_larix_settings($obs_uri,$obs_stream){ print ''; } /* * * Display Wmix settings * */ public function wpstream_wmix_settings($obs_uri,$obs_stream){ print ''; } /* * Set Settings * * */ public function wpstream_settings(){ if( !current_user_can('administrator') ){ die('Only for administrators'); } if($_SERVER['REQUEST_METHOD'] === 'POST'){ if( !wp_verify_nonce($_POST['wpstream-settings-nonce'],'wpstream-settings-nonce') ){ die('Security check'); } $allowed_html = array(); $exclude_array = array(); $allowed_html = array(); if( isset($_POST['user_streaming_channel_type_hidden']) && intval($_POST['user_streaming_channel_type_hidden'])==1 && !isset($_POST['stream_role']) ){ update_option( sanitize_key('wpstream_stream_role'), '' ); } foreach($_POST as $variable=>$value){ if ($variable!='submit'){ if (!in_array($variable, $exclude_array) ){ update_option( sanitize_key('wpstream_'.$variable), sanitize_text_field ($value) ); } if($variable=='stream_role'){ update_option( sanitize_key('wpstream_stream_role'), $value ); } } } if( isset($_GET['tab']) && $_GET['tab']=='default_options' ){ $event_settings=array(); foreach($this->global_event_options as $key=>$option){ $event_settings[$key]=''; if(isset($_POST['wpstream_event_set_'.$key]) && $_POST['wpstream_event_set_'.$key]=='on'){ $event_settings[$key]=1; }else{ $event_settings[$key]=0; } } update_option('wpstream_user_streaming_global_channel_options',$event_settings); } // reset permalinkgs global $wp_rewrite; update_option( "rewrite_rules", FALSE ); $wp_rewrite->flush_rules( true ); } $wpstream_settings_array =array( 1 => array( 'tab' => 'general_options', 'label' => esc_html__('Slug for free video/channel pages ','wpstream'), 'name' => 'free_media_slug', 'type' => 'text', 'details' => esc_html__('This will replace the default "wpstream" of all your free video/channel urls. Special characters like "&" are not permitted. To have your new slug show up you need to re-save the "Permalinks Settings" under Settings -> Permalinks, even if not making any changes.','wpstream'), ), 'free_vod_slug' => array( 'tab' => 'general_options', 'label' => esc_html__('Slug for free VOD pages ','wpstream'), 'name' => 'free_media_slug_vod', 'type' => 'text', 'details' => esc_html__('This will replace the default "wpstream_vod" of all your free VOD urls. Special characters like "&" are not permitted. To have your new slug show up you need to re-save the "Permalinks Settings" under Settings -> Permalinks, even if not making any changes.','wpstream'), ), 2 => array( 'tab' => 'general_options', 'label' => esc_html__('Non-Admin User Roles Allowed to Broadcast','wpstream'), 'name' => 'stream_role', 'type' => 'user_roles', 'details' => esc_html__('These types of users can stream via frontend shortcodes / blocks. Single individual channels are automaticlally created for streaming by non-admins.','wpstream'), ), 3 => array( 'tab' => 'general_options', 'label' => esc_html__('Non Admin Streamers Channel Type.','wpstream'), 'name' => 'user_streaming_channel_type', 'type' => 'select', 'select_values'=>array( 'free' => esc_html__('Free Live Channel','wpstream'), 'paid' => esc_html__('Pay-Per-View','wpstream') ), 'details' => esc_html__('Choose whether the channels assigned to non-admins are free-for-all or pay-per-view (WooCommerce product).','wpstream'), ), 4 => array( 'tab' => 'general_options', 'label' => esc_html__('Default Pay-Per-View Price','wpstream'), 'name' => 'user_streaming_default_price', 'type' => 'text', 'details' => esc_html__('Default price of pay-per-view channels assigned to non-admins.','wpstream'), ), 6 => array( 'tab' => 'subscription_options', 'label' => esc_html__('Use Global Subscription Mode','wpstream'), 'name' => 'global_sub', 'type' => 'slidertoogle', 'details' => esc_html__('If enabled, a client can access all the media products (live and VOD) by purchasing a single subscription. The "WooCommerce Subscriptions" plugin is required.','wpstream'), ), 7 => array( 'tab' => 'subscription_options', 'label' => esc_html__('Subscription ID for Global Subscription Mode','wpstream'), 'name' => 'global_sub_id', 'type' => 'text', 'details' => esc_html__('ID of the subscription product to be purchased for global access to media. All non-subscription video products that are not already attached to a subscription will be accessible to users that have purchased it.','wpstream'), ), 8 => array( 'tab' => 'messages_options', 'label' => esc_html__('PPV not logged in message','wpstream'), 'name' => 'product_not_login', 'type' => 'text', 'details' => esc_html__('This message will be displayed on top of the media player for pay-per-view items when user is not logged in.','wpstream'), 'default' => esc_html__('You must be logged in to watch this video.','wpstream'), ), 9 => array( 'tab' => 'messages_options', 'label' => esc_html__('PPV not purchased message','wpstream'), 'name' => 'product_not_bought', 'type' => 'text', 'details' => esc_html__('This message will be displayed on top of the media player for common pay-per-view items that have not been purchased.','wpstream'), 'default' => esc_html__('You did not yet purchase this item.','wpstream'), ), 10 => array( 'tab' => 'messages_options', 'label' => esc_html__('Subscription not purchased message','wpstream'), 'name' => 'product_not_subscribe', 'type' => 'text', 'details' => esc_html__('This message will be displayed on top of the media player for subscription-type pay-per-view items that have not been purchased.','wpstream'), 'default' => esc_html__(' You did not yet subscribe to this item.','wpstream'), ), 11 => array( 'tab' => 'messages_options', 'label' => esc_html__('Thank you message','wpstream'), 'name' => 'product_thankyou', 'type' => 'text', 'details' => esc_html__('This message will be displayed on the thank you page (after purchase) and the confirmation email.','wpstream'), 'default' => esc_html__('Thanks for your purchase. You can access your item at any time by visiting the following page: {item_link}','wpstream'), ), 12 => array( 'tab' => 'messages_options', 'label' => esc_html__('Subscription Active message','wpstream'), 'name' => 'subscription_active', 'type' => 'text', 'details' => esc_html__('This message will be displayed on subscription product page.','wpstream'), 'default' => esc_html__('Your Subscription is Active','wpstream'), ), 13 => array( 'tab' => 'messages_options', 'label' => esc_html__('You are not live message','wpstream'), 'name' => 'you_are_not_live', 'type' => 'text', 'details' => esc_html__('This message will be displayed in player.','wpstream'), 'default' => esc_html__('We are not live at this moment','wpstream'), ), 14 => array( 'tab' => 'general_options', 'label' => esc_html__('Video player theme','wpstream'), 'name' => 'video_player_theme', 'type' => 'select', 'select_values'=>array( 'default' => esc_html__('Default','wpstream'), 'city' => esc_html__('City','wpstream'), 'forest' => esc_html__('Forest','wpstream'), 'fantasy' => esc_html__('Fantasy','wpstream'), 'sea' => esc_html__('Sea','wpstream'), ), 'details' => esc_html__('Choose the video player theme to have a different look for the player.','wpstream'), ), 'wpstream_player_logo' => array( 'tab' => 'general_options', 'name' => 'player_logo', 'label' => esc_html__('Logo for the video player','wpstream'), 'type' => 'image', 'details' => esc_html__('This logo will be displayed on the the video player.','wpstream'), 'default' => '', 'image_size' => 'thumbnail', ), // hide the video player logo opacity for now // 'wpstream_player_logo_opacity' => array( // 'tab' => 'general_options', // 'name' => 'player_logo_opacity', // 'label' => esc_html__('Opacity of the video player logo','wpstream'), // 'type' => 'range', // 'details' => esc_html__('Set the opacity of the logo','wpstream'), // 'default' => '', // 'image_size' => 'thumbnail', // ), 'wpsteram_player_logo_position' => array( 'tab' => 'general_options', 'name' => 'player_logo_position', 'label' => esc_html__('Position of the video player logo','wpstream'), 'type' => 'select', 'select_values'=>array( 'top-left' => esc_html__('Top Left','wpstream'), 'top-right' => esc_html__('Top Right','wpstream'), 'bottom-left' => esc_html__('Bottom Left','wpstream'), 'bottom-right' => esc_html__('Bottom Right','wpstream'), ), 'details' => esc_html__('Choose the position of the logo on the video player.','wpstream'), 'default' => '', ), 99 => array( 'tab' => 'default_options', 'label' => esc_html__('Events Options ','wpstream'), 'name' => 'user_streaming_global_channel_options', 'type' => 'user_streaming_global_channel_options', 'details' => esc_html__('Global Options for live events.','wpstream'), ), 100 => array( 'tab' => 'default_options_vod', 'label' => esc_html__('Autoplay','wpstream'), 'name' => 'vod_autoplay', 'type' => 'slidertoogle', 'details' => esc_html__('If enabled, video will attempt to start playing automatically. This is only achievable in some browsers.','wpstream'), ), 101 => array( 'tab' => 'default_options_vod', 'label' => esc_html__('Start Muted','wpstream'), 'name' => 'vod_start_muted', 'type' => 'slidertoogle', 'details' => esc_html__('If enabled, video will start muted. This may increase the rate of autoplay in some browsers.','wpstream'), ), 102 => array( 'tab' => 'default_options_vod', 'label' => esc_html__('Lock To Website','wpstream'), 'name' => 'vod_domain_lock', 'type' => 'slidertoogle', 'details' =>sprintf ( esc_html__('If enabled, video will only display on %1$s, otherwise it can show up on any website.','wpstream'),get_bloginfo('wpurl') ), ), 103 => array( 'tab' => 'default_options_vod', 'label' => esc_html__('Encrypt Video','wpstream'), 'name' => 'vod_encrypt', 'type' => 'slidertoogle', 'details' => esc_html__('If enabled, video data will be encrypted. Enabling encryption may lead to reduced website performance under certain configurations. Encrypted video may not display in all browsers.','wpstream'), ), /* 'vod_domain_lock' =>array( 'name' => esc_html__('Video On Demand - Lock To Website','wpstream'), 'details' => sprintf ( esc_html__('If enabled, VODS will only display on %1$s, otherwise they can show up on any website.','wpstream'),get_bloginfo('wpurl') ), 'defaults' => 'no', ), 'vod_encrypt' =>array( 'name' => esc_html__('Encrypt Video on Demand','wpstream'), 'details' => esc_html__('If enabled, video data will be encrypted. Enabling encryption may lead to reduced website performance under certain configurations. Encrypted video may not display in all browsers.','wpstream'), 'defaults' => 'no', ),*/ 104 => array( 'tab' => 'support_tab', 'label' => esc_html__('Logs','wpstream'), 'name' => 'logs', 'type' => 'logs_table', 'details' => esc_html__('This is the error log of the plugin.','wpstream'), ) ); $active_tab = 'general_options'; if( isset( $_GET[ 'tab' ] ) ) { $active_tab = $_GET[ 'tab' ]; } print '

'.__('WpStream Settings','wpstream').'

'; print ''; $help_link=''; $is_basic_stream_mode = $this->wpstream_is_basic_streaming_mode(); print '
'; switch ($active_tab) { case 'general_options': $help_link='https://docs.wpstream.net/docs/general-settings/'; break; case 'default_options': $help_link='https://docs.wpstream.net/docs/default-channel-settings/'; break; case 'default_options_vod': $help_link='https://docs.wpstream.net/docs/vod-settings/'; break; case 'subscription_options': $help_link='https://docs.wpstream.net/docs/subscription-options/'; break; case 'messages_options': $help_link='https://docs.wpstream.net/docs/customize-messages/'; break; } print '
'; foreach ($wpstream_settings_array as $key=>$option){ if($option['tab']!=$active_tab){ continue; } if ( $option['type']=='user_streaming_global_channel_options' ) { print '
'; print esc_html__( 'These settings will apply to newly created channels; existing channels will not change settings if you change them here', 'wpstream'); if ( $is_basic_stream_mode ) { $this->wpstream_basic_stream_mode_message(); } print '
'; } print '
'; $options_value = get_option('wpstream_'.$option['name']) ; switch( $option['type'] ) { case 'user_roles': print ''; print $this->wpstream_select_user_roles($option['name'],$options_value); print '
'.$option['details'].'
'; break; case 'user_streaming_global_channel_options': $exclude_array=array(); $this->user_streaming_global_channel_options( $option['name'], $options_value, $exclude_array, $is_basic_stream_mode ); break; case 'text': if($options_value==''){ $options_value=''; if(isset($option['default'])){ $options_value=$option['default']; } } print ''; print ''; print '
'.$option['details'].'
'; break; case 'select': print ''; print ''; print ''; print '
'.$option['details'].'
'; break; case 'slidertoogle': print ''; print '
'; print '
'.$option['details'].'
'; print ''; print '
'; break; case 'image': $image_url = $options_value ? esc_url($options_value) : ''; $has_image = !empty($image_url); print ''; print '
'; print ''; // Preview area print '
'; print 'Preview'; print '
'; // Upload/remove buttons print '
'; print ''; print ''; print '
'; print '
'; print '
' . $option['details'] . '
'; break; case 'range': print ''; print ''; print '
'.$option['details'].'
'; break; case 'logs_table': $this->wpstream_support_tab(); break; } print '
'; } print '
'; // options wrapper if($help_link!==''){ print ''; } print '
'; if ( $active_tab != 'support_tab') { print '
'; print ''; print '
'; print '
'; } print ' '; print '
'; print '
'; } /** * Get system information for support tab * * @return array System information */ private function get_system_info() { global $wp_version; $php_version = phpversion(); $wp_version_info = $wp_version; $site_debug_mode = (defined('WP_DEBUG') && WP_DEBUG); $wp_memory_limit = WP_MEMORY_LIMIT; $wpstream_version = WPSTREAM_PLUGIN_VERSION; $wpstream_plugin_outdated = false; // Check if plugin is outdated $update_plugins = get_site_transient('update_plugins'); if (isset($update_plugins->response['plugin/wpstream.php'])) { $wpstream_plugin_outdated = true; } // Check API status $api_status = false; if (method_exists($this->main->wpstream_live_connection, 'wpstream_get_token')) { $token = $this->main->wpstream_live_connection->wpstream_get_token(); $api_status = !empty($token); } return array( 'php_version' => $php_version, 'wp_version' => $wp_version_info, 'site_debug_mode' => $site_debug_mode, 'wp_memory_limit' => $wp_memory_limit, 'wpstream_version' => $wpstream_version, 'wpstream_plugin_outdated' => $wpstream_plugin_outdated, 'api_status' => $api_status ); } /** * Render system information HTML */ private function render_system_info() { $system_info = $this->get_system_info(); ?>

render_system_info(); ?>

wpstream_get_plugins_data(); if (empty($plugins_data)) { echo ''; } else { foreach ($plugins_data as $plugin) { echo ''; echo ''; echo ''; echo ''; } } ?>
' . esc_html__('No WPStream plugins found.', 'wpstream') . '
' . esc_html($plugin['name']) . ''; echo esc_html($plugin['version']); if ( isset($plugin['new_version']) ) { echo '
'; echo ''; echo ''; echo '
' . sprintf( esc_html__('A new version is available: %s', 'wpstream'), esc_html($plugin['new_version']) ) . '
'; echo '
'; } echo '

'; } else { foreach ($logs as $log) { echo ''; echo ''; echo ''; echo ''; echo ''; } } ?>
' . esc_html__('No logs found.', 'wpstream') . '
' . esc_html(date('Y-m-d H:i:s', $log['timestamp'] ) ) . '' . esc_html($log['type']) . '' . esc_html($log['description']) . '
array( 'path' => 'wpstream/wpstream.php', ), 'WooCommerce' => array( 'path' => 'woocommerce/woocommerce.php', ), 'Meta Box' => array( 'path' => 'meta-box/meta-box.php', ), 'One Click Demo Import' => array( 'path' => 'one-click-demo-import/one-click-demo-import.php', ), 'Better Messages' => array( 'path' => 'bp-better-messages/bp-better-messages.php', ), ); foreach ($all_plugins as $plugin_path => $plugin_data) { $is_active = is_plugin_active( $plugin_path ); $has_update = isset( $update_data->response[$plugin_path] ); $plugin_info = [ 'name' => $plugin_data['Name'], 'version' => $plugin_data['Version'], 'path' => $plugin_path, 'active' => $is_active ? 'Yes' : 'No', 'needs_update' => $has_update ? 'Yes' : 'No' ]; if ($has_update) { $plugin_info['new_version'] = $update_data->response[$plugin_path]->new_version; } $all_plugins_info[] = $plugin_info; } // Filter out the elements from $all_plugins_info that are not in $wpstream_plugins foreach ( $all_plugins_info as $key => $plugin_info ) { // compare $plugin_info['path'] against the path property on each $wpstream_plugins element item // if the path is not in $wpstream_plugins, unset the element if ( !in_array( $plugin_info['path'], array_column( $wpstream_plugins, 'path' ) ) ) { unset( $all_plugins_info[$key] ); } } return $all_plugins_info; } public function wpstream_render_outdated_plugin_notice() { $has_update = get_site_transient('update_plugins'); if (isset($has_update->response['plugin/wpstream.php'])) { ?>

' . esc_html__('updates page', 'wpstream') . '' ); ?>

global_event_options as $key=>$option){ if( is_array($local_array) && !in_array($key,$local_array)){ print '
'; print ''; print '
'; print '
'.$option['details'].'
'; print ' '; print '
'; print '
'; } } } /* * Set user roles * * @since 3.0.1 */ public function wpstream_select_user_roles($name,$value){ if($value==''){ $value=array(); } $roles = get_editable_roles(); $return = ''; return $return; } /* * Set credential admin function * * @since 3.0.1 */ public function wpstream_set_wpstream_credentials(){ if($_SERVER['REQUEST_METHOD'] === 'POST'){ $allowed_html = array(); $exclude_array = array(); $allowed_html = array(); foreach($_POST as $variable=>$value){ if ($variable!='submit'){ if (!in_array($variable, $exclude_array) ){ switch ( $variable ) { case 'api_username': update_option( sanitize_key('wpstream_api_username'), sanitize_text_field($value) ); break; case 'api_password': update_option( sanitize_key('wpstream_api_password'), $value ); break; } } } } update_option('wp_estate_token_expire',0); update_option('wp_estate_curent_token',' '); delete_transient( 'wpstream_token_api'); delete_transient('wpstream_token_request_30'); delete_transient('wpstream_request_pack_data_per_user_transient'); } $allowed_html = array(); $wpstream_options_array =array( 2 => array( 'label' => 'WpStream.net Username or Email', 'name' => 'api_username', 'type' => 'text', ), 3 => array( 'label' => 'WpStream.net Password', 'name' => 'api_password', 'type' => 'password', ), ); $token = $this->main->wpstream_live_connection->wpstream_get_token(); $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_set_wpstream_credentials' ); $this->main->show_user_data($pack_details); print '
'; print '

'.__('WpStream Credentials','wpstream').'

'; if( get_option('wpstream_api_username')=='' || get_option('wpstream_api_password')== '' ){ echo '
'; $admin_url_onboard=get_admin_url().'admin.php?page=wpstream_onboard'; printf ( __('To connect your plugin, enter your WpStream credentials below or go here to create an account.','wpstream'),$admin_url_onboard); echo '
'; }else if($token==''){ $text = get_option('wpstream_curl_failed') === "0" ? ' Incorrect username or password. Please check your credentials or go here to reset your password.' : 'Not connected to WpStream. Please note the errors above and contact support.'; echo '
'.__($text,'wpstream').'
'; }else if( $this->main->wpstream_live_connection->wpstream_client_check_api_status() ){ echo '
'.__('Connected to WpStream.net!','wpstream').'
'; }else{ echo '
'.__('Failed to connect to WpStream.net. Please address CURL connectivity with your hosting provider.','wpstream').'
'; } print '
'; foreach ($wpstream_options_array as $key=>$option){ print '
'; $options_value = esc_html( get_option('wpstream_'.$option['name'],'') ); print ''; print ''; print '
'; } print '
'; print ''; print '

Video Tutorials

'; print 'How to Live Stream to WordPress with OBS'; print 'How to Live Stream to WordPress in less than 3 Minutes'; print 'How to Live-Stream to WordPress using your iPhone'; print 'More Tutorials On Our YouTube Channel'; print '
'; print '
'; print '
'; $link_new = admin_url('admin.php?page=wpstream_live_channels'); $link_new_paid = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new'); $link_new_free = admin_url('post-new.php?post_type=wpstream_product'); print ''.esc_html__('Create new Free-To-View channel','wpstream').''; print ''.esc_html__('Create Pay-Per-View channel','wpstream').''; print ''.esc_html('My Channels','wpstream').''; print '
'; } /** * Media Management * * @since 3.0.1 */ public function wpstream_media_management(){ $pack_details = $this->main->user_quota_service->request_pack_data_per_user( 'wpstream_media_management' ); $this->main->show_user_data($pack_details); print '

'.__('Upload New Recording','wpstream').'

'.$this->wpstream_present_media_upload().'
'; print '

'.__('Your Recordings','wpstream').'

'.$this->wpstream_present_file_management().'
'; } /** * * * WpStream Pagination * * @since 3.0.1 * * */ public function wpstream_pagination($pages , $range = 2) { $return=''; $showitems = ($range * 2) + 1; $paged = ( isset( $_GET['paged'] ) ) ? intval($_GET['paged']) : 1; if (1 != $pages && $pages != 0) { $return.= '"; } return $return; } /** * Media upload * * @since 3.0.1 */ public function wpstream_present_media_upload(){ $to_return=''; if ( ! $this->main->quota_manager->has_storage_quota( null, 'recordings_screen' ) ) { return '
'.esc_html__('You don\'t have enough cloud storage or data to upload a new item. Please delete some videos or upgrade your plan.','wpstream').'
'; } $formInputs=$this->main->wpstream_live_connection->wpstream_get_signed_form_upload_data(); if( !$formInputs['success'] ){ if ($formInputs['error'] == 'not_connected'){ $to_return.='
'.esc_html__('Not connected. Please connect to WpStream to upload videos.','wpstream').'
'; } else { $to_return.='
'.esc_html__('You don\'t have enough cloud storage and data to upload a new item. Please delete some videos or upgrade your plan.','wpstream').'
'; } return $to_return; } if($formInputs['success'] ===true){ $to_return.='
'; $to_return.='
'.esc_html__('Please select or drop a video file. Do not close this window during the upload!','wpstream').'
'; $to_return.='
'; $to_return.=''; $to_return.=''; $to_return.='
'; $to_return.='
'.esc_html__('Drop a video file here!','wpstream').'
'; $to_return.='
'.__('The Video File must be encoded with the following settings:
Container: MP4,
Video codec: H264,
Audio codec: AAC.
Media will fail to play if it does not follow the above settings. You may use a tool like MediaInfo to verify your file. Also you may convert it with specialized software like HandBrake.','wpstream').' '.esc_html__('Accepted file extensions: .mp4, .mov','wpstream').'
'; if(is_array($formInputs)){ foreach ($formInputs['ref'] as $name => $value) { $to_return.=''; } } $to_return.='
'; $to_return.='
'; } return $to_return; } /** * Display movie list * * @since 3.0.1 */ public function wpstream_present_file_management(){ $video_list_raw = $this->main->wpstream_live_connection->wpstream_get_videos_from_api(); if ( $video_list_raw === false ) { return '
'.esc_html__('Not connected. Please connect to WpStream to upload videos.','wpstream').'
'; } $video_list_raw_array = []; if( isset( $video_list_raw['items'] ) ){ $video_list_raw_array = $video_list_raw['items']; } $keys = array_column( $video_list_raw_array, 'time' ); array_multisort($keys, SORT_DESC , $video_list_raw_array); $to_return=''; // show pending items if ( key_exists( 'pending', $video_list_raw ) && is_array( $video_list_raw['pending'] ) ) { foreach ( $video_list_raw['pending'] as $key => $video ) { $video_size = intval($video['size']/1048576); $video_name = esc_html($video['name']); if($video_name!=''): $to_return.='
'; $to_return.='
'; $to_return.='
'; $to_return.='
'.esc_html__('File Name :','wpstream').''.''.$video_name.''.$video_size.' MB
'; $to_return.='
' . esc_html__( 'The video is still processing', 'wpstream') . '
'; $to_return.='
'; endif; } } // show uploaded items if( is_array($video_list_raw['items'] ) ) { foreach ($video_list_raw_array as $key =>$video){ $video_size = intval($video['size']/1048576); $video_name = esc_html($video['name']); if($video_name!=''): $to_return.='
'; $to_return.='
'; $to_return.='
'; $to_return.='
'.esc_html__('File Name:','wpstream').''.''.$video_name.''.$video_size.' MB
'; $to_return.='
'.esc_html__('delete file','wpstream').'
'; $to_return.=''; $to_return.='
'.esc_html__('Click to download! The url will work for the next 20 minutes!','wpstream').''; $add_free_video_url=admin_url('post-new.php?post_type=wpstream_product_vod').'&new_video_name='. rawurlencode($video_name); $add_paid_video_url=admin_url('post-new.php?post_type=product').'&new_video_name='. rawurlencode($video_name); $to_return .=''.esc_html__('Create new Free-To-View VOD from this recording').''; if (class_exists('WooCommerce')) { $to_return .=''.esc_html__('Create new Pay-Per-View VOD from this recording').''; } $to_return.='
'; endif; } $current_page= get_current_screen(); } // no items to show if ( !is_array( $video_list_raw['items'] ) || ( key_exists( 'pending', $video_list_raw ) && !is_array( $video_list_raw['pending'] ) ) ) { $to_return.= '
'.esc_html__('You don\'t have any videos.','wpstream').'
'; } return $to_return; } /** * Set defualt channels values * * @since 3.0.1 */ public function wpstream_publish_wpstream_product($post_id,$post){ if( $post->post_type == 'wpstream_product' ){ update_post_meta ($post_id,'local_event_options_test','working_on_'.$post_id); update_post_meta ($post_id, 'use_global_event_options', true); $to_save_option=array(); $global_options= get_option('wpstream_user_streaming_global_channel_options'); $local_events = get_post_meta ($post_id ,'local_event_options',true) ; if( $local_events =='' ){ if( is_array($global_options) ){ foreach($global_options as $key=>$value){ $to_save_option[sanitize_key($key)]=sanitize_text_field($value); } update_post_meta ($post_id,'local_event_options',$to_save_option); } } } } /** * save meta options * * @since 3.0.1 */ public function wpstream_free_product_update_post($post_id,$post){ if(!is_object($post) || !isset($post->post_type)) { return; } if( $post->post_type == 'wpstream_product' || $post->post_type == 'wpstream_product_vod' ): $allowed_keys=array( 'wpstream_product_type', 'wpstream_free_video', 'wpstream_free_video_external', 'wpstream_closed_captions_file' ); foreach ($_POST as $key => $value) { if( !is_array ($value) ){ if (in_array ($key, $allowed_keys)) { $postmeta = sanitize_text_field ( $value ); update_post_meta($post_id, sanitize_key($key), $postmeta ); } } } endif; } /** * save meta options * * @since 3.0.1 */ public function add_wpstream_product_metaboxes() { global $post; $post_id = $post->ID; add_meta_box( 'add_wpstream_product_metaboxes-sectionid', esc_html__( 'Video On Demand Settings', 'wpstream' ),array($this,'display_meta_options'),'wpstream_product_vod' ,'normal','default'); add_meta_box( 'custom_metabox_video_collection', esc_html__( 'Video Collection', 'wpstream' ), 'wpstream_bundle_custom_metabox_callback', 'wpstream_bundles', 'normal', 'high' ); if(function_exists('wc_get_product')): $product = wc_get_product( $post_id ); if ( $product ) { if ( $product->get_type() === 'wpstream_bundle' ) { add_meta_box( 'wpstream_woo_custom_metabox', esc_html__( 'Video Collection Options', 'wpstream' ), 'wpstream_bundle_custom_metabox_callback', 'product', 'normal', 'default' ); } } endif; } /** * make woocomerce virtual products * * @since 3.0.1 */ public function wpstream_make_product_virtual($post_id,$post){ global $post; if(isset($post->ID)){ if ( $post->post_type !== 'product' ) return; $term_list = wp_get_post_terms($post->ID, 'product_type'); if( !empty($term_list) && isset($term_list[0]->name) && in_array($term_list[0]->name, ['live_stream', 'video_on_demand', 'wpstream_bundle']) ){ update_post_meta( $post->ID, '_virtual', 'yes' ); } } } /** * render meta options * * @since 3.0.1 */ public function display_meta_options( $post ) { wp_nonce_field( plugin_basename( __FILE__ ), 'estate_agent_noncename' ); global $post; $is_live = ''; $is_video = ''; $is_video_external = ''; if( isset( $_GET['new_video_name']) && $_GET['new_video_name']!='' ){ $is_video = ' selected '; $wpstream_free_video = esc_html( $_GET['new_video_name']); }else{ $wpstream_product_type = esc_html(get_post_meta($post->ID, 'wpstream_product_type', true)); $wpstream_free_video = esc_html(get_post_meta($post->ID, 'wpstream_free_video', true)); if($wpstream_product_type==1){ $is_live = ' selected '; } if($wpstream_product_type==2){ $is_video = ' selected '; } if($wpstream_product_type==3){ $is_video_external = ' selected '; } } print'


'; $video_list = $this->main->wpstream_live_connection->wpstream_get_videos(); print '
'; print '

'; print '
'; print '

'; $wpstream_closed_captions_file = get_post_meta($post->ID, 'wpstream_closed_captions_file', true); $button_style = $wpstream_closed_captions_file ? 'style="display:none;"' : ''; print '

'; print '
'.( $wpstream_closed_captions_file ? esc_html( basename( $wpstream_closed_captions_file ) ) : '' ).''; if ( $wpstream_closed_captions_file ) { print ''; } print '

'; print '
'; $wpstream_free_video_external= esc_html(get_post_meta($post->ID, 'wpstream_free_video_external', true)); print '

'; if($wpstream_product_type==2){ $show_recording=''; $show_external='style="display:none"'; }else{ $show_recording='style="display:none"'; $show_external=''; } print '

'.esc_html__('Choose one of your existing recordings.','wpstream').'

'; print '

'.esc_html__('Upload a video from your computer or paste the URL of a YouTube/external video.','wpstream').'

'; print '
'; } /** * Add new product types to Woocommerce select product type * * @since 3.0.1 */ public function wpstream_add_products( $types ){ $types[ 'live_stream' ] = __( 'Live Channel','wpestream' ); $types[ 'video_on_demand' ] = __( 'Video On Demand','wpestream' ); return $types; } public function wpstream_add_products_class( $classname, $product_type ) { if ( 'live_stream' === $product_type ) { $classname = 'WC_Product_Live_Stream'; } if ( 'video_on_demand' === $product_type ) { $classname = 'WC_Product_Video_On_Demand'; } return $classname; } public function wpstream_add_custom_wc_products() { if( class_exists( 'WooCommerce' ) ){ require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_live_stream.php'; require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_video_on_demand.php'; } } /** * Js action to do when user pick live stream or video on demand * * @since 3.0.1 */ /** * Whether WpStream WooCommerce product UI should load for this product. * * Skips simple, course, and other non-WpStream types so LearnDash and * other integrations can use the General product data tab without conflict. * * @param int $post_id Product post ID. Uses global $post when 0. * @return bool */ public function wpstream_is_wpstream_wc_product_context( $post_id = 0 ) { if ( isset( $_GET['new_stream'] ) || isset( $_GET['new_video_name'] ) ) { return true; } if ( ! $post_id ) { global $post; $post_id = ( $post && isset( $post->ID ) ) ? (int) $post->ID : 0; } if ( ! $post_id || ! function_exists( 'wc_get_product' ) ) { return false; } $product = wc_get_product( $post_id ); if ( ! $product ) { return false; } return in_array( $product->get_type(), array( 'live_stream', 'video_on_demand', 'wpstream_bundle', 'subscription' ), true ); } /** * Js action to do when user pick live stream or video on demand * * @since 3.0.1 */ public function wpstream_products_custom_js() { if ( 'product' != get_post_type() ) : return; endif; if ( ! $this->wpstream_is_wpstream_wc_product_context() ) { return; } ?> get_id(); $term_list = wp_get_post_terms($product_id, 'product_type'); $subscription_model = intval( get_option('wpstream_global_sub','')) ; if($subscription_model==1){ // if we have Neflix mode if( $term_list[0]->name=='live_stream' || $term_list[0]->name=='video_on_demand' || $term_list[0]->name=='wpstream_bundle' ){ return false; } } return $purchaseable_product_wpblog; } /** * Add custom fields to custom product types * * @since 3.0.1 */ public function wpstream_add_custom_general_fields() { global $woocommerce, $post; if ( ! $this->wpstream_is_wpstream_wc_product_context( isset( $post->ID ) ? (int) $post->ID : 0 ) ) { return; } if(function_exists('wcs_user_has_subscription')){ echo '
'; woocommerce_wp_select( array( 'id' => '_subscript_live_event', 'label' => __( 'Is a subscription based live channel ?', 'woocommerce' ), 'options' => array("yes"=>"yes","no"=>"no", "none" => "none") ) ); echo '
'; } echo '
'; echo '
'; $selected=''; if( isset( $_GET['new_video_name']) && $_GET['new_video_name']!='' ){ $selected=esc_html($_GET['new_video_name']); } if($selected==''){ $selected= get_post_meta($post->ID,'_movie_url',true); } if( !current_user_can('administrator') ){ print '
'.esc_html('You need to be an administrator in order to assign videos','wpstream').'
'; }else{ woocommerce_wp_select( array( 'id' => '_movie_url', 'label' => __( 'Choose video', 'woocommerce' ), 'options' => $this->main->wpstream_live_connection->wpstream_get_videos(), 'selected'=> true, 'value' => $selected ) ); } echo '
'; if(function_exists('wcs_user_has_subscription')){ $selected_sub=''; echo '
'; if( isset( $_GET['wpstream_parent_sub']) && $_GET['wpstream_parent_sub']!='' ){ $selected_sub=esc_html($_GET['wpstream_parent_sub']); } if($selected_sub==''){ $selected_sub= get_post_meta($post->ID,'_wpstream_parent_sub',true); } woocommerce_wp_select( array( 'id' => '_wpstream_parent_sub', 'name' => '_wpstream_parent_sub[]', 'label' => __( 'Attach to subscription', 'woocommerce' ), 'options' => $this->wpstream_return_subscriptions_created(), 'selected'=> true, 'value' => $selected_sub, 'custom_attributes' => array('multiple' => 'multiple') ) ); echo '
'; } } public function wpstream_return_subscriptions_created(){ $return=array('0'=>'none'); $args = array( 'post_type' => 'product', 'posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => array( 'subscription'), ) ) ); $subscriptions = new WP_Query($args); if($subscriptions->have_posts()): while ($subscriptions->have_posts()): $subscriptions->the_post(); $return[ get_the_ID() ] = get_the_title(); endwhile; endif; wp_reset_postdata(); return $return; } /** * Save custom fields * * @since 3.0.1 */ public function wpstream_add_custom_general_fields_save( $post_id ){ if ( ! $this->wpstream_is_wpstream_wc_product_context( (int) $post_id ) ) { return; } $permited_values = array( '_movie_url', '_subscript_live_event', '_wpstream_parent_sub', ); foreach($_POST as $key=>$value){ update_post_meta( $post_id, 'event_passed', 0 ); if( in_array($key, $permited_values) ){ if( !empty( $_POST[$key] ) ){ $key = sanitize_key($key); $value = sanitize_text_field($_POST[$key]); if($key=='_wpstream_parent_sub'){ $value= $_POST[$key]; $value = array_map("sanitize_text_field", $value); } update_post_meta( $post_id, $key, $value ); } } } //die(); } /** * Add to cart redirect * * @since 3.0.1 */ public function wpstream_add_to_cart() { wc_get_template( 'single-product/add-to-cart/simple.php' ); } /** * Replace add to cart button * * @since 3.0.1 */ public function replacing_add_to_cart_button( $button, $product ) { global $product; $product_type = $product->get_type(); if($product_type==='live_stream' || $product_type=='video_on_demand'){ return $button = '' . __( 'Add to Cart', 'woocommerce' ) . ''; }else{ return $button; } } /** * Admin notices * * @since 3.0.1 */ public function wpstream_admin_notice() { global $pagenow; global $typenow; $wpstream_notices = get_option('wpstream_notices'); /* if ( !in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { if( !is_array($wpstream_notices) || !isset($wpstream_notices['wpstream_woo_notice']) || ( isset($wpestate_notices['wpstream_woo_notice']) && $wpestate_notices['wpstream_woo_notice']!='yes') ){ print '

'.__( 'WpStream Pay-Per-View Live Streaming and VOD only works with WooCommerce - Please enable and activate the WooCommerce plugin if you want to monetize your Live Events or Recorded Videos', 'wpstream' ).'

'; } } */ if( !in_array ('curl', get_loaded_extensions())) { print '

'.__( 'The php CURL library is not enabled on your server. WpStream plugin needs this library in order to work. Please address this issue with your hosting provider.', 'wpstream' ).'

'; } $ajax_nonce = wp_create_nonce( "wpstream_notice_nonce" ); print ''; } /** * Get plugin latest update release date from WordPress.org * @param $plugin_slug * @param $version * * @return bool */ public function get_plugin_release_date( $plugin_slug, $version = null ) { $api_url = 'https://api.wordpress.org/plugins/info/1.0/' . $plugin_slug . '.json'; $response = wp_remote_get( $api_url ); if ( is_wp_error( $response ) ) { return false; } $body = wp_remote_retrieve_body( $response ); $data = json_decode( $body, true ); if ( !$data || !isset( $data['versions'] ) ) { return false; } // no version provided, get the latest version if ( !$version ) { $version = $data['version']; } // check if the version exists in the versions array if ( !isset( $data['versions'][ $version ] ) ) { return false; } if ( isset( $data['last_updated'] ) ) { return date('Y-m-d', strtotime( $data['last_updated'] ) ); } return false; } /** * Adds notice for the WpStream update availability * when the update is not older than 30 days */ public function wpstream_plugin_update_available_notice() { if (!current_user_can('update_plugins')) { return; } $plugin_slug = 'wpstream/wpstream.php'; $update_data = get_site_transient('update_plugins'); if ( is_object( $update_data ) && property_exists( $update_data, 'response' ) && is_array($update_data->response) && key_exists($plugin_slug, $update_data->response) ) { $new_version = $update_data->response[$plugin_slug]->new_version; $release_date = $this->get_plugin_release_date( 'wpstream', $new_version ); if ( $release_date ) { $days_since_release = ( time() - strtotime( $release_date ) ) / DAY_IN_SECONDS; // if there's an update newer than 7 days, do not show the notice if ( $days_since_release < 7 ) { return; } } $update_url = wp_nonce_url( self_admin_url('update.php?action=upgrade-plugin&plugin=' . urlencode($plugin_slug)), 'upgrade-plugin_' . $plugin_slug ); echo '
'; echo '

' . __('WpStream Plugin Update Available', 'wpstream') . '

'; echo '

' . sprintf( __('Version %s is available. Please update to the latest version for new features and security improvements.', 'wpstream'), '' . esc_html($new_version) . '' ) . '

'; echo '

' . __('Update Now', 'wpstream') . '

'; echo '
'; } } /** * Admin notices * * @since 3.0.1 */ public function wpstream_update_cache_notice(){ //check_ajax_referer( 'wpstream_notice_nonce', 'security' ); $notice_type = esc_html($_POST['notice_type']); $notices = get_option('wp_stream_notices'); if(! is_array($notices) ){ $notices=array(); } $notices[$notice_type]='yes'; update_option('wpstream_notices',$notices); die(); } /** * Activate metaboxes for Streaming controls on sidebar * * @since 3.0.1 */ public function wpstream_startstreaming_sidebar_meta() { global $post; $term_list = wp_get_post_terms($post->ID, 'product_type'); add_meta_box( 'wpstream-sidebar-meta', esc_html__('Live Streaming', 'wpstream'), array($this,'wpstream_start_stream_meta'), 'wpstream_product', 'side', 'high' ); $is_subscription_live_event = esc_html(get_post_meta($post->ID,'_subscript_live_event',true)); if(!is_wp_error( $term_list )){ if( isset($term_list[0]->name) ){ if( $term_list[0]->name=='live_stream' || ($term_list[0]->name=='subscription' && $is_subscription_live_event=='yes' ) ){ add_meta_box('wpstream-sidebar-meta', esc_html__('Live Streaming', 'wpstream'), array($this,'wpstream_start_stream_meta'), 'product', 'side', 'high'); } } } } /** * edited 4.0 * * Show Streaming controls on sidebar * * @since 3.0.1 */ public function wpstream_start_stream_meta(){ global $live_event_for_user; $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user(); global $post; $local_event_options = get_post_meta ($post->ID,'local_event_options',''); if( get_post_status( $post->ID ) === 'publish' ) { $ajax_nonce = wp_create_nonce( "wpstream_start_event_nonce" ); print ''; $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_new_general_set' ); if( isset($pack_details['available_data_mb'])){ if ($pack_details['available_data_mb'] <= 0){ print ''; } } $this->wpstream_live_stream_unit($post->ID); print '
'; print '
er1
'.esc_html__('Close','wpstream').'
'; } else { esc_html_e('To Go Live, please publish your channel first !','wpstream'); } } public function wpstream_is_basic_streaming_mode(){ return $this->main->quota_manager->is_basic_streaming_mode( null, 'wpstream_is_basic_streaming_mode' ); } public function wpstream_is_use_streaming_hours() { $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_start_channel' ); return $this->main->quota_manager->uses_streaming_hours( $pack_details ); } /** * * * */ public function add_dashboard_page() { add_dashboard_page( '', '', 'administrator', 'wpstream-onboarding', '' ); } public function wpstream_load_onboarding_wizard() { // Check for wizard-specific parameter // Allow plugins to disable the onboarding wizard // Check if current user is allowed to save settings. // Don't load the interface if doing an ajax call. if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { return; } set_current_screen(); // Remove an action in the Gutenberg plugin ( not core Gutenberg ) which throws an error. remove_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' ); $this->actual_load_onboarding_wizard(); } /* * Add on boarding to footer */ public function wpstream_admin_footer_onboarding(){ if( isset($_GET['page']) && $_GET['page']==='wpstream_onboard') { $this->wpstream_onboard_display(); } } /* * On Board Display * */ public function wpstream_pre_onboard_display(){ $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_pre_onboard_display' ); $this->main->show_user_data($pack_details); $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/logo_onboarding.svg'; ?>

'.esc_html__('Quick Start','wpstream').'';?>

onboarding_wizard_header(); $this->wpstream_onboarding_step1(); $this->wpstream_onboarding_step2(); $this->wpstream_onboarding_step3_live_streaming(); $this->wpstream_onboarding_step_3_A_live_streaming_free_view(); $this->wpstream_onboarding_step_3_B_live_streaming_pay_per_view(); $this->wpstream_onboarding_step4_vod(); $this->wpstream_onboarding_step_4_free_vod(); $this->wpstream_onboarding_step_4_ppv_vod(); $this->onboarding_wizard_footer(); } /* * * On Boarding Step 1 - the login/register * */ public function wpstream_onboarding_step1(){ $wpstream_options_array =array( 2 => array( 'label' => 'WpStream.net Username or Email', 'name' => 'api_username', 'type' => 'text', ), 3 => array( 'label' => 'WpStream.net Password', 'name' => 'api_password', 'type' => 'password', ), ); $token = $this->main->wpstream_live_connection->wpstream_get_token(); ?>

'; ?>
'; } } /* * * Generate random pass * */ public function randomPassword() { $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; $pass = array(); //remember to declare $pass as an array $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache for ($i = 0; $i < 16; $i++) { $n = random_int(0, $alphaLength); $pass[] = $alphabet[$n]; } return implode($pass); //turn the array into a string } /* * * * */ public function wpstream_onboarding_step2(){ ?>

Welcome to WpStream! How would you like to start?

or

or

wpstream_onboarding_woo_warning(); } ?>
'.esc_html__('Pay-Per-View streaming requires WooCommerce. Please install the WooCommerce plugin and try again.','wpstream').'
'. esc_html__('Install WooCommerce','wpstream').'
'.esc_html__('Try Again','wpstream').'
'; } /* * * * */ public function wpstream_onboarding_step4_vod(){ ?>

or
">
base !=='wpstream_page_wpstream_onboard'){ return; } ?>

wpstream_obboarding_file_warning(); ?>
'.esc_html__('A recording is needed to create a VOD from. There are no recordings under your account. You can create new recordings by recording a live channel or uploading video files directly.','wpstream').'
'.esc_html__('Upload Video','wpstream').'
'.esc_html__('Try Again','wpstream').'
'; } /* * * * */ public function wpstream_onboarding_step_4_ppv_vod(){ $current_screen=get_current_screen(); if($current_screen->base !=='wpstream_page_wpstream_onboard'){ return; } ?>

wpstream_obboarding_file_warning(); ?> wpstream_onboarding_woo_warning(); } ?>
$channel_name, 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'product', 'post_author' => $current_user->ID ); // Insert the post into the database $post_id = wp_insert_post( $my_post ); if(is_wp_error($post_id)){ $logger = new WPStream_Logger(); $log_entry = new WpStream_Log_Entry([ 'type' => 'error', 'description' => 'Couldn\'t create channel during onboarding because of error: ' . $post_id->get_error_message(), ]); $logger->add( $log_entry ); echo json_encode( array('succes'=>false) ); }else{ $product = wc_get_product($post_id); $price = wc_format_decimal($channel_price); $product = wc_get_product( $post_id ); $product->set_price( $price ); $product->set_regular_price( $price ); // To be sure $product->save(); update_post_meta ($post_id,'event_passed',0); wp_set_object_terms( $post_id, 'live_stream', 'product_type' ); $permalink = get_edit_post_link($post_id); $permalink= add_query_arg( 'onboard', 'yes', $permalink ); $permalink= add_query_arg( 'branch', '2', $permalink ); echo json_encode( array( 'success'=> true, 'link' => ($permalink) )); } } die(); } /* * * On Boarding create channel * */ public function wpstream_on_board_create_channel(){ check_ajax_referer( 'wpstream_onboarding_nonce', 'security' ); $current_user = wp_get_current_user(); if(current_user_can('administrator')){ $channel_name=sanitize_text_field($_POST['channel_name']); $my_post = array( 'post_title' => $channel_name, 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'wpstream_product', 'post_author' => $current_user->ID ); // Insert the post into the database $post_id = wp_insert_post( $my_post ); if( is_wp_error( $post_id ) ) { $logger = new WPStream_Logger(); $log_entry = new WpStream_Log_Entry([ 'type' => 'error', 'description' => 'Couldn\'t create channel during onboarding because of error: ' . $post_id->get_error_message(), ]); $logger->add( $log_entry ); echo json_encode( array('succes'=>false) ); } else { $permalink = get_edit_post_link($post_id); $permalink= add_query_arg( 'onboard', 'yes', $permalink ); $permalink= add_query_arg( 'branch', '1', $permalink ); echo json_encode( array( 'success'=> true, 'link' => ($permalink) )); } } die(); } /* * * On Boarding create free vod * */ public function wpstream_on_board_create_free_vod(){ $current_user = wp_get_current_user(); check_ajax_referer( 'wpstream_onboarding_nonce', 'security' ); if(current_user_can('administrator')){ $channel_name =sanitize_text_field($_POST['channel_name']); $file_name =sanitize_text_field($_POST['file_name']); $my_post = array( 'post_title' => $channel_name, 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'wpstream_product_vod', 'post_author' => $current_user->ID ); // Insert the post into the database $post_id = wp_insert_post( $my_post ); if(is_wp_error($post_id)){ $logger = new WPStream_Logger(); $log_entry = new WpStream_Log_Entry([ 'type' => 'error', 'description' => 'Couldn\'t create free VOD during onboarding because of error: ' . $post_id->get_error_message(), ]); $logger->add( $log_entry ); echo json_encode( array('succes'=>false) ); }else{ update_post_meta($post_id, 'wpstream_product_type', 2); update_post_meta($post_id, 'wpstream_free_video', $file_name); $permalink = get_edit_post_link($post_id); $permalink= add_query_arg( 'onboard', 'yes', $permalink ); $permalink= add_query_arg( 'branch', '3', $permalink ); echo json_encode( array( 'success'=> true, 'link' => ($permalink) )); } } die(); } /* * * On Boarding create ppv vod * */ public function wpstream_on_board_create_ppv_vod(){ $current_user = wp_get_current_user(); check_ajax_referer( 'wpstream_onboarding_nonce', 'security' ); if(current_user_can('administrator')){ $channel_name = sanitize_text_field($_POST['channel_name']); $vod_price = floatval($_POST['vod_price']); $file_name = sanitize_text_field($_POST['file_name']); $my_post = array( 'post_title' => $channel_name, 'post_content' => '', 'post_status' => 'publish', 'post_type' => 'product', 'post_author' => $current_user->ID ); // Insert the post into the database $post_id = wp_insert_post( $my_post ); if( is_wp_error( $post_id ) ) { $logger = new WPStream_Logger(); $log_entry = new WpStream_Log_Entry([ 'type' => 'error', 'description' => 'Couldn\'t create PPV VOD during onboarding because of error: ' . $post_id->get_error_message(), ]); $logger->add( $log_entry ); echo json_encode( array('succes'=>false) ); } else { $product = wc_get_product($post_id); $price = wc_format_decimal($vod_price); $product = wc_get_product( $post_id ); $product->set_price( $price ); $product->set_regular_price( $price ); // To be sure $product->save(); update_post_meta ($post_id,'event_passed',0); update_post_meta ($post_id,'_movie_url', $file_name); wp_set_object_terms( $post_id, 'video_on_demand', 'product_type' ); $permalink = get_edit_post_link($post_id); $permalink= add_query_arg( 'onboard', 'yes', $permalink ); $permalink= add_query_arg( 'branch', '4', $permalink ); echo json_encode( array( 'success'=> true, 'link' => ($permalink) , ' $file_name'=> $file_name, )); } } die(); } /* * * On Boarding login * */ public function wpstream_on_board_login(){ check_ajax_referer( 'wpstream_onboarding_nonce', 'security' ); if(current_user_can('administrator')){ $username = sanitize_text_field($_POST['api_username']); $password = $_POST['api_password']; update_option('wpstream_api_username',$username); update_option('wpstream_api_password',$password); delete_transient( 'wpstream_token_api' ); $token = $this->main->wpstream_live_connection->wpstream_get_token(); $videos_list = $this->main->wpstream_live_connection->wpstream_get_videos(); // cleanup any previous echo before sending json ob_end_clean(); // !DO NOT SEND TOKEN TO THE CLIENT! if ($token){ echo json_encode( array( 'success'=> true )); } else { $text = get_option('wpstream_curl_failed') ? 'Login failed with critical error: ' . get_option('wpstream_curl_failed') : 'Wrong username or password!'; echo json_encode( array( 'success'=> false, 'error' => $text, )); } }else{ echo json_encode( array( 'success'=> false, 'token' => esc_html('You are not an administrator','wpstream') )); } die(); } public function wpstream_register_refresh_capthca(){ if(current_user_can('administrator')){ } } /** * AJAX proxy: fetch a captcha challenge from the baker API and return it. * Used on HTTP sites where the Altcha widget cannot run (requires Web Crypto / HTTPS). * The JS side solves the PoW locally and sends back the full base64 Altcha payload. */ public function wpstream_get_captcha_challenge() { $api_url = WPSTREAM_API . '/v2/user/getcaptcha'; $response = wp_remote_get( $api_url, array( 'timeout' => 10 ) ); if ( is_wp_error( $response ) ) { echo json_encode( array( 'success' => false, 'error' => 'Could not reach captcha service.' ) ); die(); } $body = wp_remote_retrieve_body( $response ); // Forward the challenge JSON directly to the browser header( 'Content-Type: application/json' ); echo $body; die(); } /** * @param $challenge * @param $difficulty * * @return int|null */ private function solve_pow( $challenge, $difficulty ) { $nonce = 0; $target = str_repeat( "0", $difficulty ); while ( $nonce < 5000000 ) { $hash = hash( 'sha256', $challenge . $nonce ); if ( strpos( $hash, $target ) === 0 ) { return $nonce; } $nonce++; } return null; // Return null if no solution is found within the max attempts } /* * * On Boarding login * */ public function wpstream_on_board_register(){ check_ajax_referer( 'wpstream_onboarding_nonce', 'security' ); if(current_user_can('administrator')){ $wpstream_register_email = sanitize_text_field($_POST['wpstream_register_email']); $wpstream_register_password = $_POST['wpstream_register_password']; $validate = $this->wpstream_validate_onboard_register($wpstream_register_email,$wpstream_register_password); if(!$validate['success']){ // cleanup any previous echo before sending json ob_end_clean(); echo json_encode($validate); die(); } $wpstream_altcha = isset($_POST['wpstream_altcha']) ? trim( $_POST['wpstream_altcha'] ) : ''; $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'; if ( empty($wpstream_altcha) ) { if ( $is_https ) { $message = esc_html__('Captcha verification failed. Please try again.', 'wpstream'); } else { $message = esc_html__('Security check not ready yet. Please wait a moment and try again.', 'wpstream'); } echo json_encode( array( 'success' => false, 'message' => $message ) ); die(); } $url='v2/user/create'; $curl_post_fields=array( 'email' => $wpstream_register_email, 'password' => $wpstream_register_password, 'solution' => $wpstream_altcha, 'captcha_id' => '', ); $curl_response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url,$curl_post_fields,true); $curl_response_decoded = json_decode($curl_response,JSON_OBJECT_AS_ARRAY); if($curl_response_decoded['success']){ if($curl_response_decoded['request']['registred']){ // we are registerd update_option('wpstream_api_username',$wpstream_register_email); update_option('wpstream_api_password',$wpstream_register_password); $token = $this->main->wpstream_live_connection->wpstream_get_token(); // cleanup any previous echo before sending json ob_end_clean(); echo json_encode( array( 'success' => true, 'token' => $token , 'message' => esc_html__('Your Account was created. Please stand by...','wpstream'), )); die(); }else{ // cleanup any previous echo before sending json ob_end_clean(); echo json_encode( array( 'success'=> false, 'message'=> $curl_response_decoded['request']['message'], 'curl'=>$curl_response_decoded, )); die(); } }else{ // cleanup any previous echo before sending json ob_end_clean(); echo json_encode( array( 'success'=> false, 'message'=> esc_html__('Registration could not be completed. Please try again or register on wpstream.net','wpstream'), )); die(); } }else{ // cleanup any previous echo before sending json ob_end_clean(); echo json_encode( array( 'success'=> false, 'message' => esc_html('You are not an administrator','wpstream') )); die(); } die(); } /* * * Validate for register * */ public function wpstream_validate_onboard_register($wpstream_register_email,$wpstream_register_password){ $return= array( 'success'=>true ); if ($wpstream_register_email=='' ){ $return= array( 'success'=> false, 'message' => esc_html('The email Field is Empty','wpstream') ); return $return;die(); } if(filter_var($wpstream_register_email,FILTER_VALIDATE_EMAIL) === false) { $return= array( 'success'=> false, 'message' => esc_html__('The email doesn\'t look right !','wpstream') ); return $return;die(); } $domain = mb_substr(strrchr($wpstream_register_email, "@"), 1); if( $domain!='' && !checkdnsrr ($domain) ){ $return= array( 'success'=> false, 'message' => esc_html__('The email doesn\'t look right !','wpstream') ); return $return;die(); } if(strlen($wpstream_register_password)<5){ $return= array( 'success'=> false, 'message' => esc_html('The password is too short. Please use at least 5 characters.','wpstream') ); return $return;die(); } return $return;die(); } /** * Handle the AJAX request to initiate a multipart upload * * @since 3.0.1 */ public function handle_initiate_multipart_upload() { check_ajax_referer( 'wpstream_multipart_upload_nonce', 'security' ); // Security check - only admins can do this if (!current_user_can('administrator')) { wp_send_json_error('Unauthorized access'); return; } // Get file details from request $file_name = sanitize_text_field($_POST['file_name']); $file_size = intval($_POST['file_size']); $content_type = sanitize_text_field($_POST['content_type']); $num_parts = intval($_POST['parts']); if (empty($file_name) || $file_size <= 0 || $num_parts <= 0) { wp_send_json_error('Invalid file information'); return; } // Prepare a clean filename (similar to the standard upload process) $file_name_array = explode(".", $file_name); $file_extension = $file_name_array[count($file_name_array) - 1]; $temp_file_name = $file_name_array[0]; $temp_file_name = str_replace(' ', '_', $temp_file_name); $temp_file_name = preg_replace('/\W/', '', $temp_file_name); $clean_file_name = $temp_file_name . '.' . $file_extension; // Make API call to initiate multipart upload $url = 'video/upload'; $access_token = $this->main->wpstream_live_connection->wpstream_get_token(); if (!$access_token) { wp_send_json_error('Not connected to WPStream service'); return; } $api_params = array( 'access_token' => $access_token, 'size' => $file_size, 'name' => $clean_file_name, 'content_type' => $content_type, 'parts' => $num_parts ); $response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url, $api_params, true); $response_data = json_decode($response, true); if (!isset($response_data['success']) || $response_data['success'] !== true) { $error_message = isset($response_data['error']) ? $response_data['error'] : 'Failed to initiate multipart upload'; wp_send_json_error($error_message); return; } // Return the upload ID and pre-signed URLs for each part wp_send_json_success($response_data); } /** * Handle the AJAX request to complete a multipart upload * * @since 3.0.1 */ public function handle_complete_multipart_upload() { check_ajax_referer( 'wpstream_multipart_upload_nonce', 'security' ); // Security check - only admins can do this if (!current_user_can('administrator')) { wp_send_json_error('Unauthorized access'); return; } // Get completion details $parts = json_decode(stripslashes($_POST['parts']), true); $file_name = sanitize_text_field($_POST['file_name']); $handle = sanitize_text_field($_POST['handle']); if (empty($parts) || !is_numeric($parts) || empty($file_name)) { wp_send_json_error('Invalid completion information'); return; } // Make API call to complete the multipart upload $url = 'video/upload'; $access_token = $this->main->wpstream_live_connection->wpstream_get_token(); if (!$access_token) { wp_send_json_error('Not connected to WPStream service'); return; } $api_params = array( 'access_token' => $access_token, 'parts' => $parts, 'name' => $file_name, 'handle' => $handle, 'action' => 'complete' ); $response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url, $api_params, true); $response_data = json_decode($response, true); if (!isset($response_data['success']) || $response_data['success'] !== true) { $error_message = isset($response_data['error']) ? $response_data['error'] : 'Failed to complete multipart upload'; wp_send_json_error($error_message); return; } // Return success wp_send_json_success(); } public function wpstream_settings_tab_update_plugin() { if ( !current_user_can( 'update_plugins' ) ) { wp_send_json_error( __( 'Not enough permissions to make this change', 'wpstream' ) ); } include_once ABSPATH . 'wp-admin/includes/plugin-install.php'; include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php'; include_once ABSPATH . 'wp-admin/includes/file.php'; $credentials = request_filesystem_credentials(''); if ( !WP_Filesystem( $credentials ) ) { wp_send_json_error( __( 'Failed to connect to the filesystem', 'wpstream' ) ); } $upgrader = new Plugin_Upgrader(new Automatic_Upgrader_Skin()); $plugin_path = plugin_basename( WPSTREAM_PLUGIN_PATH . 'wpstream.php' ); $result = $upgrader->upgrade( $plugin_path ); activate_plugin( $plugin_path ); if ( is_wp_error( $result ) ) { wp_send_json_error( __( 'Update failed due to', 'wpstream' ) . $result->get_error_message() ); } wp_send_json_success(); } }