PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 4.13.1
WpStream – Live Streaming, Video on Demand, Pay Per View v4.13.1
4.14.1 4.14.0 4.13.2 4.13.1 4.13 4.12.5 4.12.4 4.12.3 4.12.2 4.12.1 4.12 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5 4.5.1 4.5.11 4.5.11.1 4.5.11.2 4.5.11.4 4.5.11.5 4.5.11.6 All 181 releases
wpstream / admin / class-wpstream-admin.php

class-wpstream-admin.php in WpStream – Live Streaming, Video on Demand, Pay Per View 4.13.1, at admin/class-wpstream-admin.php

4,627 lines 233.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * The admin-specific functionality of the plugin.
5 *
6 * @link http://wpstream.net
7 * @since 3.0.1
8 *
9 * @package Wpstream
10 * @subpackage Wpstream/admin
11 */
12
13 /**
14 * The admin-specific functionality of the plugin.
15 *
16 * Defines the plugin name, version, and two examples hooks for how to
17 * enqueue the admin-specific stylesheet and JavaScript.
18 *
19 * @package Wpstream
20 * @subpackage Wpstream/admin
21 * @author wpstream <office@wpstream.net>
22 */
23 class Wpstream_Admin {
24
25
26 /**
27 * Store plugin main class to allow public access.
28 *
29 * @since 20180622
30 * @var object The main class.
31 */
32 public $main;
33
34
35 /**
36 * The ID of this plugin.
37 *
38 * @since 3.0.1
39 * @access private
40 * @var string $plugin_name The ID of this plugin.
41 */
42 private $plugin_name;
43
44 /**
45 * The version of this plugin.
46 *
47 * @since 3.0.1
48 * @access private
49 * @var string $version The current version of this plugin.
50 */
51 private $version;
52
53 /**
54 * Initialize the class and set its properties.
55 *
56 * @since 3.0.1
57 * @param string $plugin_name The name of this plugin.
58 * @param string $version The version of this plugin.
59 */
60
61 public $global_event_options ;
62
63
64
65
66
67 public function __construct( $plugin_name, $version,$plugin_main ) {
68
69 $this->plugin_name = $plugin_name;
70 $this->version = $version;
71 $this->main = $plugin_main;
72
73 add_action('init', array($this, 'load_global_event_options'));
74 }
75
76 public function load_global_event_options() {
77 $this->global_event_options = array(
78 'record' => array(
79 'name' => esc_html__('Record Live Stream','wpstream'),
80 'details' => esc_html__('If enabled, live streams will be recorded and saved to your library.','wpstream'),
81 'defaults' => 'no',
82 ),
83 'view_count' => array(
84 'name' => esc_html__('Display Viewer Count','wpstream'),
85 'details' => esc_html__('If enabled, the live viewer count will show up in the player.','wpstream'),
86 'defaults' => 'yes',
87 ),
88 'domain_lock' => array(
89 'name' => esc_html__('Lock To Website','wpstream'),
90 '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') ),
91 'defaults' => 'no',
92 ),
93 'autoplay' => array(
94 'name' => esc_html__('Autoplay','wpstream'),
95 'details' => esc_html__('If enabled, live video will attempt to start playing automatically. This is only achievable in some browsers.','wpstream'),
96 'defaults' => 'yes',
97 ),
98 'mute' => array(
99 'name' => esc_html__('Start Muted','wpstream'),
100 'details' => esc_html__('If enabled, live video will start muted. This may increase the rate of autoplay in some browsers. ','wpstream'),
101 'defaults' => 'no',
102 ),
103 'low_latency' => array(
104 'name' => esc_html__('Low Latency (beta)','wpstream'),
105 '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'),
106 'defaults' => 'no',
107 ),
108 'adaptive_bitrate' => array(
109 'name' => esc_html__('Adaptive Bitrate (beta)','wpstream'),
110 'details' => esc_html__('Ensures a smooth and uninterrupted viewing experience by adjusting video quality for viewers with reduced network speed or device capabilities.','wpstream'),
111 'defaults' => 'no',
112 ),
113 'encrypt' =>array(
114 'name' => esc_html__('Encrypt Live Stream','wpstream'),
115 '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'),
116 'defaults' => 'no',
117 ),
118 'ses_encrypt'=>array(
119 'name' => esc_html__('Use Sessions with Encryption','wpstream'),
120 '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'),
121 'defaults' => 'no',
122 ),
123 // 'autostart' =>array(
124 // 'name' => esc_html__('Auto TURN ON','wpstream'),
125 // 'details' => esc_html__('If enabled, channel will TURN ON automatically when broadcasting with an External Streaming App (RTMP Encoder/Broadcaster)','wpstream'),
126 // 'defaults' => 'no',
127 // ),
128 );
129 }
130
131 /**
132 * Register the stylesheets for the admin area.
133 *
134 * @since 3.0.1
135 */
136 public function enqueue_styles() {
137
138 /**
139 * This function is provided for demonstration purposes only.
140 *
141 * An instance of this class should be passed to the run() function
142 * defined in Wpstream_Loader as all of the hooks are defined
143 * in that particular class.
144 *
145 * The Wpstream_Loader will then create the relationship
146 * between the defined hooks and the functions defined in this
147 * class.
148 */
149 wp_enqueue_style( 'wpstream-roboto', "https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700,900&display=swap&subset=latin-ext" );
150 wp_enqueue_style(
151 $this->plugin_name,
152 plugin_dir_url( __FILE__ ) . 'css/wpstream-admin.css',
153 array(),
154 filemtime(plugin_dir_path(__FILE__) . 'css/wpstream-admin.css' ),
155 'all'
156 );
157
158 wp_enqueue_style(
159 'wpstream-on-boarding-css',
160 plugin_dir_url( __FILE__ ) . 'css/wpstream-admin-onboarding.css',
161 array(),
162 filemtime(plugin_dir_path(__FILE__) . 'css/wpstream-admin-onboarding.css'),
163 );
164
165 if (!did_action('wp_enqueue_media')) {
166 wp_enqueue_media();
167 }
168 }
169
170 /**
171 * Register the JavaScript for the admin area.
172 *
173 * @since 3.0.1
174 */
175 public function enqueue_scripts() {
176
177 wp_enqueue_script("jquery-ui-slider");
178 wp_enqueue_script("jquery-ui-datepicker");
179 wp_enqueue_script('jquery.fileupload', plugin_dir_url( __FILE__ ) .'js/jquery.fileupload.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true);
180
181 wp_enqueue_script( 'wpstream-admin-utils', plugin_dir_url( __FILE__ ) .'js/utils/admin_utils.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true);
182 wp_enqueue_script('wpstream-admin-control', plugin_dir_url( __FILE__ ) .'js/admin_control.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true);
183 wp_localize_script('wpstream-admin-control', 'wpstream_admin_control_vars',
184 array(
185 'admin_url' => get_admin_url(),
186 'multipart_upload_nonce' => wp_create_nonce( 'wpstream_multipart_upload_nonce' ),
187 'loading_url' => WPSTREAM_PLUGIN_DIR_URL.'/img/loading.gif',
188 'download_mess' => esc_html__('Click to download!','wpstream'),
189 'uploading' => esc_html__('We are uploading your file. Do not close this window!','wpstream'),
190 'upload_complete2' => esc_html__('Upload Complete! You can upload another file!','wpstream'),
191 'not_accepted' => esc_html__('The file is not an accepted video format','wpstream'),
192 'upload_complete' => esc_html__('Upload Complete!','wpstream'),
193 'no_band' => esc_html__('Not enough streaming data.','wpsteam'),
194 'no_band_no_store' => esc_html__('Not enough streaming data or storage.','wpsteam'),
195 'no_streaming_hours' => esc_html__('Not enough streaming hours.','wpstream'),
196 'exceeding_limit' => esc_html__('File size exceeds 5GB. Initiating multipart upload...','wpsteam'),
197 'upload_failed' => esc_html__('Upload Failed!','wpstream'),
198 'upload_failed2' => esc_html__('Upload Failed! Please Try again!','wpstream'),
199 'choose_a_file' => esc_html__('Choose a file&hellip;','wpstream'),
200 'preparing_multipart' => esc_html__('Preparing multipart upload...','wpstream'),
201 'uploading_part' => esc_html__('Uploading part {part} of {total}...','wpstream'),
202 'upload_failed_part' => esc_html__('Failed to upload part {part}. Please try again.','wpstream'),
203 'completing_upload' => esc_html__('Completing upload. Please wait...','wpstream'),
204 'upload_failed_part_retry' => esc_html__('Failed to upload part {part}. Retrying...','wpstream'),
205 'choose_recording' => esc_html__( 'Choose Recording', 'wpstream' ),
206 'select_recording' => esc_html__( 'Please select a recording from the list', 'wpstream' ),
207 'invalid_response' => esc_html__('Invalid response from server. Missing required upload data.', 'wpstream'),
208 'video_processing' => esc_html__( 'The video is still processing', 'wpstream' ),
209 'file_name_text' => esc_html__('File Name:','wpstream'),
210 'channel_create_error' => esc_html__('Something did not work. Please try again.', 'wpstream'),
211 'select_caption_file' => esc_html__('Select .vtt Captions File', 'wpstream'),
212 'select_button' => esc_html__('Select', 'wpstream'),
213 'remove_button' => esc_html__('Remove', 'wpstream'),
214 'use_streaming_hours' => $this->wpstream_get_start_streaming_localization_flags()['use_streaming_hours'],
215 ));
216
217 wp_enqueue_script('wpstream-recordings-videos-list', plugin_dir_url( __FILE__ ) .'js/recordings_videos_list.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true);
218 wp_localize_script( 'wpstream-recordings-videos-list', 'wpstream_recordings_videos_list_vars',
219 array(
220 'delete_file' => esc_html__('Delete file', 'wpstream'),
221 'download' => esc_html__( 'Download', 'wpstream'),
222 'download_available' => esc_html__( 'Click to download! The url will work for the next 20 minutes!', 'wpstream'),
223 'add_free_video_url' => esc_url( admin_url( 'post-new.php?post_type=wpstream_product_vod') . '&new_video_name=' ),
224 'create_ftv_vod' => esc_html__( 'Create new Free-To-View VOD from this recording' , 'wpstream' ),
225 'woocommerce_exists' => class_exists( 'WooCommerce' ),
226 'add_paid_video_url' => esc_url( admin_url( 'post-new.php?post_type=product').'&new_video_name=' ),
227 'create_ptv_vod' => esc_html__( 'Create new Pay-Per-View VOD from this recording' , 'wpstream' ),
228 )
229 );
230
231 $modified_start_streaming_file_time = gmdate( 'YmdHi', filemtime( WPSTREAM_PLUGIN_PATH . 'public/js/start_streaming.js' ) );
232 wp_enqueue_script('wpstream-start-streaming_admin', plugin_dir_url( __DIR__ ) .'public/js/start_streaming.js', array(), $modified_start_streaming_file_time, true);
233 $streaming_localization_flags = $this->wpstream_get_start_streaming_localization_flags();
234 wp_localize_script('wpstream-start-streaming_admin', 'wpstream_start_streaming_vars',
235 array(
236 'admin_url' => get_admin_url(),
237 'loading_url' => WPSTREAM_PLUGIN_DIR_URL.'/img/loading.gif',
238 'download_mess' => esc_html__('Click to download!','wpstream'),
239 'uploading' => esc_html('We are uploading your file.Do not close this window!','wpstream'),
240 'upload_complete2' => esc_html('Upload Complete! You can upload another file!','wpstream'),
241 'not_accepted' => esc_html('The file is not an accepted video format','wpstream'),
242 'upload_complete' => esc_html('Upload Complete!','wpstream'),
243 'no_band' => esc_html('Not enough streaming data.','wpsteam'),
244 'no_band_no_store' => esc_html('Not enough streaming data or storage.','wpsteam'),
245
246 'start_streaming_action'=> esc_html__('TURNING ON','wpstream'),
247 'stop_streaming_action' => esc_html__('TURNING OFF','wpstream'),
248 'start_streaming' => esc_html__('TURN ON','wpstream'),
249 'stop_streaming' => esc_html__('TURN OFF','wpstream'),
250 'failed_fetching' => esc_html__('Failed to get channel info. Please try again.','wpstream'),
251 'turned_on_tooltip' => esc_html__('Channel is now OFF. Click to turn ON.','wpstream'),
252 'turned_off_tooltip' => esc_html__('Click to turn channel off. This will interrupt any ongoing broadcast.','wpstream'),
253 'turning_on_tooltip' => esc_html__('Turning a channel on may take 1-2 minutes or more. Please be patient.','wpstream'),
254 'turning_off_tooltip' => esc_html__('This may take a few minutes.','wpstream'),
255 'error1' => esc_html__('You don\'t have enough data to start a new event!','wpstream'),
256 'failed_event_creation' => esc_html__('Failed to start the channel. Please try again in a few minutes.','wpstream'),
257 'channel_turning_on' => esc_html__('Channel is turning on','wpstream'),
258 'channel_turning_off' => esc_html__('Channel is turning off','wpstream'),
259 'channel_on' => esc_html__('Channel is ON','wpstream'),
260 'channel_off' => esc_html__('Channel is OFF','wpstream'),
261 'turn_off_confirm' => esc_html__(
262 'ARE YOU SURE you\'d like to TURN OFF the channel now? ' . PHP_EOL . PHP_EOL .
263 '- Channels TURN OFF automatically after 1 hour of inactivity (no active broadcast).' . PHP_EOL .
264 '- Manual TURN OFF is only useful if you require to change the channel settings immediately.' . PHP_EOL .
265 '- If your channel is configured with Auto TURN ON, it will turn back on as soon as there is a broadcast.',
266 'wpstream'
267 ),
268 'is_basic_streaming' => $streaming_localization_flags['is_basic_streaming'],
269 'use_streaming_hours' => $streaming_localization_flags['use_streaming_hours'],
270 'basic_streaming_warning' => esc_html__(
271 'You’ve used all available broadcast or viewer hours.' . PHP_EOL . PHP_EOL .
272 'Some live channel features will be limited, including recording, viewer count, browser broadcasting, and content protection.' . PHP_EOL . PHP_EOL .
273 'Top up your resources or upgrade your plan to use all features, or choose OK to start anyway.',
274 'wpstream'
275 ),
276 'basic_streaming_warning_traffic' => esc_html__(
277 'Your account is now in BASIC STREAMING mode.' . PHP_EOL . PHP_EOL .
278 '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 .
279 'Certain features, such as recording, viewer count, browser broadcasting, and content protection are unavailable.' . PHP_EOL . PHP_EOL .
280 '- To take advantage of all features, please choose Cancel and upgrade your plan.' . PHP_EOL .
281 '- Otherwise, choose OK to start your channel with these limitations.' . PHP_EOL . PHP_EOL .
282 'ARE YOU SURE you want to continue with Basic Streaming?',
283 'wpstream'
284 ),
285 'broadcaster_url' => esc_url( esc_url(home_url('/broadcaster-page/') ) ),
286 'is_onboarding' => isset($_GET['onboard']) && $_GET['onboard'] === 'yes' ? 'yes' : 'no',
287 ));
288
289 wp_enqueue_script('wpstream-settings', plugin_dir_url( __DIR__ ) .'/admin/js/wpstream_settings.js?v='.time(),array(), WPSTREAM_PLUGIN_VERSION, true);
290 wp_localize_script('wpstream-settings', 'wpstream_settings_vars', array(
291 'error_message' => esc_html__( 'Failed to save settings. Please try again.', 'wpstream'),
292 'choose_image_text' => esc_html__( 'Choose Logo Image', 'wpstream'),
293 'select_image_text' => esc_html__( 'Select Image', 'wpstream'),
294 'update_successful' => esc_html__( 'Update Successful.', 'wpstream'),
295 'update_failed' => esc_html__( 'Something went wrong. Try again.', 'wpstream'),
296 'broadcaster_url' => esc_url( esc_url(home_url('/broadcaster-page/') ) ),
297 ));
298
299
300 $branch = isset($_GET['branch']) ? sanitize_text_field( wp_unslash( $_GET['branch'] ) ) : '';
301 wp_enqueue_script('wpstream-on-boarding-js',plugin_dir_url( __DIR__ ) .'/admin/js/wpstream-onboarding2.js',array(), WPSTREAM_PLUGIN_VERSION, true);
302 wp_localize_script('wpstream-on-boarding-js', 'wpstreamonboarding_js_vars',
303 array(
304 'admin_url' => get_admin_url(),
305 'plugin_url' => get_dashboard_url().'/plugins.php',
306 'upload_url' => get_dashboard_url().'admin.php?page=wpstream_recordings',
307 'branch' => $branch
308 ));
309
310 $current_screen=get_current_screen();
311 // enqueue the file only on the on-boarding page and wpstream_product post type
312 $is_wpstream_onboarding_page = $current_screen->base ==='wpstream_page_wpstream_onboard';
313 $is_wpstream_onboarding_post_type_page = isset($_GET['onboard']) && $_GET['onboard'] === 'yes';
314 $onboarding_visible = $is_wpstream_onboarding_page || $is_wpstream_onboarding_post_type_page;
315 if( $onboarding_visible) {
316 wp_enqueue_script('wpstream-on-boarding-page-js', plugin_dir_url( __DIR__ ) .'admin/js/wpstream-onboarding-page.js',array(), WPSTREAM_PLUGIN_VERSION, true);
317 wp_localize_script( 'wpstream-on-boarding-page-js', 'wpstream_onboarding_page_vars',
318 array(
319 'admin_url' => get_admin_url(),
320 'request_url' => WPSTREAM_CLICK,
321 'wps_user' => get_option('wpstream_api_username_from_token'),
322 'current_page' => $is_wpstream_onboarding_post_type_page ? 'post_edit' : 'onboarding',
323 'plugin_version' => WPSTREAM_PLUGIN_VERSION,
324 'branch' => $branch,
325 )
326 );
327 }
328
329 if ( in_array( $current_screen->base, ['toplevel_page_wpstream_credentials', 'wpstream_page_wpstream_live_channels', 'wpstream_page_wpstream_recordings', 'wpstream_page_wpstream_onboard'] ) ) {
330 wp_enqueue_script( 'wpstream-user-quota-update', plugin_dir_url( __DIR__ ) . 'admin/js/wpstream-user-quota.js', array(), WPSTREAM_PLUGIN_VERSION, true );
331 wp_localize_script( 'wpstream-user-quota-update', 'wpstream_user_quota_vars', array(
332 'admin_url' => get_admin_url()
333 ));
334 }
335
336 // Add localized variables for broadcaster
337 wp_localize_script('wpstream-broadcaster', 'wpstream_broadcaster_vars', array(
338 'ajax_url' => admin_url('admin-ajax.php'),
339 'nonce' => wp_create_nonce('wpstream_broadcaster_nonce'),
340 'plugin_url' => plugin_dir_url(__FILE__),
341
342 ));
343
344 }
345
346
347 /**
348 * Add Plugin Administation menu
349 *
350 * @since 3.0.1
351 */
352
353 public function wpstream_manage_admin_menu() {
354
355 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 );
356 add_submenu_page( 'wpstream_credentials', __('WpStream Credentials','wpestream'), __('Credentials','wpestream'), 'administrator', 'wpstream_credentials', array($this,'wpstream_set_wpstream_credentials') );
357 add_submenu_page( 'wpstream_credentials', __('WpStream Live Channels','wpestream'), __('All Channels','wpestream'), 'administrator', 'wpstream_live_channels', array( $this,'wpstream_new_general_set'));
358 add_submenu_page( 'wpstream_credentials', __('WpStream Recordings','wpestream'), __('Recordings','wpestream'), 'administrator', 'wpstream_recordings', array($this,'wpstream_media_management'));
359 add_submenu_page( 'wpstream_credentials', __('WpStream Settings','wpestream'), __('Settings','wpestream'), 'administrator', 'wpstream_settings', array($this,'wpstream_settings'));
360
361 add_submenu_page( 'wpstream_credentials', __('WpStream Quick Start','wpestream'), __('WpStream Quick Start','wpestream'), 'administrator', 'wpstream_onboard', array($this,'wpstream_pre_onboard_display'));
362
363
364
365
366 }
367
368
369
370
371 /**
372 * Shows events wpstream
373 *
374 * @since 3.0.1
375 */
376
377 public function wpstream_new_general_set() {
378
379 $no_channel=1;
380
381 if(class_exists ('WC_Subscription')){
382
383 }
384
385 //event_passed
386 $args = array(
387 'posts_per_page' => -1,
388 'post_type' => 'product',
389 'post_status' => 'publish',
390 'meta_query' => array(
391 array(
392 'key' => 'event_passed',
393 'value' => 1,
394 'compare' => '!=',
395 )
396 ),
397
398 'tax_query' => array(
399 'relation' => 'AND',
400 array(
401 'taxonomy' => 'product_type',
402 'field' => 'slug',
403 'terms' => array('live_stream','subscription')
404 )
405 ),
406 );
407
408
409
410 $event_list = new WP_Query($args);
411 global $live_event_for_user;
412 $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user();
413 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_new_general_set' );
414
415 $this->main->show_user_data($pack_details);
416 if( $event_list->have_posts()){
417
418
419 print '<div class="pack_details_wrapper_transparent">
420 <h3>'.__('Your Pay-Per-View Channel List','wpstream').'</h3>';
421
422
423 $link_new = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new');
424
425 print '<a href="'.esc_url($link_new).'" class="wpstream_create_new_product_link">'.esc_html__('Create new Pay-Per-View channel.','wpstream').'</a>';
426 print '</div>';
427
428 print '<div style="clear: both;"></div><div class="event_list_wrapper">';
429
430 while ($event_list->have_posts()): $event_list->the_post();
431
432 $the_id = get_the_ID();
433 $is_subscription_live_event = esc_html(get_post_meta($the_id,'_subscript_live_event',true));
434 $term_list = wp_get_post_terms($the_id, 'product_type');
435
436 if( $term_list[0]->name=='subscription' && $is_subscription_live_event=='no'){
437 continue;
438 }
439
440 $this->wpstream_live_stream_unit($the_id);
441
442 endwhile;
443
444 print'</div>';
445 $no_channel=1;
446 }else{
447 $no_channel=0;
448 }
449
450
451 $ajax_nonce = wp_create_nonce( "wpstream_start_event_nonce" );
452 print '<input type="hidden" id="wpstream_start_event_nonce" value="'.$ajax_nonce.'">';
453
454 $current_user = wp_get_current_user();
455 $allowded_html = array();
456 $userID = $current_user->ID;
457 $user_live_streams = get_user_meta($userID,'live_shows');
458
459
460 wp_reset_postdata();
461
462
463
464
465 // free
466
467 $args_free = array(
468 'posts_per_page' => -1,
469 'post_type' => 'wpstream_product',
470 'post_status' => 'publish',
471
472
473 );
474 $event_list_free = new WP_Query($args_free);
475
476
477 if( $event_list_free->have_posts()){
478 print '<div class="pack_details_wrapper_transparent">
479 <h3>'.__('Free-To-View Channels','wpstream').'</h3>';
480
481 $link_new = admin_url('post-new.php?post_type=wpstream_product');
482 print '<a href="'.esc_url($link_new).'" class="wpstream_create_new_product_link">'.esc_html__('Create new Free-To-View channel.','wpstream').'</a>';
483 print '</div>';
484 print '<div style="clear: both;"></div><div class="event_list_wrapper">';
485
486 while ($event_list_free->have_posts()): $event_list_free->the_post();
487
488
489 $the_id = get_the_ID();
490
491 if( get_post_meta ($the_id,'event_passed',true)!=1){
492 $this->wpstream_live_stream_unit($the_id);
493 }
494
495 endwhile;
496
497 print'</div><div class="wpstream_modal_background"></div>';
498 print '<div class="wpstream_error_modal_notification"><div class="wpstream_error_content">er2</div>
499 <div class="wpstream_error_ok wpstream_button" type="button">'.esc_html__('Close','wpstream').'</div>
500 </div>';
501 $no_channel=1;
502 }else{
503 $no_channel=0;
504 }
505
506
507
508
509 $link_new_paid = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new');
510 $link_new_free = admin_url('post-new.php?post_type=wpstream_product');
511 print '<div class="no_events_warning"> ';
512 if($event_list->found_posts==0){
513 print '<div class="no_events_warning_mes">'.__('* You do not have any Pay-Per-View channels!','wpstream').'</div>';
514 }
515 if($event_list_free->found_posts==0){
516 print '<div class="no_events_warning_mes">'. __('* You do not have any free channels!','wpstream').'</div>';
517 }
518
519 print '<a href="'.esc_url($link_new_free).'" class="wpstream_no_chanel_add_channel">'.esc_html__('Add new Free-To-View channel ','wpstream').'</a>';
520 print '<a href="'.esc_url($link_new_paid).'" class="wpstream_no_chanel_add_channel">'.esc_html__('Add new Pay-Per-View channel ','wpstream').'</a>';
521
522 print '</div>';
523
524
525
526
527 }
528 // end wpstream_new_general_set
529
530
531 /**
532 * Social share
533 *
534 * @since 3.0.1
535 */
536
537 public function wpstream_social_share($the_id){
538 $protocol = is_ssl() ? 'https' : 'http';
539 $pinterest = wp_get_attachment_image_src(get_post_thumbnail_id($the_id), 'full');
540 $link = esc_url ( get_permalink($the_id) );
541 $title = get_the_title($the_id);
542 $twiter_status = urlencode( $title.' '.$link);
543 $email_link = 'subject='.urlencode ( $title ) .'&body='. urlencode( esc_url($link));
544
545 $facebook_link = esc_html($protocol).'://www.facebook.com/sharer.php?u='. esc_url($link) .'&amp;t='. urlencode(get_the_title());
546
547 ?>
548 <div class="wpstream_social_share_wrapper">
549
550 <a href="<?php print esc_url( $facebook_link); ?>" target="_blank" class="social_facebook wpstream_sharing_social">
551 <span class="dashicons dashicons-facebook-alt"></span>
552 </a>
553
554 <a href="<?php print esc_html($protocol);?>://twitter.com/intent/tweet?text=<?php echo esc_html($twiter_status); ?>" class="social_tweet wpstream_sharing_social" target="_blank">
555 <span class="dashicons dashicons-twitter"></span>
556 </a>
557
558 <a href="<?php print esc_html($protocol);?>://pinterest.com/pin/create/button/?url=<?php echo esc_url($link); ?>&amp;media=<?php if (isset( $pinterest[0])){ echo esc_url($pinterest[0]); }?>&amp;description=<?php echo urlencode(get_the_title()); ?>" target="_blank" class="social_pinterest wpstream_sharing_social">
559 <span class="dashicons dashicons-pinterest"></span>
560 </a>
561
562 <a href="<?php print esc_html($protocol);?>://api.whatsapp.com/send?text=<?php echo urlencode( get_the_title().' '. esc_url( $link )); ?>" class="social_whatsup wpstream_sharing_social" target="_blank">
563 <span class="dashicons dashicons-whatsapp"></span>
564 </a>
565
566 <a href="<?php print esc_html($protocol);?>://www.linkedin.com/sharing/share-offsite/?url=<?php echo urlencode(esc_url($link)); ?>" class="social_linkedin wpstream_sharing_social" target="_blank">
567 <span class="dashicons dashicons-linkedin"></span>
568 </a>
569
570 <a href="<?php print esc_html($protocol);?>:///www.reddit.com/submit?url==<?php echo urlencode(esc_url($link)); ?>" class="social_linkedin wpstream_sharing_social" target="_blank">
571 <span class="dashicons dashicons-reddit"></span>
572 </a>
573
574 <a href="mailto:email@email.com?<?php echo trim(esc_html($email_link));?>" data-action="share email" class="social_email wpstream_sharing_social">
575 <span class="dashicons dashicons-email-alt"></span>
576 </a>
577
578 <div class="wpstream_modal_explanations"> <?php print esc_html__('Spread the word! To let people know about your channel, click on the corresponding icon and share on the social platforms of your choice. The more the merrier!','wpstream'); ?> </div>
579 <?php
580 print '</div>';
581 }
582
583
584
585
586 /**
587 * Shows event unit card in admin
588 *
589 * @since 3.0.1
590 */
591
592 public function wpstream_live_stream_unit($the_id,$is_front=''){
593 global $live_event_for_user;
594 global $wpstream_plugin;
595 $current_user = wp_get_current_user();
596
597 if( !current_user_can('administrator')){
598 if($is_front=='' ){
599 print '<div class="event_list_unit">';
600 esc_html_e('You are not allowed to broadcast.','wpstream');
601 print '</div>';
602 return;
603 }
604
605 }
606
607 if( !$this->main->wpstream_check_user_can_stream() ){
608 print '<div class="event_list_unit">';
609 esc_html_e('You are not allowed to broadcast','wpstream');
610 print '</div>';
611 return;
612 }
613
614
615 $live_class='';
616 if(isset($live_event_for_user[$the_id])) {
617 $live_class=" wpstream_show_started";
618 }
619
620
621 if(has_post_thumbnail($the_id)){
622 $thumb = get_the_post_thumbnail_url($the_id,'thumbnail');
623 }else{
624 $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/plugin-logo.png';
625 }
626
627 $pending_streaming_class = 'hide_stream_data';
628 $external_software_streaming_class = '';
629 $obs_uri = '';
630 $obs_stream = '';
631 $live_data_url = '';
632
633 if( $live_event_for_user=='' && $is_front=='front' ){
634 $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user();
635 }
636 $channel_status = '<div class="spinner" style="visibility: visible"></div>';
637 $button_status = '<div class="spinner" style="visibility: visible"></div>';
638 if(is_array($live_event_for_user) && isset($live_event_for_user[$the_id])) {
639 $pending_streaming_class = 'pending_trigger';
640 $live_data_url = get_post_meta($the_id,'qos_url',true);
641 // $channel_status = esc_html__('Channel is on','wpstream');
642 } else {
643 $channel_status = esc_html__('Channel is OFF','wpstream');
644 $button_status = esc_html__('TURN ON','wpstream');
645 }
646
647 $server_id = get_post_meta($the_id,'server_id',true);
648 $obs_uri = get_post_meta($the_id,'obs_uri',true);
649 $obs_stream = get_post_meta($the_id,'obs_stream',true);
650 $webcaster_url = get_post_meta($the_id,'webcaster_url',true);
651 $rtmp_ip_uri = '';
652
653 $ajax_nonce = wp_create_nonce( 'wpstream_start_event_nonce' );
654 print '<input type="hidden" id="wpstream_start_event_nonce" value="'.$ajax_nonce.'">';
655 print '<div class="event_list_unit '.$live_class.' '.$pending_streaming_class.' event_unit_style_'.esc_attr($is_front).'" data-show-id="'.intval($the_id).'" data-server-id="'.$server_id.'" data-server-url="'.$rtmp_ip_uri.'"">';
656
657 print '<div class="wpstream_channel_status">'.$channel_status.'</div>';
658
659 print '<div class="server_notification"></div>';
660
661 print '<div class="event_thumb_wrapper" style="background-image:url('.$thumb.')"></div>';
662
663 print '<div class="event_title" data-prodid="'.$the_id.'">'.wp_trim_words(get_the_title($the_id),10);
664
665
666 /* print '***</br>'.get_post_meta($the_id,'obs_uri',true) .'***</br>'.
667 get_post_meta($the_id,'obs_stream',true).'***</br>'.
668 get_post_meta($the_id,'broadcast_url',true);
669 */
670 print '<div class="wpstream_channel_item_id">'.esc_html( '#ID' ).' '.$the_id.'</div>';
671 print '</div>';
672
673
674 print '<div class="start_event wpstream_button wpstream_tooltip_wrapper" data-show-id="'.$the_id.'" data-nonce="' . esc_attr( $ajax_nonce ) . '" > ' . $button_status;
675 print '<div class="wpstream_tooltip">'.esc_html__('Channel is now OFF. Click to turn ON.','wpestream').'</div>';
676 print '</div>';
677
678 print '<div class="wpstream_options_col1 wpstream_stream_browser_wrapper">';
679
680 print '<div class="wpstream_inactive_icon start_webcaster wpstream_stream_browser wpstream-button-icon wpstream_tooltip_wrapper" data-webcaster-url="'.$webcaster_url.'" data-show-id="'.$the_id.'"">';
681
682 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to go live.','wpestream').'</div>';
683 print '<div class="wpstream_tooltip">'.esc_html__('Go live with your webcam','wpestream').'</div>';
684
685 print '<svg width="41" height="51" viewBox="0 0 41 51" fill="none" xmlns="http://www.w3.org/2000/svg">
686 <path d="M40.7646 44.2989C39.8782 41.4216 38.3361 38.7814 36.181 36.4522C35.7274 35.9619 35.1629 35.3518 34.4858 34.8356C34.0448 34.4996 33.4262 34.5281 33.0182 34.9035C29.358 38.2714 25.2628 39.9088 20.4979 39.9088H20.4853C15.7103 39.9059 11.6117 38.264 7.95648 34.889C7.52404 34.4896 6.85874 34.484 6.41953 34.8764C3.30565 37.6569 1.20501 40.9206 0.175434 44.5778C-0.276291 46.1833 0.15652 47.8497 1.33328 49.0353C2.22709 49.9362 3.39869 50.4173 4.61958 50.4173C5.0357 50.4173 5.45813 50.3613 5.87645 50.247C10.147 49.081 14.0772 48.4108 17.8916 48.1983C21.1954 48.014 24.4465 48.1323 27.5541 48.5495C29.9559 48.8718 32.4237 49.3888 35.0996 50.1299C36.823 50.6076 38.459 50.1562 39.7059 48.86C40.9268 47.5901 41.2933 46.0132 40.7651 44.2994L40.7646 44.2989ZM38.0572 47.274C37.3825 47.9754 36.6367 48.1823 35.7092 47.9257C32.9321 47.1565 30.3638 46.6187 27.8578 46.2827C24.6079 45.8465 21.2117 45.723 17.7643 45.9151C13.7874 46.1365 9.70183 46.8319 5.27439 48.041C4.43435 48.2706 3.5673 48.0403 2.9568 47.425C2.35932 46.8227 2.14793 46.0108 2.37712 45.1975C3.21567 42.2171 4.7982 39.6162 7.2018 37.2734C11.0641 40.5378 15.5276 42.193 20.4845 42.196H20.4978C25.4557 42.196 29.9251 40.5386 33.7967 37.2667C34.024 37.4904 34.254 37.7359 34.5032 38.0059C36.4236 40.0816 37.7951 42.4256 38.5799 44.9728C38.8603 45.8811 38.6941 46.6125 38.0581 47.274L38.0572 47.274ZM20.4954 30.7538C13.8088 30.7523 8.54664 25.4128 8.54379 18.6256C8.5412 12.2624 13.9961 6.83353 20.3776 6.84872C27.1094 6.86467 32.4526 12.1652 32.4488 18.8231C32.4447 25.4243 27.1038 30.7547 20.4954 30.7538V30.7538ZM29.4401 18.8383C29.5559 13.9512 25.4358 9.8445 20.5347 9.83671C15.5301 9.82892 11.6488 13.9279 11.5328 18.5667C11.4086 23.5202 15.344 27.7103 20.3381 27.7926C25.5542 27.8783 29.554 23.5758 29.4401 18.8383V18.8383ZM20.4917 25.1342C17.2131 25.2436 14.1541 22.4349 14.1567 18.8924C14.1593 15.2627 16.9642 12.4191 20.5858 12.4662C24.0109 12.5111 26.8269 15.2466 26.8362 18.8471C26.8451 22.4293 23.782 25.2436 20.4917 25.1342V25.1342ZM18.5119 13.9982C17.3006 13.9908 15.6202 15.656 15.6295 16.8543C15.6328 17.3209 15.961 17.661 16.3983 17.6513C17.5973 17.6246 19.2281 16.0169 19.2696 14.8205C19.2881 14.2742 19.0371 14.0016 18.5119 13.9982L18.5119 13.9982ZM20.4964 0.568359C10.4428 0.568359 2.26333 8.74761 2.26333 18.8014C2.26333 28.8551 10.4426 37.0345 20.4964 37.0345C30.5502 37.0345 38.7295 28.8553 38.7295 18.8014C38.7291 8.7478 30.5502 0.568359 20.4964 0.568359V0.568359ZM20.4964 33.3886C12.4528 33.3886 5.90919 26.8449 5.90919 18.8014C5.90919 11.3105 11.585 5.12093 18.8624 4.30631C18.8561 4.36009 18.8528 4.41423 18.8528 4.46912C18.8468 5.37368 19.6112 6.16064 20.4927 6.15846C21.3636 6.15586 22.1283 5.39706 22.142 4.52143C22.1431 4.44874 22.1372 4.3768 22.1279 4.30596C29.4067 5.11929 35.0849 11.3092 35.0849 18.802C35.0842 26.8456 28.5404 33.3892 20.4968 33.3892L20.4964 33.3886Z" fill="black"/>
687 </svg>';
688 print '</div>';
689
690
691 print '<div class="wpstream_inactive_icon wpstream_stream_pro wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_broadcast_modal" data-show-id="'.$the_id.'"">';
692
693 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to go live.','wpestream').'</div>';
694 print '<div class="wpstream_tooltip">'.esc_html__('Go Live with external streaming app','wpestream').'</div>';
695
696 print '<svg width="51" height="38" viewBox="0 0 51 38" fill="none" xmlns="http://www.w3.org/2000/svg">
697 <path d="M48.1266 13.9634L41.891 17.5343V13.6438C41.891 10.8723 39.6525 8.63384 36.8811 8.63384H33.1504L30.1124 3.62393C28.7268 1.3324 26.2751 0 23.6103 0H10.2863C8.84722 0 7.67471 1.17251 7.67471 2.6116C7.67471 4.05068 8.84722 5.22319 10.2863 5.22319H23.6103C24.4631 5.22319 25.2093 5.64961 25.6888 6.3957L27.0744 8.63413L5.00991 8.63376C2.23843 8.63376 0 10.8722 0 13.6437V32.9901C0 35.7616 2.23843 38 5.00991 38H36.9342C39.7057 38 41.9441 35.7616 41.9441 32.9901V29.0461L48.1797 32.6169C49.2991 33.2564 50.6846 32.4571 50.6846 31.1778L50.6842 15.4022C50.6311 14.123 49.2455 13.3237 48.1261 13.9632L48.1266 13.9634ZM38.1603 32.9368C38.1603 33.6297 37.574 34.1625 36.9345 34.1625L5.01029 34.1629C4.31733 34.1629 3.78458 33.5766 3.78458 32.9372V13.5907C3.78458 12.8978 4.37086 12.365 5.01029 12.365H36.9345C37.6275 12.365 38.1603 12.9513 38.1603 13.5907V32.9368Z" fill="black"/>
698 <path d="M22.4917 21.585H9.70066C8.84784 21.585 8.15527 22.2779 8.15527 23.1304V28.247C8.15527 29.0998 8.84823 29.7923 9.70066 29.7923H22.4917C23.3445 29.7923 24.0371 29.0994 24.0371 28.247V23.1304C24.0371 22.2775 23.3445 21.585 22.4917 21.585Z" fill="black"/>
699 </svg>';
700 print '</div>';
701
702
703
704
705 print '<a href="'.esc_url($live_data_url).'" target="_blank" class="wpstream_inactive_icon wpstream_live_data wpstream_statistics_channel wpstream-button-icon wpstream_tooltip_wrapper" data-show-id="'.$the_id.'" >';
706
707 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to see live stats.','wpestream').'</div>';
708 print '<div class="wpstream_tooltip">'.esc_html__('Live Statistics','wpestream').'</div>';
709
710 print'<svg width="50" height="42" viewBox="0 0 50 42" fill="none" xmlns="http://www.w3.org/2000/svg">
711 <path fill-rule="evenodd" clip-rule="evenodd" d="M48.9001 9.02344H40.3342C39.7288 9.02344 39.2344 9.51791 39.2344 10.1233V40.4275C39.2344 41.033 39.7288 41.5274 40.3342 41.5274H48.9001C49.5055 41.5274 50 41.0329 50 40.4275V10.1233C50 9.51791 49.5055 9.02344 48.9001 9.02344V9.02344Z" fill="black"/>
712 <path fill-rule="evenodd" clip-rule="evenodd" d="M35.821 22.4067H27.2551C26.6497 22.4067 26.1553 22.9012 26.1553 23.5066V40.4277C26.1553 41.0332 26.6497 41.5276 27.2551 41.5276H35.821C36.4264 41.5276 36.9209 41.0332 36.9209 40.4277V23.5066C36.9209 22.9012 36.4264 22.4067 35.821 22.4067V22.4067Z" fill="black"/>
713 <path fill-rule="evenodd" clip-rule="evenodd" d="M22.7439 0H14.178C13.5726 0 13.0781 0.494478 13.0781 1.09989V40.4275C13.0781 41.0329 13.5726 41.5274 14.178 41.5274H22.7439C23.3493 41.5274 23.8438 41.0329 23.8438 40.4275V1.09989C23.8438 0.49447 23.3493 0 22.7439 0V0Z" fill="black"/>
714 <path fill-rule="evenodd" clip-rule="evenodd" d="M9.66573 15.2559H1.09987C0.49445 15.2559 -2.24584e-05 15.7512 -2.24584e-05 16.3558V40.4285C-2.24584e-05 41.0331 0.495325 41.5284 1.09987 41.5284H9.66573C10.2703 41.5284 10.7656 41.034 10.7656 40.4285V16.3558C10.7656 15.7503 10.2711 15.2559 9.66573 15.2559V15.2559Z" fill="black"/>
715 </svg>';
716 print '</a>';
717 print '</div>';
718
719 print '<div class="wpstream_options_col2 wpstream_show_settings_wrapper">';
720 if($is_front==''){
721 print '<div class="wpstream_show_settings wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_settings_modal" data-show-id="'.$the_id.'" value="'.esc_html__('Settings','wpstream').'">';
722
723 print '<div class="wpstream_tooltip_disabled">'.esc_html__('
724 Turn OFF the channel to change its settings.','wpestream').'</div>';
725 print '<div class="wpstream_tooltip">'.esc_html__('Channel Settings','wpestream').'</div>';
726
727 print '<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
728 <path d="M49.22 21.8648C48.82 21.6099 45.665 19.7247 44.415 19.15L42.8651 15.4C43.3251 14.1601 44.2099 10.6849 44.3652 10.0798H44.3649C44.4911 9.52035 44.3213 8.93514 43.9149 8.52987L41.47 6.09995C41.0658 5.69189 40.4795 5.52168 39.9201 5.65003C39.4601 5.75501 35.92 6.64994 34.5999 7.15012L30.8499 5.60021C30.3048 4.40012 28.4699 1.32529 28.1351 0.795199V0.79485C27.8337 0.301688 27.298 0.00069643 26.7201 0H23.2798C22.7057 0.000348769 22.1718 0.294715 21.8648 0.779859C21.6098 1.1799 19.7247 4.33487 19.15 5.58487L15.4 7.13478C14.1601 6.67476 10.6849 5.78996 10.0798 5.63469V5.63504C9.52035 5.50878 8.93513 5.67864 8.52987 6.08496L6.09995 8.52988C5.69189 8.9341 5.52168 9.52042 5.65003 10.0798C5.75501 10.5398 6.64994 14.0799 7.15012 15.4L5.60021 19.15C4.40012 19.6951 1.32529 21.53 0.795198 21.8648H0.79485C0.301688 22.1662 0.00069643 22.7019 0 23.2798V26.7149C0.000348751 27.2893 0.294715 27.8233 0.779858 28.1299C1.1799 28.3849 4.33486 30.27 5.58487 30.8448L7.13478 34.5948C6.67475 35.8347 5.78996 39.3099 5.63469 39.915H5.63504C5.50878 40.4747 5.67863 41.06 6.08496 41.4649L8.51487 43.8948V43.8951C8.9191 44.3032 9.50541 44.4731 10.0648 44.3451C10.5248 44.2401 14.0649 43.3451 15.385 42.845L19.135 44.3949C19.6801 45.595 21.515 48.6698 21.8498 49.1999C22.1525 49.6997 22.6956 50.0035 23.2798 50H26.7149C27.2893 49.9996 27.8233 49.7053 28.1299 49.2201C28.3849 48.8201 30.27 45.6651 30.8447 44.4151L34.5947 42.8652C35.8347 43.3252 39.3098 44.21 39.9149 44.3653V44.3649C40.4747 44.4912 41.0599 44.3213 41.4649 43.915L43.8948 41.4851H43.8951C44.3032 41.0809 44.473 40.4945 44.345 39.9352C44.2401 39.4751 43.3451 35.9351 42.8449 34.615L44.3949 30.865C45.5949 30.3198 48.6698 28.485 49.1999 28.1501C49.6997 27.8474 50.0034 27.3044 49.9999 26.7201V23.2799C50.0045 22.7047 49.7087 22.1683 49.2201 21.8649L49.22 21.8648ZM24.9995 35.8845C22.1099 35.882 19.3399 34.7314 17.2985 32.6866C15.2572 30.6414 14.1118 27.8694 14.1146 24.9798C14.1171 22.0903 15.2676 19.3199 17.3125 17.2785C19.3577 15.2372 22.1297 14.0921 25.0193 14.0946C27.9088 14.0974 30.6792 15.2477 32.7205 17.2928C34.7619 19.338 35.907 22.1101 35.9045 24.9996C35.8978 27.8879 34.7462 30.6557 32.7021 32.6964C30.6576 34.7367 27.8876 35.8834 24.9994 35.8845H24.9995Z" fill="black"/>
729 </svg>
730 </div>';
731
732
733 print '<a href="'.get_edit_post_link($the_id).'" class="wpstream_edit_channel wpstream-button-icon wpstream_tooltip_wrapper" target="_blank" data-show-id="'.$the_id.'"">';
734 print '<div class="wpstream_tooltip">'.esc_html__('Edit Channel','wpestream').'</div>';
735 print '<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
736 <path d="M44.8203 1.79549C42.4263 -0.598498 38.5591 -0.598498 36.1651 1.79549L4.67494 33.2246C4.55203 33.3475 4.49079 33.4088 4.42954 33.5317C4.42954 33.5317 4.42954 33.5929 4.36829 33.5929C4.30705 33.7159 4.24539 33.7771 4.24539 33.9V33.9613L0.0711091 47.5886C-0.113044 48.264 0.0711092 48.9389 0.500659 49.4301C0.868966 49.7984 1.29852 49.9826 1.78973 49.9826C1.97388 49.9826 2.15804 49.9826 2.34219 49.9213L15.9085 45.747H15.9697C16.0926 45.6858 16.2151 45.6858 16.2768 45.6241C16.2768 45.6241 16.338 45.6241 16.338 45.5629C16.4609 45.5016 16.5834 45.44 16.6451 45.3175L48.0742 13.8884C50.4682 11.4944 50.4682 7.62715 48.0742 5.23316L44.8203 1.79549Z" fill="black"/>
737 </svg>';
738 print '</a>';
739 }
740
741 print '<a href="'.get_permalink($the_id).'" target="_blank" class="wpstream_view_channel wpstream-button-icon wpstream_tooltip_wrapper" data-show-id="'.$the_id.'"">';
742 print '<div class="wpstream_tooltip">'.esc_html__('View Channel','wpestream').'</div>';
743 print '<svg width="50" height="32" viewBox="0 0 50 32" fill="none" xmlns="http://www.w3.org/2000/svg">
744 <path d="M18.6201 15.2828H21.8752C21.8752 14.069 22.8681 13.0207 24.1373 13.0207V9.76562C21.1032 9.76562 18.6201 12.2487 18.6201 15.2828Z" fill="black"/>
745 <path d="M24.855 0C12.9378 0 3.28272 10.9792 0.579292 14.3447C-0.193097 15.2826 -0.193097 16.662 0.579292 17.6553C3.28282 21.0208 12.9378 32 24.855 32C36.7722 32 46.4273 21.0208 49.1307 17.6553C49.9031 16.7174 49.9031 15.338 49.1307 14.3447C46.4275 10.9792 36.7722 0 24.855 0V0ZM24.855 25.8205C19.4482 25.8205 15.0344 21.4067 15.0344 15.9999C15.0344 10.5931 19.4482 6.17927 24.855 6.17927C30.2618 6.17927 34.6756 10.5931 34.6756 15.9999C34.6756 21.4067 30.2618 25.8205 24.855 25.8205Z" fill="black"/>
746 </svg>';
747 print '</a>';
748
749
750 print '<div class="wpstream_share_channel wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_share_modal" data-show-id="'.$the_id.'"">';
751 print '<div class="wpstream_tooltip">'.esc_html__('Share Channel','wpestream').'</div>';
752 print '<svg width="44" height="50" viewBox="0 0 44 50" fill="none" xmlns="http://www.w3.org/2000/svg">
753 <path d="M20.0777 20.5087L24.3481 17.9427C26.6432 16.5645 29.4554 16.2443 31.96 17.198C33.443 17.7642 35.1166 17.9363 36.852 17.6105C40.3163 16.9521 43.1162 14.1831 43.8115 10.7248C45.0606 4.51597 39.7751 -0.910703 33.5907 0.12835C30.2924 0.682061 27.5604 3.16211 26.5942 6.36168C26.4405 6.86646 26.3418 7.35835 26.2804 7.84466C25.9482 10.5028 24.2498 12.8044 21.9547 14.1827L19.3458 15.7456C17.1061 17.0869 14.3986 17.1792 11.9494 16.2748C10.9956 15.9241 9.96159 15.7271 8.88507 15.7271C3.39004 15.7271 -0.960663 20.7607 0.184097 26.4527C0.879447 29.911 3.67936 32.68 7.14364 33.3384C8.87902 33.6706 10.5525 33.492 12.0356 32.9259C14.5402 31.9721 17.3461 32.2919 19.6475 33.6706L23.906 36.2241C25.346 37.0855 26.2195 38.6424 26.2195 40.3159V40.3403C26.2195 45.8229 31.2287 50.1611 36.9018 49.0472C40.3602 48.3703 43.1415 45.583 43.8244 42.1246C44.9383 36.451 40.6 31.4423 35.1175 31.4423C34.0406 31.4423 33.007 31.6394 32.0532 31.9901C29.604 32.8944 26.9029 32.8022 24.6627 31.4608L20.0721 28.7038C18.6445 27.8484 17.7706 26.304 17.7706 24.6364V24.5875C17.7642 22.9208 18.6441 21.37 20.0777 20.5085L20.0777 20.5087Z" fill="black"/>
754 </svg>';
755 print '</div>';
756 print '</div>';
757
758 $this->wpstream_display_modal_seetings($the_id);
759 $this->wpstream_display_modal_share($the_id);
760 $this->wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream);
761
762 print '</div>';
763
764 }
765
766
767
768
769 /**
770 * Shows event unit card in admin - theme version
771 *
772 * @since 3.0.1
773 */
774 public function wpstream_live_stream_unit_for_theme($the_id,$is_front=''){
775 global $live_event_for_user;
776 global $wpstream_plugin;
777 $current_user = wp_get_current_user();
778
779 if( !current_user_can('administrator')){
780 if($is_front=='' ){
781 print '<div class="event_list_unit">';
782 esc_html_e('You are not allowed to broadcast.','wpstream');
783 print '</div>';
784 return;
785 }
786
787 }
788
789 if( !$this->main->wpstream_check_user_can_stream() ){
790 print '<div class="event_list_unit">';
791 esc_html_e('You are not allowed to broadcast','wpstream');
792 print '</div>';
793 return;
794 }
795
796
797 $live_class='';
798 if(isset($live_event_for_user[$the_id])) {
799 $live_class=" wpstream_show_started";
800 }
801
802
803 if(has_post_thumbnail($the_id)){
804 $thumb = get_the_post_thumbnail_url($the_id,'thumbnail');
805 }else{
806 $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/plugin-logo.png';
807 }
808
809 $pending_streaming_class = 'hide_stream_data';
810 $external_software_streaming_class = '';
811 $obs_uri = '';
812 $obs_stream = '';
813 $live_data_url = '';
814
815 if( $live_event_for_user=='' && $is_front=='front' ){
816 $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user();
817 }
818
819 $spinner_url = admin_url('images/spinner-2x.gif');
820 $button_status = '<div class="spinner" style="background-image: url(' . $spinner_url . ')"></div>';
821 $channel_status = '';
822 if(is_array($live_event_for_user) && isset($live_event_for_user[$the_id])) {
823 $pending_streaming_class = 'pending_trigger';
824 $live_data_url = get_post_meta($the_id,'qos_url',true);
825 // $channel_status = esc_html__('Channel is on','wpstream');
826 } else {
827 $channel_status = esc_html__('Channel is OFF','wpstream');
828 $button_status = esc_html__('TURN ON', 'wpstream');
829 }
830
831 $server_id = get_post_meta($the_id,'server_id',true);
832 $obs_uri = get_post_meta($the_id,'obs_uri',true);
833 $obs_stream = get_post_meta($the_id,'obs_stream',true);
834 $webcaster_url = get_post_meta($the_id,'webcaster_url',true);
835 $rtmp_ip_uri = '';
836
837 print '<div class="wpstream_theme_event_list_unit event_list_unit '.$live_class.' '.$pending_streaming_class.' event_unit_style_'.esc_attr($is_front).'" data-show-id="'.intval($the_id).'" data-server-id="'.$server_id.'" data-server-url="'.$rtmp_ip_uri.'"">';
838
839 print '<div class="wpstream_channel_status" style="' . ($channel_status ? '' : 'display: none') . '">'.$channel_status.'</div>';
840
841 print '<div class="server_notification"></div>';
842
843 print '<div class="wpstream_theme_event_thumb_wrapper">';
844 print '<div class="event_thumb_wrapper" style="background-image:url('.$thumb.')"></div>';
845 print '<div class="event_title" data-prodid="'.$the_id.'">'.wp_trim_words(get_the_title($the_id),10);
846 print '<div class="wpstream_channel_item_id">'.esc_html('#ID','wpstream').' '.$the_id.'</div>';
847 print '</div>';
848 print '</div>';
849
850 print '<div class="wpstream_theme_control_bar_wrapper">';
851
852
853 print '<div class="wpstream_options_col1 wpstream_stream_browser_wrapper">';
854
855 print '<div class="wpstream_inactive_icon start_webcaster wpstream_stream_browser wpstream-button-icon wpstream_tooltip_wrapper" data-webcaster-url="'.$webcaster_url.'" data-show-id="'.$the_id.'"">';
856
857 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to go live.','wpestream').'</div>';
858 print '<div class="wpstream_tooltip">'.esc_html__('Go live with your webcam','wpestream').'</div>';
859
860 print '<svg width="41" height="51" viewBox="0 0 41 51" fill="none" xmlns="http://www.w3.org/2000/svg">
861 <path d="M40.7646 44.2989C39.8782 41.4216 38.3361 38.7814 36.181 36.4522C35.7274 35.9619 35.1629 35.3518 34.4858 34.8356C34.0448 34.4996 33.4262 34.5281 33.0182 34.9035C29.358 38.2714 25.2628 39.9088 20.4979 39.9088H20.4853C15.7103 39.9059 11.6117 38.264 7.95648 34.889C7.52404 34.4896 6.85874 34.484 6.41953 34.8764C3.30565 37.6569 1.20501 40.9206 0.175434 44.5778C-0.276291 46.1833 0.15652 47.8497 1.33328 49.0353C2.22709 49.9362 3.39869 50.4173 4.61958 50.4173C5.0357 50.4173 5.45813 50.3613 5.87645 50.247C10.147 49.081 14.0772 48.4108 17.8916 48.1983C21.1954 48.014 24.4465 48.1323 27.5541 48.5495C29.9559 48.8718 32.4237 49.3888 35.0996 50.1299C36.823 50.6076 38.459 50.1562 39.7059 48.86C40.9268 47.5901 41.2933 46.0132 40.7651 44.2994L40.7646 44.2989ZM38.0572 47.274C37.3825 47.9754 36.6367 48.1823 35.7092 47.9257C32.9321 47.1565 30.3638 46.6187 27.8578 46.2827C24.6079 45.8465 21.2117 45.723 17.7643 45.9151C13.7874 46.1365 9.70183 46.8319 5.27439 48.041C4.43435 48.2706 3.5673 48.0403 2.9568 47.425C2.35932 46.8227 2.14793 46.0108 2.37712 45.1975C3.21567 42.2171 4.7982 39.6162 7.2018 37.2734C11.0641 40.5378 15.5276 42.193 20.4845 42.196H20.4978C25.4557 42.196 29.9251 40.5386 33.7967 37.2667C34.024 37.4904 34.254 37.7359 34.5032 38.0059C36.4236 40.0816 37.7951 42.4256 38.5799 44.9728C38.8603 45.8811 38.6941 46.6125 38.0581 47.274L38.0572 47.274ZM20.4954 30.7538C13.8088 30.7523 8.54664 25.4128 8.54379 18.6256C8.5412 12.2624 13.9961 6.83353 20.3776 6.84872C27.1094 6.86467 32.4526 12.1652 32.4488 18.8231C32.4447 25.4243 27.1038 30.7547 20.4954 30.7538V30.7538ZM29.4401 18.8383C29.5559 13.9512 25.4358 9.8445 20.5347 9.83671C15.5301 9.82892 11.6488 13.9279 11.5328 18.5667C11.4086 23.5202 15.344 27.7103 20.3381 27.7926C25.5542 27.8783 29.554 23.5758 29.4401 18.8383V18.8383ZM20.4917 25.1342C17.2131 25.2436 14.1541 22.4349 14.1567 18.8924C14.1593 15.2627 16.9642 12.4191 20.5858 12.4662C24.0109 12.5111 26.8269 15.2466 26.8362 18.8471C26.8451 22.4293 23.782 25.2436 20.4917 25.1342V25.1342ZM18.5119 13.9982C17.3006 13.9908 15.6202 15.656 15.6295 16.8543C15.6328 17.3209 15.961 17.661 16.3983 17.6513C17.5973 17.6246 19.2281 16.0169 19.2696 14.8205C19.2881 14.2742 19.0371 14.0016 18.5119 13.9982L18.5119 13.9982ZM20.4964 0.568359C10.4428 0.568359 2.26333 8.74761 2.26333 18.8014C2.26333 28.8551 10.4426 37.0345 20.4964 37.0345C30.5502 37.0345 38.7295 28.8553 38.7295 18.8014C38.7291 8.7478 30.5502 0.568359 20.4964 0.568359V0.568359ZM20.4964 33.3886C12.4528 33.3886 5.90919 26.8449 5.90919 18.8014C5.90919 11.3105 11.585 5.12093 18.8624 4.30631C18.8561 4.36009 18.8528 4.41423 18.8528 4.46912C18.8468 5.37368 19.6112 6.16064 20.4927 6.15846C21.3636 6.15586 22.1283 5.39706 22.142 4.52143C22.1431 4.44874 22.1372 4.3768 22.1279 4.30596C29.4067 5.11929 35.0849 11.3092 35.0849 18.802C35.0842 26.8456 28.5404 33.3892 20.4968 33.3892L20.4964 33.3886Z" fill="black"/>
862 </svg>';
863 esc_html_e('Webcam','wpstream');
864 print '</div>';
865
866
867 print '<div class="wpstream_inactive_icon wpstream_stream_pro wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_broadcast_modal" data-show-id="'.$the_id.'"">';
868
869 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to go live.','wpestream').'</div>';
870 print '<div class="wpstream_tooltip">'.esc_html__('Go Live with external streaming app','wpestream').'</div>';
871
872 print '<svg width="51" height="38" viewBox="0 0 51 38" fill="none" xmlns="http://www.w3.org/2000/svg">
873 <path d="M48.1266 13.9634L41.891 17.5343V13.6438C41.891 10.8723 39.6525 8.63384 36.8811 8.63384H33.1504L30.1124 3.62393C28.7268 1.3324 26.2751 0 23.6103 0H10.2863C8.84722 0 7.67471 1.17251 7.67471 2.6116C7.67471 4.05068 8.84722 5.22319 10.2863 5.22319H23.6103C24.4631 5.22319 25.2093 5.64961 25.6888 6.3957L27.0744 8.63413L5.00991 8.63376C2.23843 8.63376 0 10.8722 0 13.6437V32.9901C0 35.7616 2.23843 38 5.00991 38H36.9342C39.7057 38 41.9441 35.7616 41.9441 32.9901V29.0461L48.1797 32.6169C49.2991 33.2564 50.6846 32.4571 50.6846 31.1778L50.6842 15.4022C50.6311 14.123 49.2455 13.3237 48.1261 13.9632L48.1266 13.9634ZM38.1603 32.9368C38.1603 33.6297 37.574 34.1625 36.9345 34.1625L5.01029 34.1629C4.31733 34.1629 3.78458 33.5766 3.78458 32.9372V13.5907C3.78458 12.8978 4.37086 12.365 5.01029 12.365H36.9345C37.6275 12.365 38.1603 12.9513 38.1603 13.5907V32.9368Z" fill="black"/>
874 <path d="M22.4917 21.585H9.70066C8.84784 21.585 8.15527 22.2779 8.15527 23.1304V28.247C8.15527 29.0998 8.84823 29.7923 9.70066 29.7923H22.4917C23.3445 29.7923 24.0371 29.0994 24.0371 28.247V23.1304C24.0371 22.2775 23.3445 21.585 22.4917 21.585Z" fill="black"/>
875 </svg>';
876 esc_html_e('External App','wpstream');
877 print '</div>';
878
879
880
881
882 print '<a href="'.esc_url($live_data_url).'" target="_blank" class="wpstream_inactive_icon wpstream_live_data wpstream_statistics_channel wpstream-button-icon wpstream_tooltip_wrapper" data-show-id="'.$the_id.'" >';
883
884 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn ON the channel to see live stats.','wpestream').'</div>';
885 print '<div class="wpstream_tooltip">'.esc_html__('Live Statistics','wpestream').'</div>';
886
887 print'<svg width="50" height="42" viewBox="0 0 50 42" fill="none" xmlns="http://www.w3.org/2000/svg">
888 <path fill-rule="evenodd" clip-rule="evenodd" d="M48.9001 9.02344H40.3342C39.7288 9.02344 39.2344 9.51791 39.2344 10.1233V40.4275C39.2344 41.033 39.7288 41.5274 40.3342 41.5274H48.9001C49.5055 41.5274 50 41.0329 50 40.4275V10.1233C50 9.51791 49.5055 9.02344 48.9001 9.02344V9.02344Z" fill="black"/>
889 <path fill-rule="evenodd" clip-rule="evenodd" d="M35.821 22.4067H27.2551C26.6497 22.4067 26.1553 22.9012 26.1553 23.5066V40.4277C26.1553 41.0332 26.6497 41.5276 27.2551 41.5276H35.821C36.4264 41.5276 36.9209 41.0332 36.9209 40.4277V23.5066C36.9209 22.9012 36.4264 22.4067 35.821 22.4067V22.4067Z" fill="black"/>
890 <path fill-rule="evenodd" clip-rule="evenodd" d="M22.7439 0H14.178C13.5726 0 13.0781 0.494478 13.0781 1.09989V40.4275C13.0781 41.0329 13.5726 41.5274 14.178 41.5274H22.7439C23.3493 41.5274 23.8438 41.0329 23.8438 40.4275V1.09989C23.8438 0.49447 23.3493 0 22.7439 0V0Z" fill="black"/>
891 <path fill-rule="evenodd" clip-rule="evenodd" d="M9.66573 15.2559H1.09987C0.49445 15.2559 -2.24584e-05 15.7512 -2.24584e-05 16.3558V40.4285C-2.24584e-05 41.0331 0.495325 41.5284 1.09987 41.5284H9.66573C10.2703 41.5284 10.7656 41.034 10.7656 40.4285V16.3558C10.7656 15.7503 10.2711 15.2559 9.66573 15.2559V15.2559Z" fill="black"/>
892 </svg>';
893 esc_html_e('Statistics','wpstream');
894 print '</a>';
895 print '</div>';
896
897 print '<div class="wpstream_options_col2 wpstream_show_settings_wrapper">';
898 if($is_front==''){
899 print '<div class="wpstream_show_settings wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_settings_modal" data-show-id="'.$the_id.'" value="'.esc_html__('Settings','wpstream').'">';
900
901 print '<div class="wpstream_tooltip_disabled">'.esc_html__('Turn OFF the channel to change its settings.','wpestream').'</div>';
902 print '<div class="wpstream_tooltip">'.esc_html__('Channel Settings','wpestream').'</div>';
903
904 print '<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
905 <path d="M49.22 21.8648C48.82 21.6099 45.665 19.7247 44.415 19.15L42.8651 15.4C43.3251 14.1601 44.2099 10.6849 44.3652 10.0798H44.3649C44.4911 9.52035 44.3213 8.93514 43.9149 8.52987L41.47 6.09995C41.0658 5.69189 40.4795 5.52168 39.9201 5.65003C39.4601 5.75501 35.92 6.64994 34.5999 7.15012L30.8499 5.60021C30.3048 4.40012 28.4699 1.32529 28.1351 0.795199V0.79485C27.8337 0.301688 27.298 0.00069643 26.7201 0H23.2798C22.7057 0.000348769 22.1718 0.294715 21.8648 0.779859C21.6098 1.1799 19.7247 4.33487 19.15 5.58487L15.4 7.13478C14.1601 6.67476 10.6849 5.78996 10.0798 5.63469V5.63504C9.52035 5.50878 8.93513 5.67864 8.52987 6.08496L6.09995 8.52988C5.69189 8.9341 5.52168 9.52042 5.65003 10.0798C5.75501 10.5398 6.64994 14.0799 7.15012 15.4L5.60021 19.15C4.40012 19.6951 1.32529 21.53 0.795198 21.8648H0.79485C0.301688 22.1662 0.00069643 22.7019 0 23.2798V26.7149C0.000348751 27.2893 0.294715 27.8233 0.779858 28.1299C1.1799 28.3849 4.33486 30.27 5.58487 30.8448L7.13478 34.5948C6.67475 35.8347 5.78996 39.3099 5.63469 39.915H5.63504C5.50878 40.4747 5.67863 41.06 6.08496 41.4649L8.51487 43.8948V43.8951C8.9191 44.3032 9.50541 44.4731 10.0648 44.3451C10.5248 44.2401 14.0649 43.3451 15.385 42.845L19.135 44.3949C19.6801 45.595 21.515 48.6698 21.8498 49.1999C22.1525 49.6997 22.6956 50.0035 23.2798 50H26.7149C27.2893 49.9996 27.8233 49.7053 28.1299 49.2201C28.3849 48.8201 30.27 45.6651 30.8447 44.4151L34.5947 42.8652C35.8347 43.3252 39.3098 44.21 39.9149 44.3653V44.3649C40.4747 44.4912 41.0599 44.3213 41.4649 43.915L43.8948 41.4851H43.8951C44.3032 41.0809 44.473 40.4945 44.345 39.9352C44.2401 39.4751 43.3451 35.9351 42.8449 34.615L44.3949 30.865C45.5949 30.3198 48.6698 28.485 49.1999 28.1501C49.6997 27.8474 50.0034 27.3044 49.9999 26.7201V23.2799C50.0045 22.7047 49.7087 22.1683 49.2201 21.8649L49.22 21.8648ZM24.9995 35.8845C22.1099 35.882 19.3399 34.7314 17.2985 32.6866C15.2572 30.6414 14.1118 27.8694 14.1146 24.9798C14.1171 22.0903 15.2676 19.3199 17.3125 17.2785C19.3577 15.2372 22.1297 14.0921 25.0193 14.0946C27.9088 14.0974 30.6792 15.2477 32.7205 17.2928C34.7619 19.338 35.907 22.1101 35.9045 24.9996C35.8978 27.8879 34.7462 30.6557 32.7021 32.6964C30.6576 34.7367 27.8876 35.8834 24.9994 35.8845H24.9995Z" fill="black"/>
906 </svg>
907 </div>';
908
909
910 print '<a href="'.get_edit_post_link($the_id).'" class="wpstream_edit_channel wpstream-button-icon wpstream_tooltip_wrapper" target="_blank" data-show-id="'.$the_id.'"">';
911 print '<div class="wpstream_tooltip">'.esc_html__('Edit Channel','wpestream').'</div>';
912 print '<svg width="50" height="50" viewBox="0 0 50 50" fill="none" xmlns="http://www.w3.org/2000/svg">
913 <path d="M44.8203 1.79549C42.4263 -0.598498 38.5591 -0.598498 36.1651 1.79549L4.67494 33.2246C4.55203 33.3475 4.49079 33.4088 4.42954 33.5317C4.42954 33.5317 4.42954 33.5929 4.36829 33.5929C4.30705 33.7159 4.24539 33.7771 4.24539 33.9V33.9613L0.0711091 47.5886C-0.113044 48.264 0.0711092 48.9389 0.500659 49.4301C0.868966 49.7984 1.29852 49.9826 1.78973 49.9826C1.97388 49.9826 2.15804 49.9826 2.34219 49.9213L15.9085 45.747H15.9697C16.0926 45.6858 16.2151 45.6858 16.2768 45.6241C16.2768 45.6241 16.338 45.6241 16.338 45.5629C16.4609 45.5016 16.5834 45.44 16.6451 45.3175L48.0742 13.8884C50.4682 11.4944 50.4682 7.62715 48.0742 5.23316L44.8203 1.79549Z" fill="black"/>
914 </svg>';
915 print '</a>';
916 }
917
918 print '<a href="'.get_permalink($the_id).'" target="_blank" class="wpstream_view_channel wpstream-button-icon wpstream_tooltip_wrapper" data-show-id="'.$the_id.'"">';
919 print '<div class="wpstream_tooltip">'.esc_html__('View Channel','wpestream').'</div>';
920 print '<svg width="50" height="32" viewBox="0 0 50 32" fill="none" xmlns="http://www.w3.org/2000/svg">
921 <path d="M18.6201 15.2828H21.8752C21.8752 14.069 22.8681 13.0207 24.1373 13.0207V9.76562C21.1032 9.76562 18.6201 12.2487 18.6201 15.2828Z" fill="black"/>
922 <path d="M24.855 0C12.9378 0 3.28272 10.9792 0.579292 14.3447C-0.193097 15.2826 -0.193097 16.662 0.579292 17.6553C3.28282 21.0208 12.9378 32 24.855 32C36.7722 32 46.4273 21.0208 49.1307 17.6553C49.9031 16.7174 49.9031 15.338 49.1307 14.3447C46.4275 10.9792 36.7722 0 24.855 0V0ZM24.855 25.8205C19.4482 25.8205 15.0344 21.4067 15.0344 15.9999C15.0344 10.5931 19.4482 6.17927 24.855 6.17927C30.2618 6.17927 34.6756 10.5931 34.6756 15.9999C34.6756 21.4067 30.2618 25.8205 24.855 25.8205Z" fill="black"/>
923 </svg>';
924 esc_html_e('View','wpstream');
925 print '</a>';
926
927
928 print '<div class="wpstream_share_channel wpstream-button-icon wpstream-trigger-modal wpstream_tooltip_wrapper" data-modal="wpestate_share_modal" data-show-id="'.$the_id.'"">';
929 print '<div class="wpstream_tooltip">'.esc_html__('Share Channel','wpestream').'</div>';
930 print '<svg width="44" height="50" viewBox="0 0 44 50" fill="none" xmlns="http://www.w3.org/2000/svg">
931 <path d="M20.0777 20.5087L24.3481 17.9427C26.6432 16.5645 29.4554 16.2443 31.96 17.198C33.443 17.7642 35.1166 17.9363 36.852 17.6105C40.3163 16.9521 43.1162 14.1831 43.8115 10.7248C45.0606 4.51597 39.7751 -0.910703 33.5907 0.12835C30.2924 0.682061 27.5604 3.16211 26.5942 6.36168C26.4405 6.86646 26.3418 7.35835 26.2804 7.84466C25.9482 10.5028 24.2498 12.8044 21.9547 14.1827L19.3458 15.7456C17.1061 17.0869 14.3986 17.1792 11.9494 16.2748C10.9956 15.9241 9.96159 15.7271 8.88507 15.7271C3.39004 15.7271 -0.960663 20.7607 0.184097 26.4527C0.879447 29.911 3.67936 32.68 7.14364 33.3384C8.87902 33.6706 10.5525 33.492 12.0356 32.9259C14.5402 31.9721 17.3461 32.2919 19.6475 33.6706L23.906 36.2241C25.346 37.0855 26.2195 38.6424 26.2195 40.3159V40.3403C26.2195 45.8229 31.2287 50.1611 36.9018 49.0472C40.3602 48.3703 43.1415 45.583 43.8244 42.1246C44.9383 36.451 40.6 31.4423 35.1175 31.4423C34.0406 31.4423 33.007 31.6394 32.0532 31.9901C29.604 32.8944 26.9029 32.8022 24.6627 31.4608L20.0721 28.7038C18.6445 27.8484 17.7706 26.304 17.7706 24.6364V24.5875C17.7642 22.9208 18.6441 21.37 20.0777 20.5085L20.0777 20.5087Z" fill="black"/>
932 </svg>';
933 esc_html_e('Share','wpstream');
934 print '</div>';
935 print '</div>';
936
937
938 print '<div class="start_event wpstream_button wpstream_tooltip_wrapper" data-show-id="'.$the_id.'" > '. $button_status;
939 print '<div class="wpstream_tooltip">'.esc_html__('Channel is now OFF. Click to turn ON.','wpestream').'</div>';
940 print '</div>';
941
942 print '</div>';
943
944
945
946
947 $this->wpstream_display_modal_seetings($the_id);
948 $this->wpstream_display_modal_share($the_id);
949 $this->wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream);
950
951 print '</div>';
952
953 }
954
955
956 /*
957 *
958 * Close modal button
959 *
960 */
961
962 public function wpstream_close_modal_button(){
963 print '<div class="wpstream_close_modal"></div>';
964 }
965
966 public function wpstream_local_event_options_toggle( $is_basic_stream_mode = false ) {
967 $use_global_event_options = get_post_meta(get_the_ID(), 'use_global_event_options', true );
968 $local_event_options = get_post_meta( get_the_ID(), 'local_event_options', true );
969 $use_local_event_options_enabled = ( is_array( $local_event_options ) && empty( $use_global_event_options ) ) ||
970 ( !empty($use_global_event_options) && intval( $use_global_event_options ) === 0 );
971
972 if ( $is_basic_stream_mode ) {
973 $this->wpstream_basic_stream_mode_message();
974 }
975
976 print '<div class="wpstream_local_event_options_toggle_wrapper">';
977 print '<div class="wpstream_local_event_options_toggle_info">';
978 print '<label for="local_event_options_enabled" class="wpstream_local_event_options_label">'.esc_html__('Edit settings for this channel','wpstream').'</label>';
979 print '<span>'.sprintf(esc_html__('When is OFF, the settings from %s will be applied','wpstream'), '<a href="' . admin_url('admin.php?page=wpstream_settings&tab=default_options') . '" target="_blank">'.esc_html__('Default Channel Settings','wpstream').'</a>').'</span>';
980 print '</div>';
981 print '<label class="wpstream_switch">';
982 print '<input id="local_event_options_enabled" type="checkbox" class="wpstream_local_event_options_toggle" ' . ($use_local_event_options_enabled === true ? 'checked' : '') . ' ' . ( $is_basic_stream_mode ? 'disabled' : '' ) . '>';
983 print '<span class="wpstream_slider round"></span>';
984 print '</label>';
985 print '</div>';
986 }
987
988 public function wpstream_basic_stream_mode_message() {
989 print '<div class="basic-mode-notice">';
990 if ( $this->wpstream_is_use_streaming_hours() ) {
991 print sprintf(
992 wp_kses(
993 __(
994 'You’ve used all available broadcast or viewer hours. Default channel settings will be used for now. To edit channel settings, <a href="%s" target="_blank">top up</a> your resources or <a href="%s" target="_blank">upgrade</a> your plan.',
995 'wpstream'
996 ),
997 array( 'a' => array(
998 'href' => array(),
999 'target' => array()
1000 )
1001 )
1002 ),
1003 esc_url( 'https://wpstream.net/pricing/' ),
1004 esc_url( 'https://wpstream.net/pricing/' )
1005 );
1006 } else {
1007 print sprintf(
1008 wp_kses(
1009 __(
1010 'You are currently in Basic Streaming Mode. The default channel settings will be used instead. Please <a href="%s" target="_blank">upgrade</a> your plan to edit the channel settings.',
1011 'wpstream'
1012 ),
1013 array(
1014 'a' => array(
1015 'href' => array()
1016 )
1017 )
1018 ),
1019 esc_url( 'https://wpstream.net/pricing/' )
1020 );
1021 }
1022 print '</div>';
1023 }
1024
1025 /*
1026 *
1027 * Display modal settings
1028 *
1029 */
1030
1031 public function wpstream_display_modal_seetings($the_id){
1032 $is_basic_stream_mode = $this->wpstream_is_basic_streaming_mode();
1033
1034 print '<div class="wpstream_modal_form wpestate_settings_modal">';
1035 $this->wpstream_close_modal_button();
1036 print '<h3>';
1037 printf( esc_html__('Channel Settings (#ID %s)','wpstream'),$the_id);
1038 print '</h3>';
1039
1040 $this->wpstream_local_event_options_toggle( $is_basic_stream_mode );
1041
1042 $local_event_options = get_post_meta($the_id,'local_event_options',true);
1043 $use_global_event_options = get_post_meta($the_id, 'use_global_event_options',true);
1044 $is_local_event_options_enabled = ( is_array( $local_event_options ) && empty( $use_global_event_options ) ) ||
1045 ( !empty($use_global_event_options) && intval( $use_global_event_options ) === 0 );
1046
1047 $local_array_exclude=array('ses_encrypt','vod_domain_lock','vod_encrypt');
1048
1049 print '<div class="wpstream_event_streaming_local">';
1050 $this->user_streaming_global_channel_options(
1051 '',
1052 $local_event_options,
1053 $local_array_exclude,
1054 !$is_local_event_options_enabled,
1055 $is_basic_stream_mode
1056 );
1057 print '</div>';
1058 print '</div>';
1059 }
1060
1061
1062 /*
1063 *
1064 * Display share settings
1065 *
1066 */
1067 public function wpstream_display_modal_share($the_id){
1068 print '<div class="wpstream_modal_form wpestate_share_modal">';
1069 $this->wpstream_close_modal_button();
1070 print '<h3>'.esc_html__('Share your Channel','wpstream').'</h3>';
1071 $this->wpstream_social_share($the_id);
1072 print '</div>';
1073 }
1074
1075
1076 /*
1077 *
1078 * Display broadcast modal
1079 *
1080 */
1081
1082 public function wpstream_display_modal_broadcast($the_id,$external_software_streaming_class,$obs_uri,$obs_stream){
1083 print '<div class="wpstream_modal_form wpestate_broadcast_modal">';
1084 $this->wpstream_close_modal_button();
1085 print '<h3>'.esc_html__('Go Live with External Streaming App','wpstream').'</h3>';
1086
1087 print '<div class="wpstream_modal_explanations">'.esc_html__('Please choose your RTMP encoder/broadcaster','wpstream').'</div>';
1088
1089 print '<select class="wpstream_external_broadcast_options">';
1090 print '<option value="wpstream_obs_settings">'.esc_html('OBS','wpstream').'</option>';
1091 print '<option value="wpstream_streamyard_settings">'.esc_html('StreamYard','wpstream').'</option>';
1092 print '<option value="wpstream_restream_settings">'.esc_html('Restream','wpstream').'</option>';
1093 print '<option value="wpstream_wimx_settings">'.esc_html('vMix','wpstream').'</option>';
1094 print '<option value="wpstream_wirecast_settings">'.esc_html('Wirecast','wpstream').'</option>';
1095 print '<option value="wpstream_xplit_settings">'.esc_html('XSplit','wpstream').'</option>';
1096 print '<option value="wpstream_larix_settings">'.esc_html('Larix Broadcaster','wpstream').'</option>';
1097
1098 print '</select>';
1099
1100 $this->wpstream_obs_settings($obs_uri,$obs_stream);
1101 $this->wpstream_streamyard_settings($obs_uri,$obs_stream);
1102 $this->wpstream_restream_settings($obs_uri,$obs_stream);
1103 $this->wpstream_wmix_settings($obs_uri,$obs_stream);
1104 $this->wpstream_wirecast_settings($obs_uri,$obs_stream);
1105 $this->wpstream_xplit_settings($obs_uri,$obs_stream);
1106 $this->wpstream_larix_settings($obs_uri,$obs_stream);
1107
1108 print '</div>';
1109 }
1110
1111
1112
1113
1114 /*
1115 *
1116 * Display OBS settings
1117 *
1118 */
1119
1120 public function wpstream_obs_settings($obs_uri,$obs_stream){
1121
1122 print '<div class="external_software_streaming wpstream_obs_settings" style="display:block;">';
1123
1124 print '<div class="external_software_streaming_details">';
1125 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('Server:').' </strong>';
1126 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1127 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1128
1129 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream Key:').' </strong>
1130 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1131 print '</div>';
1132
1133 print'</div>';
1134
1135 print ' <div class="wpstream_modal_explanations">';
1136 print '<ul>
1137 <li>1. Click Settings in the OBS Window and then Select Stream.</li>
1138 <li>2. Choose Custom Streaming Server in the Stream Type dropdown menu.</li>
1139 <li>3. In the URL box, type/paste your Server.</li>
1140 <li>4. In the Stream key, type/paste your Stream key.</li>
1141 <li>5. Save changes.Close the Settings window and click on the "Start Streaming" button in the main window of OBS.</li></ul>';
1142
1143 print '</div>';
1144
1145
1146 print'</div>';
1147 }
1148
1149 /*
1150 *
1151 * Display StreamYard settings
1152 *
1153 */
1154
1155 public function wpstream_streamyard_settings($obs_uri,$obs_stream){
1156
1157 print '<div class="external_software_streaming wpstream_streamyard_settings">';
1158
1159 print '<div class="external_software_streaming_details">';
1160 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('RTMP server URL:').' </strong>';
1161 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1162 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1163
1164 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream key:').' </strong>
1165 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1166 print '</div>';
1167
1168 print'</div>';
1169
1170 print ' <div class="wpstream_modal_explanations">';
1171 print '<ul>
1172 <li>1. Set up your destination by going to your StreamYard account.</li>
1173 <li>2. Choose "Custom RTMP" and add the RTMP server URL and Stream key from WpStream.</li>
1174 <li>3. Go to "Broadcasts" then "create a broadcast".</li>
1175 <li>4. Enter Live Studio.</li>
1176 <li>5. Adjust all your preferred settings and Click on "Go Live".</li></ul>';
1177
1178 print '</div>';
1179
1180
1181 print'</div>';
1182 }
1183
1184
1185
1186 /*
1187 *
1188 * Display StreamYard settings
1189 *
1190 */
1191
1192 public function wpstream_restream_settings($obs_uri,$obs_stream){
1193
1194 print '<div class="external_software_streaming wpstream_restream_settings">';
1195
1196 print '<div class="external_software_streaming_details">';
1197 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('RTMP URL:').' </strong>';
1198 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1199 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1200
1201 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream key:').' </strong>
1202 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1203 print '</div>';
1204
1205 print'</div>';
1206
1207 print ' <div class="wpstream_modal_explanations">';
1208 print '<ul>
1209 <li>1. Go to your Restream account and set up a destination or channel.</li>
1210 <li>2. Choose "Custom RTMP" and add the RTMP URL and Stream Key from WpStream.</li>
1211 <li>3. Click on "Add Channel".</li>
1212 <li>4. Enter Live Studio.</li>
1213 <li>5. Adjust your preferred settings and Go Live.</li></ul>';
1214
1215 print '</div>';
1216
1217
1218 print'</div>';
1219 }
1220
1221
1222
1223 /*
1224 *
1225 * Display Xplit settings
1226 *
1227 */
1228
1229
1230 public function wpstream_xplit_settings($obs_uri,$obs_stream){
1231 print '<div class="external_software_streaming wpstream_xplit_settings" style="display:none;">';
1232 print '<div class="external_software_streaming_details">';
1233 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('RTMP Url:').' </strong>';
1234 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1235 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1236
1237 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream Key:').' </strong>
1238 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1239 print '</div>';
1240
1241 print'</div>';
1242
1243 print ' <div class="wpstream_modal_explanations">';
1244 print '<ul>
1245 <li>1. Click Broadcast in the XSplit Window and then click "Set up a new output".</li>
1246 <li>2. Choose Custom RTMP in the Set up a new output dropdown menu.</li>
1247 <li>3. In the URL box, type/paste your RTMP Url.</li>
1248 <li>4. In the Stream key, type/paste your Stream key.</li>
1249 <li>5. Save changes and click on the "Stream" button in the main window.</li></ul>';
1250 print '</div>';
1251
1252 print '</div>';
1253 }
1254
1255
1256
1257 /*
1258 *
1259 * Display WireCast settings
1260 *
1261 */
1262
1263
1264 public function wpstream_wirecast_settings($obs_uri,$obs_stream){
1265 print '<div class="external_software_streaming wpstream_wirecast_settings" style="display:none;">';
1266
1267 print '<div class="external_software_streaming_details">';
1268 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('Address:').' </strong>';
1269 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1270 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1271
1272 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream:').' </strong>
1273 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1274 print '</div>';
1275
1276 print'</div>';
1277
1278 print ' <div class="wpstream_modal_explanations">';
1279 print '<ul>
1280 <li>1. Click Output on the top of the screen and then Select Output Settings.</li>
1281 <li>2. In the destination, choose RTMP Server and click OK.</li>
1282 <li>3. In the Address box, type/paste your Address.</li>
1283 <li>4. In the Stream box, type/paste your Stream key.</li>
1284 <li>5. Click on OK to save changes just click the Output on the top of the screen and then Start/Stop Broadcasting.</li></ul>';
1285 print '</div>';
1286
1287 print '</div>';
1288 }
1289
1290
1291
1292 /*
1293 *
1294 * Display Larix settings
1295 *
1296 */
1297
1298
1299 public function wpstream_larix_settings($obs_uri,$obs_stream){
1300 print '<div class="external_software_streaming wpstream_larix_settings" style="display:none;">';
1301 $larix_rtmp=$obs_uri.$obs_stream;
1302 print '<div class="external_software_streaming_details">';
1303 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('RTMP:').'</strong>';
1304 print '<div class="wpstream_live_uri_text wpstream_larix_rtmp"></div>
1305 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1306
1307 print '</div>';
1308
1309 print'</div>';
1310
1311 print ' <div class="wpstream_modal_explanations">';
1312 print '<ul>
1313 <li>A. Scan the QR code.</li>
1314 <li>or</li>
1315 <li>B. Manually configure Larix with the above RTMP</li>';
1316 if(wp_is_mobile() ){
1317 print '
1318 <li>or</li>
1319 <li>C. Click on the button below </li></ul>';
1320 }
1321
1322
1323 print '</div>';
1324
1325
1326 print '<img class="print_qrcode" src="" />';
1327 if(wp_is_mobile() ){
1328 print '<a href="" class="wpstream_start_with_larix_mobile" >Start Streaming with Larix</a>';
1329 }
1330
1331
1332
1333 print '</div>';
1334 }
1335
1336
1337
1338
1339 /*
1340 *
1341 * Display Wmix settings
1342 *
1343 */
1344
1345
1346 public function wpstream_wmix_settings($obs_uri,$obs_stream){
1347 print '<div class="external_software_streaming wpstream_wimx_settings" style="display:none;">';
1348
1349 print '<div class="external_software_streaming_details">';
1350 print '<div class="event_list_unit_notificationx"><strong>'.esc_html__('URL:').' </strong>';
1351 print '<div class="wpstream_live_uri_text">' . $obs_uri.'</div>
1352 <div class="copy_live_uri">'.__('copy','wpstream').'</div>';
1353
1354 print '<div class="event_list_stream_key_wrap"><strong>'.__('Stream Key:').' </strong>
1355 <div class="wpstream_live_key_text">'. $obs_stream.'</div><div class="copy_live_key">'.__('copy','wpstream').'</div></div>';
1356 print '</div>';
1357
1358 print'</div>';
1359
1360 print ' <div class="wpstream_modal_explanations">';
1361 print '<ul>
1362 <li>1. Click on the gear icon near the stream button on the bottom.</li>
1363 <li>2. Choose a custom RTMP Server in destination.</li>
1364 <li>3. In the URL box, type/paste your URL.</li>
1365 <li>4. In the Stream key, type/paste your Stream key.</li>
1366 <li>5. Save changes. You can start streaming by clicking on the stream button at the bottom of the dashboard.</li></ul>';
1367 print '</div>';
1368
1369 print '</div>';
1370 }
1371
1372
1373
1374 /*
1375 * Set Settings
1376 *
1377 *
1378 */
1379
1380 public function wpstream_settings(){
1381
1382 if( !current_user_can('administrator') ){
1383 die('Only for administrators');
1384 }
1385
1386
1387 if($_SERVER['REQUEST_METHOD'] === 'POST'){
1388 if( !wp_verify_nonce($_POST['wpstream-settings-nonce'],'wpstream-settings-nonce') ){
1389 die('Security check');
1390 }
1391
1392 $allowed_html = array();
1393 $exclude_array = array();
1394 $allowed_html = array();
1395
1396
1397
1398 if( isset($_POST['user_streaming_channel_type_hidden']) && intval($_POST['user_streaming_channel_type_hidden'])==1 && !isset($_POST['stream_role']) ){
1399 update_option( sanitize_key('wpstream_stream_role'), '' );
1400 }
1401
1402 foreach($_POST as $variable=>$value){
1403 if ($variable!='submit'){
1404 if (!in_array($variable, $exclude_array) ){
1405 update_option( sanitize_key('wpstream_'.$variable), sanitize_text_field ($value) );
1406 }
1407
1408 if($variable=='stream_role'){
1409 update_option( sanitize_key('wpstream_stream_role'), $value );
1410 }
1411
1412 }
1413 }
1414
1415
1416 if( isset($_GET['tab']) && $_GET['tab']=='default_options' ){
1417 $event_settings=array();
1418 foreach($this->global_event_options as $key=>$option){
1419 $event_settings[$key]='';
1420 if(isset($_POST['wpstream_event_set_'.$key]) && $_POST['wpstream_event_set_'.$key]=='on'){
1421 $event_settings[$key]=1;
1422 }else{
1423 $event_settings[$key]=0;
1424 }
1425 }
1426 update_option('wpstream_user_streaming_global_channel_options',$event_settings);
1427 }
1428
1429
1430
1431
1432 // reset permalinkgs
1433 global $wp_rewrite;
1434
1435 update_option( "rewrite_rules", FALSE );
1436 $wp_rewrite->flush_rules( true );
1437
1438 }
1439
1440 $wpstream_settings_array =array(
1441 1 => array(
1442 'tab' => 'general_options',
1443 'label' => esc_html__('Slug for free video/channel pages ','wpstream'),
1444 'name' => 'free_media_slug',
1445 'type' => 'text',
1446 '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'),
1447 ),
1448
1449 'free_vod_slug' => array(
1450 'tab' => 'general_options',
1451 'label' => esc_html__('Slug for free VOD pages ','wpstream'),
1452 'name' => 'free_media_slug_vod',
1453 'type' => 'text',
1454 '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'),
1455 ),
1456
1457 2 => array(
1458 'tab' => 'general_options',
1459 'label' => esc_html__('Non-Admin User Roles Allowed to Broadcast','wpstream'),
1460 'name' => 'stream_role',
1461 'type' => 'user_roles',
1462 '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'),
1463
1464 ),
1465 3 => array(
1466 'tab' => 'general_options',
1467 'label' => esc_html__('Non Admin Streamers Channel Type.','wpstream'),
1468 'name' => 'user_streaming_channel_type',
1469 'type' => 'select',
1470 'select_values'=>array(
1471 'free' => esc_html__('Free Live Channel','wpstream'),
1472 'paid' => esc_html__('Pay-Per-View','wpstream')
1473 ),
1474 'details' => esc_html__('Choose whether the channels assigned to non-admins are free-for-all or pay-per-view (WooCommerce product).','wpstream'),
1475 ),
1476
1477 4 => array(
1478 'tab' => 'general_options',
1479 'label' => esc_html__('Default Pay-Per-View Price','wpstream'),
1480 'name' => 'user_streaming_default_price',
1481 'type' => 'text',
1482 'details' => esc_html__('Default price of pay-per-view channels assigned to non-admins.','wpstream'),
1483 ),
1484
1485
1486
1487 6 => array(
1488 'tab' => 'subscription_options',
1489 'label' => esc_html__('Use Global Subscription Mode','wpstream'),
1490 'name' => 'global_sub',
1491 'type' => 'slidertoogle',
1492 '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'),
1493 ),
1494
1495 7 => array(
1496 'tab' => 'subscription_options',
1497 'label' => esc_html__('Subscription ID for Global Subscription Mode','wpstream'),
1498 'name' => 'global_sub_id',
1499 'type' => 'text',
1500 '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'),
1501 ),
1502 8 => array(
1503 'tab' => 'messages_options',
1504 'label' => esc_html__('PPV not logged in message','wpstream'),
1505 'name' => 'product_not_login',
1506 'type' => 'text',
1507 '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'),
1508 'default' => esc_html__('You must be logged in to watch this video.','wpstream'),
1509 ),
1510 9 => array(
1511 'tab' => 'messages_options',
1512 'label' => esc_html__('PPV not purchased message','wpstream'),
1513 'name' => 'product_not_bought',
1514 'type' => 'text',
1515 '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'),
1516 'default' => esc_html__('You did not yet purchase this item.','wpstream'),
1517 ),
1518 10 => array(
1519 'tab' => 'messages_options',
1520 'label' => esc_html__('Subscription not purchased message','wpstream'),
1521 'name' => 'product_not_subscribe',
1522 'type' => 'text',
1523 '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'),
1524 'default' => esc_html__(' You did not yet subscribe to this item.','wpstream'),
1525 ),
1526 11 => array(
1527 'tab' => 'messages_options',
1528 'label' => esc_html__('Thank you message','wpstream'),
1529 'name' => 'product_thankyou',
1530 'type' => 'text',
1531 'details' => esc_html__('This message will be displayed on the thank you page (after purchase) and the confirmation email.','wpstream'),
1532 'default' => esc_html__('Thanks for your purchase. You can access your item at any time by visiting the following page: {item_link}','wpstream'),
1533 ),
1534
1535 12 => array(
1536 'tab' => 'messages_options',
1537 'label' => esc_html__('Subscription Active message','wpstream'),
1538 'name' => 'subscription_active',
1539 'type' => 'text',
1540 'details' => esc_html__('This message will be displayed on subscription product page.','wpstream'),
1541 'default' => esc_html__('Your Subscription is Active','wpstream'),
1542 ),
1543 13 => array(
1544 'tab' => 'messages_options',
1545 'label' => esc_html__('You are not live message','wpstream'),
1546 'name' => 'you_are_not_live',
1547 'type' => 'text',
1548 'details' => esc_html__('This message will be displayed in player.','wpstream'),
1549 'default' => esc_html__('We are not live at this moment','wpstream'),
1550 ),
1551
1552 14 => array(
1553 'tab' => 'general_options',
1554 'label' => esc_html__('Video player theme','wpstream'),
1555 'name' => 'video_player_theme',
1556 'type' => 'select',
1557 'select_values'=>array(
1558 'default' => esc_html__('Default','wpstream'),
1559 'city' => esc_html__('City','wpstream'),
1560 'forest' => esc_html__('Forest','wpstream'),
1561 'fantasy' => esc_html__('Fantasy','wpstream'),
1562 'sea' => esc_html__('Sea','wpstream'),
1563 ),
1564 'details' => esc_html__('Choose the video player theme to have a different look for the player.','wpstream'),
1565 ),
1566 'wpstream_player_logo' => array(
1567 'tab' => 'general_options',
1568 'name' => 'player_logo',
1569 'label' => esc_html__('Logo for the video player','wpstream'),
1570 'type' => 'image',
1571 'details' => esc_html__('This logo will be displayed on the the video player.','wpstream'),
1572 'default' => '',
1573 'image_size' => 'thumbnail',
1574 ),
1575 // hide the video player logo opacity for now
1576 // 'wpstream_player_logo_opacity' => array(
1577 // 'tab' => 'general_options',
1578 // 'name' => 'player_logo_opacity',
1579 // 'label' => esc_html__('Opacity of the video player logo','wpstream'),
1580 // 'type' => 'range',
1581 // 'details' => esc_html__('Set the opacity of the logo','wpstream'),
1582 // 'default' => '',
1583 // 'image_size' => 'thumbnail',
1584 // ),
1585 'wpsteram_player_logo_position' => array(
1586 'tab' => 'general_options',
1587 'name' => 'player_logo_position',
1588 'label' => esc_html__('Position of the video player logo','wpstream'),
1589 'type' => 'select',
1590 'select_values'=>array(
1591 'top-left' => esc_html__('Top Left','wpstream'),
1592 'top-right' => esc_html__('Top Right','wpstream'),
1593 'bottom-left' => esc_html__('Bottom Left','wpstream'),
1594 'bottom-right' => esc_html__('Bottom Right','wpstream'),
1595 ),
1596 'details' => esc_html__('Choose the position of the logo on the video player.','wpstream'),
1597 'default' => '',
1598 ),
1599
1600
1601
1602 99 => array(
1603 'tab' => 'default_options',
1604 'label' => esc_html__('Events Options ','wpstream'),
1605 'name' => 'user_streaming_global_channel_options',
1606 'type' => 'user_streaming_global_channel_options',
1607 'details' => esc_html__('Global Options for live events.','wpstream'),
1608 ),
1609
1610 100 => array(
1611 'tab' => 'default_options_vod',
1612 'label' => esc_html__('Autoplay','wpstream'),
1613 'name' => 'vod_autoplay',
1614 'type' => 'slidertoogle',
1615 'details' => esc_html__('If enabled, video will attempt to start playing automatically. This is only achievable in some browsers.','wpstream'),
1616 ),
1617
1618
1619 101 => array(
1620 'tab' => 'default_options_vod',
1621 'label' => esc_html__('Start Muted','wpstream'),
1622 'name' => 'vod_start_muted',
1623 'type' => 'slidertoogle',
1624 'details' => esc_html__('If enabled, video will start muted. This may increase the rate of autoplay in some browsers.','wpstream'),
1625 ),
1626
1627 102 => array(
1628 'tab' => 'default_options_vod',
1629 'label' => esc_html__('Lock To Website','wpstream'),
1630 'name' => 'vod_domain_lock',
1631 'type' => 'slidertoogle',
1632 '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') ),
1633 ),
1634
1635 103 => array(
1636 'tab' => 'default_options_vod',
1637 'label' => esc_html__('Encrypt Video','wpstream'),
1638 'name' => 'vod_encrypt',
1639 'type' => 'slidertoogle',
1640 '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'),
1641 ),
1642
1643 /* 'vod_domain_lock' =>array(
1644 'name' => esc_html__('Video On Demand - Lock To Website','wpstream'),
1645 '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') ),
1646 'defaults' => 'no',
1647 ),
1648 'vod_encrypt' =>array(
1649 'name' => esc_html__('Encrypt Video on Demand','wpstream'),
1650 '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'),
1651 'defaults' => 'no',
1652 ),*/
1653
1654 104 => array(
1655 'tab' => 'support_tab',
1656 'label' => esc_html__('Logs','wpstream'),
1657 'name' => 'logs',
1658 'type' => 'logs_table',
1659 'details' => esc_html__('This is the error log of the plugin.','wpstream'),
1660 )
1661
1662 );
1663
1664 $active_tab = 'general_options';
1665 if( isset( $_GET[ 'tab' ] ) ) {
1666 $active_tab = $_GET[ 'tab' ];
1667 }
1668
1669
1670 print '<div class="theme_options_tab_wpstream" style="display:block;" >
1671 <h1>'.__('WpStream Settings','wpstream').'</h1>
1672 <form method="post" action="" >';
1673
1674 print '<h2 class="nav-tab-wrapper">
1675 <a href="?page=wpstream_settings&tab=general_options" class="nav-tab '; echo $active_tab == 'general_options' ? 'nav-tab-active' : ''; echo '">'.esc_html__('General Options','wpstream').'</a>
1676 <a href="?page=wpstream_settings&tab=default_options" class="nav-tab '; echo $active_tab == 'default_options' ? 'nav-tab-active' : ''; echo '">'.esc_html__('Default Channel Settings','wpstream').'</a>
1677 <a href="?page=wpstream_settings&tab=default_options_vod" class="nav-tab '; echo $active_tab == 'default_options_vod' ? 'nav-tab-active' : ''; echo '">'.esc_html__('VOD Settings','wpstream').'</a>
1678 <a href="?page=wpstream_settings&tab=subscription_options" class="nav-tab '; echo $active_tab == 'subscription_options' ? 'nav-tab-active' : '';echo '">'.esc_html__('Subscription Options','wpstream').'</a>
1679 <a href="?page=wpstream_settings&tab=messages_options" class="nav-tab '; echo $active_tab == 'messages_options' ? 'nav-tab-active' : ''; echo '">'.esc_html__('Customize Messages','wpstream').'</a>
1680 <a href="?page=wpstream_settings&tab=support_tab" class="nav-tab '; echo $active_tab == 'support_tab' ? 'nav-tab-active' : ''; echo '">'.esc_html__('Support','wpstream').'</a>
1681 </h2>';
1682 $help_link='';
1683
1684 $is_basic_stream_mode = $this->wpstream_is_basic_streaming_mode();
1685 print '<div class="wpstream_option_wrapper">';
1686
1687 switch ($active_tab) {
1688 case 'general_options':
1689 $help_link='https://docs.wpstream.net/docs/general-settings/';
1690 break;
1691 case 'default_options':
1692 $help_link='https://docs.wpstream.net/docs/default-channel-settings/';
1693 break;
1694 case 'default_options_vod':
1695 $help_link='https://docs.wpstream.net/docs/vod-settings/';
1696 break;
1697 case 'subscription_options':
1698 $help_link='https://docs.wpstream.net/docs/subscription-options/';
1699 break;
1700 case 'messages_options':
1701 $help_link='https://docs.wpstream.net/docs/customize-messages/';
1702 break;
1703 }
1704
1705 print '<div class="options_wrapper">';
1706 foreach ($wpstream_settings_array as $key=>$option){
1707 if($option['tab']!=$active_tab){
1708 continue;
1709 }
1710
1711 if ( $option['type']=='user_streaming_global_channel_options' ) {
1712 print '<div class="default-channel-settings-info">';
1713 print esc_html__( 'These settings will apply to newly created channels; existing channels will not change settings if you change them here', 'wpstream');
1714 if ( $is_basic_stream_mode ) {
1715 $this->wpstream_basic_stream_mode_message();
1716 }
1717 print '</div>';
1718
1719 }
1720 print '<div class="wpstream_option">';
1721 $options_value = get_option('wpstream_'.$option['name']) ;
1722
1723
1724 switch( $option['type'] ) {
1725 case 'user_roles':
1726 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
1727 print $this->wpstream_select_user_roles($option['name'],$options_value);
1728 print '<div class="settings_details">'.$option['details'].'</div>';
1729 break;
1730 case 'user_streaming_global_channel_options':
1731 $exclude_array=array();
1732 $this->user_streaming_global_channel_options(
1733 $option['name'],
1734 $options_value,
1735 $exclude_array,
1736 $is_basic_stream_mode
1737 );
1738 break;
1739 case 'text':
1740 if($options_value==''){
1741 $options_value='';
1742 if(isset($option['default'])){
1743 $options_value=$option['default'];
1744 }
1745 }
1746
1747 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
1748 print '<input class="wpstream-text-input-setting" id="'.$option['name'].'" type="'.$option['type'].'" size="36" name="'.$option['name'].'" value="'.esc_attr($options_value).'" />';
1749 print '<div class="settings_details">'.$option['details'].'</div>';
1750 break;
1751 case 'select':
1752 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
1753 print '<select id="'.$option['name'].'" name="'.$option['name'].'" >';
1754 foreach($option['select_values'] as $key=>$value){
1755 print '<option value="'.$key.'" ';
1756 if( $key == esc_html($options_value) ){
1757 print ' selected ';
1758 }
1759 print '>'.$value.'</option>';
1760 }
1761 print '</select>';
1762 print '<input type="hidden" name="'.$option['name'].'_hidden" value="1" >';
1763 print '<div class="settings_details">'.$option['details'].'</div>';
1764 break;
1765 case 'slidertoogle':
1766 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
1767 print '<div style="display: flex; gap: 25px; justify-content: space-between;">';
1768 print '<div class="settings_details">'.$option['details'].'</div>';
1769 print '<label class="wpstream_switch">
1770 <input type="hidden" class="wpstream_event_option_itemc" value="0" name="'.$option['name'].'" >
1771 <input type="checkbox" class="wpstream_event_option_itemc" value="1" name="'.$option['name'].'" ';
1772 if( intval($options_value) !==0 ){
1773 print ' checked ';
1774 }
1775 print '> <span class="wpstream_slider round"></span>';
1776 print '</label>';
1777 print '</div>';
1778 break;
1779 case 'image':
1780 $image_url = $options_value ? esc_url($options_value) : '';
1781 $has_image = !empty($image_url);
1782
1783 print '<label for="' . $option['name'] . '">' . $option['label'] . '</label>';
1784 print '<div class="wpstream-image-upload-wrapper">';
1785 print '<input type="hidden" id="' . $option['name'] . '" name="' . $option['name'] . '" value="' . $image_url . '" />';
1786
1787 // Preview area
1788 print '<div class="wpstream-image-preview" style="' . (!$has_image ? 'display:none;' : '') . '">';
1789 print '<img src="' . $image_url . '" alt="Preview" />';
1790 print '</div>';
1791
1792 // Upload/remove buttons
1793 print '<div class="wpstream-image-upload-buttons">';
1794 print '<button type="button" class="wpstream-upload-image button">' . esc_html__('Upload Image', 'wpstream') . '</button>';
1795 print '<button type="button" class="wpstream-remove-image button" style="' . (!$has_image ? 'display:none;' : '') . '">' . esc_html__('Remove Image', 'wpstream') . '</button>';
1796 print '</div>';
1797
1798 print '</div>';
1799 print '<div class="settings_details">' . $option['details'] . '</div>';
1800 break;
1801 case 'range':
1802 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
1803 print '<input class="wpstream-range-input" type="range" id="'.$option['name'].'" name="'.$option['name'].'" min="0" max="100" step="10" value="'.esc_attr($options_value).'" />';
1804 print '<div class="settings_details">'.$option['details'].'</div>';
1805 break;
1806 case 'logs_table':
1807 $this->wpstream_support_tab();
1808 break;
1809 }
1810 print '</div>';
1811 }
1812 print '</div>'; // options wrapper
1813 if($help_link!==''){
1814 print '<div class="wpstream_options_help"><a href="'.esc_url($help_link).'" target="_blank" >'.esc_html__('Video Help','wpstream').'</a></div>';
1815 }
1816 print '</div>';
1817
1818
1819 if ( $active_tab != 'support_tab') {
1820 print '<div class="wpstream-save-settings">';
1821 print '<input type="submit" name="submit" class="wpstream_button wpstream_button_action" value="'.__('Save Changes','wpstream').'" />';
1822 print '<div class="spinner"></div>';
1823 print '</div>';
1824 }
1825
1826 print '<input id="wpstream-settings-nonce" name="wpstream-settings-nonce" type="hidden" value="'.wp_create_nonce('wpstream-settings-nonce').'" /> ';
1827 print '</form>';
1828 print '</div>';
1829
1830 }
1831
1832 /**
1833 * Get system information for support tab
1834 *
1835 * @return array System information
1836 */
1837 private function get_system_info() {
1838 global $wp_version;
1839
1840 $php_version = phpversion();
1841 $wp_version_info = $wp_version;
1842 $site_debug_mode = (defined('WP_DEBUG') && WP_DEBUG);
1843 $wp_memory_limit = WP_MEMORY_LIMIT;
1844
1845 $wpstream_version = WPSTREAM_PLUGIN_VERSION;
1846 $wpstream_plugin_outdated = false;
1847
1848 // Check if plugin is outdated
1849 $update_plugins = get_site_transient('update_plugins');
1850 if (isset($update_plugins->response['plugin/wpstream.php'])) {
1851 $wpstream_plugin_outdated = true;
1852 }
1853
1854 // Check API status
1855 $api_status = false;
1856 if (method_exists($this->main->wpstream_live_connection, 'wpstream_get_token')) {
1857 $token = $this->main->wpstream_live_connection->wpstream_get_token();
1858 $api_status = !empty($token);
1859 }
1860
1861 return array(
1862 'php_version' => $php_version,
1863 'wp_version' => $wp_version_info,
1864 'site_debug_mode' => $site_debug_mode,
1865 'wp_memory_limit' => $wp_memory_limit,
1866 'wpstream_version' => $wpstream_version,
1867 'wpstream_plugin_outdated' => $wpstream_plugin_outdated,
1868 'api_status' => $api_status
1869 );
1870 }
1871
1872 /**
1873 * Render system information HTML
1874 */
1875 private function render_system_info() {
1876 $system_info = $this->get_system_info();
1877 ?>
1878
1879 <div class="wpstream-system-info">
1880 <h3><?php esc_html_e('System Information', 'wpstream'); ?></h3>
1881 <table class="widefat">
1882 <tbody>
1883 <tr>
1884 <td><strong><?php esc_html_e('PHP Version', 'wpstream'); ?></strong></td>
1885 <td><?php echo esc_html($system_info['php_version']); ?></td>
1886 <td>
1887 <?php if (version_compare($system_info['php_version'], '7.4', '<')): ?>
1888 <span class="dashicons dashicons-warning" style="color: #ffb900;"></span>
1889 <?php esc_html_e('We recommend PHP 7.4 or higher', 'wpstream'); ?>
1890 <?php else: ?>
1891 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1892 <?php endif; ?>
1893 </td>
1894 </tr>
1895 <tr>
1896 <td><strong><?php esc_html_e('WordPress Version', 'wpstream'); ?></strong></td>
1897 <td><?php echo esc_html($system_info['wp_version']); ?></td>
1898 <td>
1899 <?php if (version_compare($system_info['wp_version'], '5.6', '<')): ?>
1900 <span class="dashicons dashicons-warning" style="color: #ffb900;"></span>
1901 <?php esc_html_e('We recommend WordPress 5.6 or higher', 'wpstream'); ?>
1902 <?php else: ?>
1903 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1904 <?php endif; ?>
1905 </td>
1906 </tr>
1907 <tr>
1908 <td><strong><?php esc_html_e('WP Debug Mode', 'wpstream'); ?></strong></td>
1909 <td><?php echo $system_info['site_debug_mode'] ? esc_html__('Enabled', 'wpstream') : esc_html__('Disabled', 'wpstream'); ?></td>
1910 <td>
1911 <?php if ($system_info['site_debug_mode']): ?>
1912 <span class="dashicons dashicons-info" style="color: #00a0d2;"></span>
1913 <?php esc_html_e('Debug mode should be disabled on production sites', 'wpstream'); ?>
1914 <?php else: ?>
1915 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1916 <?php endif; ?>
1917 </td>
1918 </tr>
1919 <tr>
1920 <td><strong><?php esc_html_e('WP Memory Limit', 'wpstream'); ?></strong></td>
1921 <td><?php echo esc_html($system_info['wp_memory_limit']); ?></td>
1922 <td>
1923 <?php
1924 $memory_limit = wp_convert_hr_to_bytes($system_info['wp_memory_limit']);
1925 if ($memory_limit < 64 * 1024 * 1024): // 64MB
1926 ?>
1927 <span class="dashicons dashicons-warning" style="color: #ffb900;"></span>
1928 <?php esc_html_e('We recommend at least 64MB', 'wpstream'); ?>
1929 <?php else: ?>
1930 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1931 <?php endif; ?>
1932 </td>
1933 </tr>
1934 <tr>
1935 <td><strong><?php esc_html_e('WpStream Version', 'wpstream'); ?></strong></td>
1936 <td><?php echo esc_html($system_info['wpstream_version']); ?></td>
1937 <td style="display: flex; align-items: center; gap: 5px;">
1938 <?php if ($system_info['wpstream_plugin_outdated']): ?>
1939 <span class="dashicons dashicons-warning" style="color: #ffb900;"></span>
1940 <?php esc_html_e('Update available', 'wpstream'); ?>
1941 <div class="update-button-wrapper">
1942 <button class="wpstream-update-plugin-button button button-primary" data-plugin="wpstream/wpstream.php">
1943 <?php esc_html_e('Update Now', 'wpstream'); ?>
1944 </button>
1945 </div>
1946 <?php else: ?>
1947 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1948 <?php endif; ?>
1949 </td>
1950 </tr>
1951 <tr>
1952 <td><strong><?php esc_html_e('API Connection', 'wpstream'); ?></strong></td>
1953 <td><?php echo $system_info['api_status'] ? esc_html__('Connected', 'wpstream') : esc_html__('Disconnected', 'wpstream'); ?></td>
1954 <td>
1955 <?php if (!$system_info['api_status']): ?>
1956 <span class="dashicons dashicons-warning" style="color: #ffb900;"></span>
1957 <?php esc_html_e('API connection issue', 'wpstream'); ?>
1958 <?php else: ?>
1959 <span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
1960 <?php endif; ?>
1961 </td>
1962 </tr>
1963 </tbody>
1964 </table>
1965 </div>
1966 <?php
1967 }
1968
1969 /**
1970 * Render support tab content
1971 */
1972 public function wpstream_support_tab() {
1973 ?>
1974 <div class="wrap">
1975 <div class="wpstream-support-tab-root">
1976 <?php $this->render_system_info(); ?>
1977
1978 <div class="wpstream-plugins-table-container">
1979 <h3><?php esc_html_e('Active Plugins', 'wpstream'); ?></h3>
1980 <table class="widefat wpstream-plugins-table">
1981 <thead>
1982 <tr>
1983 <th><?php esc_html_e('Plugin', 'wpstream'); ?></th>
1984 <th><?php esc_html_e('Version', 'wpstream'); ?></th>
1985 </tr>
1986 </thead>
1987 <tbody>
1988 <?php
1989 $plugins_data = $this->wpstream_get_plugins_data();
1990 if (empty($plugins_data)) {
1991 echo '<tr><td colspan="3">' . esc_html__('No WPStream plugins found.', 'wpstream') . '</td></tr>';
1992 } else {
1993 foreach ($plugins_data as $plugin) {
1994 echo '<tr>';
1995 echo '<td>' . esc_html($plugin['name']) . '</td>';
1996 echo '<td>';
1997 echo esc_html($plugin['version']);
1998 if ( isset($plugin['new_version']) ) {
1999 echo '<div class="wpstream-tooltip-container">';
2000 echo '<span class="dashicons dashicons-info wpstream-tooltip" title="' . esc_attr($plugin['new_version']) . '">';
2001 echo '</span>';
2002 echo '<div class="wpstream-custom-tooltip">' . sprintf(
2003 esc_html__('A new version is available: %s', 'wpstream'),
2004 esc_html($plugin['new_version'])
2005 ) . '</div>';
2006 echo '</div>';
2007 }
2008 echo '</td>';
2009 echo '</tr>';
2010 }
2011 }
2012 ?>
2013 </tbody>
2014 </table>
2015 </div>
2016
2017 <div class="wpstream-logs-table-container">
2018 <h3><?php esc_html_e('Recent Logs', 'wpstream'); ?></h3>
2019 <table class="widefat wpstream-logs-table">
2020 <thead>
2021 <tr>
2022 <th><?php esc_html_e('Time', 'wpstream'); ?></th>
2023 <th><?php esc_html_e('Type', 'wpstream'); ?></th>
2024 <th><?php esc_html_e('Description', 'wpstream'); ?></th>
2025 </tr>
2026 </thead>
2027 <tbody>
2028 <?php
2029 $logs = get_option('wpstream_logs');
2030 if ( !is_array($logs) || empty($logs) ) {
2031 echo '<tr><td colspan="3">' . esc_html__('No logs found.', 'wpstream') . '</td></tr>';
2032 } else {
2033 foreach ($logs as $log) {
2034 echo '<tr>';
2035 echo '<td>' . esc_html(date('Y-m-d H:i:s', $log['timestamp'] ) ) . '</td>';
2036 echo '<td>' . esc_html($log['type']) . '</td>';
2037 echo '<td>' . esc_html($log['description']) . '</td>';
2038 echo '</tr>';
2039 }
2040 }
2041 ?>
2042 </tbody>
2043 </table>
2044 </div>
2045 </div>
2046 </div>
2047 <?php
2048 }
2049
2050 /**
2051 * Get plugins data.
2052 *
2053 * @return array
2054 */
2055 public function wpstream_get_plugins_data() {
2056 if (!function_exists('get_plugins')) {
2057 require_once ABSPATH . 'wp-admin/includes/plugin.php';
2058 }
2059
2060 // Get all installed plugins
2061 $all_plugins = get_plugins();
2062 $update_data = get_site_transient('update_plugins');
2063 $all_plugins_info = [];
2064
2065 // We want to get data only for the WpStream plugins
2066 $wpstream_plugins = array(
2067 'WpStream' => array(
2068 'path' => 'wpstream/wpstream.php',
2069 ),
2070 'WooCommerce' => array(
2071 'path' => 'woocommerce/woocommerce.php',
2072 ),
2073 'Meta Box' => array(
2074 'path' => 'meta-box/meta-box.php',
2075 ),
2076 'One Click Demo Import' => array(
2077 'path' => 'one-click-demo-import/one-click-demo-import.php',
2078 ),
2079 'Better Messages' => array(
2080 'path' => 'bp-better-messages/bp-better-messages.php',
2081 ),
2082
2083 );
2084
2085 foreach ($all_plugins as $plugin_path => $plugin_data) {
2086 $is_active = is_plugin_active( $plugin_path );
2087 $has_update = isset( $update_data->response[$plugin_path] );
2088
2089 $plugin_info = [
2090 'name' => $plugin_data['Name'],
2091 'version' => $plugin_data['Version'],
2092 'path' => $plugin_path,
2093 'active' => $is_active ? 'Yes' : 'No',
2094 'needs_update' => $has_update ? 'Yes' : 'No'
2095 ];
2096
2097 if ($has_update) {
2098 $plugin_info['new_version'] = $update_data->response[$plugin_path]->new_version;
2099 }
2100
2101 $all_plugins_info[] = $plugin_info;
2102 }
2103
2104 // Filter out the elements from $all_plugins_info that are not in $wpstream_plugins
2105 foreach ( $all_plugins_info as $key => $plugin_info ) {
2106 // compare $plugin_info['path'] against the path property on each $wpstream_plugins element item
2107 // if the path is not in $wpstream_plugins, unset the element
2108 if ( !in_array( $plugin_info['path'], array_column( $wpstream_plugins, 'path' ) ) ) {
2109 unset( $all_plugins_info[$key] );
2110 }
2111 }
2112
2113 return $all_plugins_info;
2114 }
2115
2116 public function wpstream_render_outdated_plugin_notice() {
2117 $has_update = get_site_transient('update_plugins');
2118 if (isset($has_update->response['plugin/wpstream.php'])) {
2119 ?>
2120 <div class="notice notice-warning is-dismissible">
2121 <p>
2122 <?php
2123 printf(
2124 /* translators: 1: Link to update page */
2125 esc_html__('A new version of WpStream is available. Please update to the latest version for the best experience. Go to the %1$s to update now.', 'wpstream'),
2126 '<a href="' . esc_url(admin_url('update-core.php')) . '">' . esc_html__('updates page', 'wpstream') . '</a>'
2127 );
2128 ?>
2129 </p>
2130 </div>
2131 <?php
2132 }
2133 }
2134
2135
2136 /**
2137 * Set user roles
2138 *
2139 * @since 3.0.1
2140 */
2141
2142 public function user_streaming_global_channel_options(
2143 $name,
2144 $value,
2145 $local_array='',
2146 $disabled = false,
2147 $is_basic_stream_mode = false
2148 ) {
2149
2150 foreach($this->global_event_options as $key=>$option){
2151
2152 if( is_array($local_array) && !in_array($key,$local_array)){
2153 print '<div class="wpstream_setting_event_unit_wrapper wpstream-setting-'.esc_attr($key).' ">';
2154
2155 print '<label for="'.$option['name'].'">'.$option['name'].'</label>';
2156
2157 print '<div style="display: flex; gap: 25px; justify-content: space-between;">';
2158 print '<div class="settings_details">'.$option['details'].'</div>';
2159 print '
2160 <label class="wpstream_switch">
2161 <input type="checkbox" class="wpstream_event_option_item" data-attr-ajaxname="'.esc_attr($key).'" name="wpstream_event_set_'.esc_attr($key).'" ';
2162 if( isset($value[$key]) ){
2163 if( intval($value[$key]) !==0 ){
2164 print ' checked ';
2165 }
2166 }else{
2167 if($option['defaults']=='yes') {
2168 print ' checked ';
2169 }
2170 }
2171 if ( $disabled || $is_basic_stream_mode ) {
2172 print ' disabled ';
2173 }
2174
2175
2176 print '> <span class="wpstream_slider round"></span>';
2177 print '</label>';
2178 print '</div>';
2179
2180
2181 print '</div>';
2182 }
2183 }
2184
2185
2186 }
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196 /*
2197 * Set user roles
2198 *
2199 * @since 3.0.1
2200 */
2201
2202 public function wpstream_select_user_roles($name,$value){
2203 if($value==''){
2204 $value=array();
2205 }
2206
2207 $roles = get_editable_roles();
2208 $return = '<select id="wpstream_user_roles" name="'.esc_html($name).'[]" multiple>';
2209 unset( $roles['administrator'] );
2210
2211 foreach ($roles as $key=>$role){
2212 $return .= '<option value="'.$key.'" ';
2213 if( in_array($key, $value) ){
2214 $return .= ' selected ';
2215 }
2216 $return .= '>'.$role['name'].'</option>';
2217 }
2218 $return .= '</select>';
2219
2220
2221 return $return;
2222 }
2223
2224
2225 /*
2226 * Set credential admin function
2227 *
2228 * @since 3.0.1
2229 */
2230 public function wpstream_set_wpstream_credentials(){
2231
2232 if($_SERVER['REQUEST_METHOD'] === 'POST'){
2233 $allowed_html = array();
2234 $exclude_array = array();
2235 $allowed_html = array();
2236
2237 foreach($_POST as $variable=>$value){
2238 if ($variable!='submit'){
2239 if (!in_array($variable, $exclude_array) ){
2240 switch ( $variable ) {
2241 case 'api_username':
2242 update_option( sanitize_key('wpstream_api_username'), sanitize_text_field($value) );
2243 break;
2244 case 'api_password':
2245 update_option( sanitize_key('wpstream_api_password'), $value );
2246 break;
2247 }
2248 }
2249 }
2250 }
2251
2252
2253
2254
2255 update_option('wp_estate_token_expire',0);
2256 update_option('wp_estate_curent_token',' ');
2257 delete_transient( 'wpstream_token_api');
2258 delete_transient('wpstream_token_request_30');
2259 delete_transient('wpstream_request_pack_data_per_user_transient');
2260 }
2261
2262
2263 $allowed_html = array();
2264
2265
2266
2267 $wpstream_options_array =array(
2268 2 => array(
2269 'label' => 'WpStream.net Username or Email',
2270 'name' => 'api_username',
2271 'type' => 'text',
2272 ),
2273 3 => array(
2274 'label' => 'WpStream.net Password',
2275 'name' => 'api_password',
2276 'type' => 'password',
2277 ),
2278
2279 );
2280
2281
2282 $token = $this->main->wpstream_live_connection->wpstream_get_token();
2283 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_set_wpstream_credentials' );
2284
2285 $this->main->show_user_data($pack_details);
2286
2287 print '<form method="post" action="" >';
2288 print '<div class="theme_options_tab_wpstream" style="display:block;" >
2289 <h1>'.__('WpStream Credentials','wpstream').'</h1>';
2290
2291
2292 if( get_option('wpstream_api_username')=='' || get_option('wpstream_api_password')== '' ){
2293 echo '<div class="api_not_conected wpstream_orange">';
2294 $admin_url_onboard=get_admin_url().'admin.php?page=wpstream_onboard';
2295 printf ( __('To connect your plugin, enter your WpStream credentials below or go <a href="%s" target="_blank">here</a> to create an account.','wpstream'),$admin_url_onboard);
2296 echo '</div>';
2297
2298 }else if($token==''){
2299 $text = get_option('wpstream_curl_failed') === "0" ?
2300 ' Incorrect username or password. Please check your credentials or go <a href="https://wpstream.net/my-account/edit-account/" target="_blank">here</a> to reset your password.' :
2301 'Not connected to WpStream. Please note the errors above and contact support.';
2302 echo '<div class="api_not_conected">'.__($text,'wpstream').'</div>';
2303 }else if( $this->main->wpstream_live_connection->wpstream_client_check_api_status() ){
2304 echo '<div class="api_conected">'.__('Connected to WpStream.net!','wpstream').'</div>';
2305 }else{
2306 echo '<div class="api_not_conected wpstream_brown">'.__('Failed to connect to WpStream.net. Please address CURL connectivity with your hosting provider.','wpstream').'</div>';
2307 }
2308 print '<div class="wpstream_option_wrapper">';
2309 foreach ($wpstream_options_array as $key=>$option){
2310 print '<div class="wpstream_option">';
2311
2312 $options_value = esc_html( get_option('wpstream_'.$option['name'],'') );
2313 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
2314 print '<input id="'.$option['name'].'" type="'.$option['type'].'" size="36" name="'.$option['name'].'" value="'.esc_html($options_value).'" />';
2315
2316 print '</div>';
2317 }
2318 print '</div>';
2319
2320
2321 print '<input type="submit" name="submit" class="wpstream_button wpstream_button_action" value="'.__('Save Changes','wpstream').'" />';
2322
2323 print '<h3>Video Tutorials</h3>';
2324
2325 print '<a class="how_to_videos" target="_blank" href="https://youtu.be/9DQrxsKcpmQ">How to Live Stream to WordPress with OBS</a>';
2326 print '<a class="how_to_videos" target="_blank" href="https://youtu.be/qMSjJCskAfM">How to Live Stream to WordPress in less than 3 Minutes</a>';
2327 print '<a class="how_to_videos" target="_blank" href="https://youtu.be/h6myD_vhKcg">How to Live-Stream to WordPress using your iPhone</a>';
2328
2329 print '<a style="margin-top:10px;" href="https://www.youtube.com/channel/UCIjItiJc4Z7aJApj3W6ArJA" target="_blank" class="how_to_videos">More Tutorials On Our YouTube Channel</a>';
2330
2331
2332 print '</div>';
2333 print '</form>';
2334
2335 print '<div class="theme_options_tab_wpstream" style="display:block;" >';
2336 $link_new = admin_url('admin.php?page=wpstream_live_channels');
2337 $link_new_paid = admin_url('post-new.php?post_type=product').'&new_stream='. rawurlencode('new');
2338 $link_new_free = admin_url('post-new.php?post_type=wpstream_product');
2339
2340
2341 print '<a href="'.esc_url($link_new_free).'" class="wpstream_no_chanel_add_channel">'.esc_html__('Create new Free-To-View channel','wpstream').'</a>';
2342 print '<a href="'.esc_url($link_new_paid).'" class="wpstream_no_chanel_add_channel">'.esc_html__('Create Pay-Per-View channel','wpstream').'</a>';
2343 print '<a href="'.esc_url($link_new).'" class="wpstream_no_chanel_add_channel">'.esc_html('My Channels','wpstream').'</a>';
2344 print '</div>';
2345
2346
2347 }
2348
2349
2350
2351 /**
2352 * Media Management
2353 *
2354 * @since 3.0.1
2355 */
2356
2357 public function wpstream_media_management(){
2358 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_media_management' );
2359
2360 $this->main->show_user_data($pack_details);
2361
2362
2363 print '<div id="wpstream_media_upload"><h3>'.__('Upload New Recording','wpstream').'</h3>'.$this->wpstream_present_media_upload().'</div>';
2364
2365 print '<div id="wpstream_file_management"><h3 id="video_management_title">'.__('Your Recordings','wpstream').'</h3>'.$this->wpstream_present_file_management().'</div>';
2366
2367
2368 }
2369
2370
2371
2372
2373 /**
2374 *
2375 *
2376 * WpStream Pagination
2377 *
2378 * @since 3.0.1
2379 *
2380 *
2381 */
2382
2383 public function wpstream_pagination($pages , $range = 2) {
2384 $return='';
2385 $showitems = ($range * 2) + 1;
2386 $paged = ( isset( $_GET['paged'] ) ) ? intval($_GET['paged']) : 1;
2387
2388
2389 if (1 != $pages && $pages != 0) {
2390 $return.= '<ul class="pagination wpstream_pagination">';
2391 $return.= "<li class=\"roundleft\"><a href='" . get_pagenum_link($paged - 1) . "'><</a></li>";
2392
2393 $last_page = get_pagenum_link($pages);
2394 for ($i = 1; $i <= $pages; $i++) {
2395 if (1 != $pages && (!($i >= $paged + $range + 1 || $i <= $paged - $range - 1) || $pages <= $showitems )) {
2396 if ($paged == $i) {
2397 $return.= '<li class="active"><a href="' . esc_url(get_pagenum_link($i)) . '" >' . $i . '</a><li>';
2398 } else {
2399 $return.= '<li><a href="' . esc_url(get_pagenum_link($i)) . '" >' . $i . '</a><li>';
2400 }
2401 }
2402 }
2403
2404 $prev_page = get_pagenum_link($paged + 1);
2405 if (($paged + 1) > $pages) {
2406 $prev_page = get_pagenum_link($paged);
2407 } else {
2408 $prev_page = get_pagenum_link($paged + 1);
2409 }
2410
2411
2412 $return.= "<li class=\"roundright\"><a href='" . $prev_page . "'>></a><li>";
2413 $return.= "<li class=\"roundright\"><a href='" . $last_page . "'>>><li>";
2414 $return.= "</ul>";
2415 }
2416 return $return;
2417 }
2418
2419
2420
2421
2422
2423
2424 /**
2425 * Media upload
2426 *
2427 * @since 3.0.1
2428 */
2429 public function wpstream_present_media_upload(){
2430 $to_return='';
2431
2432 if ( ! $this->main->quota_manager->has_storage_quota( null, 'recordings_screen' ) ) {
2433 return '<div class="wpstream_upload_alert">'.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').'</div>';
2434 }
2435
2436 $formInputs=$this->main->wpstream_live_connection->wpstream_get_signed_form_upload_data();
2437
2438 if( !$formInputs['success'] ){
2439 if ($formInputs['error'] == 'not_connected'){
2440 $to_return.='<div class="wpstream_upload_container">'.esc_html__('Not connected. Please connect to WpStream to upload videos.','wpstream').'</div>';
2441 }
2442 else {
2443 $to_return.='<div class="wpstream_upload_alert">'.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').'</div>';
2444 }
2445 return $to_return;
2446 }
2447
2448 if($formInputs['success'] ===true){
2449
2450
2451
2452 $to_return.='<div class="wpstream_upload_container">';
2453 $to_return.='<div id="wpstream_uploaded_mes">'.esc_html__('Please select or drop a video file. Do not close this window during the upload!','wpstream').'</div>';
2454 $to_return.='<form action="https://wpstream-video.s3.amazonaws.com/"
2455 method="POST"
2456 enctype="multipart/form-data"
2457 data-singleFileUploads="true"
2458 data-limitMultiFileUploads="1"
2459 data-limitConcurrentUploads="1"
2460 class="direct-upload">';
2461
2462 $to_return.='<input id="wpstream_upload" type="file" class="inputfile inputfile-1" value="Pick a video file" name="file" multiple>';
2463 $to_return.='<label for="wpstream_upload"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"/></svg> <span id="wpstream_label_action">' . esc_html__('Choose a file&hellip;','wpstream') . '</span></label>';
2464
2465
2466 $to_return.='<div class="wpstream_file_drop_color">';
2467 $to_return.='<div class="wpstream_form_ex">'.esc_html__('Drop a video file here!','wpstream').'</div>';
2468 $to_return.='<div class="wpstream_form_ex_details">'.__('The Video File must be encoded with the following settings:<br>
2469
2470 Container: <strong>MP4</strong>,<br>
2471 Video codec: <strong>H264</strong>,<br>
2472 Audio codec: <strong>AAC</strong>.<br>
2473 Media will fail to play if it does not follow the above settings.
2474 You may use a tool like MediaInfo to verify your file. Also you may convert it with specialized software like HandBrake.','wpstream').'<strong> '.esc_html__('Accepted file extensions: .mp4, .mov','wpstream').'</strong></div>';
2475 if(is_array($formInputs)){
2476 foreach ($formInputs['ref'] as $name => $value) {
2477 $to_return.='<input type="hidden" name="'. $name.'" value="'.$value.'">';
2478 }
2479 }
2480
2481 $to_return.='
2482 <div class="progress-bar-area"></div></div>
2483 </form>';
2484
2485 $to_return.='</div>';
2486 }
2487
2488 return $to_return;
2489
2490 }
2491
2492
2493
2494
2495
2496 /**
2497 * Display movie list
2498 *
2499 * @since 3.0.1
2500 */
2501 public function wpstream_present_file_management(){
2502 $video_list_raw = $this->main->wpstream_live_connection->wpstream_get_videos_from_api();
2503
2504 if ( $video_list_raw === false ) {
2505 return '<div class="wpstream_upload_container">'.esc_html__('Not connected. Please connect to WpStream to upload videos.','wpstream').'</div>';
2506 }
2507
2508 $video_list_raw_array = [];
2509 if( isset( $video_list_raw['items'] ) ){
2510 $video_list_raw_array = $video_list_raw['items'];
2511 }
2512
2513 $keys = array_column( $video_list_raw_array, 'time' );
2514 array_multisort($keys, SORT_DESC , $video_list_raw_array);
2515
2516 $to_return='';
2517
2518 // show pending items
2519 if ( key_exists( 'pending', $video_list_raw ) && is_array( $video_list_raw['pending'] ) ) {
2520 foreach ( $video_list_raw['pending'] as $key => $video ) {
2521 $video_size = intval($video['size']/1048576);
2522 $video_name = esc_html($video['name']);
2523 if($video_name!=''):
2524 $to_return.='<div class="wpstream_video_wrapper">';
2525 $to_return.='<div class="wpstream_video_title">';
2526 $to_return.='<div class="wpstream_video_notice"></div></div>';
2527 $to_return.='<div class="wpstream_video_title"><strong class="storage_file_name">'.esc_html__('File Name :','wpstream').'</strong>'.'<span class="storage_file_name_real">'.$video_name.'</span><span class="storage_file_size">'.$video_size.' MB </span></div>';
2528 $to_return.='<div class="wpstream_video_pending">' . esc_html__( 'The video is still processing', 'wpstream') . '</div>';
2529 $to_return.='</div>';
2530 endif;
2531
2532 }
2533 }
2534
2535 // show uploaded items
2536 if( is_array($video_list_raw['items'] ) ) {
2537 foreach ($video_list_raw_array as $key =>$video){
2538 $video_size = intval($video['size']/1048576);
2539 $video_name = esc_html($video['name']);
2540 if($video_name!=''):
2541 $to_return.='<div class="wpstream_video_wrapper">';
2542
2543 $to_return.='<div class="wpstream_video_title">';
2544 $to_return.='<div class="wpstream_video_notice"></div></div>';
2545 $to_return.='<div class="wpstream_video_title"><strong class="storage_file_name">'.esc_html__('File Name:','wpstream').'</strong>'.'<span class="storage_file_name_real">'.$video_name.'</span><span class="storage_file_size">'.$video_size.' MB </span></div>';
2546 $to_return.=' <div class="wpstream_delete_media" ';
2547 $to_return.=' onclick="return confirm(\' Are you sure you wish to delete '.$video_name.'?\')" data-filename="'.$video_name.'">'.esc_html__('delete file','wpstream').'</div>';
2548 $to_return.='<div class="wpstream_get_download_link" data-filename="'.$video_name.'">'.esc_html__('download','wpstream').'</div>';
2549 $to_return.='<a href="" class="wpstream_download_link">'.esc_html__('Click to download! The url will work for the next 20 minutes!','wpstream').'</a>';
2550
2551 $add_free_video_url=admin_url('post-new.php?post_type=wpstream_product_vod').'&new_video_name='. rawurlencode($video_name);
2552 $add_paid_video_url=admin_url('post-new.php?post_type=product').'&new_video_name='. rawurlencode($video_name);
2553
2554
2555
2556 $to_return .='<a class="create_new_free_video" href="'.esc_url($add_free_video_url).'">'.esc_html__('Create new Free-To-View VOD from this recording').'</a>';
2557 if (class_exists('WooCommerce')) {
2558 $to_return .='<a class="create_new_ppv_video" href="'.esc_url($add_paid_video_url).'">'.esc_html__('Create new Pay-Per-View VOD from this recording').'</a>';
2559 }
2560
2561 $to_return.='</div>';
2562 endif;
2563
2564 }
2565 $current_page= get_current_screen();
2566 }
2567
2568 // no items to show
2569 if ( !is_array( $video_list_raw['items'] ) || ( key_exists( 'pending', $video_list_raw ) && !is_array( $video_list_raw['pending'] ) ) ) {
2570 $to_return.= '<div class="wpstream_video_wrapper">'.esc_html__('You don\'t have any videos.','wpstream').'</div>';
2571 }
2572 return $to_return;
2573 }
2574
2575
2576 /**
2577 * Set defualt channels values
2578 *
2579 * @since 3.0.1
2580 */
2581
2582
2583
2584
2585 public function wpstream_publish_wpstream_product($post_id,$post){
2586 if( $post->post_type == 'wpstream_product' ){
2587 update_post_meta ($post_id,'local_event_options_test','working_on_'.$post_id);
2588 update_post_meta ($post_id, 'use_global_event_options', true);
2589 $to_save_option=array();
2590
2591 $global_options= get_option('wpstream_user_streaming_global_channel_options');
2592
2593 $local_events = get_post_meta ($post_id ,'local_event_options',true) ;
2594
2595 if( $local_events =='' ){
2596 if( is_array($global_options) ){
2597 foreach($global_options as $key=>$value){
2598 $to_save_option[sanitize_key($key)]=sanitize_text_field($value);
2599 }
2600
2601 update_post_meta ($post_id,'local_event_options',$to_save_option);
2602
2603 }
2604 }
2605
2606
2607 }
2608 }
2609
2610 public function wpstream_create_remote_channel_on_publish( $post_id, $post ) {
2611 $is_free_channel = $post->post_type == 'wpstream_product';
2612 $is_paid_channel = $post->post_type == 'product' && has_term( 'live_stream', 'product_type', $post_id );
2613
2614 if ( !$is_free_channel && !$is_paid_channel ) {
2615 return;
2616 }
2617
2618 if ( defined( 'DOING_AUTOSAVE') && DOING_AUTOSAVE ) {
2619 return;
2620 }
2621 if ( wp_is_post_revision( $post_id ) ) {
2622 return;
2623 }
2624 if ( get_post_meta( $post_id, '_wpstream_remote_channel_created', true ) ) {
2625 return;
2626 }
2627
2628 $response = $this->main->wpstream_live_connection->wpstream_create_channel( $post_id );
2629 error_log('channel/create response for post ' . $post_id . ' is ' . print_r($response, true));
2630
2631 if ( $response && ! empty( $response['success'] ) ) {
2632 if ( isset($response['channel_id']) && $response['channel_id'] !== '' ) {
2633 update_post_meta( $post_id, 'channelId', $response['channel_id'] );
2634 update_post_meta( $post_id, 'embedUrl', LIVE_PLAYER_URL_PREFIX . '?' . http_build_query( array( 'channelId' => $response['channel_id'] ) ) );
2635 update_post_meta( $post_id, '_wpstream_remote_channel_created', 1 );
2636 }
2637 }
2638 }
2639
2640 /**
2641 * save meta options
2642 *
2643 * @since 3.0.1
2644 */
2645 public function wpstream_free_product_update_post($post_id,$post){
2646
2647 if(!is_object($post) || !isset($post->post_type)) {
2648 return;
2649 }
2650
2651
2652
2653
2654
2655
2656
2657 if( $post->post_type == 'wpstream_product' ||
2658 $post->post_type == 'wpstream_product_vod' ):
2659
2660 $allowed_keys=array(
2661 'wpstream_product_type',
2662 'wpstream_free_video',
2663 'wpstream_free_video_external',
2664 'wpstream_closed_captions_file'
2665 );
2666
2667
2668 foreach ($_POST as $key => $value) {
2669 if( !is_array ($value) ){
2670 if (in_array ($key, $allowed_keys)) {
2671 $postmeta = sanitize_text_field ( $value );
2672 update_post_meta($post_id, sanitize_key($key), $postmeta );
2673 }
2674 }
2675 }
2676
2677 endif;
2678
2679 }
2680
2681
2682 /**
2683 * save meta options
2684 *
2685 * @since 3.0.1
2686 */
2687 public function add_wpstream_product_metaboxes() {
2688 global $post;
2689 $post_id = $post->ID;
2690
2691
2692
2693
2694 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');
2695 add_meta_box( 'custom_metabox_video_collection', esc_html__( 'Video Collection', 'wpstream' ), 'wpstream_bundle_custom_metabox_callback', 'wpstream_bundles', 'normal', 'high' );
2696
2697 if(function_exists('wc_get_product')):
2698 $product = wc_get_product( $post_id );
2699 if ( $product ) {
2700
2701 if ( $product->get_type() === 'wpstream_bundle' ) {
2702 add_meta_box(
2703 'wpstream_woo_custom_metabox',
2704 esc_html__( 'Video Collection Options', 'wpstream' ),
2705 'wpstream_bundle_custom_metabox_callback',
2706 'product',
2707 'normal',
2708 'default'
2709 );
2710 }
2711 }
2712 endif;
2713
2714 }
2715
2716
2717 /**
2718 * make woocomerce virtual products
2719 *
2720 * @since 3.0.1
2721 */
2722
2723
2724 public function wpstream_make_product_virtual($post_id,$post){
2725 global $post;
2726 if(isset($post->ID)){
2727 if ( $post->post_type !== 'product' ) return;
2728 $term_list = wp_get_post_terms($post->ID, 'product_type');
2729 if( !empty($term_list) &&
2730 isset($term_list[0]->name) &&
2731 in_array($term_list[0]->name, ['live_stream', 'video_on_demand', 'wpstream_bundle'])
2732 ){
2733 update_post_meta( $post->ID, '_virtual', 'yes' );
2734 }
2735 }
2736 }
2737
2738
2739
2740 /**
2741 * render meta options
2742 *
2743 * @since 3.0.1
2744 */
2745 public function display_meta_options( $post ) {
2746 wp_nonce_field( plugin_basename( __FILE__ ), 'estate_agent_noncename' );
2747 global $post;
2748
2749 $is_live = '';
2750 $is_video = '';
2751 $is_video_external = '';
2752 if( isset( $_GET['new_video_name']) && $_GET['new_video_name']!='' ){
2753 $is_video = ' selected ';
2754 $wpstream_free_video = esc_html( $_GET['new_video_name']);
2755 }else{
2756 $wpstream_product_type = esc_html(get_post_meta($post->ID, 'wpstream_product_type', true));
2757 $wpstream_free_video = esc_html(get_post_meta($post->ID, 'wpstream_free_video', true));
2758
2759 if($wpstream_product_type==1){
2760 $is_live = ' selected ';
2761 }
2762
2763 if($wpstream_product_type==2){
2764 $is_video = ' selected ';
2765 }
2766
2767 if($wpstream_product_type==3){
2768 $is_video_external = ' selected ';
2769 }
2770 }
2771
2772 print'
2773 <p class="meta-options">
2774 <label for="wpstream_product_type">'.__('Media Type:','wpstream').' </label><br />
2775 <select id="wpstream_product_type" name="wpstream_product_type">
2776 <option value="2" '.$is_video.'>'.__('Recording','wpstream').'</option>
2777 <option value="3" '.$is_video_external.'>'.__('Self Hosted or External Video','wpstream').'</option>
2778 </select>
2779 </p>
2780 ';
2781
2782
2783 $video_list = $this->main->wpstream_live_connection->wpstream_get_videos();
2784
2785
2786 print '<div class="meta-options video_free">';
2787 print '<p class="meta-option wpstream_free_video">';
2788 print '<label for="wpstream_free_video">'.__('Choose video:','wpstream').' </label><br />
2789 <select id="wpstream_free_video" name="wpstream_free_video">';
2790
2791 if( is_array( $video_list ) ) {
2792 foreach ($video_list as $key=>$value){
2793 print '<option value="'.$key.'"';
2794 if($wpstream_free_video === $key){
2795 print ' selected ';
2796 }
2797 print '>'.$value.'</option>';
2798 }
2799 }
2800 print'</select>';
2801 print '</p> ';
2802
2803 $wpstream_closed_captions_file = get_post_meta($post->ID, 'wpstream_closed_captions_file', true);
2804
2805 $button_style = $wpstream_closed_captions_file ? 'style="display:none;"' : '';
2806
2807 print '<p class="meta-option wpstream_vod_captions_url">';
2808 print '<label for="wpstream_vod_captions_url_button">'.__('Captions file (optional):','wpstream').' </label><br />
2809 <input type="hidden" id="wpstream_closed_captions_file" name="wpstream_closed_captions_file" value="'.esc_attr($wpstream_closed_captions_file).'" />
2810 <input id="wpstream_vod_captions_url_button" type="button" class="upload_button button" value="'.esc_html__('Select .vtt Captions File','wpstream').'" '.$button_style.' />
2811 <span class="wpstream_caption_file_display">'.( $wpstream_closed_captions_file ? esc_html( basename( $wpstream_closed_captions_file ) ) : '' ).'</span>';
2812 if ( $wpstream_closed_captions_file ) {
2813 print '<input type="button" class="button wpstream_remove_caption" value="'.esc_html__('Remove','wpstream').'" style="margin-left: 5px;" />';
2814 }
2815 print '</p> ';
2816 print '</div>';
2817
2818 $wpstream_free_video_external= esc_html(get_post_meta($post->ID, 'wpstream_free_video_external', true));
2819 print '<div class="meta-options1 video_free_external">
2820 <label for="wpstream_free_video_external">'.__('Video:','wpstream').' </label><br />
2821
2822 <input id="wpstream_free_video_external" type="text" size="36" name="wpstream_free_video_external" value="'.$wpstream_free_video_external.'" />
2823 <input id="wpstream_free_video_external_button" type="button" size="40" class="upload_button button" value="'.esc_html__('Select Video','wpstream').'" />';
2824 if($wpstream_product_type==2){
2825 $show_recording='';
2826 $show_external='style="display:none"';
2827 }else{
2828 $show_recording='style="display:none"';
2829 $show_external='';
2830 }
2831 print '<p '.$show_recording.' class="wpstream_option_vod_source wpstream_show_recording">'.esc_html__('Choose one of your existing recordings.','wpstream').'</p>';
2832 print '<p '. $show_external.' class="wpstream_option_vod_source wpstream_show_external">'.esc_html__('Upload a video from your computer or paste the URL of a YouTube/external video.','wpstream').'</p>';
2833
2834 print '</div> ';
2835 }
2836
2837
2838
2839
2840
2841
2842
2843 /**
2844 * Add new product types to Woocommerce select product type
2845 *
2846 * @since 3.0.1
2847 */
2848 public function wpstream_add_products( $types ){
2849 $types[ 'live_stream' ] = __( 'Live Channel','wpestream' );
2850 $types[ 'video_on_demand' ] = __( 'Video On Demand','wpestream' );
2851
2852 return $types;
2853 }
2854
2855 public function wpstream_add_products_class( $classname, $product_type ) {
2856 if ( 'live_stream' === $product_type ) {
2857 $classname = 'WC_Product_Live_Stream';
2858 }
2859 if ( 'video_on_demand' === $product_type ) {
2860 $classname = 'WC_Product_Video_On_Demand';
2861 }
2862 return $classname;
2863 }
2864
2865 public function wpstream_add_custom_wc_products() {
2866 if( class_exists( 'WooCommerce' ) ){
2867 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_live_stream.php';
2868 require_once plugin_dir_path( dirname( __FILE__ ) ) . 'includes/class-wc_product_video_on_demand.php';
2869 }
2870 }
2871
2872 /**
2873 * Js action to do when user pick live stream or video on demand
2874 *
2875 * @since 3.0.1
2876 */
2877
2878 /**
2879 * Whether WpStream WooCommerce product UI should load for this product.
2880 *
2881 * Skips simple, course, and other non-WpStream types so LearnDash and
2882 * other integrations can use the General product data tab without conflict.
2883 *
2884 * @param int $post_id Product post ID. Uses global $post when 0.
2885 * @return bool
2886 */
2887 public function wpstream_is_wpstream_wc_product_context( $post_id = 0 ) {
2888 if ( isset( $_GET['new_stream'] ) || isset( $_GET['new_video_name'] ) ) {
2889 return true;
2890 }
2891
2892 if ( ! $post_id ) {
2893 global $post;
2894 $post_id = ( $post && isset( $post->ID ) ) ? (int) $post->ID : 0;
2895 }
2896
2897 if ( ! $post_id || ! function_exists( 'wc_get_product' ) ) {
2898 return false;
2899 }
2900
2901 $product = wc_get_product( $post_id );
2902 if ( ! $product ) {
2903 return false;
2904 }
2905
2906 return in_array(
2907 $product->get_type(),
2908 array( 'live_stream', 'video_on_demand', 'wpstream_bundle', 'subscription' ),
2909 true
2910 );
2911 }
2912
2913 /**
2914 * WooCommerce product types that use the core Regular price field.
2915 *
2916 * @return string[]
2917 */
2918 public function wpstream_get_wc_product_types_with_pricing() {
2919 return array( 'live_stream', 'video_on_demand', 'wpstream_bundle' );
2920 }
2921
2922 /**
2923 * Add show_if_* classes to the pricing panel for WpStream product types.
2924 *
2925 * WooCommerce renders .options_group.pricing with show_if_simple only. Custom
2926 * types rely on show_if_{type} classes so meta-boxes-product.js can toggle them
2927 * when the product type dropdown changes, including on unsaved new products.
2928 *
2929 * @param string $hook Admin screen hook suffix.
2930 */
2931 public function wpstream_enqueue_wc_product_pricing_visibility( $hook ) {
2932 if ( ! in_array( $hook, array( 'post.php', 'post-new.php' ), true ) ) {
2933 return;
2934 }
2935
2936 $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
2937 if ( ! $screen || 'product' !== $screen->post_type ) {
2938 return;
2939 }
2940
2941 if ( ! wp_script_is( 'wc-admin-product-meta-boxes', 'registered' ) ) {
2942 return;
2943 }
2944
2945 $types_json = wp_json_encode( array_values( $this->wpstream_get_wc_product_types_with_pricing() ) );
2946
2947 wp_add_inline_script(
2948 'wc-admin-product-meta-boxes',
2949 "jQuery( function( $ ) {
2950 var wpstreamPricingProductTypes = {$types_json};
2951 var \$pricing = $( '.options_group.pricing' );
2952 var \$soldIndividually = $( '._sold_individually_field' ).parent();
2953
2954 wpstreamPricingProductTypes.forEach( function( type ) {
2955 \$pricing.addClass( 'show_if_' + type );
2956 \$soldIndividually.addClass( 'show_if_' + type );
2957 } );
2958
2959 if ( wpstreamPricingProductTypes.indexOf( $( '#product-type' ).val() ) !== -1 ) {
2960 \$pricing.show();
2961 \$soldIndividually.show();
2962 }
2963 } );"
2964 );
2965 }
2966
2967
2968 /**
2969 * Add custom classes to the product types
2970 *
2971 * @since 3.0.1
2972 */
2973
2974 public function wpstream_hide_attributes_data_panel( $tabs) {
2975
2976 $tabs['shipping']['class'][] = 'hide_if_live_stream hide_if_video_on_demand hide_if_wpstream_bundle';
2977 $tabs['inventory']['class'][] = 'show_if_live_stream show_if_video_on_demand show_if_wpstream_bundle';
2978
2979 return $tabs;
2980 }
2981
2982
2983
2984 /**
2985 * Hide buy now on products if Netflix mode
2986 *
2987 * @since 3.12
2988 */
2989
2990
2991 public function wpstream_hide_buy_now_subscription_mode( $purchaseable_product_wpblog,$product){
2992 $product_id=$product->get_id();
2993
2994 $term_list = wp_get_post_terms($product_id, 'product_type');
2995
2996 $subscription_model = intval( get_option('wpstream_global_sub','')) ;
2997
2998 if($subscription_model==1){ // if we have Neflix mode
2999 if( $term_list[0]->name=='live_stream' || $term_list[0]->name=='video_on_demand' || $term_list[0]->name=='wpstream_bundle' ){
3000 return false;
3001 }
3002 }
3003
3004 return $purchaseable_product_wpblog;
3005 }
3006
3007
3008
3009
3010
3011
3012 /**
3013 * Add custom fields to custom product types
3014 *
3015 * @since 3.0.1
3016 */
3017
3018 public function wpstream_add_custom_general_fields() {
3019 global $woocommerce, $post;
3020
3021 if ( ! $this->wpstream_is_wpstream_wc_product_context( isset( $post->ID ) ? (int) $post->ID : 0 ) ) {
3022 return;
3023 }
3024 if(function_exists('wcs_user_has_subscription')){
3025 echo '<div class="options_group show_if_subscription">';
3026 woocommerce_wp_select(
3027 array(
3028 'id' => '_subscript_live_event',
3029 'label' => __( 'Is a subscription based live channel ?', 'woocommerce' ),
3030 'options' => array("yes"=>"yes","no"=>"no", "none" => "none")
3031 )
3032 );
3033 echo '</div>';
3034 }
3035
3036 echo '<div class="options_group show_if_live_stream" style="border:none;"></div>';
3037 echo '<div class="options_group show_if_video_on_demand">';
3038
3039
3040 $selected='';
3041 if( isset( $_GET['new_video_name']) && $_GET['new_video_name']!='' ){
3042 $selected=esc_html($_GET['new_video_name']);
3043 }
3044 if($selected==''){
3045 $selected= get_post_meta($post->ID,'_movie_url',true);
3046 }
3047 if( !current_user_can('administrator') ){
3048 print '<div style="margin:10px;">'.esc_html('You need to be an administrator in order to assign videos','wpstream').'</div>';
3049 }else{
3050 woocommerce_wp_select(
3051 array(
3052 'id' => '_movie_url',
3053 'label' => __( 'Choose video', 'woocommerce' ),
3054 'options' => $this->main->wpstream_live_connection->wpstream_get_videos(),
3055 'selected'=> true,
3056 'value' => $selected
3057 )
3058 );
3059 }
3060
3061
3062
3063 echo '</div>';
3064
3065 if(function_exists('wcs_user_has_subscription')){
3066 $selected_sub='';
3067 echo '<div class="options_group show_if_video_on_demand show_if_live_stream">';
3068 if( isset( $_GET['wpstream_parent_sub']) && $_GET['wpstream_parent_sub']!='' ){
3069 $selected_sub=esc_html($_GET['wpstream_parent_sub']);
3070 }
3071 if($selected_sub==''){
3072 $selected_sub= get_post_meta($post->ID,'_wpstream_parent_sub',true);
3073 }
3074 woocommerce_wp_select(
3075 array(
3076 'id' => '_wpstream_parent_sub',
3077 'name' => '_wpstream_parent_sub[]',
3078 'label' => __( 'Attach to subscription', 'woocommerce' ),
3079 'options' => $this->wpstream_return_subscriptions_created(),
3080 'selected'=> true,
3081 'value' => $selected_sub,
3082 'custom_attributes' => array('multiple' => 'multiple')
3083 )
3084 );
3085
3086 echo '</div>';
3087
3088 }
3089 }
3090
3091
3092 public function wpstream_return_subscriptions_created(){
3093 $return=array('0'=>'none');
3094
3095 $args = array(
3096 'post_type' => 'product',
3097 'posts_per_page' => -1,
3098 'orderby' => 'title',
3099 'order' => 'ASC',
3100 'tax_query' => array(
3101 'relation' => 'AND',
3102 array(
3103 'taxonomy' => 'product_type',
3104 'field' => 'slug',
3105 'terms' => array( 'subscription'),
3106 )
3107 )
3108 );
3109
3110 $subscriptions = new WP_Query($args);
3111 if($subscriptions->have_posts()):
3112 while ($subscriptions->have_posts()): $subscriptions->the_post();
3113 $return[ get_the_ID() ] = get_the_title();
3114 endwhile;
3115 endif;
3116
3117 wp_reset_postdata();
3118 return $return;
3119
3120 }
3121
3122
3123
3124
3125
3126
3127 /**
3128 * Save custom fields
3129 *
3130 * @since 3.0.1
3131 */
3132
3133 public function wpstream_add_custom_general_fields_save( $post_id ){
3134 if ( ! $this->wpstream_is_wpstream_wc_product_context( (int) $post_id ) ) {
3135 return;
3136 }
3137
3138 $permited_values = array(
3139 '_movie_url',
3140 '_subscript_live_event',
3141 '_wpstream_parent_sub',
3142
3143 );
3144
3145
3146
3147 foreach($_POST as $key=>$value){
3148 update_post_meta( $post_id, 'event_passed', 0 );
3149 if( in_array($key, $permited_values) ){
3150 if( !empty( $_POST[$key] ) ){
3151 $key = sanitize_key($key);
3152 $value = sanitize_text_field($_POST[$key]);
3153
3154 if($key=='_wpstream_parent_sub'){
3155 $value= $_POST[$key];
3156 $value = array_map("sanitize_text_field", $value);
3157
3158 }
3159 update_post_meta( $post_id, $key, $value );
3160 }
3161 }
3162 }
3163 //die();
3164
3165 }
3166
3167 /**
3168 * Add to cart redirect
3169 *
3170 * @since 3.0.1
3171 */
3172
3173 public function wpstream_add_to_cart() {
3174 wc_get_template( 'single-product/add-to-cart/simple.php' );
3175 }
3176
3177
3178 /**
3179 * Replace add to cart button
3180 *
3181 * @since 3.0.1
3182 */
3183 public function replacing_add_to_cart_button( $button, $product ) {
3184 global $product;
3185 $product_type = $product->get_type();
3186
3187 if($product_type==='live_stream' || $product_type=='video_on_demand'){
3188 return $button = '<a class="button" href="'.get_site_url().'/shop/?add-to-cart=' .$product->get_id(). '&quantity=1">' . __( 'Add to Cart', 'woocommerce' ) . '</a>';
3189 }else{
3190 return $button;
3191 }
3192 }
3193
3194
3195 /**
3196 * Admin notices
3197 *
3198 * @since 3.0.1
3199 */
3200 public function wpstream_admin_notice() {
3201 global $pagenow;
3202 global $typenow;
3203
3204 $wpstream_notices = get_option('wpstream_notices');
3205
3206 /*
3207 if ( !in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
3208 if( !is_array($wpstream_notices) ||
3209 !isset($wpstream_notices['wpstream_woo_notice']) ||
3210 ( isset($wpestate_notices['wpstream_woo_notice']) && $wpestate_notices['wpstream_woo_notice']!='yes') ){
3211
3212
3213 print '<div class="notice wpstream_notices notice-error is-dismissible" data-notice-type="wpstream_woo_notice" >
3214 <p>'.__( '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' ).'</p>
3215 </div>';
3216 }
3217 }
3218 */
3219
3220 if( !in_array ('curl', get_loaded_extensions())) {
3221 print '<div class="notice notice-error is-dismissible">
3222 <p>'.__( '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' ).'</p>
3223 </div>';
3224 }
3225
3226
3227 $ajax_nonce = wp_create_nonce( "wpstream_notice_nonce" );
3228 print '<input type="hidden" id="wpstream_notice_nonce" value="'.esc_html($ajax_nonce).'"/>';
3229
3230 }
3231
3232 /**
3233 * Get plugin latest update release date from WordPress.org
3234 * @param $plugin_slug
3235 * @param $version
3236 *
3237 * @return bool
3238 */
3239 public function get_plugin_release_date( $plugin_slug, $version = null ) {
3240 $api_url = 'https://api.wordpress.org/plugins/info/1.0/' . $plugin_slug . '.json';
3241 $response = wp_remote_get( $api_url );
3242
3243 if ( is_wp_error( $response ) ) {
3244 return false;
3245 }
3246
3247 $body = wp_remote_retrieve_body( $response );
3248 $data = json_decode( $body, true );
3249
3250 if ( !$data || !isset( $data['versions'] ) ) {
3251 return false;
3252 }
3253
3254 // no version provided, get the latest version
3255 if ( !$version ) {
3256 $version = $data['version'];
3257 }
3258
3259 // check if the version exists in the versions array
3260 if ( !isset( $data['versions'][ $version ] ) ) {
3261 return false;
3262 }
3263
3264 if ( isset( $data['last_updated'] ) ) {
3265 return date('Y-m-d', strtotime( $data['last_updated'] ) );
3266 }
3267
3268 return false;
3269 }
3270
3271 /**
3272 * Adds notice for the WpStream update availability
3273 * when the update is not older than 30 days
3274 */
3275 public function wpstream_plugin_update_available_notice() {
3276 if (!current_user_can('update_plugins')) {
3277 return;
3278 }
3279
3280 $plugin_slug = 'wpstream/wpstream.php';
3281 $update_data = get_site_transient('update_plugins');
3282
3283 if ( is_object( $update_data ) &&
3284 property_exists( $update_data, 'response' ) &&
3285 is_array($update_data->response) &&
3286 key_exists($plugin_slug, $update_data->response)
3287 ) {
3288 $new_version = $update_data->response[$plugin_slug]->new_version;
3289
3290 $release_date = $this->get_plugin_release_date( 'wpstream', $new_version );
3291
3292 if ( $release_date ) {
3293 $days_since_release = ( time() - strtotime( $release_date ) ) / DAY_IN_SECONDS;
3294
3295 // if there's an update newer than 7 days, do not show the notice
3296 if ( $days_since_release < 7 ) {
3297 return;
3298 }
3299 }
3300 $update_url = wp_nonce_url(
3301 self_admin_url('update.php?action=upgrade-plugin&plugin=' . urlencode($plugin_slug)),
3302 'upgrade-plugin_' . $plugin_slug
3303 );
3304
3305 echo '<div class="notice notice-warning is-dismissible">';
3306 echo '<p><strong>' . __('WpStream Plugin Update Available', 'wpstream') . '</strong></p>';
3307 echo '<p>' . sprintf(
3308 __('Version %s is available. Please update to the latest version for new features and security improvements.', 'wpstream'),
3309 '<strong>' . esc_html($new_version) . '</strong>'
3310 ) . '</p>';
3311 echo '<p><a href="' . esc_url($update_url) . '" class="button button-primary">' .
3312 __('Update Now', 'wpstream') . '</a></p>';
3313 echo '</div>';
3314 }
3315 }
3316
3317 /**
3318 * Admin notices
3319 *
3320 * @since 3.0.1
3321 */
3322 public function wpstream_update_cache_notice(){
3323
3324 //check_ajax_referer( 'wpstream_notice_nonce', 'security' );
3325
3326 $notice_type = esc_html($_POST['notice_type']);
3327 $notices = get_option('wp_stream_notices');
3328
3329 if(! is_array($notices) ){
3330 $notices=array();
3331 }
3332
3333 $notices[$notice_type]='yes';
3334
3335 update_option('wpstream_notices',$notices);
3336 die();
3337 }
3338
3339
3340
3341
3342 /**
3343 * Activate metaboxes for Streaming controls on sidebar
3344 *
3345 * @since 3.0.1
3346 */
3347 public function wpstream_startstreaming_sidebar_meta() {
3348 global $post;
3349 $term_list = wp_get_post_terms($post->ID, 'product_type');
3350
3351 add_meta_box(
3352 'wpstream-sidebar-meta',
3353 esc_html__('Live Streaming', 'wpstream'),
3354 array($this,'wpstream_start_stream_meta'),
3355 'wpstream_product',
3356 'side',
3357 'high'
3358 );
3359
3360 $is_subscription_live_event = esc_html(get_post_meta($post->ID,'_subscript_live_event',true));
3361 if(!is_wp_error( $term_list )){
3362 if( isset($term_list[0]->name) ){
3363 if( $term_list[0]->name=='live_stream' || ($term_list[0]->name=='subscription' && $is_subscription_live_event=='yes' ) ){
3364 add_meta_box('wpstream-sidebar-meta', esc_html__('Live Streaming', 'wpstream'), array($this,'wpstream_start_stream_meta'), 'product', 'side', 'high');
3365 }
3366 }
3367 }
3368
3369 }
3370
3371 /**
3372 * edited 4.0
3373 *
3374 * Show Streaming controls on sidebar
3375 *
3376 * @since 3.0.1
3377 */
3378 public function wpstream_start_stream_meta(){
3379 global $live_event_for_user;
3380 $live_event_for_user = $this->main->wpstream_live_connection->wpstream_get_live_event_for_user();
3381
3382 global $post;
3383 $local_event_options = get_post_meta ($post->ID,'local_event_options','');
3384
3385
3386
3387 if( get_post_status( $post->ID ) === 'publish' ) {
3388 $ajax_nonce = wp_create_nonce( "wpstream_start_event_nonce" );
3389 print '<input type="hidden" id="wpstream_start_event_nonce" value="'.$ajax_nonce.'">';
3390
3391 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_new_general_set' );
3392 if( isset($pack_details['available_data_mb'])){
3393 if ($pack_details['available_data_mb'] <= 0){
3394 print '<input type="hidden" id="wpstream_basic_streaming" value="true">';
3395 }
3396 }
3397
3398 $this->wpstream_live_stream_unit($post->ID);
3399 print '<div class="wpstream_modal_background"></div>';
3400 print '<div class="wpstream_error_modal_notification"><div class="wpstream_error_content">er1</div>
3401 <div class="wpstream_error_ok wpstream_button" type="button">'.esc_html__('Close','wpstream').'</div>
3402 </div>';
3403 } else {
3404 esc_html_e('To Go Live, please publish your channel first !','wpstream');
3405 }
3406 }
3407
3408
3409 public function wpstream_is_basic_streaming_mode(){
3410 return $this->main->quota_manager->is_basic_streaming_mode( null, 'wpstream_is_basic_streaming_mode' );
3411 }
3412
3413 public function wpstream_is_use_streaming_hours() {
3414 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_start_channel' );
3415 return $this->main->quota_manager->uses_streaming_hours( $pack_details );
3416 }
3417
3418 /**
3419 * Cached-only flags for start_streaming.js localization (no API on cold cache).
3420 *
3421 * @return array{is_basic_streaming: bool, use_streaming_hours: bool}
3422 */
3423 public function wpstream_get_start_streaming_localization_flags() {
3424 return $this->main->quota_manager->get_streaming_ui_flags_from_cache();
3425 }
3426
3427
3428
3429 /**
3430 *
3431 *
3432 *
3433 */
3434 public function add_dashboard_page() {
3435 add_dashboard_page( '', '', 'administrator', 'wpstream-onboarding', '' );
3436 }
3437
3438
3439
3440
3441
3442 public function wpstream_load_onboarding_wizard() {
3443
3444 // Check for wizard-specific parameter
3445 // Allow plugins to disable the onboarding wizard
3446 // Check if current user is allowed to save settings.
3447
3448
3449 // Don't load the interface if doing an ajax call.
3450 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
3451 return;
3452 }
3453
3454 set_current_screen();
3455
3456 // Remove an action in the Gutenberg plugin ( not core Gutenberg ) which throws an error.
3457 remove_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' );
3458
3459 $this->actual_load_onboarding_wizard();
3460
3461 }
3462
3463
3464 /*
3465 * Add on boarding to footer
3466 */
3467
3468
3469
3470 public function wpstream_admin_footer_onboarding(){
3471 if( isset($_GET['page']) && $_GET['page']==='wpstream_onboard') {
3472 $this->wpstream_onboard_display();
3473 }
3474 }
3475
3476
3477 /*
3478 * On Board Display
3479 *
3480 */
3481
3482 public function wpstream_pre_onboard_display(){
3483 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_pre_onboard_display' );
3484 $this->main->show_user_data($pack_details);
3485
3486 $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/logo_onboarding.svg';
3487 ?>
3488 <div id="wpstream-onboarding-root"></div>
3489 <div class="wpstream_quick_start_wrapper">
3490 <img class="wpstream_onboarding_logo" src="<?php echo esc_url($thumb); ?>" />
3491
3492 <h1><?php print esc_html__('WpStream','wpstream').' <span class="header_special">'.esc_html__('Quick Start','wpstream').'</span>';?></h1>
3493
3494
3495 <p>
3496 <?php esc_html_e('The quick start guide will help you set up Live Streaming, Video On Demand, and Monetization in a fun and interactive way. Give it a shot! ','wpstream');?>
3497 </p>
3498
3499 <div id="wpstream_trigger_quick_start" class="wpstream_button wpstream_button_action"><?php esc_html_e('Start the Guide','wpstream');?></div>
3500
3501
3502
3503 </div>
3504
3505
3506
3507 <script type="text/javascript">
3508 //<![CDATA[
3509 jQuery(document).ready(function(){
3510 jQuery(".wpstream_on_boarding_wrapper").show();
3511 jQuery(".wpstream_modal_background_onboard").show();
3512 });
3513
3514 //]]>
3515 </script>
3516
3517 <?php
3518
3519 }
3520
3521
3522
3523
3524
3525
3526
3527
3528 /*
3529 *
3530 * On Boarding Content
3531 *
3532 */
3533
3534
3535 public function wpstream_onboard_display() {
3536 $this->onboarding_wizard_header();
3537 $this->wpstream_onboarding_step1();
3538 $this->wpstream_onboarding_step2();
3539 $this->wpstream_onboarding_step3_live_streaming();
3540 $this->wpstream_onboarding_step_3_A_live_streaming_free_view();
3541 $this->wpstream_onboarding_step_3_B_live_streaming_pay_per_view();
3542 $this->wpstream_onboarding_step4_vod();
3543 $this->wpstream_onboarding_step_4_free_vod();
3544 $this->wpstream_onboarding_step_4_ppv_vod();
3545 $this->onboarding_wizard_footer();
3546 }
3547
3548
3549 /*
3550 *
3551 * On Boarding Step 1 - the login/register
3552 *
3553 */
3554
3555
3556 public function wpstream_onboarding_step1(){
3557
3558 $wpstream_options_array =array(
3559 2 => array(
3560 'label' => 'WpStream.net Username or Email',
3561 'name' => 'api_username',
3562 'type' => 'text',
3563 ),
3564 3 => array(
3565 'label' => 'WpStream.net Password',
3566 'name' => 'api_password',
3567 'type' => 'password',
3568 ),
3569
3570 );
3571 $token = $this->main->wpstream_live_connection->wpstream_get_token();
3572
3573 ?>
3574 <div class="wpstream_step_wrapper wpstream_step_1" id="wpstream_step_1">
3575 <div class="wpstream_has_credential">
3576 <h1><?php esc_html_e('WpStream Account','wpstream');?></h1>
3577
3578 <div class="wpstream_on_board_login_wrapper_explanations">
3579 <?php esc_html_e('A WpStream account is required to make use of the plugin.','wpstream');?>
3580 </div>
3581
3582
3583 <div class="wpstream_check_account_status">
3584 <?php esc_html_e( 'Checking if you are already logged.....', 'wpstream' ); ?>
3585 </div>
3586
3587 <div class="wpstream_onboarding_notification"></div>
3588
3589 <div class="wpstream_option_wrapper wpstream_on_board_login_wrapper">
3590 <h2><?php esc_html_e('Login with your WpStream Account','wpstream');?></h2>
3591 <?php
3592
3593 foreach ($wpstream_options_array as $key=>$option){
3594 print '<div class="wpstream_option">';
3595
3596 $options_value = esc_html( get_option('wpstream_'.$option['name'],'') );
3597 print '<label for="'.$option['name'].'">'.$option['label'].'</label>';
3598 print '<input id="'.$option['name'].'" type="'.$option['type'].'" size="36" name="'.$option['name'].'" value="'.esc_html($options_value).'" />';
3599
3600 print '</div>';
3601 }
3602 ?>
3603 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_login" value="<?php esc_html_e('Login','wpstream');?>" />
3604 </div>
3605
3606
3607
3608
3609 <div class="wpstream_on_board_register_wrapper">
3610 <h2><?php esc_html_e('Register for a WpStream Account','wpstream');?></h2>
3611 <div class="wpstream_option">
3612 <label for="wpstream_register_email"><?php esc_html_e('Your Email','wpstream');?></label>
3613 <input id="wpstream_register_email" type="text" size="36" name="wpstream_register_email" value="<?php echo get_option('admin_email'); ?>" />
3614
3615 </div>
3616
3617 <div class="wpstream_option">
3618 <!-- <label for="wpstream_register_password">--><?php //esc_html_e('Your Password','wpstream');?><!--</label>-->
3619 <input id="wpstream_register_password" hidden type="text" size="36" name="wpstream_register_password" value="<?php echo $this->randomPassword();?>" />
3620 <span class="" ><?php esc_html_e('We\'ll send the password to the email you attached. ', 'wpstream') ?></span>
3621 </div>
3622
3623
3624 <!-- Altcha Widget (requires HTTPS/secure context) -->
3625 <?php if ( isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ) : ?>
3626 <script async defer src="https://cdn.jsdelivr.net/gh/altcha-org/altcha/dist/altcha.min.js" type="module"></script>
3627 <div class="wpstream_option" style="display:none;">
3628 <altcha-widget
3629 challengeurl="<?php echo esc_url( WPSTREAM_API . '/v2/user/getcaptcha' ); ?>"
3630 name="altcha"
3631 auto="onload"
3632 hidefooter
3633 hidelogo
3634 strings='{"label": "<?php esc_html_e('I am not a robot', 'wpstream'); ?>", "error": "<?php esc_html_e('Verification failed', 'wpstream'); ?>", "wait": "<?php esc_html_e('Verifying...', 'wpstream'); ?>"}'
3635 ></altcha-widget>
3636 </div>
3637 <?php endif; ?>
3638
3639 <div class="wpstream_option wpstream_terms_agreement">
3640 <!-- Add "by registering you agree to the privacy terms" checkbox-->
3641 <input id="wpstream_register_privacy" type="checkbox" name="wpstream_register_privacy" />
3642 <label for="wpstream_register_privacy">
3643 <?php printf(
3644 esc_html__('By registering you agree to the %sPrivacy Policy%s','wpstream'),
3645 '<a href="https://wpstream.net/privacy-policy/" target="_blank">',
3646 '</a>'
3647 );?>
3648 </label>
3649 </div>
3650 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_register" value="<?php esc_html_e('register','wpstream');?>" />
3651 </div>
3652
3653
3654 <div id="wpstream_onboarding_action_login"><?php esc_html_e('I already have a WpStream Account','wpstream');?></div>
3655
3656 <div id="wpstream_onboarding_action_register"><?php esc_html_e('Back to Registration','wpstream');?></div>
3657
3658 </div>
3659
3660
3661 <?php
3662 $ajax_nonce = wp_create_nonce( "wpstream_onboarding_nonce");
3663 print'<input type="hidden" id="wpstream_onboarding_nonce" value="'.esc_html($ajax_nonce).'" /> ';
3664
3665 ?>
3666
3667
3668 <div id="wpstream_on_board" class="wpstream_action_next_step" data-nextthing="wpstream_step_2" style="display:none;" >Move to step 2</div>
3669 </div>
3670 <?php
3671
3672 if( !is_null( $token ) && trim( $token ) !== '' ) {
3673 print '<div id="wpstream_have_token"></div>';
3674 }
3675 }
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686 /*
3687 *
3688 * Generate random pass
3689 *
3690 */
3691
3692 public function randomPassword() {
3693 $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
3694 $pass = array(); //remember to declare $pass as an array
3695 $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
3696 for ($i = 0; $i < 16; $i++) {
3697 $n = random_int(0, $alphaLength);
3698 $pass[] = $alphabet[$n];
3699 }
3700 return implode($pass); //turn the array into a string
3701 }
3702
3703
3704 /*
3705 *
3706 *
3707 *
3708 */
3709
3710 public function wpstream_onboarding_step2(){
3711 ?>
3712
3713 <div class="wpstream_step_wrapper wpstream_step_2" id="wpstream_step_2">
3714 <h1>Welcome to <span class="header_special">WpStream</span>! How would you like to start?</h1>
3715
3716 <div class="wpstream_accordion_header wpstream_action_next_step" data-nextthing="wpstream_step_3a" ><?php esc_html_e('Go LIVE!','wpstream');?></div>
3717 <div class="wpstram_or">or</div>
3718 <div class="wpstream_accordion_header wpstream_action_next_step wpstream_step_2_create_vod" data-nextthing="wpstream_step_4a" ><?php esc_html_e('Create a Video-On-Demand (VOD)','wpstream');?></div>
3719
3720 </div>
3721
3722
3723 <?php
3724 }
3725
3726 /*
3727 *
3728 *
3729 *
3730 */
3731
3732 public function wpstream_onboarding_step3_live_streaming(){
3733 ?>
3734
3735 <div class="wpstream_step_wrapper wpstream_step_3 wpstream_onboarding_live" id="wpstream_step_3">
3736 <h1><?php esc_html_e('Do you want to charge a fee for watching?','wpstream'); ?></h1>
3737
3738 <div class="wpstream_accordion_header wpstream_action_next_step wpstream_step_3a" data-nextthing="wpstream_step_3a"><?php esc_html_e('No - Free-To-View (FTV)','wpstream');?></div>
3739 <div class="wpstram_or">or</div>
3740 <div class="wpstream_accordion_header wpstream_action_next_step" data-nextthing="wpstream_step_3b" ><?php esc_html_e('Yes - Pay-Per-View (PPV)','wpstream');?></div>
3741
3742 <div class="wpstream_initial_onboarding_controls_wrapper">
3743 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e('Prev','wpstream');?></span>
3744 </div>
3745
3746 </div>
3747
3748
3749 <?php
3750 }
3751
3752
3753 /*
3754 *
3755 *
3756 *
3757 */
3758 public function wpstream_onboarding_step_3_A_live_streaming_free_view(){
3759 ?>
3760
3761 <div class="wpstream_step_wrapper wpstream_step_3a wpstream_onboarding_live" id="wpstream_step_3a">
3762 <h1><?php esc_html_e('Let’s create your first FTV live channel','wpstream');?></h1>
3763
3764 <div id="wpstream_onboard_live_notice" class="wpstream_onboarding_notification"></div>
3765 <div id="wpstream_onboard_live" class="wpstream_accordion_container">
3766 <label>Name your first Free-To-View channel</label>
3767 <input type="text" name="channel_name" id="wpstream_onboarding_channel_name" class="wpstream_onboarding_channel_name" value="<?php esc_html_e('My first FTV channel','wpstream');?>" >
3768 <input type="submit" name="submit" id="wpstream_on_board_create_channel" class="wpstream_button wpstream_button_action wpstream_onboard_live_action" value="<?php esc_html_e('Create Channel','wpstream');?>" />
3769
3770 </div>
3771
3772 <div class="wpstream_initial_onboarding_controls_wrapper">
3773 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e('Prev','wpstream');?></span>
3774 </div>
3775
3776 </div>
3777
3778
3779 <?php
3780 }
3781
3782
3783 /*
3784 *
3785 *
3786 *
3787 */
3788
3789 public function wpstream_onboarding_step_3_B_live_streaming_pay_per_view(){
3790 ?>
3791
3792 <div class="wpstream_step_wrapper wpstream_step_3b wpstream_onboarding_live" id="wpstream_step_3b">
3793 <h1><?php esc_html_e('Make your live stream Pay Per View','wpstream');?></h1>
3794 <?php
3795 if ( class_exists( 'WooCommerce' ) ) {
3796 ?>
3797 <div id="wpstream_onboard_live_ppv_notice" class="wpstream_onboarding_notification"></div>
3798 <div id="wpstream_onboard_live_ppv" class="wpstream_accordion_container">
3799 <label><?php esc_html_e('Choose a name for your channel','wpstream');?></label>
3800 <input type="text" name="channel_name" id="wpstream_onboarding_channel_name_ppv" class="wpstream_onboarding_channel_name" value="<?php esc_html_e('My First PPV Channel','wpstream');?>">
3801 <label><?php esc_html_e('Pay-Per-View Price ($)','wpstream');?></label>
3802 <input type="text" name="channel_name" id="wpstream_onboarding_event_price_ppv" class="wpstream_onboarding_event_price" value="10">
3803 <input type="submit" name="submit" id="wpstream_onboard_live_ppv_action" class="wpstream_button wpstream_button_action wpstream_onboard_live_ppv_action" value="<?php esc_html_e('Create Channel','wpstream');?>" />
3804
3805 </div>
3806 <?php
3807 } else {
3808 $this->wpstream_onboarding_woo_warning();
3809 } ?>
3810
3811
3812 <div class="wpstream_initial_onboarding_controls_wrapper">
3813 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e('Prev','wpstream');?></span>
3814 </div>
3815 </div>
3816 <?php
3817 }
3818
3819
3820
3821
3822
3823
3824 /*
3825 * WooCommerce not installed Warning
3826 *
3827 *
3828 */
3829
3830 public function wpstream_onboarding_woo_warning(){
3831 print'<div class="wpstream_warning_onboarding">
3832 '.esc_html__('Pay-Per-View streaming requires WooCommerce. Please install the WooCommerce plugin and try again.','wpstream').'
3833 </br>
3834 <div class="wpstream_install_plugin">'. esc_html__('Install WooCommerce','wpstream').'</div>
3835
3836 <div class="wpstream_onboarding_tryagain">'.esc_html__('Try Again','wpstream').'</div>
3837 </div>';
3838 }
3839
3840
3841 /*
3842 *
3843 *
3844 *
3845 */
3846
3847 public function wpstream_onboarding_step4_vod(){
3848 ?>
3849 <div class="wpstream_step_wrapper wpstream_step_4 wpstream_onboarding_vod" id="wpstream_step_4">
3850 <h1><?php esc_html_e('Do you want to charge a fee for watching?','wpstream');?></h1>
3851
3852 <div class="wpstream_accordion_header wpstream_action_next_step wpstream_step_4a" data-control="wpstream_onboard_vod_free" data-nextthing="wpstream_step_4a" ><?php esc_html_e('No - Free-To-View (FTV)','wpstream'); ?></div>
3853 <div class="wpstram_or">or</div>
3854 <input type="hidden" id="wpstream_onboarding_video_list_nonce" value="<?php echo wp_create_nonce( "wpstream_onboarding_video_list_nonce" ); ?>">
3855 <div class="wpstream_accordion_header wpstream_action_next_step wpstream_step_4b" data-control="wpstream_onboard_vod_ppv" data-nextthing="wpstream_step_4b" ><?php esc_html_e('Yes - Pay-Per-View (PPV)','wpstream'); ?></div>
3856 <div class="wpstream_initial_onboarding_controls_wrapper">
3857 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e('Prev','wpstream');?></span>
3858 </div>
3859
3860 </div>
3861 <?php
3862 }
3863
3864
3865 /*
3866 *
3867 *
3868 *
3869 */
3870 public function wpstream_onboarding_step_4_free_vod(){
3871
3872 $current_screen=get_current_screen();
3873 if($current_screen->base !=='wpstream_page_wpstream_onboard'){
3874 return;
3875 }
3876 ?>
3877
3878 <div class="wpstream_step_wrapper wpstream_step_4a wpstream_onboarding_live" id="wpstream_step_4a">
3879 <h1><?php esc_html_e('Let’s create your first Free-To-View VOD','wpstream');?></h1>
3880 <div id="wpstream_onboard_vod_free_notice" class="wpstream_onboarding_notification"></div>
3881 <div id="wpstream_onboard_vod_free" class="wpstream_accordion_container">
3882 <div class="spinner"></div>
3883 <div class="wpstream-step-container" style="display: none">
3884 <label><?php esc_html_e('Name your FTV Video-On-Demand','wpstream')?></label>
3885 <input type="text" name="channel_name" class="wpstream_onboarding_vod_name" id="wpstream_onboarding_vod_name" value="<?php esc_html_e('My First FTV VOD','wpstream');?>" >
3886 <div id="wpstream_free_vod_dropdown_videos_list"></div>
3887 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_vod_free_action" id="wpstream_onboard_vod_free_action" value="Create FTV VOD">
3888 </div>
3889 </div>
3890 <?php $this->wpstream_obboarding_file_warning(); ?>
3891
3892 <div class="wpstream_initial_onboarding_controls_wrapper">
3893 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_4"><?php esc_html_e('Prev','wpstream');?></span>
3894 </div>
3895
3896 </div>
3897
3898
3899 <?php
3900 }
3901
3902 /*
3903 *
3904 *
3905 *
3906 */
3907 public function wpstream_obboarding_file_warning(){
3908 print '<div class="wpstream_warning_onboarding" style="display: none">
3909 '.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').'
3910 </br>
3911 <div class="wpstream_upload_video">'.esc_html__('Upload Video','wpstream').'</div>
3912
3913 <div class="wpstream_onboarding_tryagain">'.esc_html__('Try Again','wpstream').'</div>
3914 </div>';
3915 }
3916
3917 /*
3918 *
3919 *
3920 *
3921 */
3922 public function wpstream_onboarding_step_4_ppv_vod(){
3923 $current_screen=get_current_screen();
3924
3925 if($current_screen->base !=='wpstream_page_wpstream_onboard'){
3926 return;
3927 }
3928 ?>
3929
3930 <div class="wpstream_step_wrapper wpstream_step_4b wpstream_onboarding_live" id="wpstream_step_4b">
3931 <h1><?php esc_html_e('Let\'s create your first Pay-Per-View VOD','wpstream');?></h1>
3932
3933 <div id="wpstream_onboard_vod_ppv_notice" class="wpstream_onboarding_notification"></div>
3934 <?php
3935 if ( class_exists( 'WooCommerce' ) ) { ?>
3936 <div id="wpstream_onboard_vod_ppv" class="wpstream_accordion_container">
3937 <div class="spinner"></div>
3938 <div class="wpstream-step-container" style="display: none">
3939 <label><?php esc_html_e('Name your PPV Video-On-Demand','wpstream'); ?></label>
3940 <input type="text" name="channel_name" class="wpstream_onboarding_ppv_vod_name" id="wpstream_onboarding_ppv_vod_name" value="<?php esc_html_e('My First PPV VOD','wpstream');?>">
3941 <div id="wpstream_ppv_vod_dropdown_videos_list"></div>
3942 <label><?php esc_html_e('Pay-Per-View Price','wpstream');?></label>
3943 <input type="text" name="channel_name" class="wpstream_onboarding_vod_price" id="wpstream_onboarding_vod_price" value="10">
3944 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_vod_ppv_action" id="wpstream_onboard_vod_ppv_action" value="<?php esc_html_e('Create PPV VOD','wpstream');?>" />
3945 </div>
3946 </div>
3947 <?php $this->wpstream_obboarding_file_warning(); ?>
3948 <?php } else {
3949 $this->wpstream_onboarding_woo_warning();
3950 } ?>
3951 <div class="wpstream_initial_onboarding_controls_wrapper">
3952 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_4"><?php esc_html_e('Prev','wpstream');?></span>
3953 </div>
3954 </div>
3955 <?php
3956 }
3957
3958
3959
3960
3961 /*
3962 *
3963 * On boarding Header
3964 *
3965 */
3966 public function onboarding_wizard_header() {
3967 $thumb= plugin_dir_url( dirname( __FILE__ ) ). 'img/logo_onboarding.svg';
3968 ?>
3969
3970 <div class="wpstream_on_boarding_wrapper">
3971 <div class="wpstream_close_onboarding wpstream_close_initial_onboarding"></div>
3972 <img class="wpstream_onboarding_logo" src="<?php echo esc_url($thumb); ?>" />
3973 <div class="wpstream_close_onboarding_warning"></div>
3974
3975 <?php
3976 }
3977
3978
3979
3980
3981
3982 /*
3983 *
3984 * On Boarding Footer
3985 *
3986 */
3987 public function onboarding_wizard_footer() {
3988 ?>
3989 </div>
3990 <div class="wpstream_modal_background_onboard"></div>
3991 <?php
3992 }
3993
3994
3995
3996 /*
3997 *
3998 * On Boarding create PPV channel
3999 *
4000 */
4001
4002
4003 public function wpstream_on_board_create_channel_ppv(){
4004 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4005 $current_user = wp_get_current_user();
4006
4007 if(current_user_can('administrator')){
4008 $channel_name = sanitize_text_field($_POST['channel_name']);
4009 $channel_price = floatval($_POST['channel_price']);
4010 $my_post = array(
4011 'post_title' => $channel_name,
4012 'post_content' => '',
4013 'post_status' => 'publish',
4014 'post_type' => 'product',
4015 'post_author' => $current_user->ID
4016 );
4017
4018 // Insert the post into the database
4019 $post_id = wp_insert_post( $my_post );
4020
4021 if(is_wp_error($post_id)){
4022 $logger = new WPStream_Logger();
4023 $log_entry = new WpStream_Log_Entry([
4024 'type' => 'error',
4025 'description' => 'Couldn\'t create channel during onboarding because of error: ' . $post_id->get_error_message(),
4026 ]);
4027 $logger->add( $log_entry );
4028 echo json_encode( array('succes'=>false) );
4029 }else{
4030
4031 $product = wc_get_product($post_id);
4032 $price = wc_format_decimal($channel_price);
4033
4034 $product = wc_get_product( $post_id );
4035 $product->set_price( $price );
4036 $product->set_regular_price( $price ); // To be sure
4037 $product->save();
4038 update_post_meta ($post_id,'event_passed',0);
4039 wp_set_object_terms( $post_id, 'live_stream', 'product_type' );
4040
4041
4042
4043
4044 $permalink = get_edit_post_link($post_id);
4045
4046 $permalink= add_query_arg( 'onboard', 'yes', $permalink );
4047 $permalink= add_query_arg( 'branch', '2', $permalink );
4048
4049
4050 echo json_encode( array(
4051 'success'=> true,
4052 'link' => ($permalink)
4053 ));
4054 }
4055
4056 }
4057 die();
4058 }
4059
4060 /*
4061 *
4062 * On Boarding create channel
4063 *
4064 */
4065
4066
4067 public function wpstream_on_board_create_channel(){
4068 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4069 $current_user = wp_get_current_user();
4070
4071 if(current_user_can('administrator')){
4072 $channel_name=sanitize_text_field($_POST['channel_name']);
4073 $my_post = array(
4074 'post_title' => $channel_name,
4075 'post_content' => '',
4076 'post_status' => 'publish',
4077 'post_type' => 'wpstream_product',
4078 'post_author' => $current_user->ID
4079 );
4080
4081 // Insert the post into the database
4082 $post_id = wp_insert_post( $my_post );
4083
4084 if( is_wp_error( $post_id ) ) {
4085 $logger = new WPStream_Logger();
4086 $log_entry = new WpStream_Log_Entry([
4087 'type' => 'error',
4088 'description' => 'Couldn\'t create channel during onboarding because of error: ' . $post_id->get_error_message(),
4089 ]);
4090 $logger->add( $log_entry );
4091 echo json_encode( array('succes'=>false) );
4092 } else {
4093 $permalink = get_edit_post_link($post_id);
4094
4095 $permalink= add_query_arg( 'onboard', 'yes', $permalink );
4096 $permalink= add_query_arg( 'branch', '1', $permalink );
4097
4098 echo json_encode( array(
4099 'success'=> true,
4100 'link' => ($permalink)
4101 ));
4102 }
4103 }
4104 die();
4105 }
4106
4107 /*
4108 *
4109 * On Boarding create free vod
4110 *
4111 */
4112 public function wpstream_on_board_create_free_vod(){
4113 $current_user = wp_get_current_user();
4114 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4115 if(current_user_can('administrator')){
4116 $channel_name =sanitize_text_field($_POST['channel_name']);
4117 $file_name =sanitize_text_field($_POST['file_name']);
4118 $my_post = array(
4119 'post_title' => $channel_name,
4120 'post_content' => '',
4121 'post_status' => 'publish',
4122 'post_type' => 'wpstream_product_vod',
4123 'post_author' => $current_user->ID
4124 );
4125
4126 // Insert the post into the database
4127 $post_id = wp_insert_post( $my_post );
4128
4129 if(is_wp_error($post_id)){
4130 $logger = new WPStream_Logger();
4131 $log_entry = new WpStream_Log_Entry([
4132 'type' => 'error',
4133 'description' => 'Couldn\'t create free VOD during onboarding because of error: ' . $post_id->get_error_message(),
4134 ]);
4135 $logger->add( $log_entry );
4136 echo json_encode( array('succes'=>false) );
4137 }else{
4138 update_post_meta($post_id, 'wpstream_product_type', 2);
4139 update_post_meta($post_id, 'wpstream_free_video', $file_name);
4140
4141
4142 $permalink = get_edit_post_link($post_id);
4143
4144 $permalink= add_query_arg( 'onboard', 'yes', $permalink );
4145 $permalink= add_query_arg( 'branch', '3', $permalink );
4146
4147
4148 echo json_encode( array(
4149 'success'=> true,
4150 'link' => ($permalink)
4151 ));
4152 }
4153
4154 }
4155 die();
4156 }
4157
4158
4159 /*
4160 *
4161 * On Boarding create ppv vod
4162 *
4163 */
4164
4165
4166 public function wpstream_on_board_create_ppv_vod(){
4167 $current_user = wp_get_current_user();
4168 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4169
4170 if(current_user_can('administrator')){
4171 $channel_name = sanitize_text_field($_POST['channel_name']);
4172 $vod_price = floatval($_POST['vod_price']);
4173 $file_name = sanitize_text_field($_POST['file_name']);
4174
4175 $my_post = array(
4176 'post_title' => $channel_name,
4177 'post_content' => '',
4178 'post_status' => 'publish',
4179 'post_type' => 'product',
4180 'post_author' => $current_user->ID
4181 );
4182
4183 // Insert the post into the database
4184 $post_id = wp_insert_post( $my_post );
4185
4186 if( is_wp_error( $post_id ) ) {
4187 $logger = new WPStream_Logger();
4188 $log_entry = new WpStream_Log_Entry([
4189 'type' => 'error',
4190 'description' => 'Couldn\'t create PPV VOD during onboarding because of error: ' . $post_id->get_error_message(),
4191 ]);
4192 $logger->add( $log_entry );
4193 echo json_encode( array('succes'=>false) );
4194 } else {
4195
4196 $product = wc_get_product($post_id);
4197 $price = wc_format_decimal($vod_price);
4198
4199 $product = wc_get_product( $post_id );
4200 $product->set_price( $price );
4201 $product->set_regular_price( $price ); // To be sure
4202 $product->save();
4203 update_post_meta ($post_id,'event_passed',0);
4204 update_post_meta ($post_id,'_movie_url', $file_name);
4205 wp_set_object_terms( $post_id, 'video_on_demand', 'product_type' );
4206
4207
4208
4209
4210 $permalink = get_edit_post_link($post_id);
4211
4212 $permalink= add_query_arg( 'onboard', 'yes', $permalink );
4213 $permalink= add_query_arg( 'branch', '4', $permalink );
4214
4215
4216 echo json_encode( array(
4217 'success'=> true,
4218 'link' => ($permalink) ,
4219 ' $file_name'=> $file_name,
4220 ));
4221 }
4222
4223 }
4224 die();
4225 }
4226
4227
4228 /*
4229 *
4230 * On Boarding login
4231 *
4232 */
4233 public function wpstream_on_board_login(){
4234 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4235
4236 if(current_user_can('administrator')){
4237 $username = sanitize_text_field($_POST['api_username']);
4238 $password = $_POST['api_password'];
4239 update_option('wpstream_api_username',$username);
4240 update_option('wpstream_api_password',$password);
4241
4242 delete_transient( 'wpstream_token_api' );
4243
4244 $token = $this->main->wpstream_live_connection->wpstream_get_token();
4245 $videos_list = $this->main->wpstream_live_connection->wpstream_get_videos();
4246 // cleanup any previous echo before sending json
4247 ob_end_clean();
4248 // !DO NOT SEND TOKEN TO THE CLIENT!
4249 if ($token){
4250 echo json_encode( array(
4251 'success'=> true
4252 ));
4253 }
4254 else {
4255 $text = get_option('wpstream_curl_failed') ?
4256 'Login failed with critical error: ' . get_option('wpstream_curl_failed') :
4257 'Wrong username or password!';
4258 echo json_encode( array(
4259 'success'=> false,
4260 'error' => $text,
4261 ));
4262 }
4263
4264 }else{
4265 echo json_encode( array(
4266 'success'=> false,
4267 'token' => esc_html('You are not an administrator','wpstream')
4268 ));
4269 }
4270 die();
4271 }
4272
4273
4274 public function wpstream_register_refresh_capthca(){
4275
4276 if(current_user_can('administrator')){
4277
4278 }
4279 }
4280
4281 /**
4282 * AJAX proxy: fetch a captcha challenge from the baker API and return it.
4283 * Used on HTTP sites where the Altcha widget cannot run (requires Web Crypto / HTTPS).
4284 * The JS side solves the PoW locally and sends back the full base64 Altcha payload.
4285 */
4286 public function wpstream_get_captcha_challenge() {
4287 $api_url = WPSTREAM_API . '/v2/user/getcaptcha';
4288 $response = wp_remote_get( $api_url, array( 'timeout' => 10 ) );
4289
4290 if ( is_wp_error( $response ) ) {
4291 echo json_encode( array( 'success' => false, 'error' => 'Could not reach captcha service.' ) );
4292 die();
4293 }
4294
4295 $body = wp_remote_retrieve_body( $response );
4296 // Forward the challenge JSON directly to the browser
4297 header( 'Content-Type: application/json' );
4298 echo $body;
4299 die();
4300 }
4301
4302 /**
4303 * @param $challenge
4304 * @param $difficulty
4305 *
4306 * @return int|null
4307 */
4308 private function solve_pow( $challenge, $difficulty ) {
4309 $nonce = 0;
4310 $target = str_repeat( "0", $difficulty );
4311
4312 while ( $nonce < 5000000 ) {
4313 $hash = hash( 'sha256', $challenge . $nonce );
4314 if ( strpos( $hash, $target ) === 0 ) {
4315 return $nonce;
4316 }
4317 $nonce++;
4318 }
4319 return null; // Return null if no solution is found within the max attempts
4320 }
4321
4322 /*
4323 *
4324 * On Boarding login
4325 *
4326 */
4327 public function wpstream_on_board_register(){
4328 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
4329 if(current_user_can('administrator')){
4330 $wpstream_register_email = sanitize_text_field($_POST['wpstream_register_email']);
4331 $wpstream_register_password = $_POST['wpstream_register_password'];
4332
4333 $validate = $this->wpstream_validate_onboard_register($wpstream_register_email,$wpstream_register_password);
4334 if(!$validate['success']){
4335 // cleanup any previous echo before sending json
4336 ob_end_clean();
4337 echo json_encode($validate);
4338 die();
4339 }
4340
4341 $wpstream_altcha = isset($_POST['wpstream_altcha']) ? trim( $_POST['wpstream_altcha'] ) : '';
4342 $is_https = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off';
4343
4344 if ( empty($wpstream_altcha) ) {
4345 if ( $is_https ) {
4346 $message = esc_html__('Captcha verification failed. Please try again.', 'wpstream');
4347 } else {
4348 $message = esc_html__('Security check not ready yet. Please wait a moment and try again.', 'wpstream');
4349 }
4350 echo json_encode( array( 'success' => false, 'message' => $message ) );
4351 die();
4352 }
4353
4354 $url='v2/user/create';
4355 $curl_post_fields=array(
4356 'email' => $wpstream_register_email,
4357 'password' => $wpstream_register_password,
4358 'solution' => $wpstream_altcha,
4359 'captcha_id' => '',
4360 );
4361
4362 $curl_response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url,$curl_post_fields,true);
4363 $curl_response_decoded = json_decode($curl_response,JSON_OBJECT_AS_ARRAY);
4364
4365 if($curl_response_decoded['success']){
4366
4367 if($curl_response_decoded['request']['registred']){
4368 // we are registerd
4369
4370 update_option('wpstream_api_username',$wpstream_register_email);
4371 update_option('wpstream_api_password',$wpstream_register_password);
4372
4373 $token = $this->main->wpstream_live_connection->wpstream_get_token();
4374
4375 // cleanup any previous echo before sending json
4376 ob_end_clean();
4377 echo json_encode( array(
4378 'success' => true,
4379 'token' => $token ,
4380 'message' => esc_html__('Your Account was created. Please stand by...','wpstream'),
4381
4382 ));
4383 die();
4384 }else{
4385
4386 // cleanup any previous echo before sending json
4387 ob_end_clean();
4388 echo json_encode( array(
4389 'success'=> false,
4390 'message'=> $curl_response_decoded['request']['message'],
4391 'curl'=>$curl_response_decoded,
4392
4393 ));
4394 die();
4395 }
4396
4397
4398
4399
4400 }else{
4401 // cleanup any previous echo before sending json
4402 ob_end_clean();
4403 echo json_encode( array(
4404 'success'=> false,
4405 'message'=> esc_html__('Registration could not be completed. Please try again or register on wpstream.net','wpstream'),
4406
4407 ));
4408 die();
4409 }
4410
4411
4412
4413
4414
4415
4416
4417
4418 }else{
4419 // cleanup any previous echo before sending json
4420 ob_end_clean();
4421 echo json_encode( array(
4422 'success'=> false,
4423 'message' => esc_html('You are not an administrator','wpstream')
4424 ));
4425 die();
4426 }
4427
4428 die();
4429 }
4430
4431
4432 /*
4433 *
4434 * Validate for register
4435 *
4436 */
4437
4438
4439 public function wpstream_validate_onboard_register($wpstream_register_email,$wpstream_register_password){
4440
4441 $return= array(
4442 'success'=>true
4443 );
4444
4445 if ($wpstream_register_email=='' ){
4446 $return= array(
4447 'success'=> false,
4448 'message' => esc_html('The email Field is Empty','wpstream')
4449 );
4450 return $return;die();
4451 }
4452
4453 if(filter_var($wpstream_register_email,FILTER_VALIDATE_EMAIL) === false) {
4454 $return= array(
4455 'success'=> false,
4456 'message' => esc_html__('The email doesn\'t look right !','wpstream')
4457 );
4458 return $return;die();
4459 }
4460
4461
4462 $domain = mb_substr(strrchr($wpstream_register_email, "@"), 1);
4463 if( $domain!='' && !checkdnsrr ($domain) ){
4464 $return= array(
4465 'success'=> false,
4466 'message' => esc_html__('The email doesn\'t look right !','wpstream')
4467 );
4468 return $return;die();
4469 }
4470
4471
4472
4473 if(strlen($wpstream_register_password)<5){
4474 $return= array(
4475 'success'=> false,
4476 'message' => esc_html('The password is too short. Please use at least 5 characters.','wpstream')
4477 );
4478 return $return;die();
4479 }
4480
4481 return $return;die();
4482 }
4483
4484 /**
4485 * Handle the AJAX request to initiate a multipart upload
4486 *
4487 * @since 3.0.1
4488 */
4489 public function handle_initiate_multipart_upload() {
4490 check_ajax_referer( 'wpstream_multipart_upload_nonce', 'security' );
4491
4492 // Security check - only admins can do this
4493 if (!current_user_can('administrator')) {
4494 wp_send_json_error('Unauthorized access');
4495 return;
4496 }
4497
4498 // Get file details from request
4499 $file_name = sanitize_text_field($_POST['file_name']);
4500 $file_size = intval($_POST['file_size']);
4501 $content_type = sanitize_text_field($_POST['content_type']);
4502 $num_parts = intval($_POST['parts']);
4503
4504 if (empty($file_name) || $file_size <= 0 || $num_parts <= 0) {
4505 wp_send_json_error('Invalid file information');
4506 return;
4507 }
4508
4509 // Prepare a clean filename (similar to the standard upload process)
4510 $file_name_array = explode(".", $file_name);
4511 $file_extension = $file_name_array[count($file_name_array) - 1];
4512 $temp_file_name = $file_name_array[0];
4513 $temp_file_name = str_replace(' ', '_', $temp_file_name);
4514 $temp_file_name = preg_replace('/\W/', '', $temp_file_name);
4515 $clean_file_name = $temp_file_name . '.' . $file_extension;
4516
4517 // Make API call to initiate multipart upload
4518 $url = 'video/upload';
4519 $access_token = $this->main->wpstream_live_connection->wpstream_get_token();
4520
4521 if (!$access_token) {
4522 wp_send_json_error('Not connected to WPStream service');
4523 return;
4524 }
4525
4526 $api_params = array(
4527 'access_token' => $access_token,
4528 'size' => $file_size,
4529 'name' => $clean_file_name,
4530 'content_type' => $content_type,
4531 'parts' => $num_parts
4532 );
4533
4534 $response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url, $api_params, true);
4535 $response_data = json_decode($response, true);
4536
4537 if (!isset($response_data['success']) || $response_data['success'] !== true) {
4538 $error_message = isset($response_data['error']) ? $response_data['error'] : 'Failed to initiate multipart upload';
4539 wp_send_json_error($error_message);
4540 return;
4541 }
4542
4543 // Return the upload ID and pre-signed URLs for each part
4544 wp_send_json_success($response_data);
4545 }
4546
4547 /**
4548 * Handle the AJAX request to complete a multipart upload
4549 *
4550 * @since 3.0.1
4551 */
4552 public function handle_complete_multipart_upload() {
4553 check_ajax_referer( 'wpstream_multipart_upload_nonce', 'security' );
4554
4555 // Security check - only admins can do this
4556 if (!current_user_can('administrator')) {
4557 wp_send_json_error('Unauthorized access');
4558 return;
4559 }
4560
4561 // Get completion details
4562 $parts = json_decode(stripslashes($_POST['parts']), true);
4563 $file_name = sanitize_text_field($_POST['file_name']);
4564 $handle = sanitize_text_field($_POST['handle']);
4565
4566 if (empty($parts) || !is_numeric($parts) || empty($file_name)) {
4567 wp_send_json_error('Invalid completion information');
4568 return;
4569 }
4570
4571 // Make API call to complete the multipart upload
4572 $url = 'video/upload';
4573 $access_token = $this->main->wpstream_live_connection->wpstream_get_token();
4574
4575 if (!$access_token) {
4576 wp_send_json_error('Not connected to WPStream service');
4577 return;
4578 }
4579
4580 $api_params = array(
4581 'access_token' => $access_token,
4582 'parts' => $parts,
4583 'name' => $file_name,
4584 'handle' => $handle,
4585 'action' => 'complete'
4586 );
4587
4588 $response = $this->main->wpstream_live_connection->wpstream_baker_do_curl_base($url, $api_params, true);
4589 $response_data = json_decode($response, true);
4590
4591 if (!isset($response_data['success']) || $response_data['success'] !== true) {
4592 $error_message = isset($response_data['error']) ? $response_data['error'] : 'Failed to complete multipart upload';
4593 wp_send_json_error($error_message);
4594 return;
4595 }
4596
4597 // Return success
4598 wp_send_json_success();
4599 }
4600
4601 public function wpstream_settings_tab_update_plugin() {
4602 if ( !current_user_can( 'update_plugins' ) ) {
4603 wp_send_json_error( __( 'Not enough permissions to make this change', 'wpstream' ) );
4604 }
4605
4606 include_once ABSPATH . 'wp-admin/includes/plugin-install.php';
4607 include_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
4608 include_once ABSPATH . 'wp-admin/includes/file.php';
4609
4610 $credentials = request_filesystem_credentials('');
4611 if ( !WP_Filesystem( $credentials ) ) {
4612 wp_send_json_error( __( 'Failed to connect to the filesystem', 'wpstream' ) );
4613 }
4614
4615 $upgrader = new Plugin_Upgrader(new Automatic_Upgrader_Skin());
4616 $plugin_path = plugin_basename( WPSTREAM_PLUGIN_PATH . 'wpstream.php' );
4617 $result = $upgrader->upgrade( $plugin_path );
4618 activate_plugin( $plugin_path );
4619
4620 if ( is_wp_error( $result ) ) {
4621 wp_send_json_error( __( 'Update failed due to', 'wpstream' ) . $result->get_error_message() );
4622 }
4623
4624 wp_send_json_success();
4625 }
4626 }
4627