PluginProbe ʕ •ᴥ•ʔ
Presto Player / trunk
Presto Player vtrunk
4.4.1 4.4.0 4.3.3 4.3.2 4.3.1 4.3.0 4.2.4 4.2.3 4.2.2 4.2.0 4.2.1 trunk 1.10.0 1.10.1 1.10.2 1.11.0 1.12.0 1.13.0 1.14.0 1.14.1 1.5.10 1.5.11 1.5.12 1.5.13 1.5.14 1.5.15 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.10 1.6.11 1.6.12 1.6.13 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.8.0 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.13 2.0.14 2.0.15 2.0.16 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.2.0 2.2.1 2.2.2 2.2.3 2.2.3-beta1 2.3.0 2.3.1 2.3.2 2.3.3 3.0.0 3.0.0-beta1 3.0.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.1.0 3.1.1 3.1.2 3.1.3 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4
presto-player / inc / Services / Learn.php
presto-player / inc / Services Last commit date
API 1 week ago Abilities 1 week ago Blocks 3 weeks ago License 1 month ago OAuth 1 week ago AdminNotice.php 2 months ago AdminNotices.php 2 months ago AjaxActions.php 2 months ago Blocks.php 2 years ago Compatibility.php 11 months ago FeatureAnnounce.php 1 week ago Learn.php 1 week ago Menu.php 1 week ago Migrations.php 2 years ago NpsSurvey.php 6 months ago Onboarding.php 2 months ago Player.php 3 weeks ago PluginInstaller.php 1 week ago PreloadService.php 2 years ago ProCompatibility.php 3 weeks ago ReusableVideos.php 2 months ago RewriteRulesManager.php 2 years ago Scripts.php 2 months ago Settings.php 3 months ago Shortcodes.php 1 week ago Streamer.php 2 months ago Translation.php 3 weeks ago Usage.php 1 week ago VideoPostType.php 3 weeks ago
Learn.php
825 lines
1 <?php
2 /**
3 * Learn tab progress tracking service.
4 *
5 * @package PrestoPlayer
6 * @subpackage Services
7 */
8
9 namespace PrestoPlayer\Services;
10
11 /**
12 * Persists per-user progress on the Learn tab cards in user meta.
13 */
14 class Learn {
15
16 /**
17 * User meta key for storing learn progress.
18 *
19 * @var string
20 */
21 const META_KEY = 'presto_player_learn_progress';
22
23 /**
24 * Register hooks.
25 */
26 public function register() {
27 add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) );
28 }
29
30 /**
31 * Register REST API routes.
32 */
33 public function register_rest_routes() {
34 register_rest_route(
35 'presto-player/v1',
36 '/get-learn-chapters',
37 array(
38 'methods' => 'GET',
39 'callback' => array( $this, 'get_learn_chapters' ),
40 'permission_callback' => function () {
41 return current_user_can( 'publish_posts' );
42 },
43 )
44 );
45
46 register_rest_route(
47 'presto-player/v1',
48 '/update-learn-progress',
49 array(
50 'methods' => 'POST',
51 'callback' => array( $this, 'save_learn_progress' ),
52 'permission_callback' => function () {
53 return current_user_can( 'publish_posts' );
54 },
55 'args' => array(
56 'chapterId' => array(
57 'required' => true,
58 'type' => 'string',
59 'sanitize_callback' => 'sanitize_text_field',
60 ),
61 'stepId' => array(
62 'required' => true,
63 'type' => 'string',
64 'sanitize_callback' => 'sanitize_text_field',
65 ),
66 'completed' => array(
67 'required' => true,
68 'type' => 'boolean',
69 ),
70 ),
71 )
72 );
73 }
74
75 /**
76 * Get chapters with user progress merged.
77 *
78 * Returns the chapters array directly (not wrapped),
79 * matching the shape consumed by src/admin/dashboard/pages/learn/.
80 *
81 * @return \WP_REST_Response
82 */
83 public function get_learn_chapters() {
84 $chapters = self::get_chapters_structure();
85 $progress = get_user_meta( get_current_user_id(), self::META_KEY, true );
86
87 if ( ! is_array( $progress ) ) {
88 $progress = array();
89 }
90
91 // Merge progress into chapters.
92 foreach ( $chapters as &$chapter ) {
93 $chapter_id = $chapter['id'];
94 foreach ( $chapter['steps'] as &$step ) {
95 $step_id = $step['id'];
96 $step['completed'] = ! empty( $progress[ $chapter_id ][ $step_id ] );
97 }
98 }
99
100 return new \WP_REST_Response( $chapters, 200 );
101 }
102
103 /**
104 * Save progress for a single step.
105 *
106 * @param \WP_REST_Request $request Request object.
107 * @return \WP_REST_Response
108 */
109 public function save_learn_progress( $request ) {
110 $chapter_id = $request->get_param( 'chapterId' );
111 $step_id = $request->get_param( 'stepId' );
112 $completed = (bool) $request->get_param( 'completed' );
113
114 $user_id = get_current_user_id();
115 $progress = get_user_meta( $user_id, self::META_KEY, true );
116
117 if ( ! is_array( $progress ) ) {
118 $progress = array();
119 }
120
121 if ( ! isset( $progress[ $chapter_id ] ) ) {
122 $progress[ $chapter_id ] = array();
123 }
124
125 $progress[ $chapter_id ][ $step_id ] = $completed;
126
127 update_user_meta( $user_id, self::META_KEY, $progress );
128
129 /**
130 * Fires after learn progress is saved for the current user.
131 *
132 * @param array $progress Full progress array for the user (all chapters/steps).
133 */
134 do_action( 'presto_player_learn_progress_saved', $progress );
135
136 return new \WP_REST_Response(
137 array(
138 'success' => true,
139 ),
140 200
141 );
142 }
143
144 /**
145 * Check if all steps in a chapter are completed for the given progress.
146 *
147 * @param array $chapter Single chapter array from get_chapters_structure().
148 * @param array $progress Full progress array (chapter_id => step_id => bool).
149 * @return bool True if every step in the chapter is completed.
150 */
151 public static function is_chapter_complete( $chapter, $progress ) {
152 $chapter_id = isset( $chapter['id'] ) ? $chapter['id'] : '';
153 if ( empty( $chapter_id ) || empty( $chapter['steps'] ) || ! is_array( $chapter['steps'] ) ) {
154 return false;
155 }
156
157 foreach ( $chapter['steps'] as $step ) {
158 $step_id = isset( $step['id'] ) ? $step['id'] : '';
159 if ( empty( $step_id ) ) {
160 continue;
161 }
162 if ( empty( $progress[ $chapter_id ][ $step_id ] ) ) {
163 return false;
164 }
165 }
166
167 return true;
168 }
169
170 /**
171 * Get the chapters and steps structure.
172 *
173 * Shape (mirrors the SureDash Learn module so the admin dashboard
174 * components render uniformly across both plugins):
175 * - chapter.id string Kebab-case identifier.
176 * - chapter.title string Localized heading.
177 * - chapter.description string Localized subheading shown under the title.
178 * - chapter.docsUrl string Optional "Learn how" external link.
179 * - chapter.isNew bool Optional; shows a "New" badge on the card.
180 * - chapter.steps array Ordered list of step arrays.
181 *
182 * - step.id string Unique within the chapter.
183 * - step.title string Localized step title.
184 * - step.description string Localized body copy shown when expanded.
185 * - step.docsUrl string Optional "Read documentation" link.
186 * - step.headerAction array { label, url } — optional primary CTA.
187 * - step.isPro bool Whether the step is a Pro upsell.
188 * - step.screenshot array { url, alt } — optional screenshot image.
189 * - step.prompts array Optional list of example prompt strings.
190 *
191 * Optional string fields default to empty; the frontend hides the
192 * corresponding affordance when empty. `completed` is injected by
193 * get_learn_chapters() from user meta and is not part of this static tree.
194 *
195 * @return array
196 */
197 public static function get_chapters_structure() {
198 $dashboard_base = 'admin.php?page=presto-dashboard&post_type=pp_video_block';
199
200 return array(
201 // Chapter 1 — Getting Started.
202 array(
203 'id' => 'getting-started',
204 'title' => __( 'Getting Started', 'presto-player' ),
205 'description' => __( 'Create your first video and learn the core Presto Player workflow.', 'presto-player' ),
206 'docsUrl' => '',
207 'steps' => array(
208 array(
209 'id' => 'add-first-video',
210 'title' => __( 'Add a Presto Player video block', 'presto-player' ),
211 'description' => __( 'Create a Presto Player video block in the block editor and embed your first video — from YouTube, Vimeo, or a self-hosted file.', 'presto-player' ),
212 'docsUrl' => 'https://prestoplayer.com/docs/using-presto-player-with-gutenberg/',
213 'headerAction' => array(
214 'label' => __( 'Create Video', 'presto-player' ),
215 'url' => admin_url( 'post-new.php?post_type=pp_video_block' ),
216 ),
217 'isPro' => false,
218 'screenshot' => array(
219 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-New-Media-Presto.jpg',
220 'alt' => __( 'Add a Presto Player video block', 'presto-player' ),
221 ),
222 ),
223 array(
224 'id' => 'choose-video-source',
225 'title' => __( 'Choose your video source', 'presto-player' ),
226 'description' => __( 'Learn the difference between YouTube, Vimeo, self-hosted, and Bunny.net — pick the right source for your use case.', 'presto-player' ),
227 'docsUrl' => 'https://prestoplayer.com/docs/presto-player-any-host/',
228 'headerAction' => array(
229 'label' => '',
230 'url' => '',
231 ),
232 'isPro' => false,
233 'screenshot' => array(
234 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Choose-Your-Media-Source-Presto.jpg',
235 'alt' => __( 'Choose your video source', 'presto-player' ),
236 ),
237 ),
238 array(
239 'id' => 'manage-media-hub',
240 'title' => __( 'Manage your Media Hub', 'presto-player' ),
241 'description' => __( 'Browse, search, and organize all your videos in one central library. The Media Hub is your video command center.', 'presto-player' ),
242 'docsUrl' => 'https://prestoplayer.com/docs/video-sync/',
243 'headerAction' => array(
244 'label' => __( 'Open Media Hub', 'presto-player' ),
245 'url' => admin_url( $dashboard_base . '&tab=MediaHub' ),
246 ),
247 'isPro' => false,
248 'screenshot' => array(
249 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/05/Screenshot-2026-05-07-at-2.11.19-PM-1-scaled.png',
250 'alt' => __( 'Manage your Media Hub', 'presto-player' ),
251 ),
252 ),
253 array(
254 'id' => 'use-shortcodes',
255 'title' => __( 'Use shortcodes to embed anywhere', 'presto-player' ),
256 'description' => __( 'Copy a shortcode from the Media Hub to embed videos in widgets, classic editor, or any page builder that supports shortcodes.', 'presto-player' ),
257 'docsUrl' => 'https://prestoplayer.com/docs/presto-shortcodes/',
258 'headerAction' => array(
259 'label' => __( 'View Media Hub', 'presto-player' ),
260 'url' => admin_url( $dashboard_base . '&tab=MediaHub' ),
261 ),
262 'isPro' => false,
263 'screenshot' => array(
264 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Screenshot-2026-04-28-at-11.15.02-PM.png',
265 'alt' => __( 'Use shortcodes to embed anywhere', 'presto-player' ),
266 ),
267 ),
268 ),
269 ),
270 // Chapter 2 — Player Customization.
271 array(
272 'id' => 'player-customization',
273 'title' => __( 'Player Customization', 'presto-player' ),
274 'description' => __( 'Fine-tune how your videos look, feel, and behave.', 'presto-player' ),
275 'docsUrl' => '',
276 'steps' => array(
277 array(
278 'id' => 'customize-controls',
279 'title' => __( 'Customize player controls', 'presto-player' ),
280 'description' => __( 'Choose which controls are visible — play, progress, volume, speed, fullscreen, PiP, and more.', 'presto-player' ),
281 'docsUrl' => 'https://prestoplayer.com/docs/how-to-use-video-presets/',
282 'headerAction' => array(
283 'label' => __( 'Edit Preset', 'presto-player' ),
284 'url' => admin_url( $dashboard_base . '&tab=Settings&section=presets' ),
285 ),
286 'isPro' => false,
287 'screenshot' => array(
288 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Edit-Preset-Presto.jpg',
289 'alt' => __( 'Customize player controls', 'presto-player' ),
290 ),
291 ),
292 array(
293 'id' => 'configure-playback',
294 'title' => __( 'Configure playback behavior', 'presto-player' ),
295 'description' => __( 'Set autoplay, muted start, save position, play-in-viewport, and preload options per preset.', 'presto-player' ),
296 'docsUrl' => 'https://prestoplayer.com/docs/play-inline-option-explained/',
297 'headerAction' => array(
298 'label' => __( 'Edit Preset', 'presto-player' ),
299 'url' => admin_url( $dashboard_base . '&tab=Settings&section=presets' ),
300 ),
301 'isPro' => false,
302 'screenshot' => array(
303 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Configure-Playback-Behavior-Presto.jpg',
304 'alt' => __( 'Configure playback behavior', 'presto-player' ),
305 ),
306 ),
307 array(
308 'id' => 'add-captions',
309 'title' => __( 'Add captions & subtitles', 'presto-player' ),
310 'description' => __( 'Upload SRT/VTT caption files or enable auto-generated captions to make your videos accessible.', 'presto-player' ),
311 'docsUrl' => 'https://prestoplayer.com/docs/how-to-create-video-captions/',
312 'headerAction' => array(
313 'label' => '',
314 'url' => '',
315 ),
316 'isPro' => false,
317 'screenshot' => array(
318 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Upload-Captions-for-Bunny-Presto.jpg',
319 'alt' => __( 'Add captions and subtitles', 'presto-player' ),
320 ),
321 ),
322 array(
323 'id' => 'add-timestamps',
324 'title' => __( 'Add chapters to videos', 'presto-player' ),
325 'description' => __( 'Create clickable chapter markers so viewers can jump to specific sections inside a video.', 'presto-player' ),
326 'docsUrl' => 'https://prestoplayer.com/docs/presto-timestamps/',
327 'headerAction' => array(
328 'label' => '',
329 'url' => '',
330 ),
331 'isPro' => false,
332 'screenshot' => array(
333 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Clickable-Chapters-Presto.jpg',
334 'alt' => __( 'Add chapters to videos', 'presto-player' ),
335 ),
336 ),
337 array(
338 'id' => 'setup-audio',
339 'title' => __( 'Set up audio playback', 'presto-player' ),
340 'description' => __( 'Use the dedicated audio block for podcasts, music, or voice content — same preset system as video.', 'presto-player' ),
341 'docsUrl' => 'https://prestoplayer.com/docs/presto-player-audio/',
342 'headerAction' => array(
343 'label' => '',
344 'url' => '',
345 ),
346 'isPro' => false,
347 'screenshot' => array(
348 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Presto-Audio-Playback-Presto-Player.jpg',
349 'alt' => __( 'Set up audio playback', 'presto-player' ),
350 ),
351 ),
352 array(
353 'id' => 'add-custom-css',
354 'title' => __( 'Add custom CSS to the player', 'presto-player' ),
355 'description' => __( 'Inject custom CSS for advanced visual tweaks beyond the built-in branding options.', 'presto-player' ),
356 'docsUrl' => 'https://prestoplayer.com/docs/how-to-customize-presets/',
357 'headerAction' => array(
358 'label' => __( 'Edit Custom CSS', 'presto-player' ),
359 'url' => admin_url( $dashboard_base . '&tab=Settings&section=custom-css' ),
360 ),
361 'isPro' => true,
362 'screenshot' => array(
363 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Screenshot-2026-04-28-at-11.03.38-PM-scaled.png',
364 'alt' => __( 'Add custom CSS to the player', 'presto-player' ),
365 ),
366 ),
367 ),
368 ),
369 // Chapter 3 — Branding & Presets.
370 array(
371 'id' => 'branding-presets',
372 'title' => __( 'Branding & Presets', 'presto-player' ),
373 'description' => __( 'Match the player to your brand and save reusable configurations.', 'presto-player' ),
374 'docsUrl' => '',
375 'steps' => array(
376 array(
377 'id' => 'set-brand-color',
378 'title' => __( 'Set your brand color', 'presto-player' ),
379 'description' => __( 'Choose a color for the play button, progress bar, and interactive elements to match your site identity.', 'presto-player' ),
380 'docsUrl' => 'https://prestoplayer.com/docs/how-to-customize-presets/',
381 'headerAction' => array(
382 'label' => __( 'Set Color', 'presto-player' ),
383 'url' => admin_url( $dashboard_base . '&tab=Settings&section=branding' ),
384 ),
385 'isPro' => false,
386 'screenshot' => array(
387 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Setup-Brand-Color-Presto.jpg',
388 'alt' => __( 'Set your brand color', 'presto-player' ),
389 ),
390 ),
391 array(
392 'id' => 'create-preset',
393 'title' => __( 'Create a video preset', 'presto-player' ),
394 'description' => __( 'Save a reusable preset with your preferred controls, autoplay, and style settings — apply it across multiple videos in one click.', 'presto-player' ),
395 'docsUrl' => 'https://prestoplayer.com/docs/video-presets/',
396 'headerAction' => array(
397 'label' => __( 'Create Preset', 'presto-player' ),
398 'url' => admin_url( $dashboard_base . '&tab=Settings&section=presets' ),
399 ),
400 'isPro' => false,
401 'screenshot' => array(
402 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Create-a-New-Preset-Presto.jpg',
403 'alt' => __( 'Create a video preset', 'presto-player' ),
404 ),
405 ),
406 array(
407 'id' => 'add-logo',
408 'title' => __( 'Add a logo watermark', 'presto-player' ),
409 'description' => __( 'Upload your logo to display as a clickable watermark on your videos — professional branding in one click.', 'presto-player' ),
410 'docsUrl' => 'https://prestoplayer.com/docs/dynamic-watermark/',
411 'headerAction' => array(
412 'label' => __( 'Upload Logo', 'presto-player' ),
413 'url' => admin_url( $dashboard_base . '&tab=Settings&section=branding' ),
414 ),
415 'isPro' => true,
416 'screenshot' => array(
417 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Logo-Watermark-in-Preset-Presto.jpg',
418 'alt' => __( 'Add a logo watermark', 'presto-player' ),
419 ),
420 ),
421 ),
422 ),
423 // Chapter 4 — Embedding & Page Builders.
424 array(
425 'id' => 'embedding-page-builders',
426 'title' => __( 'Embedding & Page Builders', 'presto-player' ),
427 'description' => __( 'Place videos anywhere on your site — Gutenberg, Elementor, Divi, Beaver Builder, or shortcodes.', 'presto-player' ),
428 'docsUrl' => '',
429 'steps' => array(
430 array(
431 'id' => 'embed-gutenberg',
432 'title' => __( 'Add a video in Gutenberg', 'presto-player' ),
433 'description' => __( 'Open the block editor, add a Presto Player block, select your video source, and publish.', 'presto-player' ),
434 'docsUrl' => 'https://prestoplayer.com/docs/using-presto-player-with-gutenberg/',
435 'headerAction' => array(
436 'label' => __( 'Add to Page', 'presto-player' ),
437 'url' => admin_url( 'post-new.php' ),
438 ),
439 'isPro' => false,
440 'screenshot' => array(
441 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Presto-Block-in-Gutenberg-Presto.jpg',
442 'alt' => __( 'Add a video in Gutenberg', 'presto-player' ),
443 ),
444 ),
445 array(
446 'id' => 'embed-elementor',
447 'title' => __( 'Add a video in Elementor', 'presto-player' ),
448 'description' => __( 'Use the Presto Player Elementor widget to embed videos in any Elementor layout or template.', 'presto-player' ),
449 'docsUrl' => 'https://prestoplayer.com/docs/using-presto-player-with-elementor/',
450 'headerAction' => array(
451 'label' => '',
452 'url' => '',
453 ),
454 'isPro' => false,
455 'screenshot' => array(
456 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Presto-Widget-using-Elementor-Presto.jpg',
457 'alt' => __( 'Add a video in Elementor', 'presto-player' ),
458 ),
459 ),
460 array(
461 'id' => 'embed-beaver-builder',
462 'title' => __( 'Add a video in Beaver Builder', 'presto-player' ),
463 'description' => __( 'Use the Presto Player module inside any Beaver Builder page or template.', 'presto-player' ),
464 'docsUrl' => 'https://prestoplayer.com/docs/using-presto-player-with-beaver-builder/',
465 'headerAction' => array(
466 'label' => '',
467 'url' => '',
468 ),
469 'isPro' => false,
470 'screenshot' => array(
471 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Presto-module-in-Beaver-Builder.jpg',
472 'alt' => __( 'Add a video in Beaver Builder', 'presto-player' ),
473 ),
474 ),
475 array(
476 'id' => 'embed-classic-editor',
477 'title' => __( 'Use with the Classic Editor', 'presto-player' ),
478 'description' => __( 'Embed videos via shortcodes in the classic WordPress editor — paste the shortcode and publish.', 'presto-player' ),
479 'docsUrl' => 'https://prestoplayer.com/docs/use-with-classic-editor/',
480 'headerAction' => array(
481 'label' => '',
482 'url' => '',
483 ),
484 'isPro' => false,
485 'screenshot' => array(
486 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/ce-classic-editor-shortcode-scaled.png',
487 'alt' => __( 'Use with the Classic Editor', 'presto-player' ),
488 ),
489 ),
490 array(
491 'id' => 'create-popup',
492 'title' => __( 'Create a video popup', 'presto-player' ),
493 'description' => __( 'Launch videos in a lightbox popup triggered by a button, image, or link — grab attention without leaving the page.', 'presto-player' ),
494 'docsUrl' => 'https://prestoplayer.com/docs/presto-popups/',
495 'headerAction' => array(
496 'label' => __( 'Try Popups', 'presto-player' ),
497 'url' => admin_url( 'post-new.php?post_type=page' ),
498 ),
499 'isPro' => true,
500 'screenshot' => array(
501 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Add-Presto-Popups-Presto-Player.jpg',
502 'alt' => __( 'Create a video popup', 'presto-player' ),
503 ),
504 ),
505 array(
506 'id' => 'create-playlist',
507 'title' => __( 'Create a playlist', 'presto-player' ),
508 'description' => __( 'Group related videos into a sequential playlist — perfect for course modules, series, or curated content collections.', 'presto-player' ),
509 'docsUrl' => 'https://prestoplayer.com/docs/presto-player-playlists/',
510 'headerAction' => array(
511 'label' => __( 'Create Playlist', 'presto-player' ),
512 'url' => admin_url( 'post-new.php?post_type=page' ),
513 ),
514 'isPro' => true,
515 'screenshot' => array(
516 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Presto-Playlist-Block-Presto-.jpg',
517 'alt' => __( 'Create a playlist', 'presto-player' ),
518 ),
519 ),
520 ),
521 ),
522 // Chapter 5 — Analytics & Engagement.
523 array(
524 'id' => 'analytics-engagement',
525 'title' => __( 'Analytics & Engagement', 'presto-player' ),
526 'description' => __( 'Track how your audience watches and turn viewers into leads.', 'presto-player' ),
527 'docsUrl' => '',
528 'steps' => array(
529 array(
530 'id' => 'enable-analytics',
531 'title' => __( 'Enable analytics', 'presto-player' ),
532 'description' => __( 'Turn on view tracking to collect watch data — views, watch time, and engagement — for every video on your site.', 'presto-player' ),
533 'docsUrl' => '',
534 'headerAction' => array(
535 'label' => __( 'Enable Analytics', 'presto-player' ),
536 'url' => admin_url( $dashboard_base . '&tab=Settings&section=viewing-analytics' ),
537 ),
538 'isPro' => true,
539 'screenshot' => array(
540 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Enable-Analytics-Presto.jpg',
541 'alt' => __( 'Enable analytics', 'presto-player' ),
542 ),
543 ),
544 array(
545 'id' => 'view-insights',
546 'title' => __( 'View video insights', 'presto-player' ),
547 'description' => __( 'See total views, average watch time, and engagement trends per video from the Analytics dashboard.', 'presto-player' ),
548 'docsUrl' => '',
549 'headerAction' => array(
550 'label' => __( 'View Analytics', 'presto-player' ),
551 'url' => admin_url( $dashboard_base . '&tab=Analytics' ),
552 ),
553 'isPro' => true,
554 'screenshot' => array(
555 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/View-Analytics-Presto.jpg',
556 'alt' => __( 'View video insights', 'presto-player' ),
557 ),
558 ),
559 array(
560 'id' => 'track-user-engagement',
561 'title' => __( 'Track per-user engagement', 'presto-player' ),
562 'description' => __( 'See exactly who watched what and for how long — powerful for course creators and membership sites.', 'presto-player' ),
563 'docsUrl' => '',
564 'headerAction' => array(
565 'label' => __( 'View Analytics', 'presto-player' ),
566 'url' => admin_url( $dashboard_base . '&tab=Analytics' ),
567 ),
568 'isPro' => true,
569 'screenshot' => array(
570 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Track-Per-User-Engagement-Presto.jpg',
571 'alt' => __( 'Track per-user engagement', 'presto-player' ),
572 ),
573 ),
574 array(
575 'id' => 'setup-email-capture',
576 'title' => __( 'Set up email capture', 'presto-player' ),
577 'description' => __( 'Capture email addresses mid-video and sync subscribers with your email marketing tool automatically.', 'presto-player' ),
578 'docsUrl' => 'https://prestoplayer.com/docs/how-to-capture-emails/',
579 'headerAction' => array(
580 'label' => __( 'Configure Email', 'presto-player' ),
581 'url' => admin_url( $dashboard_base . '&tab=Settings&section=email-capture' ),
582 ),
583 'isPro' => true,
584 'screenshot' => array(
585 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Email-Capture-Presto.jpg',
586 'alt' => __( 'Set up email capture', 'presto-player' ),
587 ),
588 ),
589 array(
590 'id' => 'connect-google-analytics',
591 'title' => __( 'Connect Google Analytics', 'presto-player' ),
592 'description' => __( 'Send video play events to your existing GA4 property for unified site-wide analytics tracking.', 'presto-player' ),
593 'docsUrl' => '',
594 'headerAction' => array(
595 'label' => __( 'Configure GA', 'presto-player' ),
596 'url' => admin_url( $dashboard_base . '&tab=Settings&section=google-analytics' ),
597 ),
598 'isPro' => true,
599 'screenshot' => array(
600 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Connect-Presto-with-Existing-GA-Presto.jpg',
601 'alt' => __( 'Connect Google Analytics', 'presto-player' ),
602 ),
603 ),
604 ),
605 ),
606 // Chapter 6 — Integrations & Advanced.
607 array(
608 'id' => 'integrations-advanced',
609 'title' => __( 'Integrations & Advanced', 'presto-player' ),
610 'description' => __( 'Connect Presto Player with your LMS, CDN, CRM, and SEO tools.', 'presto-player' ),
611 'docsUrl' => '',
612 'steps' => array(
613 array(
614 'id' => 'connect-bunny',
615 'title' => __( 'Connect Bunny.net for private hosting', 'presto-player' ),
616 'description' => __( 'Set up Bunny.net Stream for CDN-powered private video hosting with adaptive HLS streaming — fast, secure, global.', 'presto-player' ),
617 'docsUrl' => 'https://prestoplayer.com/docs/bunnycdn/',
618 'headerAction' => array(
619 'label' => __( 'Connect Bunny', 'presto-player' ),
620 'url' => admin_url( $dashboard_base . '&tab=Settings&section=bunny-net' ),
621 ),
622 'isPro' => true,
623 'screenshot' => array(
624 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/PP-BNS-01.png',
625 'alt' => __( 'Connect Bunny.net for private hosting', 'presto-player' ),
626 ),
627 ),
628 array(
629 'id' => 'use-bunny-library',
630 'title' => __( 'Use the Bunny.net video library', 'presto-player' ),
631 'description' => __( 'Browse and embed videos directly from your Bunny.net library without leaving WordPress.', 'presto-player' ),
632 'docsUrl' => 'https://prestoplayer.com/docs/bunnynet-video-library-integration/',
633 'headerAction' => array(
634 'label' => '',
635 'url' => '',
636 ),
637 'isPro' => true,
638 'screenshot' => array(
639 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Connect-BunnyNet-Videos-Presto.jpg',
640 'alt' => __( 'Use the Bunny.net video library', 'presto-player' ),
641 ),
642 ),
643 array(
644 'id' => 'auto-captions-bunny',
645 'title' => __( 'Enable automatic captions', 'presto-player' ),
646 'description' => __( 'Let Bunny.net auto-transcribe your videos and generate caption files — hands-free accessibility.', 'presto-player' ),
647 'docsUrl' => 'https://prestoplayer.com/docs/automatic-captions/',
648 'headerAction' => array(
649 'label' => '',
650 'url' => '',
651 ),
652 'isPro' => true,
653 'screenshot' => array(
654 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/Enable-Automatic-Captions-Presto.jpg',
655 'alt' => __( 'Enable automatic captions', 'presto-player' ),
656 ),
657 ),
658 array(
659 'id' => 'integrate-learndash',
660 'title' => __( 'Integrate with LearnDash', 'presto-player' ),
661 'description' => __( 'Track video progress as course completion — students must watch to advance to the next lesson.', 'presto-player' ),
662 'docsUrl' => 'https://prestoplayer.com/docs/use-presto-player-with-learndash/',
663 'headerAction' => array(
664 'label' => '',
665 'url' => '',
666 ),
667 'isPro' => true,
668 'screenshot' => array(
669 'url' => 'https://prestoplayer.com/wp-content/uploads/2021/12/pp-1-7-video-progresion-learndash.png',
670 'alt' => __( 'Integrate with LearnDash', 'presto-player' ),
671 ),
672 ),
673 array(
674 'id' => 'integrate-lifterlms',
675 'title' => __( 'Integrate with LifterLMS', 'presto-player' ),
676 'description' => __( 'Connect Presto Player with LifterLMS for video-based course progression and completion tracking.', 'presto-player' ),
677 'docsUrl' => 'https://prestoplayer.com/docs/lifterlms-advanced-videos-presto-player/',
678 'headerAction' => array(
679 'label' => '',
680 'url' => '',
681 ),
682 'isPro' => true,
683 'screenshot' => array(
684 'url' => 'https://prestoplayer.com/wp-content/uploads/2021/11/pp-lifter-settings-courses.png',
685 'alt' => __( 'Integrate with LifterLMS', 'presto-player' ),
686 ),
687 ),
688 array(
689 'id' => 'integrate-tutorlms',
690 'title' => __( 'Integrate with TutorLMS', 'presto-player' ),
691 'description' => __( 'Use Presto Player as the video engine for TutorLMS courses — full progress tracking included.', 'presto-player' ),
692 'docsUrl' => 'https://prestoplayer.com/docs/tutorlms/',
693 'headerAction' => array(
694 'label' => '',
695 'url' => '',
696 ),
697 'isPro' => true,
698 'screenshot' => array(
699 'url' => 'https://prestoplayer.com/wp-content/uploads/2024/06/video-source.png',
700 'alt' => __( 'Integrate with TutorLMS', 'presto-player' ),
701 ),
702 ),
703 array(
704 'id' => 'connect-fluent-crm',
705 'title' => __( 'Connect Fluent CRM', 'presto-player' ),
706 'description' => __( 'Sync email captures and video engagement data with Fluent CRM for automated marketing workflows.', 'presto-player' ),
707 'docsUrl' => 'https://prestoplayer.com/docs/fluent-crm-presto-player/',
708 'headerAction' => array(
709 'label' => '',
710 'url' => '',
711 ),
712 'isPro' => true,
713 'screenshot' => array(
714 'url' => 'https://prestoplayer.com/wp-content/uploads/2021/10/image-3-2-1024x900.png',
715 'alt' => __( 'Connect Fluent CRM', 'presto-player' ),
716 ),
717 ),
718 array(
719 'id' => 'optimize-video-seo',
720 'title' => __( 'Optimize video SEO with RankMath', 'presto-player' ),
721 'description' => __( 'Add structured video schema data to boost search visibility — works automatically with RankMath.', 'presto-player' ),
722 'docsUrl' => 'https://prestoplayer.com/docs/seo-optimize-presto-player-videos-using-rank-math/',
723 'headerAction' => array(
724 'label' => '',
725 'url' => '',
726 ),
727 'isPro' => false,
728 'screenshot' => array(
729 'url' => 'https://prestoplayer.com/wp-content/uploads/2026/04/PP-SEO-01.png',
730 'alt' => __( 'Optimize video SEO with RankMath', 'presto-player' ),
731 ),
732 ),
733 ),
734 ),
735 // Chapter 7 — AI Abilities.
736 array(
737 'id' => 'presto-player-ai',
738 'title' => __( 'AI Abilities', 'presto-player' ),
739 'description' => __( 'Let Claude, ChatGPT or Cursor manage your videos. Just ask, in plain English.', 'presto-player' ),
740 'docsUrl' => '',
741 'isNew' => true,
742 'steps' => array(
743 array(
744 'id' => 'enable-ai-access',
745 'title' => __( 'Turn on AI access', 'presto-player' ),
746 'description' => __( 'Switch on AI access in the settings so assistants like Claude, ChatGPT and Cursor can securely connect to your site.', 'presto-player' ),
747 'docsUrl' => '',
748 'headerAction' => array(
749 'label' => __( 'Open AI Settings', 'presto-player' ),
750 'url' => admin_url( $dashboard_base . '&tab=Settings&section=mcp' ),
751 ),
752 'isPro' => false,
753 'screenshot' => array(
754 'url' => '',
755 'alt' => '',
756 ),
757 ),
758 array(
759 'id' => 'allow-changes',
760 'title' => __( 'Allow AI to make changes', 'presto-player' ),
761 'description' => __( 'By default AI is read-only — it can list, search and report on your videos and analytics, but cannot change anything. Turn on “Allow AI to make changes” to let it create, update and delete too. Enable this only when you trust the assistant, because it can then modify or permanently remove content on your site.', 'presto-player' ),
762 'docsUrl' => '',
763 'headerAction' => array(
764 'label' => '',
765 'url' => '',
766 ),
767 'isPro' => false,
768 'screenshot' => array(
769 'url' => '',
770 'alt' => '',
771 ),
772 ),
773 array(
774 'id' => 'what-you-can-ask',
775 'title' => __( 'What you can ask', 'presto-player' ),
776 'description' => __( 'Just talk to it in plain English. Here are some things you can say:', 'presto-player' ),
777 'docsUrl' => '',
778 'headerAction' => array(
779 'label' => '',
780 'url' => '',
781 ),
782 'prompts' => array(
783 __( 'Add this YouTube video and give me the shortcode', 'presto-player' ),
784 __( 'Embed this Vimeo video on my site', 'presto-player' ),
785 __( 'Upload my MP4 as a self-hosted player', 'presto-player' ),
786 __( 'Which videos got the most views this month?', 'presto-player' ),
787 __( 'Where do viewers drop off in this video?', 'presto-player' ),
788 __( 'Who are my most active viewers?', 'presto-player' ),
789 __( 'Show me all videos with ‘training’ in the title', 'presto-player' ),
790 __( 'Rename this video and update its description', 'presto-player' ),
791 __( 'Get the shortcode for this video', 'presto-player' ),
792 __( 'Auto-generate chapters from the captions on this video', 'presto-player' ),
793 __( 'Translate this video’s captions to Spanish', 'presto-player' ),
794 ),
795 'isPro' => false,
796 'screenshot' => array(
797 'url' => '',
798 'alt' => '',
799 ),
800 ),
801 array(
802 'id' => 'search-library',
803 'title' => __( 'Search your library', 'presto-player' ),
804 'description' => __( 'Not sure what is possible? Open the AI settings — every ability is listed there with a search box, so you can see exactly what the assistant can do. And in chat, just ask it to find things and it searches your Media Hub and analytics for you.', 'presto-player' ),
805 'docsUrl' => '',
806 'headerAction' => array(
807 'label' => __( 'Open AI Settings', 'presto-player' ),
808 'url' => admin_url( $dashboard_base . '&tab=Settings&section=mcp' ),
809 ),
810 'prompts' => array(
811 __( 'Show me all my videos about ‘onboarding’', 'presto-player' ),
812 __( 'Find the video I embedded on my pricing page', 'presto-player' ),
813 ),
814 'isPro' => false,
815 'screenshot' => array(
816 'url' => '',
817 'alt' => '',
818 ),
819 ),
820 ),
821 ),
822 );
823 }
824 }
825