PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.3.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.3.8
4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 4.2.1 All 138 releases
learnpress / inc / TemplateHooks / CourseBuilder / Lesson / BuilderEditLessonTemplate.php

BuilderEditLessonTemplate.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.3.8, at inc/TemplateHooks/CourseBuilder/Lesson/BuilderEditLessonTemplate.php

467 lines 15.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Template hooks Course Builder.
4 *
5 * @since 4.3.0
6 * @version 1.0.0
7 */
8
9 namespace LearnPress\TemplateHooks\CourseBuilder\Lesson;
10
11 use Exception;
12 use LearnPress\CourseBuilder\CourseBuilder;
13 use LearnPress\CourseBuilder\CourseBuilderAccessPolicy;
14 use LearnPress\Helpers\Singleton;
15 use LearnPress\Helpers\Template;
16 use LearnPress\Models\LessonPostModel;
17 use LearnPress\Models\UserModel;
18 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
19 use LearnPress\TemplateHooks\Course\AdminEditCurriculumTemplate;
20 use LP_Settings;
21 use WP_User;
22
23 class BuilderEditLessonTemplate {
24 use Singleton;
25
26 public function init() {
27 add_filter( 'lp/rest/ajax/allow_callback', [ $this, 'allow_callback' ] );
28 }
29
30 /**
31 * Display layout edit/create lesson.
32 *
33 * @param array $data [ 'userModel' => UserModel, 'item_id' => int|string ]
34 *
35 * @throws Exception
36 */
37 public function layout( array $data = [] ) {
38 $userModel = $data['userModel'] ?? false;
39 if ( ! $userModel || ! $userModel->is_instructor() ) {
40 throw new Exception( __( 'You do not have permission to create or edit lessons', 'learnpress' ) );
41 }
42
43 $item_id = $data['item_id'] ?? '';
44 if ( empty( $item_id ) ) {
45 throw new Exception( __( 'Invalid lesson ID', 'learnpress' ) );
46 }
47
48 if ( ! CourseBuilderAccessPolicy::can_access_tab_post( 'lessons', $item_id ) ) {
49 throw new Exception( __( "Sorry, you don't have permission to access this content", 'learnpress' ) );
50 }
51
52 $is_create_new = $item_id === CourseBuilder::POST_NEW;
53 $lessonModel = false;
54
55 if ( ! $is_create_new ) {
56 $lessonModel = LessonPostModel::find( (int) $item_id, true );
57 if ( ! $lessonModel ) {
58 throw new Exception( __( 'Lesson not found', 'learnpress' ) );
59 }
60 }
61
62 $data['lessonModel'] = $lessonModel;
63
64 $section = [
65 'wrap' => sprintf(
66 '<div class="lp-cb-content" data-post-id="%1$s">',
67 esc_attr( $item_id )
68 ),
69 'header' => $this->html_header( $data ),
70 'tabs' => $this->html_tabs( $data ),
71 'wrap_end' => '</div>',
72 ];
73
74 echo Template::combine_components( $section );
75 }
76
77 public function html_header( array $data = [] ): string {
78 $userModel = $data['userModel'] ?? false;
79 if ( ! $userModel instanceof UserModel ) {
80 return '';
81 }
82
83 $wp_user = new WP_User( $userModel );
84 $lessonModel = $data['lessonModel'] ?? false;
85 $hide_instructor_access_admin_screen = LP_Settings::is_hide_instructor_access_admin_screen();
86 $title = $lessonModel ? $lessonModel->get_the_title() : __( 'Add New Lesson', 'learnpress' );
87 $status = $lessonModel ? sanitize_key( (string) $lessonModel->post_status ) : '';
88 $status_label = 'future' === $status ? __( 'scheduled', 'learnpress' ) : $status;
89 $hide_wp_edit_link = $hide_instructor_access_admin_screen && user_can( $wp_user, UserModel::ROLE_INSTRUCTOR );
90 $main_action_label = $lessonModel && 'publish' === $status ? __( 'Update', 'learnpress' ) : __( 'Publish', 'learnpress' );
91
92 $section = [
93 'header_wrap' => '<div class="lp-cb-header">',
94 'header_left' => '<div class="lp-cb-header__left">',
95 'title' => sprintf(
96 '<h1 class="lp-cb-header__title">%s</h1>',
97 esc_html( $title )
98 ),
99 'status_badge' => $lessonModel && $status ? sprintf(
100 '<span class="lesson-status %1$s">%2$s</span>',
101 esc_attr( $status ),
102 esc_html( $status_label )
103 ) : '',
104 'link_edit_on_wp' => $lessonModel && ! $hide_wp_edit_link ? sprintf(
105 '<a href="%1$s" class="lp-cb-admin-link" target="_blank" title="%2$s"%3$s>
106 <span class="dashicons dashicons-wordpress"></span>
107 <span>%2$s</span>
108 </a>',
109 esc_url( admin_url( 'post.php?post=' . $lessonModel->get_id() . '&action=edit' ) ),
110 esc_attr__( 'Edit with WordPress', 'learnpress' ),
111 'trash' === $status ? ' style="display:none"' : ''
112 ) : '',
113 'header_left_end' => '</div>',
114 'header_actions' => '<div class="lp-cb-header__actions">',
115 'dropdown_wrap' => '<div class="cb-header-actions-dropdown cb-header-actions-dropdown--single">',
116 'update_btn' => sprintf(
117 '<div class="cb-btn-update cb-btn-primary cb-btn-main-action"
118 data-status="%1$s"
119 data-title-update="%2$s"
120 data-title-publish="%3$s">%4$s</div>',
121 esc_attr( 'publish' ),
122 esc_attr__( 'Update', 'learnpress' ),
123 esc_attr__( 'Publish', 'learnpress' ),
124 esc_html( $main_action_label )
125 ),
126 'dropdown_wrap_end' => '</div>',
127 'header_actions_end' => '</div>',
128 'header_end' => '</div>',
129 ];
130
131 return Template::combine_components( $section );
132 }
133
134 public function html_tabs( array $data = [] ): string {
135 $section_tab = [
136 'tabs_wrap' => '<div class="lp-cb-tabs">',
137 'tabs' => '',
138 'tabs_end' => '</div>',
139 ];
140
141 $section_content = [
142 'wrap' => '<div class="lp-cb-tab-content">',
143 'content' => '',
144 'wrap-end' => '</div>',
145 ];
146
147 $tabs = apply_filters(
148 'learn-press/course-builder/lessons/edit/tabs',
149 [
150 'overview' => [
151 'title' => esc_html__( 'Overview', 'learnpress' ),
152 'html' => $this->html_tab_overview( $data ),
153 ],
154 'settings' => [
155 'title' => esc_html__( 'Settings', 'learnpress' ),
156 'html' => $this->html_tab_settings( $data ),
157 ],
158 ],
159 $data
160 );
161
162 $tab_active = array_key_first( $tabs );
163 if ( isset( $_GET['tab'] ) && isset( $tabs[ $_GET['tab'] ] ) ) {
164 $tab_active = $_GET['tab'];
165 }
166
167 foreach ( $tabs as $key => $tab ) {
168 $is_active = $key === $tab_active;
169
170 $section_tab['tabs'] .= sprintf(
171 '<a href="#" class="lp-cb-tabs__item %s" data-tab-section="%s">%s</a>',
172 $is_active ? 'is-active' : '',
173 esc_attr( $tab['slug'] ?? $key ),
174 esc_html( $tab['title'] ?? '' )
175 );
176
177 $section_content['content'] .= sprintf(
178 '<div class="lp-cb-tab-panel %s" data-section="%s">%s</div>',
179 $is_active ? '' : 'lp-hidden',
180 esc_attr( $tab['slug'] ?? $key ),
181 $tab['html'] ?? ''
182 );
183 }
184
185 return Template::combine_components(
186 [
187 'tabs' => Template::combine_components( $section_tab ),
188 'contents' => Template::combine_components( $section_content ),
189 ]
190 );
191 }
192
193 public function html_tab_overview( array $data = [] ): string {
194 wp_enqueue_script( 'lp-course-builder' );
195
196 $lesson_model = $data['lessonModel'] ?? false;
197 $lesson_id = $data['item_id'] ?? ( $lesson_model ? $lesson_model->get_id() : CourseBuilder::POST_NEW );
198
199 if ( absint( $lesson_id ) && ! $lesson_model ) {
200 $lesson_model = LessonPostModel::find( absint( $lesson_id ), true );
201 if ( empty( $lesson_model ) ) {
202 return '';
203 }
204 }
205
206 $html_assigned = $this->assigned_course( $lesson_model );
207 $html_edit_title = $this->edit_title( $lesson_model );
208 $html_permalink = $this->edit_permalink( $lesson_model );
209 $html_edit_desc = $this->edit_desc( $lesson_model );
210 $section = [
211 'wrapper' => sprintf( '<div class="cb-section__lesson-edit" data-lesson-id="%s">', $lesson_id ),
212 'edit_title' => $html_edit_title,
213 'wrapper_title_assigned' => '<div class="cb-section__lesson-title-assigned">',
214 'assigned_course' => $html_assigned,
215 'wrapper_title_assigned_end' => '</div>',
216 'edit_permalink' => $html_permalink,
217 'edit_desc' => $html_edit_desc,
218 'wrapper_end' => '</div>',
219 ];
220
221 return Template::combine_components( $section );
222 }
223
224 public function html_tab_settings( array $data = [] ): string {
225 $lesson_model = $data['lessonModel'] ?? false;
226 $lesson_id = $data['item_id'] ?? ( $lesson_model ? $lesson_model->get_id() : CourseBuilder::POST_NEW );
227
228 if ( $lesson_id === CourseBuilder::POST_NEW || absint( $lesson_id ) <= 0 ) {
229 return sprintf( '<span class="lp-message lp-message--info">%s</span>', __( 'Please save Lesson before setting lesson', 'learnpress' ) );
230 }
231
232 if ( ! $lesson_model ) {
233 $lesson_model = LessonPostModel::find( absint( $lesson_id ), true );
234 if ( empty( $lesson_model ) ) {
235 return '';
236 }
237 }
238
239 if ( ! class_exists( 'LP_Meta_Box_Lesson' ) ) {
240 require_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/lesson/settings.php';
241 }
242
243 $metabox = new \LP_Meta_Box_Lesson();
244 ob_start();
245 $metabox->output( $lesson_model );
246 $settings = ob_get_clean();
247
248 $output = [
249 'wrapper' => sprintf( '<div class="cb-section__lesson-edit" data-lesson-id="%s">', $lesson_id ),
250 'form_setting' => '<form name="lp-form-setting-lesson" class="lp-form-setting-lesson" method="post" enctype="multipart/form-data">',
251 'settings' => $settings,
252 'form_setting_end' => '</form>',
253 'wrapper_end' => '</div>',
254 ];
255
256 return Template::combine_components( $output );
257 }
258
259 /**
260 * Allow callback for AJAX.
261 * @use self::render_edit_course_curriculum
262 * @use self::render_html
263 *
264 * @param array $callbacks
265 *
266 * @return array
267 */
268 public function allow_callback( array $callbacks ): array {
269 $callbacks[] = AdminEditCurriculumTemplate::class . ':render_edit_course_curriculum';
270
271 return $callbacks;
272 }
273
274 public function assigned_course( $lesson_model ) {
275 $assign_course = ! empty( $lesson_model ) ? $this->get_assigned( $lesson_model->get_id() ) : '';
276 $html_courses = '';
277 $assigned = sprintf( '<span class="lesson-not-assigned">%s</span>', __( 'Not assigned yet', 'learnpress' ) );
278 if ( ! empty( $assign_course ) ) {
279 $courses = is_array( $assign_course ) && isset( $assign_course['id'] )
280 ? array( $assign_course )
281 : $assign_course;
282
283 $course_htmls = array();
284 foreach ( $courses as $course ) {
285 $course_id = $course['id'] ?? 0;
286 $course_title = $course['title'] ?? '';
287
288 if ( $course_id && $course_title ) {
289 $course_link = BuilderCourseTemplate::instance()->get_link_edit( $course_id );
290 $course_htmls[] = sprintf(
291 '<a href="%s" target="_blank">%s</a>',
292 esc_url( $course_link ),
293 esc_html( $course_title )
294 );
295 }
296 }
297
298 if ( ! empty( $course_htmls ) ) {
299 $assigned = implode( ', ', $course_htmls );
300 }
301 }
302
303 $html_courses = sprintf(
304 '<div class="cb-item-edit-assigned lesson-assigned-courses"><span class="label">%s</span> %s</div>',
305 __( 'Assigned', 'learnpress' ),
306 $assigned
307 );
308
309 return $html_courses;
310 }
311
312 public function edit_permalink( $lesson_model ): string {
313 $post_id = ! empty( $lesson_model ) ? absint( $lesson_model->get_id() ) : 0;
314 $post = $post_id ? get_post( $post_id ) : null;
315 $post_name = $post && ! empty( $post->post_name ) ? (string) $post->post_name : '';
316 $full_url = '';
317 $base_url = '';
318 $display_classes = 'cb-permalink-display';
319 $placeholder_class = 'cb-item-edit-permalink__placeholder';
320 $notice_no_link = __(
321 'Permalink is only available if the item is already assigned to a course.',
322 'learnpress'
323 );
324 $placeholder_text = __( 'Permalink will be available after saving.', 'learnpress' );
325 $show_unavailable = true;
326
327 if ( $post_id ) {
328 $current_status = $post && ! empty( $post->post_status ) ? sanitize_key( $post->post_status ) : '';
329 if ( 'draft' !== $current_status ) {
330 $course_id_of_item = \LP_Course_DB::getInstance()->get_course_by_item_id( $post_id );
331 if ( $course_id_of_item ) {
332 $course = learn_press_get_course( $course_id_of_item );
333 if ( $course ) {
334 $full_url = urldecode( $course->get_item_link( $post_id ) );
335 $base_url = $full_url;
336 $show_unavailable = false;
337
338 if ( ! empty( $post_name ) ) {
339 $base_url = trailingslashit( preg_replace( '/' . preg_quote( $post_name, '/' ) . '\/?$/', '', $full_url ) );
340 }
341 }
342 }
343 }
344 }
345
346 if ( $show_unavailable && $post_id ) {
347 $placeholder_text = $notice_no_link;
348 }
349
350 if ( $show_unavailable ) {
351 $display_classes .= ' lp-hidden';
352 } else {
353 $placeholder_class .= ' lp-hidden';
354 }
355
356 $state_a = sprintf(
357 '<span class="cb-item-edit-permalink__label">%s</span>
358 <div class="%s">
359 <a href="%s" target="_blank" class="cb-permalink-url">%s</a>
360 <button type="button" class="cb-permalink-edit-btn" title="%s">
361 <span class="dashicons dashicons-edit"></span>
362 </button>
363 </div>',
364 __( 'Permalink', 'learnpress' ),
365 esc_attr( $display_classes ),
366 esc_url( $full_url ),
367 esc_html( $full_url ),
368 __( 'Edit', 'learnpress' )
369 );
370
371 $state_b = sprintf(
372 '<div class="cb-permalink-editor lp-hidden">
373 <span class="cb-permalink-prefix">%s</span>
374 <div class="cb-permalink-input-row">
375 <input type="text" name="lesson_permalink" id="lesson_permalink" value="%s" class="cb-permalink-slug-input" placeholder="%s">
376 <div class="cb-permalink-actions">
377 <button type="button" class="cb-permalink-ok-btn">%s</button>
378 <button type="button" class="cb-permalink-cancel-btn">%s</button>
379 </div>
380 </div>
381 </div>',
382 esc_html( $base_url ),
383 esc_attr( $post_name ),
384 esc_attr__( 'your-slug', 'learnpress' ),
385 __( 'OK', 'learnpress' ),
386 __( 'Cancel', 'learnpress' )
387 );
388
389 $hidden_base = sprintf(
390 '<input type="hidden" id="cb-permalink-base-url" value="%s">',
391 esc_attr( $base_url )
392 );
393
394 $placeholder = sprintf(
395 '<span class="%s">%s</span>',
396 esc_attr( $placeholder_class ),
397 esc_html( $placeholder_text )
398 );
399
400 $view = [
401 'wrapper' => '<div class="cb-item-edit-permalink cb-course-edit-permalink">',
402 'state_a' => $state_a,
403 'state_b' => $state_b,
404 'hidden_base' => $hidden_base,
405 'placeholder' => $placeholder,
406 'wrapper_end' => '</div>',
407 ];
408
409 return Template::combine_components( $view );
410 }
411
412 public function edit_title( $lesson_model ) {
413 $title = ! empty( $lesson_model ) ? $lesson_model->get_the_title() : '';
414 $edit = [
415 'wrapper' => '<div class="cb-lesson-edit-title">',
416 'label' => sprintf( '<label for="title" class="cb-lesson-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
417 'input' => sprintf( '<input type="text" name="lesson_title" size="30" value="%s" id="title" class="cb-lesson-edit-title__input">', $title ),
418 'wrapper_end' => '</div>',
419 ];
420
421 return Template::combine_components( $edit );
422 }
423
424 public function edit_desc( $lesson_model ) {
425 $desc = ! empty( $lesson_model ) ? $lesson_model->get_the_content() : '';
426 $editor_id = 'lesson_description_editor';
427 $editor_settings = array(
428 'textarea_name' => 'lesson_description',
429 'textarea_rows' => 10,
430 'teeny' => false,
431 'media_buttons' => true,
432 'tinymce' => array(
433 'content_style' => "body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif; font-size: 14px; line-height: 1.6; color: #1e1e1e; }",
434 'toolbar1' => 'formatselect,bold,italic,underline,bullist,numlist,blockquote,alignleft,aligncenter,alignright,link,unlink,spellchecker,wp_adv',
435 'toolbar2' => 'strikethrough,hr,forecolor,pastetext,removeformat,charmap,outdent,indent,undo,redo,wp_help',
436 ),
437 'quicktags' => true,
438 );
439
440 ob_start();
441 wp_editor( $desc, $editor_id, $editor_settings );
442 $editor_html = ob_get_clean();
443
444 $edit = [
445 'wrapper' => '<div class="cb-lesson-edit-desc">',
446 'label' => sprintf( '<label for="lesson_description" class="cb-lesson-edit-desc__label">%s</label>', __( 'Description', 'learnpress' ) ),
447 'edit' => $editor_html,
448 'wrapper_end' => '</div>',
449 ];
450
451 return Template::combine_components( $edit );
452 }
453
454 public function get_assigned( $id ) {
455 $courses = learn_press_get_item_courses( $id );
456
457 if ( empty( $courses ) ) {
458 return array();
459 }
460
461 return array(
462 'id' => $courses[0]->ID,
463 'title' => $courses[0]->post_title ?? '',
464 );
465 }
466 }
467