0 && ! doing_filter( 'the_content' ) ) { self::$rendered[ $name ][ $item_id ] = true; } } public static function reset(): void { self::$rendered = array(); self::$template = null; } public static function content( $content ) { if ( ! is_string( $content ) || ! is_singular( array( PostTypes::LESSON, PostTypes::QUIZ ) ) ) { return $content; } $post = get_post(); if ( ! $post instanceof \WP_Post || (int) get_queried_object_id() !== (int) $post->ID || doing_filter( 'get_the_excerpt' ) || doing_filter( 'wp_trim_excerpt' ) || doing_action( 'wp_head' ) ) { return $content; } $item_id = RouteContext::item_id() > 0 ? RouteContext::item_id() : Context::item_id( array(), null ); $item = $item_id > 0 ? ( Services::curriculum_repo()->items( array( $item_id ) )[ $item_id ] ?? null ) : null; if ( null === $item ) { return $content; } $unit = Services::unit_repo()->get_many( array( $item->unit_id ) )[ $item->unit_id ] ?? null; $before = ''; $after = ''; if ( null !== $unit && UnitType::LESSON === $unit->type && true === \RoosterLMS\Core\Settings::get( 'lesson_media_in_use' ) && ! self::placed( $content, MediaPlayer::NAME, MediaPlayer::SHORTCODE, $item->id ) && null !== Services::media_repo()->for_owner( MediaOwner::UNIT, $item->unit_id, MediaRole::PRIMARY ) ) { $before = self::block( MediaPlayer::NAME, array( MediaPlayer::class, 'render' ) ); } if ( null !== $unit && UnitType::ASSIGNMENT === $unit->type && ! self::placed( $content, AssignmentView::NAME, AssignmentView::SHORTCODE, $item->id ) ) { $after .= self::block( AssignmentView::NAME, array( AssignmentView::class, 'render' ) ); } $user = get_current_user_id(); if ( $user > 0 && ! self::placed( $content, QaView::NAME, QaView::SHORTCODE, $item->id ) && ( \RoosterLMS\Blocks\Learner::is_enrolled( $user, $item->course_id ) || current_user_can( 'edit_post', (int) $post->ID ) ) ) { if ( 'end' !== \RoosterLMS\Community\CommunitySettings::get( 'qa_place' ) ) { $after .= self::block( QaView::NAME, array( QaView::class, 'render' ), array( 'panel' => true ) ); } elseif ( null !== $unit && UnitType::QUIZ === $unit->type ) { self::after_quiz(); } else { $after .= self::block( QaView::NAME, array( QaView::class, 'render' ) ); } } return $before . $content . $after; } public static function media_changed( $owner_type, $owner_id = 0, $role = 0, $what = '' ): void { unset( $owner_id, $role ); if ( MediaOwner::UNIT->value === (int) $owner_type && 'set' === $what && true !== \RoosterLMS\Core\Settings::get( 'lesson_media_in_use' ) ) { \RoosterLMS\Core\Settings::update( array( 'lesson_media_in_use' => true ) ); } } private static function after_quiz(): void { if ( has_filter( 'render_block_rooster-lms/quiz', array( self::class, 'append_qa' ) ) ) { return; } add_filter( 'render_block_rooster-lms/quiz', array( self::class, 'append_qa' ), 10, 1 ); } public static function append_qa( $html ) { remove_filter( 'render_block_rooster-lms/quiz', array( self::class, 'append_qa' ), 10 ); return is_string( $html ) ? $html . QaView::render( array() ) : $html; } private static function placed( string $content, string $name, string $shortcode, int $item_id ): bool { return has_block( 'rooster-lms/' . $name, $content ) || has_shortcode( $content, $shortcode ) || isset( self::$rendered[ $name ][ $item_id ] ) || self::in_template( $name ); } private static function in_template( string $name ): bool { $content = isset( $GLOBALS['_wp_current_template_content'] ) && is_string( $GLOBALS['_wp_current_template_content'] ) ? $GLOBALS['_wp_current_template_content'] : ''; if ( '' === $content ) { return false; } if ( null === self::$template || self::$template[0] !== $content ) { $names = array(); self::collect( parse_blocks( $content ), $names, 0 ); self::$template = array( $content, $names ); } return isset( self::$template[1][ 'rooster-lms/' . $name ] ); } private static function collect( array $blocks, array &$names, int $depth ): void { foreach ( $blocks as $block ) { $block_name = is_string( $block['blockName'] ?? null ) ? $block['blockName'] : ''; if ( '' === $block_name ) { continue; } $names[ $block_name ] = true; $attrs = is_array( $block['attrs'] ?? null ) ? $block['attrs'] : array(); $inner = ''; if ( $depth < 5 && 'core/pattern' === $block_name && is_string( $attrs['slug'] ?? null ) ) { $pattern = \WP_Block_Patterns_Registry::get_instance()->get_registered( $attrs['slug'] ); $inner = is_array( $pattern ) && is_string( $pattern['content'] ?? null ) ? $pattern['content'] : ''; } if ( '' !== $inner ) { self::collect( parse_blocks( $inner ), $names, $depth + 1 ); } if ( is_array( $block['innerBlocks'] ?? null ) && array() !== $block['innerBlocks'] ) { self::collect( $block['innerBlocks'], $names, $depth ); } } } private static function block( string $name, callable $render, array $attrs = array() ): string { return BlockRegistry::is_registered( $name ) ? "\n\n" : (string) $render( $attrs ); } }