true]). */ public function edit_course_curriculum_layout( CourseModel $courseModel, array $context = [] ) { wp_enqueue_style( 'lp-edit-curriculum' ); wp_enqueue_script( 'lp-edit-course' ); $args = array_merge( [ 'id_url' => 'edit-course-curriculum', 'course_id' => $courseModel->ID, ], $context ); $call_back = [ 'class' => self::class, 'method' => 'render_edit_course_curriculum', ]; echo TemplateAJAX::load_content_via_ajax( $args, $call_back ); } /** * Allow callback for AJAX. * @use self::render_edit_course_curriculum * @use self::render_html * * @param array $callbacks * * @return array */ public function allow_callback( array $callbacks ): array { $callbacks[] = get_class( $this ) . ':render_edit_course_curriculum'; $callbacks[] = get_class( $this ) . ':render_list_items_not_assign'; return $callbacks; } /** * Render edit course curriculum html. * * @throws Exception */ public static function render_edit_course_curriculum( array $data ): stdClass { $course_id = $data['course_id'] ?? 0; $courseModel = CourseModel::find( $course_id, true ); if ( ! $courseModel ) { throw new Exception( __( 'Course not found', 'learnpress' ) ); } self::instance()->courseModel = $courseModel; self::instance()->context_data = $data; // Store context data for filters $coursePostModel = new CoursePostModel( $courseModel ); if ( ! $coursePostModel->check_capabilities_create() ) { throw new Exception( __( 'You do not have permission to edit this course', 'learnpress' ) ); } $content = new stdClass(); $content->content = self::instance()->html_edit_curriculum( $courseModel ); return $content; } /** * HTML for edit curriculum. * * @param CourseModel $courseModel * * @return string */ public function html_edit_curriculum( CourseModel $courseModel ): string { $html_sections = ''; // Get sections items $sections_items = $courseModel->get_section_items(); $count_sections = count( $sections_items ); foreach ( $sections_items as $section_items ) { $html_sections .= $this->html_edit_section( $courseModel, $section_items ); } $sections = [ 'wrap' => '
', 'list-sections' => $html_sections, 'section-clone' => $this->html_edit_section( $courseModel ), 'wrap_end' => '
', ]; $section = [ 'wrap' => '
', 'heading' => '
', 'h4' => sprintf( '

%s

', __( 'Details', 'learnpress' ) ), 'count-sections' => sprintf( '
%s
', $count_sections, sprintf( __( '%1$s %2$s', 'learnpress' ), $count_sections, sprintf( '%s%s', __( 'Section', 'learnpress' ), __( 'Sections', 'learnpress' ) ) ) ), 'count-items' => sprintf( '
%s
', $courseModel->count_items(), sprintf( __( '%1$s %2$s', 'learnpress' ), $courseModel->count_items(), sprintf( '%s%s', __( 'Item', 'learnpress' ), __( 'Items', 'learnpress' ) ) ) ), 'section-toggle' => '
', 'heading_end' => '
', 'sections' => Template::combine_components( $sections ), 'add_new_section' => $this->html_add_new_section(), 'select_items' => $this->html_popup_items_to_select_clone( $courseModel ), 'wrap_end' => '
', ]; return Template::combine_components( $section ); } /** * HTML for edit section. * * @param CourseModel $courseModel * @param null|object $section_items * * @return string */ public function html_edit_section( CourseModel $courseModel, $section_items = null ): string { $is_clone = is_null( $section_items ); $total_items = 0; $items = []; $html_items = ''; $section_id = $section_items->section_id ?? 0; $section_name = $section_items->section_name ?? ''; if ( ! $is_clone ) { $total_items = count( $section_items->items ?? [] ); $items = $section_items->items ?? []; foreach ( $items as $item ) { $html_items .= $this->html_section_item( $courseModel, $item ); } } $section_list_items = [ 'wrap' => '', ]; $section = [ 'wrap' => sprintf( '
', $section_id, $is_clone ? 'clone lp-hidden' : '' ), 'head' => '
', 'drag' => sprintf( '', __( 'Drag to reorder section', 'learnpress' ) ), 'loading' => '', 'title' => $this->html_input_section_title( $section_name ), 'btn-edit' => sprintf( '', __( 'Edit section title', 'learnpress' ) ), 'btn-delete' => sprintf( '', Template::convert_data_to_json( [ 'action' => 'course_delete_section', 'course_id' => $courseModel->get_id(), 'id_url' => 'course-delete-section', ] ), __( 'Are you sure?', 'learnpress' ), __( 'This section will be deleted. The items in this section will no longer be assigned to this course, but will not be permanently deleted.', 'learnpress' ), __( 'Delete Section', 'learnpress' ) ), 'btn-update' => sprintf( '', __( 'Update' ) ), 'btn-cancel' => sprintf( '', __( 'Cancel' ) ), 'count-items' => sprintf( '
%s
', $total_items, sprintf( __( '%1$s %2$s', 'learnpress' ), $total_items, sprintf( '%s%s', __( 'Item', 'learnpress' ), __( 'Items', 'learnpress' ) ) ) ), 'toggle' => '
', 'head_end' => '
', 'wrap_content' => '
', 'section-content' => '
', 'section-description' => sprintf( '
%s%s%s
', $this->html_edit_section_description( $section_items->section_description ?? '' ), sprintf( '', __( 'Update' ) ), sprintf( '', __( 'Cancel' ) ) ), 'section-list-items' => Template::combine_components( $section_list_items ), 'section-content-end' => '
', 'section-item-actions' => $this->html_section_item_actions(), 'wrap_content_end' => '
', 'wrap_end' => '
', ]; return Template::combine_components( $section ); } /** * HTML input section title. * * @param string $section_name * * @return string */ public function html_input_section_title( string $section_name = '' ): string { return sprintf( '', esc_attr( $section_name ), esc_attr__( 'Update section title', 'learnpress' ), esc_attr__( 'Section title is required', 'learnpress' ), Template::convert_data_to_json( [ 'action' => 'course_update_section', 'course_id' => $this->courseModel->get_id(), 'id_url' => 'course-update-section-title', ] ) ); } /** * HTML for section description input. * * @param string|null $section_description * * @return string */ public function html_edit_section_description( string $section_description = '' ): string { return sprintf( '', esc_attr( $section_description ), esc_attr__( '+ Add Description', 'learnpress' ), Template::convert_data_to_json( [ 'action' => 'course_update_section', 'course_id' => $this->courseModel->get_id(), 'id_url' => 'course-update-section-description', ] ) ); } /** * HTML add new section. * * @return string */ public function html_add_new_section(): string { $section = [ 'wrap' => '
', 'icon' => '', 'input' => sprintf( '', esc_attr__( 'Create a new section', 'learnpress' ), esc_attr__( 'Section title is required', 'learnpress' ), Template::convert_data_to_json( [ 'action' => 'course_add_section', 'course_id' => $this->courseModel->get_id(), 'id_url' => 'course-add-section', ] ), ), 'button' => sprintf( '', __( 'Add Section', 'learnpress' ) ), 'wrap_end' => '
', ]; return Template::combine_components( $section ); } /** * HTML for section item. * $item is null when clone item new * * @param CourseModel $courseModel * @param null|object $item * * @return string */ public function html_section_item( CourseModel $courseModel, $item = null ): string { $is_clone = is_null( $item ); $item_id = $item->item_id ?? 0; $item_title = $item->title ?? ''; $item_type = $item->item_type ?? ''; /** * @var $itemModel PostModel */ $itemModel = $courseModel->get_item_model( $item_id, $item_type ); $edit_button = apply_filters( 'learn-press/admin/curriculum/section-item/edit-button', sprintf( '
  • ', __( 'Edit item detail', 'learnpress' ), $itemModel ? $itemModel->get_edit_link() : '' ), $item, $itemModel, $courseModel ); $section_action = [ 'wrap' => '', ]; $section_action = apply_filters( 'learn-press/admin/curriculum/section-item/actions', $section_action, $item, $itemModel, $courseModel, $this->context_data ); $section = [ 'li' => sprintf( '
  • ', $item_id, $item_type, $item_type, $is_clone ? 'clone lp-hidden' : '' ), 'drag' => sprintf( '', __( 'Drag to reorder item', 'learnpress' ) ), 'icon' => '
    ', 'loading' => '', 'input-title' => sprintf( '', 'lp-item-title-input', wp_kses_post( $item_title ), esc_attr__( 'Item title is required', 'learnpress' ) ), 'btn-update' => sprintf( '', __( 'Update' ) ), 'btn-cancel' => sprintf( '', __( 'Cancel' ) ), 'item_actions' => Template::combine_components( $section_action ), 'li_end' => '
  • ', ]; return Template::combine_components( $section ); } public function html_section_item_actions(): string { $course_item_types = CourseModel::item_types_support(); $html_buttons = ''; foreach ( $course_item_types as $type ) { $item_label = CourseModel::item_types_label( $type ); $html_buttons .= sprintf( '', $type, sprintf( __( 'Create a new %s', 'learnpress' ), $item_label ), sprintf( __( 'Add %s', 'learnpress' ), $item_label ), sprintf( __( 'New %s', 'learnpress' ), $item_label ) ); } $section = [ 'wrap' => '
    ', 'buttons' => $html_buttons, 'btn-select-items' => sprintf( '', __( 'Content Bank', 'learnpress' ) ), 'add-item-type' => $this->html_add_item_type(), 'wrap_end' => '
    ', ]; return Template::combine_components( $section ); } /** * HTML for section item new. * * @return string */ public function html_add_item_type(): string { $section = [ 'wrap' => '
    ', 'icon-plus' => '
    ', 'item-ico-type' => '
    ', 'actions' => '
    ', 'input' => sprintf( '', 'lp-add-item-type-title-input', esc_attr__( 'Item title is required', 'learnpress' ) ), 'button_add' => '', 'button_cancel' => sprintf( '', __( 'Cancel' ) ), 'actions_end' => '
    ', 'wrap_end' => '
    ', ]; return Template::combine_components( $section ); } /** * HTML for popup items to select. * * @param CourseModel $course_model * * @return string */ public function html_popup_items_to_select_clone( CourseModel $course_model ): string { /** * @uses self::render_list_items_not_assign */ $html_items = TemplateAJAX::load_content_via_ajax( [ 'id_url' => 'list-items-not-assign', 'enableScrollToView' => false, 'course_id' => $course_model->ID, 'item_type' => LP_LESSON_CPT, 'paged' => 1, ], [ 'class' => self::class, 'method' => 'render_list_items_not_assign', ] ); $tabs = []; $course_item_types = CourseModel::item_types_support(); foreach ( $course_item_types as $type ) { $item_label = CourseModel::item_types_label( $type ); $tabs[ $type ] = $item_label; } $section = [ 'wrap-script-template' => '