PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / 4.14.1
WpStream – Live Streaming, Video on Demand, Pay Per View v4.14.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-onboarding.php

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

912 lines 34.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Onboarding workflow module.
4 *
5 * @package Wpstream
6 * @subpackage Wpstream/admin
7 */
8
9 /**
10 * Owns the Quick Start wizard and its account/content actions.
11 */
12 class Wpstream_Onboarding {
13
14 /** @var Wpstream Main plugin module. */
15 private $main;
16
17 /** @var bool Whether the wizard footer callback has been registered. */
18 private $footer_registered = false;
19
20 /**
21 * @param Wpstream $main Main plugin module.
22 */
23 public function __construct( $main ) {
24 $this->main = $main;
25 }
26
27 /**
28 * Render the Quick Start entry point.
29 *
30 * @return string
31 */
32 public function render() {
33 if ( ! current_user_can( 'administrator' ) ) {
34 return '';
35 }
36
37 if ( ! $this->footer_registered ) {
38 add_action( 'admin_footer', function () {
39 if ( current_user_can( 'administrator' ) ) {
40 $this->render_wizard();
41 }
42 } );
43 $this->footer_registered = true;
44 }
45
46 ob_start();
47 $this->render_quick_start();
48 return (string) ob_get_clean();
49 }
50
51 /**
52 * Render a named legacy fragment for compatibility forwarders.
53 *
54 * @internal Only Wpstream_Admin compatibility methods should call this.
55 *
56 * @param string $part Fragment name.
57 * @return mixed
58 */
59 public function render_part( $part ) {
60 $parts = array(
61 'quick_start' => 'render_quick_start',
62 'wizard' => 'render_wizard',
63 'wizard_header' => 'render_wizard_header',
64 'wizard_footer' => 'render_wizard_footer',
65 'account' => 'render_account_step',
66 'password' => 'random_password',
67 'path' => 'render_path_step',
68 'live' => 'render_live_step',
69 'live_free' => 'render_live_free_step',
70 'live_ppv' => 'render_live_ppv_step',
71 'woo_warning' => 'render_woo_warning',
72 'vod' => 'render_vod_step',
73 'vod_free' => 'render_vod_free_step',
74 'file_warning' => 'render_file_warning',
75 'vod_ppv' => 'render_vod_ppv_step',
76 'dashboard_page'=> 'register_dashboard_page',
77 'standalone' => 'load_standalone_wizard',
78 'page_footer' => 'render_page_footer',
79 );
80
81 if ( ! isset( $parts[ $part ] ) ) {
82 return new WP_Error( 'unknown_onboarding_fragment', __( 'Unknown onboarding fragment.', 'wpstream' ) );
83 }
84
85 return $this->{$parts[ $part ]}();
86 }
87
88 /** Register the legacy hidden dashboard endpoint. */
89 private function register_dashboard_page() {
90 add_dashboard_page( '', '', 'administrator', 'wpstream-onboarding', '' );
91 }
92
93 /** Bootstrap the legacy standalone wizard context. */
94 private function load_standalone_wizard() {
95 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
96 return;
97 }
98
99 set_current_screen();
100 remove_action( 'admin_print_styles', 'gutenberg_block_editor_admin_print_styles' );
101 echo $this->render();
102 }
103
104 /** Render the legacy page-footer entry point when Quick Start is active. */
105 private function render_page_footer() {
106 if ( current_user_can( 'administrator' )
107 && isset( $_GET['page'] )
108 && 'wpstream_onboard' === $_GET['page'] ) {
109 $this->render_wizard();
110 }
111 }
112
113 /** Render the Quick Start landing screen. */
114 private function render_quick_start() {
115 $pack_details = $this->main->quota_manager->get_live_quota_data( 'wpstream_pre_onboard_display' );
116 $this->main->show_user_data( $pack_details );
117 $thumb = plugin_dir_url( dirname( __FILE__ ) ) . 'img/logo_onboarding.svg';
118 ?>
119 <div id="wpstream-onboarding-root"></div>
120 <div class="wpstream_quick_start_wrapper">
121 <img class="wpstream_onboarding_logo" src="<?php echo esc_url( $thumb ); ?>" />
122
123 <h1><?php print esc_html__( 'WpStream', 'wpstream' ) . ' <span class="header_special">' . esc_html__( 'Quick Start', 'wpstream' ) . '</span>'; ?></h1>
124
125 <p>
126 <?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' ); ?>
127 </p>
128
129 <div id="wpstream_trigger_quick_start" class="wpstream_button wpstream_button_action"><?php esc_html_e( 'Start the Guide', 'wpstream' ); ?></div>
130 </div>
131
132 <script type="text/javascript">
133 //<![CDATA[
134 jQuery(document).ready(function(){
135 jQuery(".wpstream_on_boarding_wrapper").show();
136 jQuery(".wpstream_modal_background_onboard").show();
137 });
138 //]]>
139 </script>
140 <?php
141 }
142
143 /** Render the complete onboarding wizard. */
144 private function render_wizard() {
145 /**
146 * Filter the onboarding wizard steps.
147 *
148 * @since 4.14.0
149 *
150 * @param array $steps Step slug => callable, in display order.
151 */
152 $steps = (array) apply_filters(
153 'wpstream_onboarding_steps',
154 array(
155 'account' => array( $this->main->admin, 'wpstream_onboarding_step1' ),
156 'path' => array( $this->main->admin, 'wpstream_onboarding_step2' ),
157 'live' => array( $this->main->admin, 'wpstream_onboarding_step3_live_streaming' ),
158 'live_free' => array( $this->main->admin, 'wpstream_onboarding_step_3_A_live_streaming_free_view' ),
159 'live_ppv' => array( $this->main->admin, 'wpstream_onboarding_step_3_B_live_streaming_pay_per_view' ),
160 'vod' => array( $this->main->admin, 'wpstream_onboarding_step4_vod' ),
161 'vod_free' => array( $this->main->admin, 'wpstream_onboarding_step_4_free_vod' ),
162 'vod_ppv' => array( $this->main->admin, 'wpstream_onboarding_step_4_ppv_vod' ),
163 )
164 );
165
166 $this->render_wizard_header();
167 foreach ( $steps as $step ) {
168 if ( is_callable( $step ) ) {
169 call_user_func( $step );
170 }
171 }
172 $this->render_wizard_footer();
173 }
174
175 /** Open the wizard wrapper. */
176 private function render_wizard_header() {
177 $thumb = plugin_dir_url( dirname( __FILE__ ) ) . 'img/logo_onboarding.svg';
178 ?>
179 <div class="wpstream_on_boarding_wrapper">
180 <div class="wpstream_close_onboarding wpstream_close_initial_onboarding"></div>
181 <img class="wpstream_onboarding_logo" src="<?php echo esc_url( $thumb ); ?>" />
182 <div class="wpstream_close_onboarding_warning"></div>
183 <?php
184 }
185
186 /** Close the wizard wrapper and render its backdrop. */
187 private function render_wizard_footer() {
188 ?>
189 </div>
190 <div class="wpstream_modal_background_onboard"></div>
191 <?php
192 }
193
194 /** Render the account login and registration step. */
195 private function render_account_step() {
196 $options = array(
197 2 => array(
198 'label' => 'WpStream.net Username or Email',
199 'name' => 'api_username',
200 'type' => 'text',
201 ),
202 3 => array(
203 'label' => 'WpStream.net Password',
204 'name' => 'api_password',
205 'type' => 'password',
206 ),
207 );
208 $connected = $this->main->wpstream_live_connection->is_connected();
209 ?>
210 <div class="wpstream_step_wrapper wpstream_step_1" id="wpstream_step_1">
211 <div class="wpstream_has_credential">
212 <h1><?php esc_html_e( 'WpStream Account', 'wpstream' ); ?></h1>
213
214 <div class="wpstream_on_board_login_wrapper_explanations">
215 <?php esc_html_e( 'A WpStream account is required to make use of the plugin.', 'wpstream' ); ?>
216 </div>
217
218 <div class="wpstream_check_account_status">
219 <?php esc_html_e( 'Checking if you are already logged.....', 'wpstream' ); ?>
220 </div>
221
222 <div class="wpstream_onboarding_notification"></div>
223
224 <div class="wpstream_option_wrapper wpstream_on_board_login_wrapper">
225 <h2><?php esc_html_e( 'Login with your WpStream Account', 'wpstream' ); ?></h2>
226 <?php
227 foreach ( $options as $option ) {
228 print '<div class="wpstream_option">';
229 print '<label for="' . $option['name'] . '">' . $option['label'] . '</label>';
230 if ( 'password' === $option['type'] ) {
231 print '<input id="' . $option['name'] . '" type="password" size="36" name="' . $option['name'] . '" value="" autocomplete="current-password" />';
232 } else {
233 $value = esc_html( get_option( 'wpstream_' . $option['name'], '' ) );
234 print '<input id="' . $option['name'] . '" type="' . $option['type'] . '" size="36" name="' . $option['name'] . '" value="' . esc_html( $value ) . '" />';
235 }
236 print '</div>';
237 }
238 ?>
239 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_login" value="<?php esc_html_e( 'Login', 'wpstream' ); ?>" />
240 </div>
241
242 <div class="wpstream_on_board_register_wrapper">
243 <h2><?php esc_html_e( 'Register for a WpStream Account', 'wpstream' ); ?></h2>
244 <div class="wpstream_option">
245 <label for="wpstream_register_email"><?php esc_html_e( 'Your Email', 'wpstream' ); ?></label>
246 <input id="wpstream_register_email" type="text" size="36" name="wpstream_register_email" value="<?php echo get_option( 'admin_email' ); ?>" />
247 </div>
248
249 <div class="wpstream_option">
250 <input id="wpstream_register_password" hidden type="text" size="36" name="wpstream_register_password" value="<?php echo $this->random_password(); ?>" />
251 <span><?php esc_html_e( 'We\'ll send the password to the email you attached. ', 'wpstream' ); ?></span>
252 </div>
253
254 <?php if ( isset( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'] ) : ?>
255 <script async defer src="<?php echo esc_url( plugin_dir_url( __FILE__ ) . 'js/vendor/altcha.min.js?ver=3.2.1' ); ?>" type="module"></script>
256 <div class="wpstream_option" style="display:none;">
257 <altcha-widget
258 challengeurl="<?php echo esc_url( WPSTREAM_API . '/v2/user/getcaptcha' ); ?>"
259 name="altcha"
260 auto="onload"
261 hidefooter
262 hidelogo
263 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' ); ?>"}'
264 ></altcha-widget>
265 </div>
266 <?php endif; ?>
267
268 <div class="wpstream_option wpstream_terms_agreement">
269 <input id="wpstream_register_privacy" type="checkbox" name="wpstream_register_privacy" />
270 <label for="wpstream_register_privacy">
271 <?php
272 printf(
273 esc_html__( 'By registering you agree to the %sPrivacy Policy%s', 'wpstream' ),
274 '<a href="https://wpstream.net/privacy-policy/" target="_blank">',
275 '</a>'
276 );
277 ?>
278 </label>
279 </div>
280 <input type="submit" name="submit" class="wpstream_button wpstream_button_action wpstream_onboard_register" value="<?php esc_html_e( 'register', 'wpstream' ); ?>" />
281 </div>
282
283 <div id="wpstream_onboarding_action_login"><?php esc_html_e( 'I already have a WpStream Account', 'wpstream' ); ?></div>
284 <div id="wpstream_onboarding_action_register"><?php esc_html_e( 'Back to Registration', 'wpstream' ); ?></div>
285 </div>
286
287 <?php $ajax_nonce = wp_create_nonce( 'wpstream_onboarding_nonce' ); ?>
288 <input type="hidden" id="wpstream_onboarding_nonce" value="<?php echo esc_html( $ajax_nonce ); ?>" />
289 <div id="wpstream_on_board" class="wpstream_action_next_step" data-nextthing="wpstream_step_2" style="display:none;">Move to step 2</div>
290 </div>
291 <?php
292
293 if ( $connected ) {
294 print '<div id="wpstream_have_token"></div>';
295 }
296 }
297
298 /** Generate the registration password used by the account step. */
299 private function random_password() {
300 $alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890';
301 $password = array();
302 $alpha_length = strlen( $alphabet ) - 1;
303 for ( $index = 0; $index < 16; $index++ ) {
304 $password[] = $alphabet[ random_int( 0, $alpha_length ) ];
305 }
306
307 return implode( $password );
308 }
309
310 /** Render the live-or-VOD path choice. */
311 private function render_path_step() {
312 ?>
313 <div class="wpstream_step_wrapper wpstream_step_2" id="wpstream_step_2">
314 <h1>Welcome to <span class="header_special">WpStream</span>! How would you like to start?</h1>
315 <div class="wpstream_accordion_header wpstream_action_next_step" data-nextthing="wpstream_step_3"><?php esc_html_e( 'Go LIVE!', 'wpstream' ); ?></div>
316 <div class="wpstram_or">or</div>
317 <div class="wpstream_accordion_header wpstream_action_next_step wpstream_step_2_create_vod" data-nextthing="wpstream_step_4"><?php esc_html_e( 'Create a Video-On-Demand (VOD)', 'wpstream' ); ?></div>
318 </div>
319 <?php
320 }
321
322 /** Render the free-or-paid live choice. */
323 private function render_live_step() {
324 ?>
325 <div class="wpstream_step_wrapper wpstream_step_3 wpstream_onboarding_live" id="wpstream_step_3">
326 <h1><?php esc_html_e( 'Do you want to charge a fee for watching?', 'wpstream' ); ?></h1>
327 <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>
328 <div class="wpstram_or">or</div>
329 <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>
330 <div class="wpstream_initial_onboarding_controls_wrapper">
331 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
332 </div>
333 </div>
334 <?php
335 }
336
337 /** Render the free live-channel creation step. */
338 private function render_live_free_step() {
339 ?>
340 <div class="wpstream_step_wrapper wpstream_step_3a wpstream_onboarding_live" id="wpstream_step_3a">
341 <h1><?php esc_html_e( 'Let’s create your first FTV live channel', 'wpstream' ); ?></h1>
342 <div id="wpstream_onboard_live_notice" class="wpstream_onboarding_notification"></div>
343 <div id="wpstream_onboard_live" class="wpstream_accordion_container">
344 <label>Name your first Free-To-View channel</label>
345 <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' ); ?>">
346 <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' ); ?>" />
347 </div>
348 <div class="wpstream_initial_onboarding_controls_wrapper">
349 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
350 </div>
351 </div>
352 <?php
353 }
354
355 /** Render the paid live-channel creation step. */
356 private function render_live_ppv_step() {
357 ?>
358 <div class="wpstream_step_wrapper wpstream_step_3b wpstream_onboarding_live" id="wpstream_step_3b">
359 <h1><?php esc_html_e( 'Make your live stream Pay Per View', 'wpstream' ); ?></h1>
360 <?php if ( class_exists( 'WooCommerce' ) ) : ?>
361 <div id="wpstream_onboard_live_ppv_notice" class="wpstream_onboarding_notification"></div>
362 <div id="wpstream_onboard_live_ppv" class="wpstream_accordion_container">
363 <label><?php esc_html_e( 'Choose a name for your channel', 'wpstream' ); ?></label>
364 <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' ); ?>">
365 <label><?php esc_html_e( 'Pay-Per-View Price ($)', 'wpstream' ); ?></label>
366 <input type="text" name="channel_name" id="wpstream_onboarding_event_price_ppv" class="wpstream_onboarding_event_price" value="10">
367 <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' ); ?>" />
368 </div>
369 <?php else : ?>
370 <?php $this->render_woo_warning(); ?>
371 <?php endif; ?>
372 <div class="wpstream_initial_onboarding_controls_wrapper">
373 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
374 </div>
375 </div>
376 <?php
377 }
378
379 /** Render the missing-WooCommerce warning. */
380 private function render_woo_warning() {
381 print '<div class="wpstream_warning_onboarding">
382 ' . esc_html__( 'Pay-Per-View streaming requires WooCommerce. Please install the WooCommerce plugin and try again.', 'wpstream' ) . '
383 </br>
384 <div class="wpstream_install_plugin">' . esc_html__( 'Install WooCommerce', 'wpstream' ) . '</div>
385 <div class="wpstream_onboarding_tryagain">' . esc_html__( 'Try Again', 'wpstream' ) . '</div>
386 </div>';
387 }
388
389 /** Render the free-or-paid VOD choice. */
390 private function render_vod_step() {
391 ?>
392 <div class="wpstream_step_wrapper wpstream_step_4 wpstream_onboarding_vod" id="wpstream_step_4">
393 <h1><?php esc_html_e( 'Do you want to charge a fee for watching?', 'wpstream' ); ?></h1>
394 <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>
395 <div class="wpstram_or">or</div>
396 <input type="hidden" id="wpstream_onboarding_video_list_nonce" value="<?php echo wp_create_nonce( 'wpstream_onboarding_video_list_nonce' ); ?>">
397 <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>
398 <div class="wpstream_initial_onboarding_controls_wrapper">
399 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_2"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
400 </div>
401 </div>
402 <?php
403 }
404
405 /** Render the free VOD creation step. */
406 private function render_vod_free_step() {
407 $current_screen = get_current_screen();
408 if ( ! $current_screen || 'wpstream_page_wpstream_onboard' !== $current_screen->base ) {
409 return;
410 }
411 ?>
412 <div class="wpstream_step_wrapper wpstream_step_4a wpstream_onboarding_live" id="wpstream_step_4a">
413 <h1><?php esc_html_e( 'Let’s create your first Free-To-View VOD', 'wpstream' ); ?></h1>
414 <div id="wpstream_onboard_vod_free_notice" class="wpstream_onboarding_notification"></div>
415 <div id="wpstream_onboard_vod_free" class="wpstream_accordion_container">
416 <div class="spinner"></div>
417 <div class="wpstream-step-container" style="display: none">
418 <label><?php esc_html_e( 'Name your FTV Video-On-Demand', 'wpstream' ); ?></label>
419 <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' ); ?>">
420 <div id="wpstream_free_vod_dropdown_videos_list"></div>
421 <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">
422 </div>
423 </div>
424 <?php $this->render_file_warning(); ?>
425 <div class="wpstream_initial_onboarding_controls_wrapper">
426 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_4"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
427 </div>
428 </div>
429 <?php
430 }
431
432 /** Render the missing-recording warning. */
433 private function render_file_warning() {
434 print '<div class="wpstream_warning_onboarding" style="display: none">
435 ' . 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' ) . '
436 </br>
437 <div class="wpstream_upload_video">' . esc_html__( 'Upload Video', 'wpstream' ) . '</div>
438 <div class="wpstream_onboarding_tryagain">' . esc_html__( 'Try Again', 'wpstream' ) . '</div>
439 </div>';
440 }
441
442 /** Render the paid VOD creation step. */
443 private function render_vod_ppv_step() {
444 $current_screen = get_current_screen();
445 if ( ! $current_screen || 'wpstream_page_wpstream_onboard' !== $current_screen->base ) {
446 return;
447 }
448 ?>
449 <div class="wpstream_step_wrapper wpstream_step_4b wpstream_onboarding_live" id="wpstream_step_4b">
450 <h1><?php esc_html_e( 'Let\'s create your first Pay-Per-View VOD', 'wpstream' ); ?></h1>
451 <div id="wpstream_onboard_vod_ppv_notice" class="wpstream_onboarding_notification"></div>
452 <?php if ( class_exists( 'WooCommerce' ) ) : ?>
453 <div id="wpstream_onboard_vod_ppv" class="wpstream_accordion_container">
454 <div class="spinner"></div>
455 <div class="wpstream-step-container" style="display: none">
456 <label><?php esc_html_e( 'Name your PPV Video-On-Demand', 'wpstream' ); ?></label>
457 <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' ); ?>">
458 <div id="wpstream_ppv_vod_dropdown_videos_list"></div>
459 <label><?php esc_html_e( 'Pay-Per-View Price', 'wpstream' ); ?></label>
460 <input type="text" name="channel_name" class="wpstream_onboarding_vod_price" id="wpstream_onboarding_vod_price" value="10">
461 <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' ); ?>" />
462 </div>
463 </div>
464 <?php $this->render_file_warning(); ?>
465 <?php else : ?>
466 <?php $this->render_woo_warning(); ?>
467 <?php endif; ?>
468 <div class="wpstream_initial_onboarding_controls_wrapper">
469 <span class="wpstream_onboard_initial_bubble_prev" data-step="wpstream_step_4"><?php esc_html_e( 'Prev', 'wpstream' ); ?></span>
470 </div>
471 </div>
472 <?php
473 }
474
475 /**
476 * Dispatch an onboarding AJAX action through the workflow interface.
477 *
478 * @param string $action WordPress AJAX action name.
479 * @return mixed
480 */
481 public function handle_ajax( $action ) {
482 $handlers = array(
483 'wpstream_on_board_login' => 'handle_login',
484 'wpstream_on_board_register' => 'handle_register',
485 'wpstream_get_captcha_challenge' => 'handle_captcha_challenge',
486 'wpstream_on_board_create_channel' => 'handle_create_channel',
487 'wpstream_on_board_create_channel_ppv' => 'handle_create_channel_ppv',
488 'wpstream_on_board_create_free_vod' => 'handle_create_free_vod',
489 'wpstream_on_board_create_ppv_vod' => 'handle_create_ppv_vod',
490 );
491
492 if ( ! isset( $handlers[ $action ] ) ) {
493 return new WP_Error( 'unknown_onboarding_action', __( 'Unknown onboarding action.', 'wpstream' ) );
494 }
495
496 return $this->{$handlers[ $action ]}();
497 }
498
499 /** Log in to WpStream during onboarding. */
500 private function handle_login() {
501 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
502
503 if ( current_user_can( 'administrator' ) ) {
504 $username = sanitize_text_field( $_POST['api_username'] );
505 $password = $_POST['api_password'];
506 update_option( 'wpstream_api_username', $username );
507 update_option( 'wpstream_api_password', $password, false );
508 delete_transient( 'wpstream_token_api' );
509
510 $connected = $this->main->wpstream_live_connection->is_connected();
511 $this->main->wpstream_live_connection->wpstream_get_videos();
512 ob_end_clean();
513
514 if ( $connected ) {
515 echo json_encode( array( 'success' => true ) );
516 } else {
517 $text = get_option( 'wpstream_curl_failed' )
518 ? 'Login failed with critical error: ' . get_option( 'wpstream_curl_failed' )
519 : 'Wrong username or password!';
520 echo json_encode(
521 array(
522 'success' => false,
523 'error' => $text,
524 )
525 );
526 }
527 } else {
528 echo json_encode(
529 array(
530 'success' => false,
531 'token' => esc_html__( 'You are not an administrator', 'wpstream' ),
532 )
533 );
534 }
535
536 die();
537 }
538
539 /** Fetch a captcha challenge from the WpStream API. */
540 private function handle_captcha_challenge() {
541 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
542 if ( ! current_user_can( 'administrator' ) ) {
543 wp_send_json( array( 'success' => false, 'error' => esc_html__( 'You are not an administrator', 'wpstream' ) ) );
544 }
545
546 $response = $this->main->wpstream_live_connection->get( WPSTREAM_API . '/v2/user/getcaptcha' );
547 if ( is_wp_error( $response ) ) {
548 wp_send_json( array( 'success' => false, 'error' => 'Could not reach captcha service.' ) );
549 }
550
551 wp_send_json( $response );
552 }
553
554 /** Register a new WpStream account during onboarding. */
555 private function handle_register() {
556 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
557 if ( current_user_can( 'administrator' ) ) {
558 $email = sanitize_text_field( $_POST['wpstream_register_email'] );
559 $password = $_POST['wpstream_register_password'];
560 $validate = $this->validate_registration( $email, $password );
561
562 if ( ! $validate['success'] ) {
563 ob_end_clean();
564 echo json_encode( $validate );
565 die();
566 }
567
568 $altcha = isset( $_POST['wpstream_altcha'] ) ? trim( $_POST['wpstream_altcha'] ) : '';
569 $is_https = isset( $_SERVER['HTTPS'] ) && 'off' !== $_SERVER['HTTPS'];
570 if ( empty( $altcha ) ) {
571 $message = $is_https
572 ? esc_html__( 'Captcha verification failed. Please try again.', 'wpstream' )
573 : esc_html__( 'Security check not ready yet. Please wait a moment and try again.', 'wpstream' );
574 echo json_encode( array( 'success' => false, 'message' => $message ) );
575 die();
576 }
577
578 $response = $this->main->wpstream_live_connection->request(
579 'v2/user/create',
580 array(
581 'email' => $email,
582 'password' => $password,
583 'solution' => $altcha,
584 'captcha_id' => '',
585 )
586 );
587 if ( is_wp_error( $response ) ) {
588 $response = array( 'success' => false );
589 }
590
591 if ( ! empty( $response['success'] ) ) {
592 if ( $response['request']['registred'] ) {
593 update_option( 'wpstream_api_username', $email );
594 update_option( 'wpstream_api_password', $password, false );
595 $connected = $this->main->wpstream_live_connection->is_connected();
596 ob_end_clean();
597 echo json_encode(
598 array(
599 'success' => true,
600 'token' => $connected,
601 'message' => esc_html__( 'Your Account was created. Please stand by...', 'wpstream' ),
602 )
603 );
604 die();
605 }
606
607 ob_end_clean();
608 echo json_encode(
609 array(
610 'success' => false,
611 'message' => $response['request']['message'],
612 'curl' => $response,
613 )
614 );
615 die();
616 }
617
618 ob_end_clean();
619 echo json_encode(
620 array(
621 'success' => false,
622 'message' => esc_html__( 'Registration could not be completed. Please try again or register on wpstream.net', 'wpstream' ),
623 )
624 );
625 die();
626 }
627
628 ob_end_clean();
629 echo json_encode(
630 array(
631 'success' => false,
632 'message' => esc_html__( 'You are not an administrator', 'wpstream' ),
633 )
634 );
635 die();
636 }
637
638 /** @return mixed */
639 private function handle_create_channel() {
640 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
641 $current_user = wp_get_current_user();
642
643 if ( current_user_can( 'administrator' ) ) {
644 $channel_name = sanitize_text_field( $_POST['channel_name'] );
645 $result = $this->main->streaming_content_creation->create(
646 array(
647 'actor_id' => intval( $current_user->ID ),
648 'owner_id' => intval( $current_user->ID ),
649 'kind' => 'live_channel',
650 'access' => 'free',
651 'title' => $channel_name,
652 )
653 );
654
655 if ( empty( $result['success'] ) ) {
656 $this->log_creation_error( 'Couldn\'t create channel during onboarding because of error: ', $result );
657 echo json_encode( array( 'success' => false ) );
658 } else {
659 $post_id = intval( $result['content_id'] );
660 /**
661 * Fires when an onboarding step creates Streaming Content.
662 *
663 * @since 4.14.0
664 *
665 * @param string $step live_free, live_ppv, vod_free or vod_ppv.
666 * @param int $content_id Created Streaming Content post ID.
667 * @param string $kind live_channel or vod.
668 */
669 do_action( 'wpstream_onboarding_step_completed', 'live_free', $post_id, 'live_channel' );
670 $this->send_creation_success( $post_id, '1' );
671 }
672 }
673
674 die();
675 }
676
677 /** @return mixed */
678 private function handle_create_channel_ppv() {
679 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
680 $current_user = wp_get_current_user();
681
682 if ( current_user_can( 'administrator' ) ) {
683 $channel_name = sanitize_text_field( $_POST['channel_name'] );
684 $channel_price = isset( $_POST['channel_price'] ) ? wp_unslash( $_POST['channel_price'] ) : '';
685 $result = $this->main->streaming_content_creation->create(
686 array(
687 'actor_id' => intval( $current_user->ID ),
688 'owner_id' => intval( $current_user->ID ),
689 'kind' => 'live_channel',
690 'access' => 'paid',
691 'title' => $channel_name,
692 'price' => $channel_price,
693 )
694 );
695
696 if ( empty( $result['success'] ) ) {
697 $this->log_creation_error( 'Couldn\'t create channel during onboarding because of error: ', $result );
698 echo json_encode( array( 'success' => false ) );
699 } else {
700 $post_id = intval( $result['content_id'] );
701 do_action( 'wpstream_onboarding_step_completed', 'live_ppv', $post_id, 'live_channel' );
702 $this->send_creation_success( $post_id, '2' );
703 }
704 }
705
706 die();
707 }
708
709 /** @return mixed */
710 private function handle_create_free_vod() {
711 $current_user = wp_get_current_user();
712 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
713
714 if ( current_user_can( 'administrator' ) ) {
715 $channel_name = sanitize_text_field( $_POST['channel_name'] );
716 $file_name = sanitize_text_field( $_POST['file_name'] );
717 $result = $this->main->streaming_content_creation->create(
718 array(
719 'actor_id' => intval( $current_user->ID ),
720 'owner_id' => intval( $current_user->ID ),
721 'kind' => 'vod',
722 'access' => 'free',
723 'title' => $channel_name,
724 'source_recording' => $file_name,
725 )
726 );
727
728 if ( empty( $result['success'] ) ) {
729 $this->log_creation_error( 'Couldn\'t create free VOD during onboarding because of error: ', $result );
730 echo json_encode( array( 'success' => false ) );
731 } else {
732 $post_id = intval( $result['content_id'] );
733 do_action( 'wpstream_onboarding_step_completed', 'vod_free', $post_id, 'vod' );
734 $this->send_creation_success( $post_id, '3' );
735 }
736 }
737
738 die();
739 }
740
741 /** @return mixed */
742 private function handle_create_ppv_vod() {
743 $current_user = wp_get_current_user();
744 check_ajax_referer( 'wpstream_onboarding_nonce', 'security' );
745
746 if ( current_user_can( 'administrator' ) ) {
747 $channel_name = sanitize_text_field( $_POST['channel_name'] );
748 $vod_price = isset( $_POST['vod_price'] ) ? wp_unslash( $_POST['vod_price'] ) : '';
749 $file_name = sanitize_text_field( $_POST['file_name'] );
750 $result = $this->main->streaming_content_creation->create(
751 array(
752 'actor_id' => intval( $current_user->ID ),
753 'owner_id' => intval( $current_user->ID ),
754 'kind' => 'vod',
755 'access' => 'paid',
756 'title' => $channel_name,
757 'source_recording' => $file_name,
758 'price' => $vod_price,
759 )
760 );
761
762 if ( empty( $result['success'] ) ) {
763 $this->log_creation_error( 'Couldn\'t create PPV VOD during onboarding because of error: ', $result );
764 echo json_encode( array( 'success' => false ) );
765 } else {
766 $post_id = intval( $result['content_id'] );
767 do_action( 'wpstream_onboarding_step_completed', 'vod_ppv', $post_id, 'vod' );
768 $this->send_creation_success( $post_id, '4', $file_name );
769 }
770 }
771
772 die();
773 }
774
775 /**
776 * Record a content-creation failure using the existing onboarding message.
777 *
778 * @param string $prefix Error description prefix.
779 * @param array $result Creation result.
780 * @return void
781 */
782 private function log_creation_error( $prefix, $result ) {
783 $logger = new WPStream_Logger();
784 $log_entry = new WpStream_Log_Entry(
785 array(
786 'type' => 'error',
787 'description' => $prefix . ( $result['error'] ?? 'unknown' ),
788 )
789 );
790 $logger->add( $log_entry );
791 }
792
793 /**
794 * Send the edit link returned by successful onboarding content creation.
795 *
796 * @param int $post_id Created content ID.
797 * @param string $branch Wizard branch.
798 * @param string|null $file_name Legacy PPV VOD response value.
799 * @return void
800 */
801 private function send_creation_success( $post_id, $branch, $file_name = null ) {
802 $permalink = add_query_arg( 'onboard', 'yes', get_edit_post_link( $post_id ) );
803 $permalink = add_query_arg( 'branch', $branch, $permalink );
804 $response = array(
805 'success' => true,
806 'link' => $permalink,
807 );
808
809 if ( null !== $file_name ) {
810 $response[' $file_name'] = $file_name;
811 }
812
813 echo json_encode( $response );
814 }
815
816 /**
817 * Validate onboarding registration credentials.
818 *
819 * @param string $email Submitted email address.
820 * @param string $password Submitted password.
821 * @return array{success: bool, message?: string}
822 */
823 public function validate_registration( $email, $password ) {
824 $result = array( 'success' => true );
825
826 if ( '' === $email ) {
827 return array(
828 'success' => false,
829 'message' => esc_html__( 'The email Field is Empty', 'wpstream' ),
830 );
831 }
832
833 if ( false === filter_var( $email, FILTER_VALIDATE_EMAIL ) ) {
834 return array(
835 'success' => false,
836 'message' => esc_html__( 'The email doesn\'t look right !', 'wpstream' ),
837 );
838 }
839
840 $domain = mb_substr( strrchr( $email, '@' ), 1 );
841 if ( '' !== $domain && ! checkdnsrr( $domain ) ) {
842 return array(
843 'success' => false,
844 'message' => esc_html__( 'The email doesn\'t look right !', 'wpstream' ),
845 );
846 }
847
848 if ( strlen( $password ) < 5 ) {
849 return array(
850 'success' => false,
851 'message' => esc_html__( 'The password is too short. Please use at least 5 characters.', 'wpstream' ),
852 );
853 }
854
855 return $result;
856 }
857
858 /**
859 * Enqueue and configure the assets used by the onboarding workflow.
860 *
861 * @return void
862 */
863 public function enqueue_assets() {
864 $branch = isset( $_GET['branch'] ) ? sanitize_text_field( wp_unslash( $_GET['branch'] ) ) : '';
865
866 wp_enqueue_style(
867 'wpstream-on-boarding-css',
868 plugin_dir_url( __FILE__ ) . 'css/wpstream-admin-onboarding.css',
869 array(),
870 filemtime( plugin_dir_path( __FILE__ ) . 'css/wpstream-admin-onboarding.css' )
871 );
872
873 wp_enqueue_script(
874 'wpstream-on-boarding-js',
875 plugin_dir_url( __FILE__ ) . 'js/wpstream-onboarding2.js',
876 array(),
877 WPSTREAM_PLUGIN_VERSION,
878 true
879 );
880 wp_localize_script(
881 'wpstream-on-boarding-js',
882 'wpstreamonboarding_js_vars',
883 array(
884 'admin_url' => get_admin_url(),
885 'plugin_url' => get_dashboard_url() . '/plugins.php',
886 'upload_url' => get_dashboard_url() . 'admin.php?page=wpstream_recordings',
887 'branch' => $branch,
888 )
889 );
890
891 wp_enqueue_script(
892 'wpstream-on-boarding-page-js',
893 plugin_dir_url( __FILE__ ) . 'js/wpstream-onboarding-page.js',
894 array(),
895 WPSTREAM_PLUGIN_VERSION,
896 true
897 );
898 wp_localize_script(
899 'wpstream-on-boarding-page-js',
900 'wpstream_onboarding_page_vars',
901 array(
902 'admin_url' => get_admin_url(),
903 'request_url' => WPSTREAM_CLICK,
904 'wps_user' => get_option( 'wpstream_api_username_from_token' ),
905 'current_page' => isset( $_GET['onboard'] ) && 'yes' === $_GET['onboard'] ? 'post_edit' : 'onboarding',
906 'plugin_version' => WPSTREAM_PLUGIN_VERSION,
907 'branch' => $branch,
908 )
909 );
910 }
911 }
912