diff --git a/.changelogs/course-outline-block-1.yml b/.changelogs/course-outline-block-1.yml new file mode 100644 index 0000000000..5eb8e5b5c6 --- /dev/null +++ b/.changelogs/course-outline-block-1.yml @@ -0,0 +1,3 @@ +significance: patch +type: changed +entry: Increase maximum number of Courses shown in drop down select to 100. diff --git a/.changelogs/course-outline-block-2.yml b/.changelogs/course-outline-block-2.yml new file mode 100644 index 0000000000..43d62fa7cf --- /dev/null +++ b/.changelogs/course-outline-block-2.yml @@ -0,0 +1,3 @@ +significance: patch +type: fixed +entry: Add fallback course for editor single template block render preview. diff --git a/.changelogs/course-outline-block.yml b/.changelogs/course-outline-block.yml new file mode 100644 index 0000000000..209d5188b0 --- /dev/null +++ b/.changelogs/course-outline-block.yml @@ -0,0 +1,4 @@ +significance: patch +type: fixed +entry: Add `inherit from current course` option for Course Outline block when + editing Single Course template. diff --git a/includes/abstracts/abstract.llms.shortcode.course.element.php b/includes/abstracts/abstract.llms.shortcode.course.element.php index 65793e75cf..34568a6882 100644 --- a/includes/abstracts/abstract.llms.shortcode.course.element.php +++ b/includes/abstracts/abstract.llms.shortcode.course.element.php @@ -5,7 +5,7 @@ * @package LifterLMS/Abstracts/Classes * * @since 3.6.0 - * @version 3.6.0 + * @version [version] */ defined( 'ABSPATH' ) || exit; @@ -46,28 +46,40 @@ protected function get_default_attributes() { * $atts & $content are both filtered before being passed to get_output() * output is filtered so the return of get_output() doesn't need its own filter * - * @return string - * @since 3.6.0 - * @version 3.6.0 + * @since 3.6.0 + * @since [version] Add fallback for editor block rendering. + * + * @return string */ protected function get_output() { // Get a reference to the current page where the shortcode is displayed. global $post; - $current_post = $post; - $course = get_post( $this->get_attribute( 'course_id' ) ); + $current_id = $post->ID ?? null; + + $id = $this->get_attribute( 'course_id' ); + + if ( ! $id ) { + $id = $current_id; + } + + if ( ! $id && llms_is_editor_block_rendering() ) { + $id = LLMS_Shortcodes_Blocks::get_placeholder_course_id(); + } + + $course = get_post( $id ); // We don't have a post object to proceed with. if ( ! $course ) { return ''; } - if ( 'course' !== $course->post_type ) { + if ( in_array( $course->post_type, array( 'lesson', 'llms_quiz' ), true ) ) { // Get the parent. $parent = llms_get_post_parent_course( $course ); - // Post type doesn't have a parent so we can't display a syllabus. + // Post type doesn't have a parent, so we can't display a syllabus. if ( ! $parent ) { return ''; } @@ -77,18 +89,22 @@ protected function get_output() { } + if ( ! $current_id && llms_is_editor_block_rendering() ) { + $current_id = LLMS_Shortcodes_Blocks::get_placeholder_course_id(); + } + ob_start(); // Hack the global so our syllabus template works. - if ( $course->ID != $current_post->ID ) { + if ( $course->ID !== $current_id ) { $post = $course; } $this->template_function(); // Restore the global. - if ( $course->ID != $current_post->ID ) { - $post = $current_post; + if ( $course->ID !== $current_id ) { + $post = get_post( $current_id ); } return ob_get_clean(); diff --git a/includes/shortcodes/class.llms.shortcode.course.outline.php b/includes/shortcodes/class.llms.shortcode.course.outline.php index 7884afbcc4..1b816e6792 100644 --- a/includes/shortcodes/class.llms.shortcode.course.outline.php +++ b/includes/shortcodes/class.llms.shortcode.course.outline.php @@ -7,7 +7,7 @@ * @package LifterLMS/Shortcodes/Classes * * @since 3.5.1 - * @version 3.19.2 + * @version [version] */ defined( 'ABSPATH' ) || exit; @@ -84,13 +84,31 @@ protected function get_default_attributes() { * $atts & $content are both filtered before being passed to get_output() * output is filtered so the return of get_output() doesn't need its own filter * - * @return string - * @since 3.5.1 - * @version 3.19.2 + * @since 3.5.1 + * @since 3.19.2 Unknown. + * @since [version] Add fallback for editor block rendering. + * + * @return string */ protected function get_output() { - $course = new LLMS_Course( $this->get_attribute( 'course_id' ) ); + // Get a reference to the current page where the shortcode is displayed. + global $post; + + $current_id = $post->ID ?? null; + + $id = $this->get_attribute( 'course_id' ); + + if ( ! $id ) { + $id = $current_id; + } + + // Show the first course when in Editor if none selected. + if ( ! $id && llms_is_editor_block_rendering() ) { + $id = LLMS_Shortcodes_Blocks::get_placeholder_course_id(); + } + + $course = new LLMS_Course( $id ); $student = llms_get_student(); $args = array( diff --git a/includes/shortcodes/class.llms.shortcodes.blocks.php b/includes/shortcodes/class.llms.shortcodes.blocks.php index a5b25d463e..885131db61 100644 --- a/includes/shortcodes/class.llms.shortcodes.blocks.php +++ b/includes/shortcodes/class.llms.shortcodes.blocks.php @@ -5,7 +5,7 @@ * @package LifterLMS/Classes/Shortcodes * * @since 7.2.0 - * @version 7.2.0 + * @version [version] */ defined( 'ABSPATH' ) || exit; @@ -258,6 +258,27 @@ public function render_block( array $attributes, string $content, WP_Block $bloc trim( $html ) ); } + + /** + * Returns ID of first published course. + * + * @since [version] + * + * @return int + */ + public static function get_placeholder_course_id(): int { + + $courses = get_posts( + array( + 'post_type' => 'course', + 'posts_per_page' => 1, + 'post_status' => 'publish', + ) + ); + + return $courses[0]->ID ?? 0; + + } } return LLMS_Shortcodes_Blocks::instance(); diff --git a/packages/components/src/post-select/index.js b/packages/components/src/post-select/index.js index a727aa08ab..d56d438943 100644 --- a/packages/components/src/post-select/index.js +++ b/packages/components/src/post-select/index.js @@ -8,9 +8,9 @@ export const llmsPostTypes = [ 'llms_quiz' ]; -export const getPostTypeName = ( slug, format = 'name' ) => { +export const getPostTypeName = ( slug = 'course', format = 'name' ) => { const name = slug?.replace( 'llms_', '' ); - const title = name.charAt( 0 ).toUpperCase() + name.slice( 1 ); + const title = name?.charAt( 0 )?.toUpperCase() + name?.slice( 1 ); return format === 'name' ? name : title; }; @@ -22,39 +22,39 @@ export const useLlmsPostType = () => { }; export const usePostOptions = ( postType = 'course' ) => { + const queryArgs = { + per_page: 100, + status: 'publish', + }; + const { posts, currentPostType } = useSelect( ( select ) => { return { - posts: select( 'core' ).getEntityRecords( 'postType', postType ), + posts: select( 'core' ).getEntityRecords( 'postType', postType, queryArgs ), currentPostType: select( 'core/editor' )?.getCurrentPostType(), }; }, [] ); - const postTypeName = getPostTypeName( postType ); - const options = []; - if ( ! llmsPostTypes.includes( currentPostType ) ) { + const isSingleCourseTemplate = useSelect( ( select ) => { + return select( 'core/edit-site' )?.getEditedPostId( 'template' )?.includes( 'single-course' ); + } ); + + const postTypeName = getPostTypeName( postType ); + + if ( ! llmsPostTypes.includes( currentPostType ) && ! isSingleCourseTemplate ) { options.push( { - label: __( 'Select course', 'lifterlms' ), + label: __( 'Select ', 'lifterlms' ) + postTypeName, value: 0, } ); } - if ( posts?.length ) { - posts.forEach( ( post ) => { - options.push( { - label: post.title.rendered + ' (ID: ' + post.id + ')', - value: post.id, - } ); - } ); - } - - if ( llmsPostTypes.includes( currentPostType ) ) { + if ( llmsPostTypes.includes( currentPostType ) || isSingleCourseTemplate ) { options.unshift( { label: sprintf( // Translators: %s = Post type name. __( 'Inherit from current %s', 'lifterlms' ), - getPostTypeName( currentPostType ) + postTypeName ), value: 0, } ); @@ -67,6 +67,15 @@ export const usePostOptions = ( postType = 'course' ) => { } ); } + if ( posts?.length ) { + posts.forEach( ( post ) => { + options.push( { + label: post.title.rendered + ' (ID: ' + post.id + ')', + value: post.id, + } ); + } ); + } + return options; };