File manager - Edit - /home/theblueo/tv/fb4e3b/course.tar
Back
ld-course-metaboxes.php 0000666 00000003216 15214044143 0011143 0 ustar 00 <?php /** * Course Metaboxes. * * Introduces metaboxes at Add/Edit Course page to be used as * a wrapper by the React application at front-end. * * @package LearnDash */ namespace LearnDash\Course\Metaboxes; /** * Add the metaboxes to course post type. * * @return void */ function add_meta_boxes() { $screen = get_current_screen(); if ( 'sfwd-courses' !== get_post_type( get_the_ID() ) && 'sfwd-courses_page_courses-builder' !== $screen->id ) { return; } add_meta_box( 'sfwd-course-lessons', sprintf( '%s', \LearnDash_Custom_Label::get_label( 'lessons' ) ), 'LearnDash\Course\Metaboxes\meta_box_lessons_callback', null, 'side' ); add_meta_box( 'sfwd-course-topics', sprintf( '%s', \LearnDash_Custom_Label::get_label( 'topics' ) ), 'LearnDash\Course\Metaboxes\meta_box_topics_callback', null, 'side' ); add_meta_box( 'sfwd-course-quizzes', sprintf( '%s', \LearnDash_Custom_Label::get_label( 'quizzes' ) ), 'LearnDash\Course\Metaboxes\meta_box_quizzes_callback', null, 'side' ); } add_action( 'add_meta_boxes_sfwd-courses', 'LearnDash\Course\Metaboxes\add_meta_boxes' ); add_action( 'learndash_add_meta_boxes', 'LearnDash\Course\Metaboxes\add_meta_boxes' ); /** * Callback to render lessons metabox. * * @return void */ function meta_box_lessons_callback() { ?> <div id="sfwd-lessons-app"></div> <?php } /** * Callback to render topics metabox. * * @return void */ function meta_box_topics_callback() { ?> <div id="sfwd-topics-app"></div> <?php } /** * Callback to render quizzes metabox. * * @return void */ function meta_box_quizzes_callback() { ?> <div id="sfwd-quizzes-app"></div> <?php } ld-course-navigation.php 0000666 00000070137 15214044143 0011321 0 ustar 00 <?php /** * Function that help the user navigate through the course * * @since 2.1.0 * * @package LearnDash\Navigation */ /** * Generate previous post link for lesson or topic * * @since 2.1.0 * * @param string $prevlink * @param boolean $url return a url instead of HTML link * @return string previous post link output */ function learndash_previous_post_link( $prevlink='', $url = false, $post = null ) { if ( empty( $post) ) { global $post; } if ( empty( $post) ) { return $prevlink; } if ( $post->post_type == 'sfwd-lessons' ) { $link_name = learndash_get_label_course_step_previous( learndash_get_post_type_slug ( 'lesson' ) ); $posts = learndash_get_lesson_list( null, array( 'num' => 0 ) ); } else if ( $post->post_type == 'sfwd-topic' ) { $link_name = learndash_get_label_course_step_previous( learndash_get_post_type_slug ( 'topic' ) ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $post ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } $posts = learndash_get_topic_list( $lesson_id ); } else { return $prevlink; } foreach ( $posts as $k => $p ) { if ( $p instanceof WP_Post ) { if ( $p->ID == $post->ID ) { $found_at = $k; break; } } } if ( isset( $found_at) && ! empty( $posts[ $found_at -1] ) ) { if ( 'id' === $url ) { return $posts[ $found_at -1]->ID; } else if ( $url ) { return get_permalink( $posts[ $found_at -1]->ID ); } else { $permalink = get_permalink( $posts[ $found_at -1 ]->ID ); if ( is_rtl() ) { $link_name_with_arrow = $link_name; } else { $link_name_with_arrow = '<span class="meta-nav">←</span> ' . $link_name; } $link = '<a href="'.$permalink.'" class="prev-link" rel="prev">' . $link_name_with_arrow . '</a>'; /** * Filter previous post link output * * @since 2.1.0 * * @param string $link */ return apply_filters( 'learndash_previous_post_link', $link, $permalink, $link_name, $post ); } } else { return $prevlink; } } /** * Generate next post link for lesson or topic * * @since 2.1.0 * * @param string $prevlink * @param boolean $url return a url instead of HTML link. * Added 3.1 'id' will return next step post ID. * @param object $post WP_Post object * @return string next post link output */ function learndash_next_post_link( $prevlink='', $url = false, $post = null ) { if ( empty( $post) ) { global $post; } if ( empty( $post) ) { return $prevlink; } if ( $post->post_type == 'sfwd-lessons' ) { $link_name = learndash_get_label_course_step_next( learndash_get_post_type_slug( 'lesson' ) ); $course_id = learndash_get_course_id( $post ); $posts = learndash_get_lesson_list( $course_id, array( 'num' => 0 ) ); } else if ( $post->post_type == 'sfwd-topic' ) { $link_name = learndash_get_label_course_step_next( learndash_get_post_type_slug( 'topic' ) ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $post->ID ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } $posts = learndash_get_topic_list( $lesson_id ); } else { return $prevlink; } foreach ( $posts as $k => $p ) { if ( $p instanceof WP_Post ) { if ( $p->ID == $post->ID ) { $found_at = $k; break; } } } if ( isset( $found_at) && ! empty( $posts[ $found_at + 1] ) ) { if ( 'id' === $url ) { return $posts[ $found_at + 1]->ID; } else if ( $url ) { return get_permalink( $posts[ $found_at + 1]->ID ); } else { $permalink = get_permalink( $posts[ $found_at + 1]->ID ); if ( is_rtl() ) { $link_name_with_arrow = $link_name ; } else { $link_name_with_arrow = $link_name . ' <span class="meta-nav">→</span>'; } $link = '<a href="'.$permalink.'" class="next-link" rel="next">' . $link_name_with_arrow.'</a>'; /** * Filter next post link output * * @since 2.1.0 * * @param string $link */ return apply_filters( 'learndash_next_post_link', $link, $permalink, $link_name, $post ); } // } else if ( $post->post_type == 'sfwd-topic' ) { // if ( ( isset( $lesson_id ) ) && ( ! empty( $lesson_id ) ) ) { // $lesson_post = get_post( $lesson_id ); // if ( ( is_a( $lesson_post, 'WP_Post' ) ) && ( $lesson_post->post_type === learndash_get_post_type_slug( 'lesson' ) ) ) { // return learndash_next_post_link( $prevlink, $url, $lesson_post ); // } // } } else { return $prevlink; } } /** * Don't show previous/next link in certain situations * * @since 2.1.0 * * @param string $prevlink * @return string */ function learndash_clear_prev_next_links( $prevlink='' ){ global $post; if ( ! is_singular() || empty( $post->post_type) || ( $post->post_type != 'sfwd-lessons' && $post->post_type != 'sfwd-quiz' && $post->post_type != 'sfwd-courses' && $post->post_type != 'sfwd-topic' && $post->post_type != 'sfwd-assignment') ) { return $prevlink; } else { return ''; } } add_filter( 'previous_post_link', 'learndash_clear_prev_next_links', 1, 2 ); add_filter( 'next_post_link', 'learndash_clear_prev_next_links', 1, 2 ); /** * Output quiz continue link * * @since x.x. * * @param int $id quiz id * @return string output of link */ function learndash_quiz_continue_link( $id ) { global $status, $pageQuizzes; $course_id = learndash_get_course_id( $id ); if ( ( !empty( $course_id ) ) && ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) ) { $lesson_id = learndash_course_get_single_parent_step( $course_id, $id ); if ( empty( $lesson_id ) ) { $url = get_permalink( $course_id ); $url = add_query_arg( array( 'quiz_type' => 'global', 'quiz_redirect' => 1, 'course_id' => $course_id, 'quiz_id' => $id ), $url ); } else { $url = get_permalink( $lesson_id ); $url = add_query_arg( array( 'quiz_type' => 'lesson', 'quiz_redirect' => 1, 'lesson_id' => $lesson_id, 'quiz_id' => $id ), $url ); } if ( ( isset( $url ) ) && ( !empty( $url ) ) ) { $returnLink = '<a id="quiz_continue_link" href="'. $url .'">' . esc_html( LearnDash_Custom_Label::get_label( 'button_click_here_to_continue' ) ) . '</a>'; } } else { $quizmeta = get_post_meta( $id, '_sfwd-quiz' , true ); if ( ! empty( $quizmeta['sfwd-quiz_lesson'] ) ) { $return_id = $quiz_lesson = $quizmeta['sfwd-quiz_lesson']; } if ( empty( $quiz_lesson) ) { $return_id = $course_id = learndash_get_course_id( $id ); $url = get_permalink( $return_id ); $url .= strpos( 'a'.$url, '?' )? '&':'?'; $url .= 'quiz_type=global&quiz_redirect=1&course_id='.$course_id.'&quiz_id='.$id; $returnLink = '<a id="quiz_continue_link" href="'.$url.'">' . esc_html( LearnDash_Custom_Label::get_label( 'button_click_here_to_continue' ) ) . '</a>'; } else { $url = get_permalink( $return_id ); $url .= strpos( 'a'.$url, '?' )? '&':'?'; $url .= 'quiz_type=lesson&quiz_redirect=1&lesson_id='.$return_id.'&quiz_id='.$id; $returnLink = '<a id="quiz_continue_link" href="'.$url.'">' . esc_html( LearnDash_Custom_Label::get_label( 'button_click_here_to_continue' ) ) . '</a>'; } } // Why are we checking the WordPress version? Shouldn't this be checking the LD version?? $version = get_bloginfo( 'version' ); if ( $version >= '1.5.1' ) { /** * Filter output of quiz continue link * * @since 2.1.0 * * @param string $returnLink */ return apply_filters( 'learndash_quiz_continue_link', $returnLink, $url ); } else { /** * Filter output of quiz continue link * * @since 2.1.0 * * @param string $returnLink */ return apply_filters( 'learndash_quiz_continue_link', $returnLink ); } } function learndash_quiz_continue_link_OLD( $id ) { global $status, $pageQuizzes; $quizmeta = get_post_meta( $id, '_sfwd-quiz' , true ); if ( ! empty( $quizmeta['sfwd-quiz_lesson'] ) ) { $return_id = $quiz_lesson = $quizmeta['sfwd-quiz_lesson']; } if ( empty( $quiz_lesson) ) { $return_id = $course_id = learndash_get_course_id( $id ); $url = get_permalink( $return_id ); $url .= strpos( 'a'.$url, '?' )? '&':'?'; $url .= 'quiz_type=global&quiz_redirect=1&course_id='.$course_id.'&quiz_id='.$id; $returnLink = '<a id="quiz_continue_link" href="'.$url.'">' . esc_html( LearnDash_Custom_Label::get_label( 'button_click_here_to_continue' ) ) . '</a>'; } else { $url = get_permalink( $return_id ); $url .= strpos( 'a'.$url, '?' )? '&':'?'; $url .= 'quiz_type=lesson&quiz_redirect=1&lesson_id='.$return_id.'&quiz_id='.$id; $returnLink = '<a id="quiz_continue_link" href="'.$url.'">' . esc_html( LearnDash_Custom_Label::get_label( 'button_click_here_to_continue' ) ) . '</a>'; } // Why are we checking the WordPress version? Shouldn't this be checking the LD version?? $version = get_bloginfo( 'version' ); if ( $version >= '1.5.1' ) { /** * Filter output of quiz continue link * * @since 2.1.0 * * @param string $returnLink */ return apply_filters( 'learndash_quiz_continue_link', $returnLink, $url ); } else { /** * Filter output of quiz continue link * * @since 2.1.0 * * @param string $returnLink */ return apply_filters( 'learndash_quiz_continue_link', $returnLink ); } } /** * Output LearnDash topic dots * Indicates name of topic and whether it's been completed * * @since 2.1.0 * * @param int $lesson_id * @param boolean $show_text * @param string $type dots|list * @param int $user_id * @return string output */ function learndash_topic_dots( $lesson_id, $show_text = false, $type = 'dots', $user_id = null, $course_id = null ) { if ( empty( $lesson_id ) ) { return ''; } $topics = learndash_get_topic_list( $lesson_id, $course_id ); if ( empty( $topics[0]->ID ) ) { return ''; } $topics_progress = learndash_get_course_progress( $user_id, $topics[0]->ID, $course_id ); if ( ! empty( $topics_progress['posts'][0] ) ) { $topics = $topics_progress['posts']; } if ( $type == 'array' ) { return $topics; } $html = "<div id='learndash_topic_dots-".$lesson_id. "' class='learndash_topic_dots type-".$type."'>"; if ( ! empty( $show_text) ) { $html .= '<strong>'.$show_text.'</strong>'; } switch ( $type ) { case 'list': $html .= '<ul>'; $sn = 0; foreach ( $topics as $topic ) { $sn++; if ( $topic->completed ) { $completed = 'topic-completed'; } else { $completed = 'topic-notcompleted'; } /** * Filter output of list topic dots * * @since 2.1.0 * * @param string */ $html .= apply_filters( 'learndash_topic_dots_item', "<li><a class='".$completed."' href='".get_permalink( $topic->ID )."' title='".$topic->post_title."'><span>".$topic->post_title.'</span></a></li>', $topic, $completed, $type, $sn ); } $html .= '</ul>'; break; case 'dots': default: $sn = 0; foreach ( $topics as $topic ) { $sn++; if ( $topic->completed ) { $completed = 'topic-completed'; } else { $completed = 'topic-notcompleted'; } /** * Filter output of topic dots * * @since 2.1.0 * * @param string */ $html .= apply_filters( 'learndash_topic_dots_item', '<a class="'.$completed.'" href="'.get_permalink( $topic->ID ).'"><SPAN TITLE="'.$topic->post_title.'"></SPAN></a>', $topic, $completed, $type, $sn ); } break; } $html .= '</div>'; return $html; } /** * Get lesson list for course * * @since 2.1.0 * * @param int $id id of resource * @return array list of lessons */ function learndash_get_lesson_list( $id = null, $atts = array() ) { global $post; if ( empty( $id ) ) { if ( $post instanceof WP_Post ) { $id = $post->ID; } } $course_id = learndash_get_course_id( $id ); if ( empty( $course_id ) ) { return array(); } global $wpdb; $lessons = sfwd_lms_get_post_options( 'sfwd-lessons' ); //$course_options = get_post_meta( $course_id, '_sfwd-courses', true ); //$course_orderby = @$course_options['sfwd-courses_course_lesson_orderby']; //$course_order = @$course_options['sfwd-courses_course_lesson_order']; //$orderby = ( empty( $course_orderby) ) ? $lessons['orderby'] : $course_orderby; //$order = ( empty( $course_order) ) ? $lessons['order'] : $course_order; $course_lessons_args = learndash_get_course_lessons_order( $course_id ); $orderby = ( isset( $course_lessons_args[ 'orderby' ] ) ) ? $course_lessons_args[ 'orderby' ] : 'title'; $order = ( isset( $course_lessons_args[ 'order' ] ) ) ? $course_lessons_args[ 'order' ] : 'ASC'; switch ( $orderby ) { case 'title': $orderby = 'title'; break; case 'date': $orderby = 'date'; break; } $lessons_args = array( 'array' => true, 'course_id' => $course_id, 'post_type' => 'sfwd-lessons', 'meta_key' => 'course_id', 'meta_value' => $course_id, 'orderby' => $orderby, 'order' => $order, ); $lessons_args = array_merge( $lessons_args, $atts ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); $ld_course_steps_object->load_steps(); $course_steps = $ld_course_steps_object->get_steps('t'); if ( ( isset( $course_steps[$lessons_args['post_type']] ) ) && ( !empty( $course_steps[$lessons_args['post_type']] ) ) ) { $lessons_args['post__in'] = $course_steps[$lessons_args['post_type']]; $lessons_args['orderby'] = 'post__in'; unset($lessons_args['order']); unset($lessons_args['meta_key']); unset($lessons_args['meta_value']); } else { return array(); } } /** * Filter for lessons list args * * @since 2.5.7 */ $lessons_args = apply_filters( 'learndash_get_lesson_list_args', $lessons_args, $id, $course_id ); if ( !empty( $lessons_args ) ) { return ld_lesson_list( $lessons_args ); } } /** * Get topics list for a lesson * * @since 2.1.0 * * @param int $for_lesson_id * @return array topics list */ function learndash_get_topic_list( $for_lesson_id = null, $course_id = null ) { if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $for_lesson_id ); } if ( ( ! empty( $for_lesson_id ) ) && ( ! empty( $course_id ) ) ) { $transient_key = 'learndash_lesson_topics_' . $course_id . '_' . $for_lesson_id; } elseif ( ! empty( $for_lesson_id ) ) { $transient_key = 'learndash_lesson_topics_' . $for_lesson_id; } else { $transient_key = 'learndash_lesson_topics_all'; } $topics_array = LDLMS_Transients::get( $transient_key ); if ( false === $topics_array ) { if ( ! empty( $for_lesson_id ) ) { $lessons_options = sfwd_lms_get_post_options( 'sfwd-lessons' ); $orderby = $lessons_options['orderby']; $order = $lessons_options['order']; if ( ! empty( $course_id ) ) { $course_lessons_args = learndash_get_course_lessons_order( $course_id ); $orderby = isset( $course_lessons_args['orderby'] ) ? $course_lessons_args['orderby'] : 'title'; $order = isset( $course_lessons_args['order'] ) ? $course_lessons_args['order'] : 'ASC'; } } else { $orderby = 'name'; $order = 'ASC'; } $topics_query_args = array( 'post_type' => 'sfwd-topic', 'numberposts' => -1, 'orderby' => $orderby, 'order' => $order, ); if ( ! empty( $for_lesson_id ) ) { $topics_query_args['meta_key'] = 'lesson_id'; $topics_query_args['meta_value'] = $for_lesson_id; $topics_query_args['meta_compare'] = '='; } if ( 'yes' === LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) ) { if ( ! empty( $course_id ) ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); $ld_course_steps_object->load_steps(); $steps = $ld_course_steps_object->get_steps(); if ( ( isset( $steps['sfwd-lessons'][ $for_lesson_id ]['sfwd-topic'] ) ) && ( ! empty( $steps['sfwd-lessons'][ $for_lesson_id ]['sfwd-topic'] ) ) ) { $topic_ids = array_keys( $steps['sfwd-lessons'][ $for_lesson_id ]['sfwd-topic'] ); $topics_query_args['include'] = $topic_ids; $topics_query_args['orderby'] = 'post__in'; unset( $topics_query_args['order'] ); unset( $topics_query_args['meta_key'] ); unset( $topics_query_args['meta_value'] ); unset( $topics_query_args['meta_compare'] ); } else { return array(); } } } $topics = get_posts( $topics_query_args ); if ( ! empty( $topics ) ) { if ( empty( $for_lesson_id ) ) { $topics_array = array(); foreach ( $topics as $topic ) { if ( 'yes' === LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) ) { $course_id = learndash_get_course_id( $topic->ID ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $topic->ID ); } else { $lesson_id = learndash_get_setting( $topic, 'lesson' ); } if ( ! empty( $lesson_id ) ) { // Need to clear out the post_content before transient storage. $topic->post_content = 'EMPTY'; $topics_array[ $lesson_id ][] = $topic; } } LDLMS_Transients::set( $transient_key, $topics_array, MINUTE_IN_SECONDS ); return $topics_array; } else { LDLMS_Transients::set( $transient_key, $topics, MINUTE_IN_SECONDS ); return $topics; } } } else { return $topics_array; } } /** * Get quiz list for resource * * @since 2.1.0 * * @param int $id id of resource (topic, lesson, etc) * @return array list of quizzes */ function learndash_get_global_quiz_list( $id = null ){ global $post; if ( empty( $id ) ) { if ( ! empty( $post->ID ) ) { $id = $post->ID; } else { return array(); } } //COURSEIDCHANGE $course_id = learndash_get_course_id( $id ); if (!empty($course_id)) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $quiz_ids = learndash_course_get_children_of_step( $course_id, $course_id, 'sfwd-quiz' ); if ( !empty( $quiz_ids ) ) { return get_posts( array( 'post_type' => 'sfwd-quiz', 'posts_per_page' => -1, 'include' => $quiz_ids, 'orderby' => 'post__in', 'order' => 'ASC' )); } } else { $transient_key = "learndash_quiz_course_". $course_id; $quizzes_new = LDLMS_Transients::get( $transient_key ); if ( $quizzes_new === false ) { $course_settings = learndash_get_setting( $course_id ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $orderby = ( empty( $course_settings['course_lesson_orderby'] ) ) ? @$lessons_options['orderby'] : $course_settings['course_lesson_orderby']; $order = ( empty( $course_settings['course_lesson_order'] ) ) ? @$lessons_options['order'] : $course_settings['course_lesson_order']; $quizzes = get_posts( array( 'post_type' => 'sfwd-quiz', 'posts_per_page' => -1, 'meta_key' => 'course_id', 'meta_value' => $course_id, 'meta_compare' => '=', 'orderby' => $orderby, 'order' => $order )); $quizzes_new = array(); foreach ( $quizzes as $k => $quiz ) { $quiz_lesson = learndash_get_setting( $quiz, 'lesson' ); if ( empty( $quiz_lesson) ) { $quizzes_new[] = $quizzes[ $k ]; } } LDLMS_Transients::set( $transient_key, $quizzes_new, MINUTE_IN_SECONDS ); } return $quizzes_new; } } } function learndash_get_global_quiz_list_OLD( $id = null ){ global $post; if ( empty( $id ) ) { if ( ! empty( $post->ID ) ) { $id = $post->ID; } else { return array(); } } //COURSEIDCHANGE $course_id = learndash_get_course_id( $id ); if (!empty($course_id)) { $transient_key = "learndash_quiz_course_". $course_id; $quizzes_new = LDLMS_Transients::get( $transient_key ); if ( $quizzes_new === false ) { $course_settings = learndash_get_setting( $course_id ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $orderby = ( empty( $course_settings['course_lesson_orderby'] ) ) ? @$lessons_options['orderby'] : $course_settings['course_lesson_orderby']; $order = ( empty( $course_settings['course_lesson_order'] ) ) ? @$lessons_options['order'] : $course_settings['course_lesson_order']; $quizzes = get_posts( array( 'post_type' => 'sfwd-quiz', 'posts_per_page' => -1, 'meta_key' => 'course_id', 'meta_value' => $course_id, 'meta_compare' => '=', 'orderby' => $orderby, 'order' => $order )); $quizzes_new = array(); foreach ( $quizzes as $k => $quiz ) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $quiz->ID ); $quiz_lesson = learndash_course_get_single_parent_step( $course_id, $quiz->ID ); } else { $quiz_lesson = learndash_get_setting( $quiz, 'lesson' ); } if ( empty( $quiz_lesson) ) { $quizzes_new[] = $quizzes[ $k ]; } } LDLMS_Transients::set( $transient_key, $quizzes_new, MINUTE_IN_SECONDS ); } return $quizzes_new; } } /** * Get lesson list output for course * * @since 2.1.0 * * @param int|obj $course course id or course WP_Post * @return string html output of lesson list for course */ /** * Get lesson list output for course * * @since 2.1.0 * * @param int|obj $course course id or course WP_Post * @return string html output of lesson list for course */ function learndash_get_course_lessons_list( $course = null, $user_id = null, $lessons_args = array() ) { if ( empty( $course ) ) { $course_id = learndash_get_course_id(); } if ( is_numeric( $course ) ) { $course_id = $course; $course = get_post( $course_id ); } if ( empty( $course->ID ) ) { return array(); } $course_settings = learndash_get_setting( $course ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $orderby = ( empty( $course_settings['course_lesson_orderby'] ) ) ? @$lessons_options['orderby'] : $course_settings['course_lesson_orderby']; $order = ( empty( $course_settings['course_lesson_order'] ) ) ? @$lessons_options['order'] : $course_settings['course_lesson_order']; $lesson_query_pagination = 'true'; if ( ( isset( $lessons_args['num'] ) ) && ( $lessons_args['num'] !== false ) ) { if ( intval( $lessons_args['num'] ) == 0 ) { $lesson_query_pagination = ''; $posts_per_page = -1; } else { $posts_per_page = intval( $lessons_args['num'] ); } } else { $posts_per_page = learndash_get_course_lessons_per_page( $course->ID ); if ( empty( $posts_per_page ) ) { $posts_per_page = -1; $lesson_query_pagination = ''; } } $lesson_paged = 1; if ( isset( $lessons_args['paged'] ) ) { $lesson_paged = intval( $lessons_args['paged'] ); } else if ( isset( $_GET['ld-lesson-page'] ) ) { $lesson_paged = intval( $_GET['ld-lesson-page'] ); } if ( empty( $lesson_paged ) ) { $lesson_paged = 1; } $opt = array( 'post_type' => 'sfwd-lessons', 'meta_key' => 'course_id', 'meta_value' => $course->ID, 'order' => $order, 'orderby' => $orderby, 'posts_per_page' => $posts_per_page, 'paged' => $lesson_paged, 'pagination' => $lesson_query_pagination, 'pager_context' => 'course_lessons', 'return' => 'array', 'user_id' => $user_id, 'course_id' => $course->ID, ); $opt = wp_parse_args( $lessons_args, $opt ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course->ID ); $lesson_ids = $ld_course_steps_object->get_children_steps( $course->ID, $opt['post_type'] ); //error_log('lesson_ids<pre>'. print_r($lesson_ids, true) .'</pre>'); if ( !empty( $lesson_ids ) ) { $opt['include'] = implode( ",", $lesson_ids ); $opt['orderby'] = 'post__in'; $opt['course_id'] = $course->ID; unset($opt['order']); unset($opt['meta_key']); unset($opt['meta_value']); } else { return array(); } } $lessons = SFWD_CPT::loop_shortcode( $opt ); return $lessons; } /** * Get quiz list output for course * * @since 2.1.0 * * @param int|obj $course course id or course WP_Post * @return string html output of quiz list for course */ function learndash_get_course_quiz_list( $course = null, $user_id = null ) { if ( empty( $course ) ) { $course_id = learndash_get_course_id(); $course = get_post( $course_id ); } if ( is_numeric( $course ) ) { $course_id = $course; $course = get_post( $course_id ); } if ( empty( $course->ID ) ) { return array(); } $course_settings = learndash_get_setting( $course ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $orderby = ( empty( $course_settings['course_lesson_orderby'] ) ) ? @$lessons_options['orderby'] : $course_settings['course_lesson_orderby']; $order = ( empty( $course_settings['course_lesson_order'] ) ) ? @$lessons_options['order'] : $course_settings['course_lesson_order']; $opt = array( 'post_type' => 'sfwd-quiz', 'meta_key' => 'course_id', 'meta_value' => $course->ID, 'order' => $order, 'orderby' => $orderby, //'posts_per_page' => empty( $lessons_options['posts_per_page'] ) ? -1 : $lessons_options['posts_per_page'], 'posts_per_page' => -1, 'user_id' => $user_id, 'return' => 'array', 'user_id' => $user_id ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course->ID ); $lesson_ids = $ld_course_steps_object->get_children_steps( $course->ID, $opt['post_type'] ); //error_log('lesson_ids<pre>'. print_r($lesson_ids, true) .'</pre>'); if ( !empty( $lesson_ids ) ) { $opt['include'] = implode( ",", $lesson_ids ); $opt['orderby'] = 'post__in'; $opt['course_id'] = $course->ID; unset($opt['order']); unset($opt['meta_key']); unset($opt['meta_value']); } else { return array(); } } $quizzes = SFWD_CPT::loop_shortcode( $opt ); return $quizzes; } /** * Get lesson list output for quiz * * @since 2.1.0 * * @param int|obj $quiz quiz id or quiz WP_Post * @return string html output of lesson list for quiz */ function learndash_get_lesson_quiz_list( $lesson, $user_id = null, $course_id = null ) { if ( is_numeric( $lesson ) ) { $lesson_id = $lesson; $lesson = get_post( $lesson_id ); } if ( empty( $lesson->ID ) ) { return array(); } if (empty( $course_id )) $course_id = learndash_get_course_id( $lesson ); $course_settings = learndash_get_setting( $course_id ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $orderby = ( empty( $course_settings['course_lesson_orderby'] ) ) ? @$lessons_options['orderby'] : $course_settings['course_lesson_orderby']; $order = ( empty( $course_settings['course_lesson_order'] ) ) ? @$lessons_options['order'] : $course_settings['course_lesson_order']; $opt = array( 'post_type' => 'sfwd-quiz', 'meta_key' => 'lesson_id', 'meta_value' => $lesson->ID, 'order' => $order, 'orderby' => $orderby, //'posts_per_page' => empty( $lessons_options['posts_per_page'] ) ? -1 : $lessons_options['posts_per_page'], 'posts_per_page' => -1, 'user_id' => $user_id, 'return' => 'array', 'user_id' => $user_id, 'course_id' => $course_id ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); if ( $ld_course_steps_object ) { $quiz_ids = $ld_course_steps_object->get_children_steps( $lesson->ID, $opt['post_type'] ); if ( !empty( $quiz_ids ) ) { $opt['include'] = implode( ",", $quiz_ids ); $opt['orderby'] = 'post__in'; //$opt['course_id'] = $course_id; unset($opt['order']); unset($opt['meta_key']); unset($opt['meta_value']); } else { return array(); } } } $quizzes = SFWD_CPT::loop_shortcode( $opt ); return $quizzes; } ld-course-list-shortcode.php 0000666 00000161356 15214044143 0012131 0 ustar 00 <?php /** * Shortcodes and helper functions for listing * courses, lessons, quizzes, and topics * * @since 2.1.0 * * @package LearnDash\Shortcodes */ /** * Shortcode to list courses * * @since 2.1.0 * * @param array $attr shortcode attributes * @return string shortcode output */ function ld_course_list( $attr ) { global $learndash_shortcode_used; $attr_defaults = apply_filters( 'ld_course_list_shortcode_attr_defaults', array( 'include_outer_wrapper' => 'true', 'num' => false, 'paged' => 1, 'post_type' => learndash_get_post_type_slug( 'course' ), 'post_status' => 'publish', 'order' => 'DESC', 'orderby' => 'ID', 'user_id' => false, 'mycourses' => null, 'status' => null, 'post__in' => null, 'course_id' => '', // Not sure why these are here as there is not supported logic. // 'lesson_id' => '', // 'topic_id' => '', 'meta_key' => '', 'meta_value' => '', 'meta_compare' => '', 'tag' => '', 'tag_id' => 0, 'tag__and' => '', 'tag__in' => '', 'tag__not_in' => '', 'tag_slug__and' => '', 'tag_slug__in' => '', 'cat' => '', 'category_name' => 0, 'category__and' => '', 'category__in' => '', 'category__not_in' => '', 'tax_compare' => 'AND', 'categoryselector' => '', 'show_thumbnail' => 'true', 'show_content' => 'true', 'author__in' => '', 'col' => '', 'progress_bar' => 'false', 'array' => false, 'course_grid' => 'true', ), $attr ); $post_type_slug = 'course'; $post_type_Class = 'LearnDash_Settings_Courses_Taxonomies'; if ( ( isset( $attr['post_type'] ) ) && ( !empty( $attr['post_type'] ) ) ) { if ( $attr['post_type'] == learndash_get_post_type_slug( 'lesson' ) ) { $post_type_slug = 'lesson'; $post_type_Class = 'LearnDash_Settings_Lessons_Taxonomies'; } elseif ( $attr['post_type'] == learndash_get_post_type_slug( 'topic' ) ) { $post_type_slug = 'topic'; $post_type_Class = 'LearnDash_Settings_Topics_Taxonomies'; } elseif ( $attr['post_type'] == learndash_get_post_type_slug( 'quiz' ) ) { $post_type_slug = 'quiz'; $post_type_Class = 'LearnDash_Settings_Quizzes_Taxonomies'; } } if ( !empty( $post_type_slug ) ) { $attr_defaults = array_merge( $attr_defaults, array( $post_type_slug . '_categoryselector' => '', $post_type_slug . '_cat' => '', $post_type_slug . '_category_name' => '', $post_type_slug . '_category__and' => '', $post_type_slug . '_category__in' => '', $post_type_slug . '_category__not_in' => '', $post_type_slug . '_tag' => '', $post_type_slug . '_tag_id' => '', $post_type_slug . '_tag__and' => '', $post_type_slug . '_tag__in' => '', $post_type_slug . '_tag__not_in' => '', $post_type_slug . '_tag_slug__and' => '', $post_type_slug . '_tag_slug__in' => '', ) ); } $atts = shortcode_atts( $attr_defaults, $attr ); if ( ( $atts['mycourses'] == 'true' ) || ( $atts['mycourses'] == 'enrolled' ) ) { if ( is_user_logged_in() ) { $atts['mycourses'] = 'enrolled'; } else { return ''; } } else if ( $atts['mycourses'] == 'not-enrolled' ) { if ( is_user_logged_in() ) { $atts['mycourses'] = 'not-enrolled'; } else { return ''; } } else { $atts['mycourses'] = null; } $atts['course_status'] = array(); if ( 'enrolled' === $atts['mycourses'] ) { if ( ! empty( $atts['status'] ) ) { if ( ! is_array( $atts['status'] ) ) { $atts['status'] = explode(',', $atts['status'] ); } $atts['status'] = array_map( 'trim', $atts['status'] ); foreach( $atts['status'] as $course_status ) { if ( 'completed' == $course_status ) { $atts['course_status'][] = 'COMPLETED'; } else if ( 'in_progress' == $course_status ) { $atts['course_status'][] = 'IN_PROGRESS'; } else if ( 'not_started' == $course_status ) { $atts['course_status'][] = 'NOT_STARTED'; } } } } else { $atts['course_status'] = null; } unset( $atts['status'] ); if ( $atts['post__in'] === '' ) $atts['post__in'] = null; //if ( isset( $atts['num'] ) ) // $atts['num'] = intval( $atts['num'] ); if ( $atts['num'] === false ) { if ( ( isset( $atts['course_id'] ) ) && ( !empty( $atts['course_id'] ) ) ) { $atts['num'] = learndash_get_course_lessons_per_page( intval( $atts['course_id'] ) ); } else { $atts['num'] = LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'per_page' ); } } else if ( $atts['num'] == '-1' ) { $atts['num'] = 0; } else { $atts['num'] = intval( $atts['num'] ); } if ( $atts['num'] == 0 ) { $atts['num'] = -1; } $atts = apply_filters( 'ld_course_list_shortcode_attr_values', $atts, $attr ); if ( is_user_logged_in() ) { if ( ( isset( $atts['user_id'] ) ) && ( $atts['user_id'] === false ) ) { $atts['user_id'] = get_current_user_id(); } else if ( ( isset( $atts['user_id'] ) ) && ( $atts['user_id'] !== false ) ) { if ( learndash_is_admin_user() ) { // Good leave the user_id in place. } else if ( learndash_is_group_leader_user( get_current_user_id() ) ) { $groups = learndash_get_administrators_group_ids( get_current_user_id() ); if ( !empty( $groups ) ) { $user_courses = array(); foreach ( $groups as $group_id ) { if ( learndash_is_user_in_group( $atts['user_id'], $group_id ) ) { $group_courses = learndash_group_enrolled_courses( $group_id ); if ( !empty( $group_courses ) ) { $user_courses = array_merge( $user_courses, $group_courses ); } } } if ( !empty( $user_courses ) ) { $atts['post__in'] = $user_courses; } } else { $atts['user_id'] = get_current_user_id(); } } else { $atts['user_id'] = get_current_user_id(); } } } else { $atts['user_id'] = false; $atts['mycourses'] = null; } extract( $atts ); global $post; $filter = array( 'post_type' => $post_type, 'post_status' => $post_status, 'posts_per_page' => $num, 'paged' => $paged, 'order' => $order, 'orderby' => $orderby ); $meta_query = array(); // Added an empty meta query set. Then we check later and if still empty we remove it before calling get_posts. if ( !isset( $filter['meta_query'] ) ) $filter['meta_query'] = array(); if ( ! empty( $author__in ) ) { $filter['author__in'] = $author__in; } /* if ( ! empty( $meta_key ) ) { $filter['meta_key'] = $meta_key; } if ( ! empty( $meta_value ) ) { $filter['meta_value'] = $meta_value; } if ( ! empty( $meta_compare ) ) { if ( !empty( $filter['meta_key'] ) ) { $filter['meta_compare'] = $meta_compare; } } */ if ( ( ! empty( $meta_key ) ) && ( ! empty( $meta_value ) ) ) { //if ( $meta_key == 'course_id' ) { // if ( empty( $course_id ) ) { // $course_id = $meta_value; // $atts['course_id'] = $meta_value; // } //} else { $meta_query = array( 'key' => $meta_key, 'value' => $meta_value ); if ( empty( $meta_compare ) ) $meta_compare = '='; $meta_query['compare'] = $meta_compare; $filter['meta_query'][] = $meta_query; //} } if ( ( !empty( $course_id ) ) && ( is_null( $post__in ) ) ) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $filter['post__in'] = learndash_course_get_steps_by_type( $course_id, $atts['post_type']); } else { $meta_query = array( 'key' => 'course_id', 'value' => intval( $course_id ), 'compare' => '=', ); } $filter['meta_query'][] = $meta_query; } else if ( ! empty( $post__in ) ) { $filter['post__in'] = $post__in; } if ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'wp_post_category' ) == 'yes') { if ( ! empty( $cat ) ) { //$filter['cat'] = $cat; if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => intval( $cat ) ); } if ( ! empty( $category_name ) ) { //$filter['category_name'] = $category_name; if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => trim( $category_name ) ); } if ( ! empty( $category__and ) ) { //$filter['category__and'] = explode( ',', $category__and ); $category__and = array_map('intval', explode( ',', $category__and ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $category__and, 'operator' => 'AND' ); } if ( ! empty( $category__in ) ) { //$filter['category__in'] = explode( ',', $category__in ); $category__in = array_map('intval', explode( ',', $category__in ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $category__in, 'operator' => 'IN' ); } if ( ! empty( $category__not_in ) ) { //$filter['category__not_in'] = explode( ',', $category__not_in ); $category__not_in = array_map('intval', explode( ',', $category__not_in ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => $category__not_in, 'operator' => 'NOT IN' ); } } if ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'wp_post_tag' ) == 'yes') { if ( ! empty( $tag ) ) { //$filter['tag'] = $tag; if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'slug', 'terms' => trim( $tag ) ); } if ( ! empty( $tag_id ) ) { //$filter['tag_id'] = $tag; if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'term_id', 'terms' => intval( $tag_id ), ); } if ( ! empty( $tag__and ) ) { //$filter['tag__and'] = explode( ',', $tag__and ); $tag__and = array_map('intval', explode( ',', $tag__and ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'term_id', 'terms' => $tag__and, 'operator' => 'AND' ); } if ( ! empty( $tag__in ) ) { //$filter['tag__in'] = explode( ',', $tag__in ); $tag__in = array_map('intval', explode( ',', $tag__in ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'term_id', 'terms' => $tag__in, 'operator' => 'IN' ); } if ( ! empty( $tag__not_in ) ) { //$filter['tag__not_in'] = explode( ',', $tag__not_in ); $tag__not_in = array_map('intval', explode( ',', $tag__not_in ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'term_id', 'terms' => $tag__not_in, 'operator' => 'NOT IN' ); } if ( ! empty( $tag_slug__and ) ) { //$filter['tag_slug__and'] = explode( ',', $tag_slug__and ); $tag_slug__and = array_map('trim', explode( ',', $tag_slug__and ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'slug', 'terms' => $tag_slug__and, 'operator' => 'AND' ); } if ( ! empty( $tag_slug__in ) ) { //$filter['tag_slug__in'] = explode( ',', $tag_slug__in ); $tag_slug__in = array_map('trim', explode( ',', $tag_slug__in ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'post_tag', 'field' => 'slug', 'terms' => $tag_slug__in, 'operator' => 'IN' ); } } if ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'ld_'. $post_type_slug .'_category' ) == 'yes') { // course_cat="123" if ( ( isset( $atts[$post_type_slug .'_cat'] ) ) && ( ! empty( $atts[$post_type_slug .'_cat'] ) ) ) { if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'term_id', 'terms' => intval( $atts[$post_type_slug .'_cat'] ) ); } // course_category_name (string) - use category slug. // course_category_name="course-category-one" if ( ( isset( $atts[$post_type_slug .'_category_name'] ) ) && ( ! empty( $atts[$post_type_slug .'_category_name'] ) ) ) { if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'slug', 'terms' => trim( $atts[$post_type_slug .'_category_name'] ) ); } // course_category__and (array) - use category id. if ( ( isset( $atts[$post_type_slug .'_category__and'] ) ) && ( ! empty( $atts[$post_type_slug .'_category__and'] ) ) ) { $cat__and = array_map('intval', explode( ',', $atts[$post_type_slug .'_category__and'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'term_id', 'terms' => $cat__and, 'operator' => 'AND', 'include_children' => false, ); } // course_category__in (array) - use category id. if ( ( isset( $atts[$post_type_slug .'_category__in'] ) ) && ( ! empty( $atts[$post_type_slug .'_category__in'] ) ) ) { $cat__in = array_map('intval', explode( ',', $atts[$post_type_slug .'_category__in'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'term_id', 'terms' => $cat__in, 'operator' => 'IN', 'include_children' => false, ); } // course_category___not_in (array) - use category id. if ( ( isset( $atts[$post_type_slug .'_category__not_in'] ) ) && ( ! empty( $atts[$post_type_slug .'_category__not_in'] ) ) ) { $cat__not_in = array_map('intval', explode( ',', $atts[$post_type_slug .'_category__not_in'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'term_id', 'terms' => $cat__not_in, 'operator' => 'NOT IN', 'include_children' => false, ); } } if ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'ld_'. $post_type_slug .'_tag' ) == 'yes') { // course_tag (string) - use tag slug. if ( ( isset( $atts[$post_type_slug .'_tag'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag'] ) ) ) { if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'slug', 'terms' => trim( $atts[$post_type_slug .'_tag'] ) ); } // course_tag_id (int) - use tag id. if ( ( isset( $atts[$post_type_slug .'_tag_id'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag_id'] ) ) ) { if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'term_id', 'terms' => intval( $atts[$post_type_slug .'_tag_id'] ) ); } // course_tag__and (array) - use tag ids. if ( ( isset( $atts[$post_type_slug .'_tag__and'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag__and'] ) ) ) { $tag__and = array_map('intval', explode( ',', $atts[$post_type_slug .'_tag__and'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'term_id', 'terms' => $tag__and, 'operator' => 'AND' ); } // course_tag__in (array) - use tag ids. if ( ( isset( $atts[$post_type_slug .'_tag__in'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag__in'] ) ) ) { $tag__in = array_map('intval', explode( ',', $atts[$post_type_slug .'_tag__in'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'term_id', 'terms' => $tag__in, 'operator' => 'IN' ); } // course_tag__not_in (array) - use tag ids. if ( ( isset( $atts[$post_type_slug .'_tag__not_in'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag__not_in'] ) ) ) { $tag__not_in = array_map('intval', explode( ',', $atts[$post_type_slug .'_tag__not_in'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'term_id', 'terms' => $tag__not_in, 'operator' => 'NOT IN' ); } // course_tag_slug__and (array) - use tag slugs. if ( ( isset( $atts[$post_type_slug .'_tag_slug__and'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag_slug__and'] ) ) ) { $tag_slug__and = array_map('trim', explode( ',', $atts[$post_type_slug .'_tag_slug__and'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_tag', 'field' => 'slug', 'terms' => $tag_slug__and, 'operator' => 'AND' ); } // course_tag_slug__in (array) - use tag slugs. if ( ( isset( $atts[$post_type_slug .'_tag_slug__in'] ) ) && ( ! empty( $atts[$post_type_slug .'_tag_slug__in'] ) ) ) { $tag_slug__in = array_map('trim', explode( ',', $atts[$post_type_slug .'_tag_slug__in'] ) ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug.'_tag', 'field' => 'slug', 'terms' => $tag_slug__in, 'operator' => 'IN' ); } } if ( ( isset( $filter['tax_query'] ) ) && ( count( $filter['tax_query'] ) > 1 ) ) { // Due to a quick on WP_Query the 'compare' option needs to be in the first position. // So we save off the current tax_query, add the 'relation', then merge in the original tax_query $tax_query = $filter['tax_query']; $filter['tax_query'] = array( 'relation' => $tax_compare ); $filter['tax_query'] = array_merge( $filter['tax_query'], $tax_query ); } else if ( ! empty( $meta_compare ) ) { $filter['meta_compare'] = $meta_compare; } // Logic to determine the exact post ids to query. This will help drive the category selectors below and prevent extra queries. $shortcode_course_id = null; if ( is_null( $post__in ) ) { if ( $mycourses == 'enrolled' ) { $filter['post__in'] = learndash_user_get_enrolled_courses( $atts['user_id'] ); if ( empty( $filter['post__in'] ) ) return; if ( ! empty( $course_status ) ) { $activity_query_args = array( 'post_types' => 'sfwd-courses', 'activity_types' => 'course', 'activity_status' => $course_status, 'orderby_order' => 'users.ID, posts.post_title', 'date_format' => 'F j, Y H:i:s', 'per_page' => '' ); $activity_query_args['user_ids'] = array( $atts['user_id'] ); $activity_query_args['post_ids'] = $filter['post__in']; $user_courses_reports = learndash_reports_get_activity( $activity_query_args ); if ( !empty( $user_courses_reports['results'] ) ) { //foreach( $user_courses_reports['results'] as $result ) { $filter['post__in'] = wp_list_pluck( $user_courses_reports['results'], 'post_id' ); $filter['post__in'] = array_map( 'absint', $filter['post__in'] ); } } } else if ( $mycourses == 'not-enrolled' ) { $filter['post__not_in'] = learndash_user_get_enrolled_courses( $atts['user_id'] ); if ( empty( $filter['post__not_in'] ) ) unset( $filter['post__not_in'] ); } } $filter = apply_filters('learndash_ld_course_list_query_args', $filter, $atts ); if ( $array == 'true' ) { return get_posts( $filter ); } if ( ( $post ) && ( is_a( $post, 'WP_Post' ) ) && ( $post->post_type == $post_type ) ) { if ( ( isset( $filter['post__not_in'] ) ) && ( !empty( $filter['post__not_in'] ) ) ) { $filter['post__not_in'][] = $post->ID; } else { $filter['post__not_in'] = array( $post->ID ); } } // At this point the $filter var contains all the shortcode processing logic. // So now we want to save off the var to one used by the category selector (if used). $filter_cat = $filter; $filter_cat['posts_per_page'] = -1; $ld_categorydropdown = ''; $categories = array(); $ld_categories = array(); //if ( $include_outer_wrapper == 'true' ) { if ( ( trim( $categoryselector ) == 'true' ) && ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'wp_post_category' ) == 'yes') ) { $cats = array(); if ( ( isset( $_GET['catid'] ) ) && ( !empty( $_GET['catid'] ) ) ) { $atts['cat'] = intval( $_GET['catid'] ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'category', 'field' => 'term_id', 'terms' => intval( $_GET['catid'] ) ); } //if ( isset( $filter_cat['post__in'] ) ) { //$filter_cat['include'] = $filter_cat['post__in']; // unset( $filter_cat['post__in'] ); //} //if ( isset( $filter_cat['post__not_in'] ) ) { //$filter_cat['include'] = $filter_cat['post__in']; // unset( $filter_cat['post__not_in'] ); //} $cat_posts = get_posts( $filter_cat ); // We first need to build a listing of the categories used by each of the queried posts. if ( !empty( $cat_posts ) ) { foreach( $cat_posts as $cat_post ) { $post_categories = wp_get_post_categories( $cat_post->ID ); if ( !empty( $post_categories ) ) { foreach( $post_categories as $c ) { if ( empty( $cats[ $c ] ) ) { $cat = get_category( $c ); $cats[ $c ] = array( 'id' => $cat->cat_ID, 'name' => $cat->name, 'slug' => $cat->slug, 'parent' => $cat->parent, 'count' => 0, 'posts' => array() ); } $cats[ $c ]['count']++; $cats[ $c ]['posts'][] = $post->ID; } } } // Once we have these categories we need to requery the categories in order to get them into a proper ordering. if ( !empty( $cats ) ) { // And also let this query be filtered. $get_categories_args = apply_filters( 'learndash_course_list_category_args', array( 'taxonomy' => 'category', 'type' => $post_type, 'include' => array_keys($cats), 'orderby' => 'name', 'order' => 'ASC' ) ); if ( !empty( $get_categories_args ) ) { $categories = get_categories( $get_categories_args ); } } } } else { $categoryselector = ''; $atts['categoryselector']; } // We can only support one of the other category OR course_category selectors if ( ( trim( $atts[$post_type_slug .'_categoryselector'] ) == 'true' ) && ( empty( $categoryselector ) ) && ( LearnDash_Settings_Section::get_section_setting( $post_type_Class, 'ld_'. $post_type_slug .'_category' ) == 'yes') ) { $ld_cats = array(); if ( ( isset( $_GET[$post_type_slug . '_catid'] ) ) && ( !empty( $_GET[$post_type_slug . '_catid'] ) ) ) { $atts[$post_type_slug .'_cat'] = intval( $_GET[$post_type_slug . '_catid'] ); if ( !isset( $filter['tax_query'] ) ) $filter['tax_query'] = array(); $filter['tax_query'][] = array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'field' => 'term_id', 'terms' => intval( $_GET[$post_type_slug . '_catid'] ) ); } $cat_posts = get_posts( $filter_cat ); // We first need to build a listing of the categories used by each of the queried posts. if ( !empty( $cat_posts ) ) { $args = array('fields' => 'ids'); foreach( $cat_posts as $cat_post ) { $post_categories = wp_get_object_terms($cat_post->ID, 'ld_'. $post_type_slug .'_category', $args); if ( !empty( $post_categories ) ) { foreach( $post_categories as $c ) { if ( empty( $ld_cats[ $c ] ) ) { $ld_cat = get_term( $c, 'ld_'. $post_type_slug .'_category' ); $ld_cats[ $c ] = array( 'id' => $ld_cat->cat_ID, 'name' => $ld_cat->name, 'slug' => $ld_cat->slug, 'parent' => $ld_cat->parent, 'count' => 0, 'posts' => array() ); } $ld_cats[ $c ]['count']++; $ld_cats[ $c ]['posts'][] = $cat_post->ID; } } } // Once we have these categories we need to requery the categories in order to get them into a proper ordering. if ( !empty( $ld_cats ) ) { // And also let this query be filtered. $get_ld_categories_args = apply_filters( 'learndash_course_list_'. $post_type_slug .'_category_args', array( 'taxonomy' => 'ld_'. $post_type_slug .'_category', 'type' => $post_type, 'include' => array_keys( $ld_cats ), 'orderby' => 'name', 'order' => 'ASC' ) ); $post_type_object = get_post_type_object( $atts['post_type'] ); $tax_object = get_taxonomy('ld_'. $post_type_slug .'_category'); if ( !empty( $get_ld_categories_args ) ) { $ld_categories = get_terms( $get_ld_categories_args ); } } } } else { $atts[$post_type_slug .'_categoryselector'] = ''; } //} $loop = new WP_Query( $filter ); $level = ob_get_level(); ob_start(); if ( $include_outer_wrapper == 'true' ) { if ( !empty( $categories ) ) { $categorydropdown = '<div id="ld_categorydropdown">'; $categorydropdown.= '<form method="get"> <label for="ld_categorydropdown_select">' . esc_html__( 'Categories', 'learndash' ) . '</label> <select id="ld_categorydropdown_select" name="catid" onChange="jQuery(\'#ld_categorydropdown form\').submit()">'; $categorydropdown.= '<option value="">' . esc_html__( 'Select category', 'learndash' ) . '</option>'; foreach( $categories as $category ) { if ( isset( $cats[$category->term_id] ) ) { $cat = $cats[$category->term_id]; $selected =( empty( $_GET['catid'] ) || $_GET['catid'] != $cat['id'] ) ? '' : 'selected="selected"'; $categorydropdown.= "<option value='" . $cat['id'] . "' " . $selected . '>' . $cat['name'] . ' (' . $cat['count'] . ')</option>'; } } $categorydropdown.= "</select><input type='submit' style='display:none'></form></div>"; /** * Filter HTML output of category dropdown * * @since 2.1.0 * * @param string $categorydropdown */ echo apply_filters( 'ld_categorydropdown', $categorydropdown, $atts, $filter ); } if ( !empty( $ld_categories ) ) { $ld_categorydropdown = '<div id="ld_'. $post_type_slug .'_categorydropdown">'; $ld_categorydropdown.= '<form method="get"> <label for="ld_'. $post_type_slug .'_categorydropdown_select">' . $tax_object->labels->name . '</label> <select id="ld_'. $post_type_slug .'_categorydropdown_select" name="'. $post_type_slug .'_catid" onChange="jQuery(\'#ld_'. $post_type_slug .'_categorydropdown form\').submit()">'; $ld_categorydropdown.= '<option value="">' . sprintf( esc_html_x( 'Select %s', 'placeholder: LD Category label', 'learndash' ), $tax_object->labels->name ) . '</option>'; foreach( $ld_categories as $ld_category ) { if ( isset( $ld_cats[$ld_category->term_id] ) ) { $ld_cat = $ld_cats[$ld_category->term_id]; $selected =( empty( $_GET[$post_type_slug . '_catid'] ) || $_GET[$post_type_slug . '_catid'] != $ld_category->term_id ) ? '' : 'selected="selected"'; $ld_categorydropdown .= "<option value='" . $ld_category->term_id . "' " . $selected . '>' . $ld_cat['name'] . ' (' . $ld_cat['count'] . ')</option>'; } } $ld_categorydropdown.= "</select><input type='submit' style='display:none'></form></div>"; /** * Filter HTML output of category dropdown * * @since 2.1.0 * * @param string $categorydropdown */ echo apply_filters( 'ld_'. $post_type_slug .'_categorydropdown', $ld_categorydropdown, $atts, $filter ); } } $filter_json = htmlspecialchars( json_encode( $atts ) ); $filter_md5 = md5( $filter_json ); if ( $include_outer_wrapper == 'true' ) { ?><div id="ld-course-list-content-<?php echo $filter_md5 ?>" class="ld-course-list-content" data-shortcode-atts="<?php echo $filter_json; ?>"><?php } ?><div class="ld-course-list-items row"><?php /** * The following was added in 2.5.9 to allow better work with Gutenberg block rendering. * Seems when we call the $loop->the_post() in the section below we are changing the * global $post object. The problem is after this loop we call wp_reset_postdata() but * the global $post is not being reset. This is really only an issue with the Gutenberg * render blocks. * * @since 2.5.9 */ // if ( ( defined( 'REST_REQUEST' ) ) && ( true === REST_REQUEST ) ) { $post_save = $post; // } while ( $loop->have_posts() ) { $loop->the_post(); if ( empty( $atts['course_id'] ) ) { $course_id = $course_id = learndash_get_course_id( get_the_ID()); } else { $course_id = $atts['course_id']; } echo SFWD_LMS::get_template( 'course_list_template', array( 'shortcode_atts' => $atts, 'course_id' => $course_id ) ); //} } ?></div><?php if ( ( isset( $filter['posts_per_page'] ) ) && ( intval( $filter['posts_per_page'] ) > 0 ) ) { $course_list_pager = array(); if ( isset( $loop->query_vars['paged'] ) ) $course_list_pager['paged'] = $loop->query_vars['paged']; else $course_list_pager['paged'] = $filter['paged']; $course_list_pager['total_items'] = intval( $loop->found_posts ); $course_list_pager['total_pages'] = intval( $loop->max_num_pages ); echo SFWD_LMS::get_template( 'learndash_pager.php', array( 'pager_results' => $course_list_pager, 'pager_context' => 'course_list' ) ); } if ( $include_outer_wrapper == 'true' ) { ?></div><?php } $output = learndash_ob_get_clean( $level ); //if ( ( defined( 'REST_REQUEST' ) ) && ( true === REST_REQUEST ) ) { $post = $post_save; //$GLOBALS['post'] = $post_save; setup_postdata( $post_save ); //} else { /* Restore original Post Data */ // wp_reset_postdata(); //} $learndash_shortcode_used = true; /** * Filter HTML output of category dropdown * * @since 2.1.0 * * @param string $output */ return apply_filters( 'ld_course_list', $output, $atts, $filter ); } add_shortcode( 'ld_course_list', 'ld_course_list' ); /** * Shortcode to list lessons * * @since 2.1.0 * * @param array $attr shortcode attributes * @return string shortcode output */ function ld_lesson_list( $attr = array() ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( !is_array( $attr ) ) { $attr = array(); } $attr['post_type'] = learndash_get_post_type_slug( 'lesson' ); $attr['mycourses'] = false; $attr['status'] = false; // If we have a course_id. Then we set the orderby to match the items within the course. if ( ( isset( $attr['course_id'] ) ) && ( !empty( $attr['course_id'] ) ) ) { $attr['course_id'] = absint( $attr['course_id'] ); $course_steps = learndash_course_get_steps_by_type( $attr['course_id'], $attr['post_type'] ); if ( !empty( $course_steps ) ) { $attr['post__in'] = $course_steps; } if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { if ( !isset( $attr['order'] ) ) $attr['order'] = 'ASC'; if ( !isset( $attr['orderby'] ) ) $attr['orderby'] = 'post__in'; } } return ld_course_list( $attr ); } add_shortcode( 'ld_lesson_list', 'ld_lesson_list' ); /** * Shortcode to list quizzes * * @since 2.1.0 * * @param array $attr shortcode attributes * @return string shortcode output */ function ld_quiz_list( $attr = array() ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( !is_array( $attr ) ) { $attr = array(); } $attr['post_type'] = learndash_get_post_type_slug( 'quiz' ); $attr['mycourses'] = false; $attr['status'] = false; // If we have a course_id. Then we set the orderby to match the items within the course. if ( ( isset( $attr['course_id'] ) ) && ( !empty( $attr['course_id'] ) ) ) { $attr['course_id'] = absint( $attr['course_id'] ); $course_steps = array(); if ( isset( $attr['lesson_id'] ) ) { $attr['lesson_id'] = absint( $attr['lesson_id'] ); if ( ! empty( $attr['lesson_id'] ) ) { $course_steps = learndash_get_lesson_quiz_list( $attr['lesson_id'], null, $attr['course_id'] ); if ( ! empty( $course_steps ) ) { $course_steps = wp_list_pluck( $course_steps, 'post' ); $course_steps = wp_list_pluck( $course_steps, 'ID' ); } } else { $course_steps = learndash_get_global_quiz_list( $attr['course_id'] ); if ( ! empty( $course_steps ) ) { $course_steps = wp_list_pluck( $course_steps, 'ID' ); } } } else { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_steps = learndash_course_get_steps_by_type( intval( $attr['course_id'] ), $attr['post_type'] ); } } if ( !empty( $course_steps ) ) { $attr['post__in'] = $course_steps; //if ( !isset( $attr['orderby'] ) ) $attr['orderby'] = 'post__in'; } if ( !isset( $attr['order'] ) ) $attr['order'] = 'ASC'; if ( !isset( $attr['orderby'] ) ) $attr['orderby'] = 'title'; } return ld_course_list( $attr ); } add_shortcode( 'ld_quiz_list', 'ld_quiz_list' ); /** * Shortcode to list topics * * @since 2.1.0 * * @param array $attr shortcode attributes * @return string shortcode output */ function ld_topic_list( $attr = array() ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( !is_array( $attr ) ) { $attr = array(); } $attr['post_type'] = learndash_get_post_type_slug( 'topic' ); $attr['mycourses'] = false; $attr['status'] = false; // If we have a course_id. Then we set the orderby to match the items within the course. if ( ( isset( $attr['course_id'] ) ) && ( ! empty( $attr['course_id'] ) ) ) { $attr['course_id'] = absint( $attr['course_id'] ); $course_steps = array(); if ( isset( $attr['lesson_id'] ) ) { $attr['lesson_id'] = absint( $attr['lesson_id'] ); if ( ! empty( $attr['lesson_id'] ) ) { $course_steps = learndash_get_topic_list( $attr['lesson_id'], $attr['course_id'] ); if ( ! empty( $course_steps ) ) { $course_steps = wp_list_pluck( $course_steps, 'ID' ); } } else { $course_steps = learndash_course_get_steps_by_type( intval( $attr['course_id'] ), $attr['post_type'] ); } } else { $course_steps = learndash_course_get_steps_by_type( intval( $attr['course_id'] ), $attr['post_type'] ); } if ( ! empty( $course_steps ) ) { $attr['post__in'] = $course_steps; //if ( !isset( $attr['orderby'] ) ) $attr['orderby'] = 'post__in'; } if ( !isset( $attr['order'] ) ) $attr['order'] = 'ASC'; if ( !isset( $attr['orderby'] ) ) $attr['orderby'] = 'title'; } return ld_course_list( $attr ); } add_shortcode( 'ld_topic_list', 'ld_topic_list' ); /** * Check if user has access * * @todo duplicate function, exists in other places * check it's use and consolidate * * @since 2.1.0 * * @param int $course_id * @param int $user_id * @return bool */ function ld_course_check_user_access( $course_id, $user_id = null ) { return sfwd_lms_has_access( $course_id, $user_id ); } /** * Shortcode to display content to users that have access to current course id * * @todo function is duplicate of learndash_student_check_shortcode() * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_visitor_check_shortcode( $atts, $content = '' ) { global $learndash_shortcode_used; if ( ! empty( $content ) ) { if ( ! is_array( $atts ) ) { if ( ! empty( $atts ) ) { $atts = array( $atts ); } else { $atts = array(); } } $defaults = array( 'course_id' => learndash_get_course_id(), 'content' => $content, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters('learndash_visitor_shortcode_atts', $atts ); if ( ( ! is_user_logged_in() ) || ( ( ! empty( $atts['course_id'] ) ) && ( ! sfwd_lms_has_access( $atts['course_id'] ) ) ) ) { $learndash_shortcode_used = true; $atts['content'] = do_shortcode( $atts['content'] ); return SFWD_LMS::get_template( 'learndash_course_visitor_message', array( 'shortcode_atts' => $atts, ), false ); } else { $content = ''; } } return $content; } add_shortcode( 'visitor', 'learndash_visitor_check_shortcode' ); /** * Shortcode to display content to users that have access to current course id * * @todo function is duplicate of learndash_visitor_check_shortcode() * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_student_check_shortcode( $atts, $content = null ) { global $learndash_shortcode_used; if ( ( ! empty( $content ) ) && ( is_user_logged_in() ) ) { if ( ! is_array( $atts ) ) { if ( ! empty( $atts ) ) { $atts = array( $atts ); } else { $atts = array(); } } $defaults = array( 'course_id' => learndash_get_course_id(), 'user_id' => get_current_user_id(), 'content' => $content, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters('learndash_student_shortcode_atts', $atts ); if ( ( !empty( $atts['content'] ) ) && ( !empty( $atts['user_id'] ) ) && ( !empty( $atts['course_id'] ) ) && ( $atts['user_id'] == get_current_user_id() ) ) { // The reason we are doing this check is because 'sfwd_lms_has_access' will return true if the course does not exist. // This needs to be changed to return some other value because true signals the calling function that all is well. $course_id = learndash_get_course_id( $atts['course_id'] ); if ( $course_id == $atts['course_id'] ) { if ( sfwd_lms_has_access( $atts['course_id'], $atts['user_id'] ) ) { $learndash_shortcode_used = true; $atts['content'] = do_shortcode( $atts['content'] ); return SFWD_LMS::get_template( 'learndash_course_student_message', array( 'shortcode_atts' => $atts, ), false ); } } } } return ''; } add_shortcode( 'student', 'learndash_student_check_shortcode' ); /** * Shortcode to display content to users that have access to current group id * * @todo function is duplicate of learndash_visitor_check_shortcode() * * @since 2.3 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_ld_group_check_shortcode( $atts, $content = null ) { global $learndash_shortcode_used; if ( ( is_singular() ) && ( !is_null( $content ) ) && ( is_user_logged_in() ) ) { $defaults = array( 'group_id' => 0, 'user_id' => get_current_user_id(), 'content' => $content, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters('learndash_ld_group_shortcode_atts', $atts, $content); if ( ( !empty( $atts['content'] ) ) && ( !empty( $atts['user_id'] ) ) && ( !empty( $atts['group_id'] ) ) && ( $atts['user_id'] == get_current_user_id() ) ) { if ( learndash_is_user_in_group( $atts['user_id'], $atts['group_id'] ) ) { $learndash_shortcode_used = true; $atts['content'] = do_shortcode( $atts['content'] ); return SFWD_LMS::get_template( 'learndash_group_message', array( 'shortcode_atts' => $atts, ), false ); } } } return ''; } add_shortcode( 'ld_group', 'learndash_ld_group_check_shortcode' ); /** * Generates output for course status shortcodes * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @param string $status status of course * @return string shortcode output */ function learndash_course_status_content_shortcode( $atts, $content, $status ) { $atts['user_id'] = empty( $atts['user_id'] ) ? get_current_user_id() : intval( $atts['user_id'] ); $atts['course_id'] = empty( $atts['course_id'] ) ? learndash_get_course_id() : learndash_get_course_id( intval( $atts['course_id'] ) ); if ( ( ! empty( $atts['course_id'] ) ) && ( ! empty( $atts['user_id'] ) ) && ( $atts['user_id'] == get_current_user_id() ) ) { if ( sfwd_lms_has_access( $atts['course_id'], $atts['user_id'] ) ) { if ( learndash_course_status( $atts['course_id'], $atts['user_id'] ) == $status ) { return do_shortcode( $content ); } } } return ''; } /** * Shortcode that shows the content if the user has completed the course. * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_course_complete_shortcode( $atts = array(), $content = '' ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( ! empty( $content ) ) { if ( ! is_array( $atts ) ) { if ( !empty( $atts ) ) { $atts = array( $atts ); } else { $atts = array(); } } $defaults = array( 'content' => $content, 'course_id' => false, 'user_id' => false, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters( 'learndash_course_complete_shortcode_atts', $atts ); $atts['content'] = learndash_course_status_content_shortcode( $atts, $atts['content'], esc_html__( 'Completed', 'learndash' ) ); return SFWD_LMS::get_template( 'learndash_course_complete_message', array( 'shortcode_atts' => $atts, ), false ); } } add_shortcode( 'course_complete', 'learndash_course_complete_shortcode' ); /** * Shortcode that shows the content if the user is in progress on the course. * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_course_inprogress_shortcode( $atts = array(), $content = '' ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( ! empty( $content ) ) { if ( ! is_array( $atts ) ) { if ( !empty( $atts ) ) { $atts = array( $atts ); } else { $atts = array(); } } $defaults = array( 'content' => $content, 'course_id' => false, 'user_id' => false, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters( 'learndash_course_inprogress_shortcode_atts', $atts ); $atts['content'] = learndash_course_status_content_shortcode( $atts, $atts['content'], esc_html__( 'In Progress', 'learndash' ) ); return SFWD_LMS::get_template( 'learndash_course_inprogress_message', array( 'shortcode_atts' => $atts, ), false ); } } add_shortcode( 'course_inprogress', 'learndash_course_inprogress_shortcode' ); /** * Shortcode that shows the content if the user has mnot started the course * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_course_notstarted_shortcode( $atts = array(), $content = '' ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; if ( ! empty( $content ) ) { if ( ! is_array( $atts ) ) { if ( !empty( $atts ) ) { $atts = array( $atts ); } else { $atts = array(); } } $defaults = array( 'content' => $content, 'course_id' => false, 'user_id' => false, 'autop' => true ); $atts = wp_parse_args( $atts, $defaults ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters( 'learndash_course_notstarted_shortcode_atts', $atts ); $atts['content'] = learndash_course_status_content_shortcode( $atts, $atts['content'], esc_html__( 'Not Started', 'learndash' ) ); return SFWD_LMS::get_template( 'learndash_course_not_started_message', array( 'shortcode_atts' => $atts, ), false ); } } add_shortcode( 'course_notstarted', 'learndash_course_notstarted_shortcode' ); /** * Shortcode that shows the Course Expire date for user access. * * @since 2.1.0 * * @param array $attr shortcode attributes * @param string $content content of shortcode * @return string shortcode output */ function learndash_course_expire_status_shortcode( $atts, $content ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; $content_shortcode = ''; $atts = shortcode_atts( array( 'course_id' => learndash_get_course_id(), 'user_id' => get_current_user_id(), 'label_before' => sprintf( esc_html_x('%s access will expire on:', 'Course access will expire on:', 'learndash'), LearnDash_Custom_Label::get_label( 'course' ) ), 'label_after' => sprintf( esc_html_x('%s access expired on:', 'Course access expired on:', 'learndash'), LearnDash_Custom_Label::get_label( 'course' ) ), 'format' => get_option('date_format') .' '. get_option('time_format'), 'autop' => true ), $atts ); if ( ( true === $atts['autop'] ) || ( 'true' === $atts['autop'] ) || ( '1' === $atts['autop'] ) ) { $atts['autop'] = true; } else { $atts['autop'] = false; } $atts = apply_filters('learndash_ld_course_expire_status_shortcode_atts', $atts ); if ( ( !empty( $atts['course_id'] ) ) && ( !empty( $atts['user_id'] ) ) ) { if ( sfwd_lms_has_access( $atts['course_id'], $atts['user_id'] ) ) { $course_meta = get_post_meta( $atts['course_id'], '_sfwd-courses', true ); $courses_access_from = ld_course_access_from( $atts['course_id'], $atts['user_id'] ); if ( empty( $courses_access_from ) ) { $courses_access_from = learndash_user_group_enrolled_to_course_from( $atts['user_id'], $atts['course_id'] ); } if ( !empty( $courses_access_from ) ) { $expire_on = ld_course_access_expires_on( $atts['course_id'], $atts['user_id'] ); if (!empty($expire_on)) { if ($expire_on > time()) { $content_shortcode .= $atts['label_before']; } else { $content_shortcode .= $atts['label_after']; } $content_shortcode .= ' '. date($atts['format'], $expire_on + (get_option('gmt_offset') * 3600)); } } $atts['content'] = do_shortcode( $content_shortcode ); return SFWD_LMS::get_template( 'learndash_course_expire_status_message', array( 'shortcode_atts' => $atts, ), false ); } } if (!empty( $content_shortcode ) ) { $content .= $content_shortcode; } return $content; } add_shortcode( 'ld_course_expire_status', 'learndash_course_expire_status_shortcode' ); function learndash_quiz_shortcode( $atts, $content = '', $show_materials = false ) { global $learndash_shortcode_used, $learndash_shortcode_atts; $atts = shortcode_atts( array( 'quiz_id' => 0, 'course_id' => 0, 'quiz_pro_id' => 0, ), $atts ); // Just to ensure compliance. $quiz_id = $atts['quiz_id'] = absint( $atts['quiz_id'] ); $course_id = $atts['course_id'] = absint( $atts['course_id'] ); $quiz_pro_id = $atts['quiz_pro_id'] = absint( $atts['quiz_pro_id'] ); if ( empty( $atts['quiz_id'] ) ) { return $content; } $quiz_post = get_post( $atts['quiz_id'] ); if ( ! is_a( $quiz_post, 'WP_Post' ) ) { return $content; } if ( empty( $course_id ) ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) !== 'yes' ) { $course_id = learndash_get_setting( $quiz_post, 'course' ); $course_id = absint( $course_id ); if ( ! empty( $course_id ) ) { $atts['course_id'] = $course_id; } } } $learndash_shortcode_atts['ld_quiz'] = $atts; // Clear out any previous 'LDAdvQuiz' data. if ( isset( $learndash_shortcode_atts['LDAdvQuiz'] ) ) { unset( $learndash_shortcode_atts['LDAdvQuiz'] ); } $learndash_shortcode_used = true; $lesson_progression_enabled = false; if ( ! empty( $atts['course_id'] ) ) { $lesson_progression_enabled = learndash_lesson_progression_enabled( $atts['course_id'] ); } $has_access = ''; $user_id = get_current_user_id(); $quiz_post = get_post( $atts['quiz_id'] ); if ( $quiz_post instanceof WP_Post ) { $quiz_settings = learndash_get_setting( $atts['quiz_id'] ); $meta = SFWD_CPT_Instance::$instances[ 'sfwd-quiz' ]->get_settings_values( 'sfwd-quiz' ); $show_content = ! ( ! empty( $lesson_progression_enabled ) && ! is_quiz_accessable( $user_id, $quiz_post, false, $course_id ) ); $attempts_count = 0; $repeats = ( isset( $quiz_settings['repeats'] ) ) ? trim( $quiz_settings['repeats'] ) : ''; if ( '' === $repeats ) { if ( ! empty( $quiz_settings['quiz_pro'] ) ) { $quiz_mapper = new WpProQuiz_Model_QuizMapper(); $pro_quiz_edit = $quiz_mapper->fetch( $quiz_settings['quiz_pro'] ); if ( ( $pro_quiz_edit ) && ( is_a( $pro_quiz_edit, 'WpProQuiz_Model_Quiz' ) ) ) { if ( ( isset( $atts['quiz_id'] ) ) && ( ! empty( $atts['quiz_id'] ) ) ) { $pro_quiz_edit->setPostId( $atts['quiz_id'] ); } if ( $pro_quiz_edit->isQuizRunOnce() ) { $repeats = 0; // Update for later. learndash_update_setting( $quiz_post, 'repeats', $repeats ); } } } } if ( $repeats !== '' ) { if ( $user_id ) { $usermeta = get_user_meta( $user_id, '_sfwd-quizzes', true ); $usermeta = maybe_unserialize( $usermeta ); if ( ! is_array( $usermeta ) ) { $usermeta = array(); } if ( ! empty( $usermeta ) ) { foreach ( $usermeta as $k => $v ) { if ( ( intval( $v['quiz'] ) === $atts['quiz_id'] ) ) { if ( ! empty( $atts['course_id'] ) ) { if ( ( isset( $v['course'] ) ) && ( ! empty( $v['course'] ) ) && ( absint( $v['course'] ) === absint( $atts['course_id'] ) ) ) { // Count the number of time the student has taken the quiz where the course_id matches. $attempts_count++; } } elseif ( empty( $atts['course_id'] ) ) { if ( ( isset( $v['course'] ) ) && ( empty( $v['course'] ) ) && ( absint( $v['course'] ) === absint( $atts['course_id'] ) ) ) { // Count the number of time the student has taken the quiz where the course_id is zero. $attempts_count++; } } } } } } } $attempts_left = ( ( $repeats === '' ) || ( absint( $repeats ) >= absint( $attempts_count ) ) ); $bypass_course_limits_admin_users = false; if ( $user_id ) { if ( learndash_is_admin_user( $user_id ) ) { $bypass_course_limits_admin_users = LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Admin_User', 'bypass_course_limits_admin_users' ); if ( 'yes' === $bypass_course_limits_admin_users ) { $bypass_course_limits_admin_users = true; } else { $bypass_course_limits_admin_users = false; } } // For logged in users to allow an override filter. $bypass_course_limits_admin_users = apply_filters( 'learndash_prerequities_bypass', $bypass_course_limits_admin_users, $user_id, $course_id, $quiz_post ); } if ( ( true === $bypass_course_limits_admin_users ) && ( ! $attempts_left ) ) { $attempts_left = 1; } /** * Filters the quiz attempts left for user. * * @since 3.1 * * @param boolean $attempts_left True is Quiz attempts left. False if none. * @param integer $attempts_count Number of Quiz attemplts already taken. * @param integer $user_id ID of User taking Quiz. * @param integer $quiz_id ID of Quiz being taken. * @return integer Zero or greater value. * See example https://bitbucket.org/snippets/learndash/Gjygja */ $attempts_left = apply_filters( 'learndash_quiz_attempts', $attempts_left, absint( $attempts_count ), absint( $user_id ), absint( $quiz_post->ID ) ); $attempts_left = absint( $attempts_left ); if ( ! empty( $lesson_progression_enabled ) && ! is_quiz_accessable( $user_id, $quiz_post, false, $course_id ) ) { add_filter( 'comments_array', 'learndash_remove_comments', 1, 2 ); } $materials = ''; /** * Filter for content access * * If not null, will display instead of quiz content * * @since 2.1.0 * * @param string */ $access_message = apply_filters( 'learndash_content_access', null, $quiz_post ); if ( ! is_null( $access_message ) ) { $quiz_content = $access_message; } else { if ( true === $show_materials ) { if ( ! empty( $quiz_settings['quiz_materials'] ) ) { $materials = wp_specialchars_decode( $quiz_settings['quiz_materials'], ENT_QUOTES ); if ( ! empty( $materials ) ) { $materials = do_shortcode( $materials ); } } } $quiz_content = ''; if ( ! empty( $quiz_settings['quiz_pro'] ) ) { $quiz_settings['lesson'] = 0; $quiz_settings['topic'] = 0; if ( ( ! empty( $course_id ) ) && ( ! empty( $quiz_id ) ) ) { $quiz_settings['topic'] = learndash_course_get_single_parent_step( $course_id, $quiz_id, learndash_get_post_type_slug( 'topic' ) ); $quiz_settings['topic'] = absint( $quiz_settings['topic'] ); $quiz_settings['lesson'] = learndash_course_get_single_parent_step( $course_id, $quiz_id, learndash_get_post_type_slug( 'lesson' ) ); $quiz_settings['lesson'] = absint( $quiz_settings['lesson'] ); } $quiz_content = wptexturize( do_shortcode( '[LDAdvQuiz ' . $quiz_settings['quiz_pro'] . ' quiz_pro_id="' . $quiz_settings['quiz_pro'] . '" quiz_id="' . $quiz_post->ID . '" course_id="' . $course_id . '" lesson_id="' . $quiz_settings['lesson'] . '" topic_id="' . $quiz_settings['topic'] . '"]' ) ); } /** * Filter quiz content * * @since 2.1.0 * * @param string $quiz_content */ $quiz_content = apply_filters( 'learndash_quiz_content', $quiz_content, $quiz_post ); } $level = ob_get_level(); ob_start(); $template_file = SFWD_LMS::get_template( 'quiz', null, null, true ); if ( ! empty( $template_file ) ) { include $template_file; } $content = learndash_ob_get_clean( $level ); // Added this defined wrap in v2.1.8 as it was effecting <pre></pre>, <code></code> and other formatting of the content. // See wrike https://www.wrike.com/open.htm?id=77352698 as to why this define exists if ( ( defined( 'LEARNDASH_NEW_LINE_AND_CR_TO_SPACE' ) ) && ( LEARNDASH_NEW_LINE_AND_CR_TO_SPACE == true ) ) { // Why is this here? $content = str_replace( array( "\n", "\r" ), ' ', $content ); } $user_has_access = $has_access ? 'user_has_access':'user_has_no_access'; /** * Filter content to be return inside div * * @since 2.1.0 * * @param string $content */ $content = '<div class="learndash ' . $user_has_access . '" id="learndash_post_' . $quiz_post->ID . '">' . apply_filters( 'learndash_content', $content, $quiz_post ) . '</div>'; } return $content; } add_shortcode( 'ld_quiz', 'learndash_quiz_shortcode' ); function ld_course_list_shortcode_pager() { $reply_data = array(); if ( ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) $paged = intval( $_POST['paged'] ); else $paged = 1; if ( ( isset( $_POST['shortcode_atts'] ) ) && ( !empty( $_POST['shortcode_atts'] ) ) ) $shortcode_atts = $_POST['shortcode_atts']; else $shortcode_atts = array(); $shortcode_atts['include_outer_wrapper'] = 'false'; $shortcode_atts['paged'] = $paged; $reply_data['content'] = ld_course_list( $shortcode_atts ); echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_course_list_shortcode_pager', 'ld_course_list_shortcode_pager' ); add_action( 'wp_ajax_nopriv_ld_course_list_shortcode_pager', 'ld_course_list_shortcode_pager' ); ld-course-info-widget.php 0000666 00000140333 15214044143 0011372 0 ustar 00 <?php /** * Course info and navigation widgets * * @since 2.1.0 * * @package LearnDash\Widgets */ // This filter will parse the text of the widget for shortcodes. add_filter( 'widget_text', 'do_shortcode' ); add_filter( 'widget_text_content', 'do_shortcode' ); add_filter( 'widget_custom_html', 'do_shortcode' ); add_filter( 'widget_custom_html_content', 'do_shortcode' ); class LearnDash_Course_Info_Widget extends WP_Widget { /** * Setup Course Info Widget */ function __construct() { $widget_ops = array( 'classname' => 'widget_ldcourseinfo', 'description' => sprintf( esc_html_x( 'LearnDash - %s attempt and score information of users. Visible only to users logged in.', 'placeholders: course', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ) ); $control_ops = array(); //'width' => 400, 'height' => 350); parent::__construct( 'ldcourseinfo', sprintf( esc_html_x( '%s Information', 'Course Information', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ), $widget_ops, $control_ops ); } /** * Displays widget * * @since 2.1.0 * * @param array $args widget arguments * @param array $instance widget instance * @return string widget output */ function widget( $args, $instance ) { global $learndash_shortcode_used; extract( $args ); /** * Filter widget title * * @since 2.1.0 * * @param string */ $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance ); if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); if ( empty( $current_user->ID ) ) { return; } $user_id = $current_user->ID; } $courseinfo = learndash_course_info( $user_id, $instance ); if ( empty( $courseinfo ) ) { return; } echo $before_widget; if ( ! empty( $title ) ) { echo $before_title . $title . $after_title; } echo $courseinfo; echo $after_widget; $learndash_shortcode_used = true; } /** * Handles widget updates in admin * * @since 2.1.0 * * @param array $new_instance * @param array $old_instance * @return array $instance */ function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['registered_show_thumbnail'] = esc_attr( $new_instance['registered_show_thumbnail'] ); if ( $new_instance['registered_num'] != '' ) $instance['registered_num'] = intval( $new_instance['registered_num'] ); else $instance['registered_num'] = false; $instance['registered_orderby'] = esc_attr( $new_instance['registered_orderby'] ); $instance['registered_order'] = esc_attr( $new_instance['registered_order'] ); if ( $new_instance['progress_num'] != '' ) $instance['progress_num'] = intval( $new_instance['progress_num'] ); else $instance['progress_num'] = false; $instance['progress_orderby'] = esc_attr( $new_instance['progress_orderby'] ); $instance['progress_order'] = esc_attr( $new_instance['progress_order'] ); if ( $new_instance['quiz_num'] != '' ) $instance['quiz_num'] = intval( $new_instance['quiz_num'] ); else $instance['quiz_num'] = false; $instance['quiz_orderby'] = esc_attr( $new_instance['quiz_orderby'] ); $instance['quiz_order'] = esc_attr( $new_instance['quiz_order'] ); return $instance; } /** * Display widget form in admin * * @since 2.1.0 * * @param array $instance widget instance */ function form( $instance ) { $instance = wp_parse_args( (array) $instance, array( 'title' => '', 'registered_show_thumbnail' => '', 'registered_num' => false, 'registered_orderby' => '', 'registered_order' => '', 'progress_num' => false, 'progress_orderby' => '', 'progress_order' => '', 'quiz_num' => false, 'quiz_orderby' => '', 'quiz_order' => '', ) ); $title = strip_tags( $instance['title'] ); $registered_show_thumbnail = esc_attr( $instance['registered_show_thumbnail'] ); if ( $instance['registered_num'] != '' ) $registered_num = abs(intval( $instance['registered_num'] )); else $registered_num = ''; $registered_orderby = esc_attr( $instance['registered_orderby'] ); $registered_order = esc_attr( $instance['registered_order'] ); if ( $instance['registered_num'] != '' ) $progress_num = abs(intval( $instance['progress_num'] )); else $progress_num = ''; $progress_orderby = esc_attr( $instance['progress_orderby'] ); $progress_order = esc_attr( $instance['progress_order'] ); if ( $instance['quiz_num'] != '' ) $quiz_num = abs( intval( $instance['quiz_num'] )); else $quiz_num = ''; $quiz_orderby = esc_attr( $instance['quiz_orderby'] ); $quiz_order = esc_attr( $instance['quiz_order'] ); //$text = format_to_edit($instance['text']); ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'learndash' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /> </p> <p> <label for="<?php echo $this->get_field_id( 'registered_show_thumbnail' ); ?>"><?php echo esc_html__( 'Registered show thumbnail:', 'learndash' ) ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'registered_show_thumbnail' ); ?>" name="<?php echo $this->get_field_name( 'registered_show_thumbnail' ); ?>"> <option value="" <?php selected( $registered_show_thumbnail, '' ); ?>><?php echo esc_html__('Yes (default)', 'learndash') ?></option> <option value="false" <?php selected( $registered_show_thumbnail, 'false' ); ?>><?php echo esc_html__('No', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'registered_num' ); ?>"><?php echo esc_html__( 'Registered per page:', 'learndash' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'registered_num' ); ?>" name="<?php echo $this->get_field_name( 'registered_num' ); ?>" type="number" min="0" value="<?php echo $registered_num; ?>" /> <span class="description"><?php printf( esc_html_x( 'Default is %d. Set to zero for no pagination.', 'placeholders: default per page', 'learndash' ), LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'per_page' ) ) ?></span> </p> <p> <label for="<?php echo $this->get_field_id( 'registered_orderby' ); ?>"><?php echo esc_html__( 'Registered order by:', 'learndash' ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'registered_orderby' ); ?>" name="<?php echo $this->get_field_name( 'registered_orderby' ); ?>"> <option value="" <?php selected( $registered_orderby, '' ); ?>><?php echo esc_html__('Title (default) - Order by post title', 'learndash') ?></option> <option value="id" <?php selected( $registered_orderby, 'id' ); ?>><?php echo esc_html__('ID - Order by post id', 'learndash') ?></option> <option value="date" <?php selected( $registered_orderby, 'date' ); ?>><?php echo esc_html__('Date - Order by post date', 'learndash') ?></option> <option value="menu_order" <?php selected( $registered_orderby, 'menuorder' ); ?>><?php echo esc_html__('Menu - Order by Page Order Value', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'registered_order' ); ?>"><?php echo esc_html__( 'Registered order:', 'learndash' ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'registered_order' ); ?>" name="<?php echo $this->get_field_name( 'registered_order' ); ?>"> <option value="" <?php selected( $registered_order, '' ); ?>><?php echo esc_html__('ASC (default) - lowest to highest values', 'learndash') ?></option> <option value="DESC" <?php selected( $registered_order, 'DESC' ); ?>><?php echo esc_html__('DESC - highest to lowest values', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'progress_num' ); ?>"><?php echo sprintf( esc_html_x( '%s progress per page:', 'placeholder: course', 'learndash' ) , LearnDash_Custom_Label::get_label( 'course' ) ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'progress_num' ); ?>" name="<?php echo $this->get_field_name( 'progress_num' ); ?>" type="number" min="0" value="<?php echo $progress_num; ?>" /> <span class="description"><?php printf( esc_html_x( 'Default is %d. Set to zero for no pagination.', 'placeholders: default per page', 'learndash' ), LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'progress_num' ) ) ?></span> </p> <p> <label for="<?php echo $this->get_field_id( 'progress_orderby' ); ?>"><?php echo esc_html__( 'Progress order by:', 'learndash' ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'progress_orderby' ); ?>" name="<?php echo $this->get_field_name( 'progress_orderby' ); ?>"> <option value="" <?php selected( $progress_orderby, '' ); ?>><?php echo esc_html__('Title (default) - Order by post title', 'learndash') ?></option> <option value="id" <?php selected( $progress_orderby, 'id' ); ?>><?php echo esc_html__('ID - Order by post id', 'learndash') ?></option> <option value="date" <?php selected( $progress_orderby, 'date' ); ?>><?php echo esc_html__('Date - Order by post date', 'learndash') ?></option> <option value="menu_order" <?php selected( $progress_orderby, 'menu_order' ); ?>><?php echo esc_html__('Menu - Order by Page Order Value', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'progress_order' ); ?>"><?php echo esc_html__( 'Progress order:', 'learndash' ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'progress_order' ); ?>" name="<?php echo $this->get_field_name( 'progress_order' ); ?>"> <option value="" <?php selected( $progress_order, '' ); ?>><?php echo esc_html__('ASC (default) - lowest to highest values', 'learndash') ?></option> <option value="DESC" <?php selected( $progress_order, 'DESC' ); ?>><?php echo esc_html__('DESC - highest to lowest values', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'quiz_num' ); ?>"><?php echo sprintf( esc_html_x( '%s per page:', 'placeholder: quizzes', 'learndash' ), LearnDash_Custom_Label::get_label( 'Quizzes' ) ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'quiz_num' ); ?>" name="<?php echo $this->get_field_name( 'quiz_num' ); ?>" type="number" min="0" value="<?php echo $quiz_num; ?>" /> <span class="description"><?php printf( esc_html_x( 'Default is %d. Set to zero for no pagination.', 'placeholders: default per page', 'learndash' ), LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'quiz_num' ) ) ?></span> </p> <p> <label for="<?php echo $this->get_field_id( 'quiz_orderby' ); ?>"><?php echo sprintf( esc_html_x( '%s order by:', 'placeholder: quizzes', 'learndash' ), LearnDash_Custom_Label::get_label( 'Quizzes' ) ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'quiz_orderby' ); ?>" name="<?php echo $this->get_field_name( 'quiz_orderby' ); ?>"> <option value="" <?php selected( $quiz_orderby, '' ); ?>><?php echo esc_html__( 'Date Taken (default) - Order by date taken', 'learndash' ); ?></option> <option value="title" <?php selected( $quiz_orderby, 'title' ); ?>><?php echo esc_html__('Title - Order by post title', 'learndash') ?></option> <option value="id" <?php selected( $quiz_orderby, 'id' ); ?>><?php echo esc_html__('ID - Order by post id', 'learndash') ?></option> <option value="date" <?php selected( $quiz_orderby, 'date' ); ?>><?php echo esc_html__('Date - Order by post date', 'learndash') ?></option> <option value="menu_order" <?php selected( $quiz_orderby, 'menu_order' ); ?>><?php echo esc_html__('Menu - Order by Page Order Value', 'learndash') ?></option> </select> </p> <p> <label for="<?php echo $this->get_field_id( 'quiz_order' ); ?>"><?php echo sprintf( esc_html_x( '%s order:', 'placeholder: quizzes', 'learndash' ), LearnDash_Custom_Label::get_label( 'Quizzes' ) ); ?></label> <select class="widefat" id="<?php echo $this->get_field_id( 'quiz_order' ); ?>" name="<?php echo $this->get_field_name( 'quiz_order' ); ?>"> <option value="" <?php selected( $quiz_order, '' ); ?>><?php echo esc_html__('DESC (default) - highest to lowest values', 'learndash') ?></option> <option value="ASC" <?php selected( $quiz_order, 'ASC' ); ?>><?php echo esc_html__('ASC - lowest to highest values', 'learndash') ?></option> </select> </p> <?php } } add_action( 'widgets_init', function() { return register_widget("LearnDash_Course_Info_Widget"); }); class LearnDash_Course_Navigation_Widget extends WP_Widget { /** * Setup Course Navigation Widget */ function __construct() { $widget_ops = array( 'classname' => 'widget_ldcoursenavigation', 'description' => sprintf( esc_html_x( 'LearnDash - %s Navigation. Shows lessons and topics on the current course.', 'LearnDash - Course Navigation. Shows lessons and topics on the current course.', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ) ); $control_ops = array(); //'width' => 400, 'height' => 350); parent::__construct( 'widget_ldcoursenavigation', sprintf( esc_html_x( '%s Navigation', 'Course Navigation Label', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ), $widget_ops, $control_ops ); } /** * Displays widget * * @since 2.1.0 * * @param array $args widget arguments * @param array $instance widget instance * @return string widget output */ public function widget( $args, $instance ) { global $learndash_shortcode_used; //global $post; $post = get_post( get_the_id() ); if ( ( ! is_a( $post, 'WP_Post' ) ) || ( empty( $post->ID ) ) || ( ! is_single() ) ) { return; } $course_id = learndash_get_course_id( $post->ID ); if ( empty( $course_id ) ) { return; } //$course_price_type = learndash_get_course_meta_setting( $course_id, 'course_price_type' ); // If the course price type is not 'open' and the user is not logged in then abort. //if ( ( 'open' !== $course_price_type ) && ( ! is_user_logged_in() ) ) { // return; //} $instance['show_widget_wrapper'] = true; $instance['current_lesson_id'] = 0; $instance['current_step_id'] = 0; $lesson_query_args = array(); $course_lessons_per_page = learndash_get_course_lessons_per_page( $course_id ); if ( $course_lessons_per_page > 0 ) { if ( in_array( $post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) { $instance['current_step_id'] = $post->ID; if ( 'sfwd-lessons' === $post->post_type ) { $instance['current_lesson_id'] = $post->ID; } else if ( in_array( $post->post_type, array( 'sfwd-topic', 'sfwd-quiz') ) ) { $instance['current_lesson_id'] = learndash_course_get_single_parent_step( $course_id, $post->ID, 'sfwd-lessons' ); } if ( ! empty( $instance['current_lesson_id'] ) ) { $course_lesson_ids = learndash_course_get_steps_by_type( $course_id, 'sfwd-lessons' ); if ( ! empty( $course_lesson_ids ) ) { $course_lessons_paged = array_chunk( $course_lesson_ids, $course_lessons_per_page, true ); $lessons_paged = 0; foreach ( $course_lessons_paged as $paged => $paged_set ) { if ( in_array( $instance['current_lesson_id'], $paged_set ) ) { $lessons_paged = $paged + 1; break; } } if ( ! empty( $lessons_paged ) ) { $lesson_query_args['pagination'] = 'true'; $lesson_query_args['paged'] = $lessons_paged; } } } else if ( in_array( $post->post_type, array( 'sfwd-quiz' ) ) ) { // If here we have a global Quiz. So we set the pager to the max number $course_lesson_ids = learndash_course_get_steps_by_type( $course_id, 'sfwd-lessons' ); if ( ! empty( $course_lesson_ids ) ) { $course_lessons_paged = array_chunk( $course_lesson_ids, $course_lessons_per_page, true ); $lesson_query_args['paged'] = count( $course_lessons_paged ); } } } } else { if ( in_array( $post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) { $instance['current_step_id'] = $post->ID; if ( 'sfwd-lessons' === $post->post_type ) { $instance['current_lesson_id'] = $post->ID; } else if ( in_array( $post->post_type, array( 'sfwd-topic', 'sfwd-quiz') ) ) { $instance['current_lesson_id'] = learndash_course_get_single_parent_step( $course_id, $post->ID, 'sfwd-lessons' ); } } } extract( $args ); /** * Filter widget title * * @since 2.1.0 * * @param string */ $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance ); echo $before_widget; if ( ! empty( $title ) ) { echo $before_title . $title . $after_title; } learndash_course_navigation( $course_id, $instance, $lesson_query_args ); echo $after_widget; $learndash_shortcode_used = true; } /** * Handles widget updates in admin * * @since 2.1.0 * * @param array $new_instance * @param array $old_instance * @return array $instance */ function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); $instance['show_lesson_quizzes'] = isset( $new_instance['show_lesson_quizzes'] ) ? (bool) $new_instance['show_lesson_quizzes'] : false; $instance['show_topic_quizzes'] = isset( $new_instance['show_topic_quizzes'] ) ? (bool) $new_instance['show_topic_quizzes'] : false; $instance['show_course_quizzes'] = isset( $new_instance['show_course_quizzes'] ) ? (bool) $new_instance['show_course_quizzes'] : false; return $instance; } /** * Display widget form in admin * * @since 2.1.0 * * @param array $instance widget instance */ function form( $instance ) { $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) ); $title = strip_tags( $instance['title'] ); $show_lesson_quizzes = isset( $instance['show_lesson_quizzes'] ) ? (bool) $instance['show_lesson_quizzes'] : false; $show_topic_quizzes = isset( $instance['show_topic_quizzes'] ) ? (bool) $instance['show_topic_quizzes'] : false; $show_course_quizzes = isset( $instance['show_course_quizzes'] ) ? (bool) $instance['show_course_quizzes'] : false; ?> <p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'learndash' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /> </p> <p> <input class="checkbox" type="checkbox" <?php checked( $show_course_quizzes ); ?> id="<?php echo $this->get_field_id( 'show_course_quizzes' ); ?>" name="<?php echo $this->get_field_name( 'show_course_quizzes' ); ?>" /> <label for="<?php echo $this->get_field_id( 'show_course_quizzes' ); ?>"><?php echo sprintf( esc_html_x( 'Show %1$s %2$s?', 'Show Course Quizzes?', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ), LearnDash_Custom_Label::get_label( 'quizzes' ) ); ?></label> </p> <p> <input class="checkbox" type="checkbox" <?php checked( $show_lesson_quizzes ); ?> id="<?php echo $this->get_field_id( 'show_lesson_quizzes' ); ?>" name="<?php echo $this->get_field_name( 'show_lesson_quizzes' ); ?>" /> <label for="<?php echo $this->get_field_id( 'show_lesson_quizzes' ); ?>"><?php echo sprintf( esc_html_x( 'Show %1$s %2$s?', 'Show Lesson Quizzes', 'learndash' ), LearnDash_Custom_Label::get_label( 'lesson' ), LearnDash_Custom_Label::get_label( 'quizzes' ) ); ?></label> </p> <p> <input class="checkbox" type="checkbox" <?php checked( $show_topic_quizzes ); ?> id="<?php echo $this->get_field_id( 'show_topic_quizzes' ); ?>" name="<?php echo $this->get_field_name( 'show_topic_quizzes' ); ?>" /> <label for="<?php echo $this->get_field_id( 'show_topic_quizzes' ); ?>"><?php echo sprintf( esc_html_x( 'Show %1$s %2$s?', 'Show Topic Quizzes?', 'learndash' ), LearnDash_Custom_Label::get_label( 'topic' ), LearnDash_Custom_Label::get_label( 'quizzes' ) ); ?></label> </p> <?php /* ?> <p> <label for="<?php echo $this->get_field_id( 'lessons_per_page' ); ?>"><?php echo sprintf( esc_html_x( '%s per page', 'placeholder: Lessons', 'learndash' ), LearnDash_Custom_Label::get_label( 'lessons' ) ); ?></label> <input type="text" id="<?php echo $this->get_field_id( 'lessons_per_page' ); ?>" name="<?php echo $this->get_field_name( 'lessons_per_page' ); ?>" value="<?php echo $lessons_per_page; ?>" /> </p> <?php */ ?> <?php } } add_action( 'widgets_init', function( ) { return register_widget("LearnDash_Course_Navigation_Widget"); } ); /** * Outputs course navigation template for widget * * @since 2.1.0 * * @param int $course_id course id * @param widget_instance array of widgert settings * @param lesson_query_args array of query options for pagnination etc. * * @return string course navigation output */ function learndash_course_navigation( $course_id, $widget_instance = array(), $lesson_query_args = array() ) { $course = get_post( $course_id ); if ( empty( $course->ID ) || $course_id != $course->ID ) { return; } if ( empty( $course->ID ) || $course->post_type != 'sfwd-courses' ) { return; } if ( is_user_logged_in() ) $user_id = get_current_user_id(); else $user_id = 0; $course_navigation_widget_pager = array(); global $course_navigation_widget_pager; add_action( 'learndash_course_lessons_list_pager', function( $query_result = null ) { global $course_navigation_widget_pager; $course_navigation_widget_pager['paged'] = 1; if ( ( isset( $query_result->query_vars['paged'] ) ) && ( $query_result->query_vars['paged'] > 1 ) ) $course_navigation_widget_pager['paged'] = $query_result->query_vars['paged']; $course_navigation_widget_pager['total_items'] = $query_result->found_posts; $course_navigation_widget_pager['total_pages'] = $query_result->max_num_pages; } ); $lessons = learndash_get_course_lessons_list( $course, $user_id, $lesson_query_args ); $template_file = SFWD_LMS::get_template( 'course_navigation_widget', array( 'course_id' => $course_id, 'course' => $course, 'lessons' => $lessons, 'widget' => $widget_instance ), null, true ); if ( ! empty( $template_file ) ) { include( $template_file ); } } /** * Outputs course navigation admin template for widget * * @since 2.1.0 * * @param int $course_id course id * @param widget_instance array of widgert settings * @param lesson_query_args array of query options for pagnination etc. * * @return string course navigation output */ function learndash_course_navigation_admin( $course_id, $instance = array(), $lesson_query_args = array() ) { $course = get_post( $course_id ); if ( empty( $course->ID ) || $course_id != $course->ID ) { return; } $course = get_post( $course_id ); if ( empty( $course->ID ) || $course->post_type != 'sfwd-courses' ) { return; } if ( is_user_logged_in() ) $user_id = get_current_user_id(); else $user_id = 0; $course_navigation_admin_pager = array(); global $course_navigation_admin_pager; add_action( 'learndash_course_lessons_list_pager', function( $query_result = null ) { global $course_navigation_admin_pager; $course_navigation_admin_pager['paged'] = 1; if ( ( isset( $query_result->query_vars['paged'] ) ) && ( $query_result->query_vars['paged'] > 1 ) ) $course_navigation_admin_pager['paged'] = $query_result->query_vars['paged']; $course_navigation_admin_pager['total_items'] = $query_result->found_posts; $course_navigation_admin_pager['total_pages'] = $query_result->max_num_pages; } ); $lessons = learndash_get_course_lessons_list( $course, $user_id, $lesson_query_args ); $quizzes = learndash_get_course_quiz_list( $course_id, $user_id ); SFWD_LMS::get_template( 'course_navigation_admin', array( 'user_id' => $user_id, 'course_id' => $course_id, 'course' => $course, 'lessons' => $lessons, 'course_quiz_list' => $quizzes, 'widget' => $instance ), true ); } function learndash_course_switcher_admin( $course_id ) { $template_file = SFWD_LMS::get_template( 'course_navigation_switcher_admin', array(), null, true ); if ( ! empty( $template_file ) ) { include( $template_file ); } } /** * Register course navigation meta box for admin * * @since 2.1.0 */ /* function learndash_course_navigation_admin_box() { $post_types = array('sfwd-courses', 'sfwd-lessons', 'sfwd-quiz', 'sfwd-topic'); foreach( $post_types as $post_type ) { add_meta_box( 'learndash_course_navigation_admin_meta', esc_html__( 'Associated Content', 'learndash' ), 'learndash_course_navigation_admin_box_content', $post_type, 'side', 'high' ); } } add_action( 'add_meta_boxes', 'learndash_course_navigation_admin_box' ); */ /** * Hook to add the needed style and script files needed to handle pager * * @since 2.5.4 */ function learndash_course_step_edit_init() { global $learndash_assets_loaded; $screen = get_current_screen(); if ( ( $screen->base == 'post') && ( in_array( $screen->post_type, array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) ) { $filepath = SFWD_LMS::get_template( 'learndash_pager.css', null, null, true ); if ( !empty( $filepath ) ) { wp_enqueue_style( 'learndash_pager_css', learndash_template_url_from_path( $filepath ), array(), LEARNDASH_SCRIPT_VERSION_TOKEN ); wp_style_add_data( 'learndash_pager_css', 'rtl', 'replace' ); $learndash_assets_loaded['styles']['learndash_pager_css'] = __FUNCTION__; } $filepath = SFWD_LMS::get_template( 'learndash_pager.js', null, null, true ); if ( !empty( $filepath ) ) { wp_enqueue_script( 'learndash_pager_js', learndash_template_url_from_path( $filepath ), array( 'jquery' ), LEARNDASH_SCRIPT_VERSION_TOKEN, true ); $learndash_assets_loaded['scripts']['learndash_pager_js'] = __FUNCTION__; } } } add_action( 'load-post.php', 'learndash_course_step_edit_init' ); add_action( 'load-post-new.php', 'learndash_course_step_edit_init' ); /** * Add content to course navigation meta box for admi * * @since 2.1.0 */ function learndash_course_navigation_admin_box_content() { if ( ( isset($_GET['post'] ) ) && ( !empty( $_GET['post'] ) ) ) { $course_id = learndash_get_course_id( intval( $_GET['post'] ) ); if ( !empty( $course_id ) ) { $instance = array(); $instance['show_widget_wrapper'] = true; $instance['course_id'] = $course_id; $instance['current_lesson_id'] = 0; $instance['current_step_id'] = 0; $lesson_query_args = array(); $lesson_query_args['pagination'] = 'true'; $lesson_query_args['paged'] = 1; //if ( $course_id != intval( $_GET['post'] ) ) // $widget_instance['current_step_id'] = intval( $_GET['post'] ); //else // $widget_instance['current_step_id'] = 0; //$current_post_type = get_post_type( $_GET['post'] ); $current_post = get_post( intval( $_GET['post'] ) ); if ( ( is_a( $current_post, 'WP_Post' ) ) && ( is_user_logged_in() ) && ( in_array( $current_post->post_type, array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) ) { $course_lessons_per_page = learndash_get_course_lessons_per_page( $course_id ); if ( $course_lessons_per_page > 0 ) { if ( in_array( $current_post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) { $instance['current_step_id'] = $current_post->ID; if ( $current_post->post_type == 'sfwd-lessons' ) { $instance['current_lesson_id'] = $instance['current_step_id']; } else if ( in_array( $current_post->post_type, array('sfwd-topic', 'sfwd-quiz') ) ) { $instance['current_lesson_id'] = learndash_course_get_single_parent_step( $course_id, $instance['current_step_id'], 'sfwd-lessons' ); } if ( !empty( $instance['current_lesson_id'] ) ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); $course_lesson_ids = $ld_course_steps_object->get_children_steps( $course_id, 'sfwd-lessons' ); if ( !empty( $course_lesson_ids ) ) { $course_lessons_paged = array_chunk( $course_lesson_ids, $course_lessons_per_page, true ); $lessons_paged = 0; foreach( $course_lessons_paged as $paged => $paged_set ) { if ( in_array( $instance['current_lesson_id'], $paged_set ) ) { $lessons_paged = $paged + 1; break; } } if ( !empty( $lessons_paged ) ) { $lesson_query_args['pagination'] = 'true'; $lesson_query_args['paged'] = $lessons_paged; } } } else if ( in_array( $current_post->post_type, array( 'sfwd-quiz') ) ) { // If here we have a global Quiz. So we set the pager to the max number $course_lesson_ids = learndash_course_get_steps_by_type( $course_id, 'sfwd-lessons' ); if ( !empty( $course_lesson_ids ) ) { $course_lessons_paged = array_chunk( $course_lesson_ids, $course_lessons_per_page, true ); $lesson_query_args['paged'] = count( $course_lessons_paged ); } } } } else { $lesson_query_args['pagination'] = 'false'; if ( in_array( $current_post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) { $instance['current_step_id'] = $current_post->ID; if ( $current_post->post_type == 'sfwd-lessons' ) { $instance['current_lesson_id'] = $current_post->ID; } else if ( in_array( $current_post->post_type, array('sfwd-topic', 'sfwd-quiz') ) ) { $instance['current_lesson_id'] = learndash_course_get_single_parent_step( $course_id, $current_post->ID, 'sfwd-lessons' ); } } } } learndash_course_navigation_admin( $course_id, $instance, $lesson_query_args ); } else { echo sprintf( // translators: placeholders: Course. esc_html_x( 'No associated %s', 'placeholder: Course', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ); } if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { learndash_course_switcher_admin( $course_id ); } } } /** * Get course info html output for user (helper function) * * @since 2.1.0 * * @param int $user_id * @return string course info output */ function learndash_course_info( $user_id, $atts = array() ) { return SFWD_LMS::get_course_info( $user_id, $atts ); } /** * Shortcode get course info html output for user (helper function) * * @since 2.1.0 * * @param array $atts shortcode attributes * @return string course info output */ function learndash_course_info_shortcode( $atts = array() ) { global $learndash_shortcode_used; if ( ( isset( $atts['user_id'] ) ) && ( !empty( $atts['user_id'] ) ) ) { $user_id = intval( $atts['user_id'] ); unset( $atts['user_id'] ); } else { $current_user = wp_get_current_user(); if ( empty( $current_user->ID ) ) { return; } $user_id = $current_user->ID; } $learndash_shortcode_used = true; return SFWD_LMS::get_course_info( $user_id, $atts ); } add_shortcode( 'ld_course_info', 'learndash_course_info_shortcode' ); function learndash_user_course_points_shortcode( $atts, $content = '' ) { global $learndash_shortcode_used; $defaults = array( 'user_id' => get_current_user_id(), 'context' => 'ld_user_course_points' ); $atts = wp_parse_args( $atts, $defaults ); if ( !isset( $atts['user_id'] ) ) return; $learndash_shortcode_used = true; $user_couse_points = learndash_get_user_course_points( $atts['user_id'] ); $content = SFWD_LMS::get_template( 'learndash_course_points_user_message', array( 'user_course_points' => $user_couse_points, 'user_id' => $atts['user_id'], 'shortcode_atts' => $atts, ), false ); return $content; } add_shortcode( 'ld_user_course_points', 'learndash_user_course_points_shortcode' ); /** * Shortcoude output profile for user * * @since 2.1.0 * * @param array $atts shortcode attributes * @return string output profile for user */ function learndash_profile( $atts ) { global $learndash_shortcode_used; // Add check to ensure user it logged in if ( !is_user_logged_in() ) return ''; $defaults = array( 'user_id' => get_current_user_id(), 'per_page' => false, 'order' => 'DESC', 'orderby' => 'ID', 'course_points_user' => 'yes', 'expand_all' => false, 'profile_link' => 'yes', 'show_header' => 'yes', 'show_quizzes' => 'yes', 'show_search' => 'yes', 'search' => '', ); $atts = wp_parse_args( $atts, $defaults ); if ( ( strtolower($atts['expand_all'] ) == 'yes' ) || ( $atts['expand_all'] == 'true' ) || ( $atts['expand_all'] == '1' )) $atts['expand_all'] = true; else $atts['expand_all'] = false; if ( ( strtolower($atts['show_header'] ) == 'yes' ) || ( $atts['show_header'] == 'true' ) || ( $atts['show_header'] == '1' )) $atts['show_header'] = 'yes'; else $atts['show_header'] = false; if ( ( strtolower($atts['show_search'] ) == 'yes' ) || ( $atts['show_search'] == 'true' ) || ( $atts['show_search'] == '1' )) $atts['show_search'] = 'yes'; else $atts['show_search'] = false; if ( ( strtolower($atts['course_points_user'] ) == 'yes' ) || ( $atts['course_points_user'] == 'true' ) || ( $atts['course_points_user'] == '1' )) $atts['course_points_user'] = 'yes'; else $atts['course_points_user'] = false; if ( $atts['per_page'] === false ) { $atts['per_page'] = $atts['quiz_num'] = LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Per_Page', 'per_page' ); } else { $atts['per_page'] = intval( $atts['per_page'] ); } if ( $atts['per_page'] > 0 ) { $atts['paged'] = 1; } else { unset( $atts['paged'] ); $atts['nopaging'] = true; } if ( ( strtolower( $atts['profile_link'] ) == 'yes' ) || ( $atts['profile_link'] == 'true' ) || ( $atts['profile_link'] == '1' ) ) $atts['profile_link'] = true; else $atts['profile_link'] = false; if ( ( strtolower( $atts['show_quizzes'] ) == 'yes' ) || ( $atts['show_quizzes'] == 'true' ) || ( $atts['show_quizzes'] == '1' ) ) $atts['show_quizzes'] = true; else $atts['show_quizzes'] = false; if ( ( isset( $_GET['ld-profile-search'] ) ) && ( ! empty( $_GET['ld-profile-search'] ) ) ) { $atts['search'] = esc_attr( $_GET['ld-profile-search'] ); } $atts = apply_filters('learndash_profile_shortcode_atts', $atts ); if ( isset( $atts['search'] ) ) { $atts['s'] = $atts['search']; unset( $atts['search'] ); } if ( empty( $atts['user_id'] ) ) return; $current_user = get_user_by( 'id', $atts['user_id'] ); $user_courses = ld_get_mycourses( $atts['user_id'], $atts ); $usermeta = get_user_meta( $atts['user_id'], '_sfwd-quizzes', true ); $quiz_attempts_meta = empty( $usermeta ) ? false : $usermeta; $quiz_attempts = array(); if ( ! empty( $quiz_attempts_meta ) ) { foreach ( $quiz_attempts_meta as $quiz_attempt ) { $c = learndash_certificate_details( $quiz_attempt['quiz'], $atts['user_id'] ); $quiz_attempt['post'] = get_post( $quiz_attempt['quiz'] ); $quiz_attempt['percentage'] = ! empty( $quiz_attempt['percentage'] ) ? $quiz_attempt['percentage'] : ( ! empty( $quiz_attempt['count'] ) ? $quiz_attempt['score'] * 100 / $quiz_attempt['count'] : 0 ); if ( $atts['user_id'] == get_current_user_id() && ! empty( $c['certificateLink'] ) && ( ( isset( $quiz_attempt['percentage'] ) && $quiz_attempt['percentage'] >= $c['certificate_threshold'] * 100 ) ) ) { $quiz_attempt['certificate'] = $c; } if ( !isset( $quiz_attempt['course'] ) ) $quiz_attempt['course'] = learndash_get_course_id( $quiz_attempt['quiz'] ); $course_id = intval( $quiz_attempt['course'] ); $quiz_attempts[$course_id][] = $quiz_attempt; } } $profile_pager = array(); if ( ( isset( $atts['per_page'] ) ) && ( intval( $atts['per_page'] ) > 0 ) ) { $atts['per_page'] = intval( $atts['per_page'] ); if ( ( isset( $_GET['ld-profile-page'] ) ) && ( !empty( $_GET['ld-profile-page'] ) ) ) { $profile_pager['paged'] = intval( $_GET['ld-profile-page'] ); } else { $profile_pager['paged'] = 1; } $profile_pager['total_items'] = count( $user_courses ); $profile_pager['total_pages'] = ceil( count( $user_courses ) / $atts['per_page'] ); $user_courses = array_slice ( $user_courses, ( $profile_pager['paged'] * $atts['per_page'] ) - $atts['per_page'], $atts['per_page'], false ); } $learndash_shortcode_used = true; return SFWD_LMS::get_template( 'profile', array( 'user_id' => $atts['user_id'], 'quiz_attempts' => $quiz_attempts, 'current_user' => $current_user, 'user_courses' => $user_courses, 'shortcode_atts' => $atts, 'profile_pager' => $profile_pager ) ); } add_shortcode( 'ld_profile', 'learndash_profile' ); function wp_ajax_ld_course_registered_pager() { if ( !is_user_logged_in() ) return ''; if ( ! current_user_can( 'read' ) ) return ''; add_filter('learndash_course_info_paged', function( $paged = 1, $context = '' ) { if ( ( $context == 'registered' ) && ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) { $paged = intval( $_POST['paged'] ); } // Always return $paged return $paged; }, 10, 2 ); $reply_data = array(); if ( isset( $_POST['shortcode_atts'] ) ) $shortcode_atts = $_POST['shortcode_atts']; else $shortcode_atts = array(); $user_id = get_current_user_id(); if ( learndash_is_group_leader_user() ) { if ( ( isset( $shortcode_atts['user_id'] ) ) && ( ! empty( $shortcode_atts['user_id'] ) ) ) { if ( learndash_is_group_leader_of_user( $user_id, $shortcode_atts['user_id'] ) ) { $user_id = intval( $shortcode_atts['user_id'] ); } } } else if ( learndash_is_admin_user() ) { if ( ( isset( $shortcode_atts['user_id'] ) ) && ( ! empty( $shortcode_atts['user_id'] ) ) ) { $user_id = intval( $shortcode_atts['user_id'] ); } } $shortcode_atts['return'] = true; $shortcode_atts['type'] = 'registered'; // Setup the pager filter. if ( !learndash_ajax_pager_verify_atts( $user_id, $shortcode_atts ) ) { return ''; } $user_progress = SFWD_LMS::get_course_info( $user_id, $shortcode_atts ); if ( ( isset( $user_progress['courses_registered'] ) ) && ( !empty( $user_progress['courses_registered'] ) ) ) { $courses_registered = $user_progress['courses_registered']; $level = ob_get_level(); ob_start(); $template_file = SFWD_LMS::get_template( 'course_registered_rows', null, null, true ); if ( ! empty( $template_file ) ) { include $template_file; } $reply_data['content'] = learndash_ob_get_clean( $level ); } if ( isset( $user_progress['courses_registered_pager'] ) ) { $reply_data['pager'] = SFWD_LMS::get_template( 'learndash_pager.php', array( 'pager_results' => $user_progress['courses_registered_pager'], 'pager_context' => 'course_info_registered' ) ); } echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_course_registered_pager', 'wp_ajax_ld_course_registered_pager' ); function wp_ajax_ld_course_progress_pager() { if ( !is_user_logged_in() ) return ''; add_filter('learndash_course_info_paged', function( $paged = 1, $context = '' ) { if ( ( $context == 'courses' ) && ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) { $paged = intval( $_POST['paged'] ); } // Always return $paged return $paged; }, 10, 2 ); $reply_data = array(); if ( isset( $_POST['shortcode_atts'] ) ) $shortcode_atts = $_POST['shortcode_atts']; else $shortcode_atts = array(); $user_id = get_current_user_id(); if ( ( isset( $shortcode_atts['user_id'] ) ) && ( ! empty( $shortcode_atts['user_id'] ) ) ) { $shortcode_atts['user_id'] = absint( $shortcode_atts['user_id'] ); if ( $user_id !== $shortcode_atts['user_id'] ) { if ( ( learndash_is_group_leader_user() ) && ( learndash_is_group_leader_of_user( $user_id, $shortcode_atts['user_id'] ) ) ) { $user_id = intval( $shortcode_atts['user_id'] ); } else if ( learndash_is_admin_user() ) { $user_id = intval( $shortcode_atts['user_id'] ); } } } $shortcode_atts['return'] = true; $shortcode_atts['type'] = 'course'; // Setup the pager filter. if ( !learndash_ajax_pager_verify_atts( $user_id, $shortcode_atts) ) { return ''; } $user_progress = SFWD_LMS::get_course_info( $user_id, $shortcode_atts ); if ( ( isset( $user_progress['course_progress'] ) ) && ( !empty( $user_progress['course_progress'] ) ) ) { $courses_registered = $user_progress['courses_registered']; $course_progress = $user_progress['course_progress']; $level = ob_get_level(); ob_start(); $template_file = SFWD_LMS::get_template( 'course_progress_rows', null, null, true ); if ( ! empty( $template_file ) ) { include $template_file; } $reply_data['content'] = learndash_ob_get_clean( $level ); } if ( isset( $user_progress['course_progress_pager'] ) ) { $reply_data['pager'] = SFWD_LMS::get_template( 'learndash_pager.php', array( 'pager_results' => $user_progress['course_progress_pager'], 'pager_context' => 'course_info_courses' ) ); } echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_course_progress_pager', 'wp_ajax_ld_course_progress_pager' ); add_action( 'wp_ajax_nopriv_ld_course_progress_pager', 'wp_ajax_ld_course_progress_pager' ); function wp_ajax_ld_quiz_progress_pager() { if ( ! is_user_logged_in() ) return ''; if ( ! current_user_can( 'read' ) ) return ''; add_filter('learndash_quiz_info_paged', function( $paged = 1 ) { if ( ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) { $paged = intval( $_POST['paged'] ); } return $paged; }); if ( isset( $_POST['shortcode_atts'] ) ) $shortcode_atts = $_POST['shortcode_atts']; else $shortcode_atts = array(); $user_id = get_current_user_id(); if ( ( isset( $shortcode_atts['user_id'] ) ) && ( ! empty( $shortcode_atts['user_id'] ) ) ) { $shortcode_atts['user_id'] = absint( $shortcode_atts['user_id'] ); if ( $user_id !== $shortcode_atts['user_id'] ) { if ( ( learndash_is_group_leader_user() ) && ( learndash_is_group_leader_of_user( $user_id, $shortcode_atts['user_id'] ) ) ) { $user_id = intval( $shortcode_atts['user_id'] ); } else if ( learndash_is_admin_user() ) { $user_id = intval( $shortcode_atts['user_id'] ); } } } $shortcode_atts['return'] = true; $shortcode_atts['type'] = 'quiz'; // Setup the pager filter. if ( !learndash_ajax_pager_verify_atts( $user_id, $shortcode_atts ) ) { return ''; } $reply_data = array(); $user_progress = SFWD_LMS::get_course_info( $user_id, $shortcode_atts ); if ( ( isset( $user_progress['quizzes'] ) ) && ( !empty( $user_progress['quizzes'] ) ) ) { $quizzes = $user_progress['quizzes']; $level = ob_get_level(); ob_start(); $template_file = SFWD_LMS::get_template( 'quiz_progress_rows', null, null, true ); if ( ! empty( $template_file ) ) { include $template_file; } $reply_data['content'] = learndash_ob_get_clean( $level ); } if ( isset( $user_progress['quizzes_pager'] ) ) { $reply_data['pager'] = SFWD_LMS::get_template( 'learndash_pager.php', array( 'pager_results' => $user_progress['quizzes_pager'], 'pager_context' => 'course_info_quizzes' ) ); } echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_quiz_progress_pager', 'wp_ajax_ld_quiz_progress_pager' ); /** * Course Navigation AJAX Pager handler function * * @since 2.5.4 */ function wp_ajax_ld_course_navigation_pager() { $reply_data = array(); if ( ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) { $paged = intval( $_POST['paged'] ); } else { $paged = 1; } if ( ( isset( $_POST['widget_data']['course_id'] ) ) && ( !empty( $_POST['widget_data']['course_id'] ) ) ) { $course_id = intval( $_POST['widget_data']['course_id'] ); } else { $course_id = 0; } if ( ( isset( $_POST['widget_data']['widget_instance'] ) ) && ( !empty( $_POST['widget_data']['widget_instance'] ) ) ) { $widget_instance = $_POST['widget_data']['widget_instance']; } else { $widget_instance = array(); } if ( ( !empty( $course_id ) ) && ( !empty( $widget_instance ) ) ) { $lesson_query_args = array(); $course_lessons_per_page = learndash_get_course_lessons_per_page( $course_id ); if ( $course_lessons_per_page > 0 ) { $lesson_query_args['pagination'] = 'true'; $lesson_query_args['paged'] = $paged; } $widget_instance['show_widget_wrapper'] = false; $level = ob_get_level(); ob_start(); learndash_course_navigation( $course_id, $widget_instance, $lesson_query_args ); $reply_data['content'] = learndash_ob_get_clean( $level ); } echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_course_navigation_pager', 'wp_ajax_ld_course_navigation_pager' ); add_action( 'wp_ajax_nopriv_ld_course_navigation_pager', 'wp_ajax_ld_course_navigation_pager' ); /** * Course Navigation AJAX Pager handler function * * @since 2.5.4 */ function wp_ajax_ld_course_navigation_admin_pager() { $reply_data = array(); if ( ( isset( $_POST['paged'] ) ) && ( !empty( $_POST['paged'] ) ) ) { $paged = intval( $_POST['paged'] ); } else { $paged = 1; } if ( ( isset( $_POST['widget_data'] ) ) && ( !empty( $_POST['widget_data'] ) ) ) { $widget_data = $_POST['widget_data']; } else { $widget_data = array(); } if ( ( isset( $widget_data['course_id'] ) ) && ( !empty( $widget_data['course_id'] ) ) ) { $course_id = intval( $widget_data['course_id'] ); } else { $course_id = 0; } if ( ( !empty( $course_id ) ) && ( !empty( $widget_data ) ) ) { if ( ( isset( $_POST['widget_data']['nonce'] ) ) && ( ! empty( $_POST['widget_data']['nonce'] ) ) && ( wp_verify_nonce( $_POST['widget_data']['nonce'], 'ld_course_navigation_admin_pager_nonce_' . $course_id . '_' . get_current_user_id() ) ) ) { $lesson_query_args = array(); //$course_lessons_per_page = learndash_get_course_lessons_per_page( $course_id ); //if ( $course_lessons_per_page > 0 ) { $lesson_query_args['pagination'] = 'true'; $lesson_query_args['paged'] = $paged; //} $widget_data['show_widget_wrapper'] = false; $level = ob_get_level(); ob_start(); learndash_course_navigation_admin( $course_id, $widget_data, $lesson_query_args ); $reply_data['content'] = learndash_ob_get_clean( $level ); } } echo json_encode( $reply_data ); die(); } add_action( 'wp_ajax_ld_course_navigation_admin_pager', 'wp_ajax_ld_course_navigation_admin_pager' ); function learndash_ajax_pager_verify_atts( $user_id, $shortcode_atts ) { $use_filter = false; if ( ( !empty( $user_id ) ) && ( isset( $shortcode_atts['pagenow'] ) ) ) { if ( ( isset( $shortcode_atts['pagenow_nonce'] ) ) && ( !empty( $shortcode_atts['pagenow_nonce'] ) ) ) { if ( ( $shortcode_atts['pagenow'] == 'profile.php' ) || ( $shortcode_atts['pagenow'] == 'user-edit.php' ) ) { if ( wp_verify_nonce( $shortcode_atts['pagenow_nonce'], $shortcode_atts['pagenow'] .'-'. $user_id ) ) { $use_filter = true; } } else if ( $shortcode_atts['pagenow'] == 'group_admin_page' ) { if ( ( isset( $shortcode_atts['group_id'] ) ) && ( intval( $shortcode_atts['group_id'] ) ) ) { if ( wp_verify_nonce( $shortcode_atts['pagenow_nonce'], $shortcode_atts['pagenow'] .'-'. intval( $shortcode_atts['group_id'] ).'-'. $user_id ) ) { $use_filter = true; } } } else if ( $shortcode_atts['pagenow'] == 'learndash' ) { if ( wp_verify_nonce( $shortcode_atts['pagenow_nonce'], $shortcode_atts['pagenow'] .'-'. $user_id ) ) { // Hard return here because we don't want to set $user_filter to true as that will trigger the // logic below to show the admin only details link. return true; } } } if ( $use_filter == true ) { // The following filter is called during the template output. Normally if the admin is viewing profile.php // We show the edit options. but via AJAX we don't know from where the user is viewing. It may be a front-end // page etc. So as part of the shortcode atts we store the pagenow and a nonce we then verify within the logic below. add_filter( 'learndash_show_user_course_complete_options', function( $show_admin_options, $user_id = 0 ) { if ( current_user_can( 'edit_users' ) ) { $show_admin_options = true; } return $show_admin_options; }, 1, 2 ); } } return $use_filter; } ld-course-progress.php 0000666 00000243753 15214044143 0011034 0 ustar 00 <?php /** * Course Progress Functions * * @since 2.1.0 * * @package LearnDash\Course */ /** * Output HTML output to mark a course complete * * Must meet requirements of course * * @since 2.1.0 * * @param object $post WP_Post lesson, topic. * @return string HTML output to mark course complete */ function learndash_mark_complete( $post, $atts = array() ) { if ( ! is_user_logged_in() ) { return ''; } $user_id = get_current_user_id(); if ( isset( $_POST['sfwd_mark_complete'] ) && isset( $_POST['post'] ) && $post->ID == intval( $_POST['post'] ) ) { return ''; } $bypass_course_limits_admin_users = false; if ( learndash_is_admin_user( $user_id ) ) { $bypass_course_limits_admin_users = LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Section_General_Admin_User', 'bypass_course_limits_admin_users' ); if ( 'yes' === $bypass_course_limits_admin_users ) { $bypass_course_limits_admin_users = true; } else { $bypass_course_limits_admin_users = false; } } else { $bypass_course_limits_admin_users = false; } // For logged in users to allow an override filter. $bypass_course_limits_admin_users = apply_filters( 'learndash_prerequities_bypass', $bypass_course_limits_admin_users, $user_id, $post->ID, $post ); $course_id = learndash_get_course_id( $post->ID ); if ( ( learndash_lesson_progression_enabled() ) && ( ! $bypass_course_limits_admin_users ) ) { if ( 'sfwd-lessons' === $post->post_type ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['this']->completed ) ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $progress['this']->ID, $user_id ) ) { return learndash_show_mark_incomplete($post, $atts ); } } if ( ! empty( $progress['prev'] ) && empty( $progress['prev']->completed ) && learndash_lesson_progression_enabled() ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $progress['prev']->ID, $user_id ) ) { return ''; } } if ( ! learndash_lesson_topics_completed( $post->ID ) ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $post->ID, $user_id ) ) { return ''; } } } if ( 'sfwd-topic' === $post->post_type ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['this']->completed ) ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $progress['this']->ID, $user_id ) ) { return learndash_show_mark_incomplete($post, $atts ); } } if ( ! empty( $progress['prev'] ) && empty( $progress['prev']->completed ) && learndash_lesson_progression_enabled() ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $progress['prev']->ID, $user_id ) ) { return ''; } } if ( learndash_lesson_progression_enabled() ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { // $course_id = learndash_get_course_id( $post->ID ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } $lesson = get_post( $lesson_id ); if ( ! is_previous_complete( $lesson ) ) { if ( ! apply_filters( 'learndash_previous_step_completed', false, $lesson->ID, $user_id ) ) { return ''; } } } } } else { $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['this']->completed ) ) { return ''; } } if ( lesson_hasassignments( $post ) ) { global $learndash_assignment_upload_message; $ret = SFWD_LMS::get_template( 'learndash_lesson_assignment_upload_form.php', array( 'course_step_post' => $post, 'user_id' => $user_id, 'assignment_upload_error_message' => $learndash_assignment_upload_message, ) ); return $ret; } else { $return = ''; $button_disabled = ''; $time = 0; $timeval = learndash_forced_lesson_time( $post ); if ( ! empty( $timeval ) ) { $time = learndash_convert_lesson_time_time( $timeval ); /* $time_sections = explode( ' ', $timeval ); $h = $m = $s = 0; foreach ( $time_sections as $k => $v ) { $value = trim( $v ); if ( strpos( $value, 'h' ) ) { $h = intVal( $value ); } elseif ( strpos( $value, 'm' ) ) { $m = intVal( $value ); } elseif ( strpos( $value, 's' ) ) { $s = intVal( $value ); } } $time = $h * 60 * 60 + $m * 60 + $s; if ( $time == 0 ) { $time = (int) $timeval; } */ } if ( ( ! learndash_is_admin_user( $user_id ) ) || ( ! $bypass_course_limits_admin_users ) ) { if ( ! empty( $time ) ) { $time_cookie_key = learndash_forced_lesson_time_cookie_key( $post ); // Set the mark complete button disabled. $button_disabled = " disabled='disabled' "; wp_enqueue_script( 'jquery-cookie', plugins_url( 'js/jquery.cookie' . leardash_min_asset() . '.js', WPPROQUIZ_FILE ), array( 'jquery' ), '1.4.0', true ); global $learndash_assets_loaded; $learndash_assets_loaded['scripts']['jquery-cookie'] = __FUNCTION__; } } /** * Allow the outside world to filter the form/button atts array * * @since 3.0 * @param array $atts Arry of form, button, and timer attributes to override id and class. * @param object $post WP_Post object being displayed. */ $atts = apply_filters( 'learndash_mark_complete_form_atts', $atts, $post ); if ( isset( $atts['form']['id'] ) ) { $form_id = ' id="' . esc_attr( $atts['form']['id'] ) . '" '; } else { $form_id = ''; } if ( isset( $atts['form']['class'] ) ) { $form_class = ' class="sfwd-mark-complete ' . esc_attr( $atts['form']['class'] ) . '" '; } else { $form_class = ' class="sfwd-mark-complete" '; } if ( isset( $atts['button']['id'] ) ) { $button_id = ' id="' . esc_attr( $atts['button']['id'] ) . '" '; } else { $button_id = ''; } if ( isset( $atts['button']['class'] ) ) { $button_class = ' class="learndash_mark_complete_button ' . esc_attr( $atts['button']['class'] ) . '" '; } else { $button_class = ' class="learndash_mark_complete_button" '; } $form_fields = '<input type="hidden" value="' . $post->ID . '" name="post" /> <input type="hidden" value="' . learndash_get_course_id( $post->ID ) . '" name="course_id" /> <input type="hidden" value="' . wp_create_nonce( 'sfwd_mark_complete_' . get_current_user_id() . '_' . $post->ID ) . '" name="sfwd_mark_complete" /> <input type="submit" ' . $button_id . ' value="' . esc_html( LearnDash_Custom_Label::get_label( 'button_mark_complete' ) ) . '" ' . $button_class . ' ' . $button_disabled . '/>'; /** * Allow the outside world to filter the form fields. * * @since 3.0 * @param string $form_fields. * @param object $post WP_Post object being displayed. */ $form_fields = apply_filters( 'learndash_mark_complete_form_fields', $form_fields, $post ); $return .= '<form ' . $form_id . ' ' . $form_class . ' method="post" action="">' . $form_fields . '</form>'; if ( ( ! learndash_is_admin_user( $user_id ) ) || ( ! $bypass_course_limits_admin_users ) ) { if ( ! empty( $time ) ) { if ( isset( $atts['timer']['id'] ) ) { $timer_id = ' id="' . esc_attr( $atts['timer']['id'] ) . '" '; } else { $timer_id = ''; } $timer_class = ' class="learndash_timer'; if ( isset( $atts['timer']['class'] ) ) { $timer_class .= ' ' . esc_attr( $atts['timer']['class'] ); } $timer_class .= '" '; $return .= '<span ' . $timer_id . ' ' . $timer_class . ' data-timer-seconds="' . $time . '" data-button="input.learndash_mark_complete_button" data-cookie-key="' . $time_cookie_key . '"></span>'; } } } /** * Filter HTML output to mark course complete * * @since 2.1.0 * * @param string $return */ return apply_filters( 'learndash_mark_complete', $return, $post ); } function learndash_ajax_mark_complete( $quiz_id = null, $lesson_id = null ) { if ( empty( $quiz_id ) || empty( $lesson_id ) ) { return; } global $post; $current_user = wp_get_current_user(); $user_id = $current_user->ID; $can_attempt_again = learndash_can_attempt_again( $user_id, $quiz_id ); if ( $can_attempt_again ) { $link = learndash_next_lesson_quiz( false, $user_id, $lesson_id, null ); } else { $link = learndash_next_lesson_quiz( false, $user_id, $lesson_id, array( $quiz_id ) ); } } /** * Are topics completed for lesson * * @since 2.1.0 * * @param int $lesson_id Lesson ID. * @param bool $mark_lesson_complete Should we mark lesson complete. * @return bool */ function learndash_lesson_topics_completed( $lesson_id, $mark_lesson_complete = false ) { $topics = learndash_get_topic_list( $lesson_id ); if ( empty( $topics[0]->ID ) ) { return true; } $progress = learndash_get_course_progress( null, $topics[0]->ID ); if ( empty( $progress['posts'] ) || ! is_array( $progress['posts'] ) ) { return false; } foreach ( $progress['posts'] as $topic ) { if ( empty( $topic->completed ) ) { return false; } } if ( $mark_lesson_complete ) { $user_id = get_current_user_id(); learndash_process_mark_complete( null, $lesson_id ); } // learndash_get_next_lesson_redirect(); . return true; } /** * Process request to mark a course complete * * @since 2.1.0 * * @param int $post WP_Post object. */ function learndash_mark_complete_process( $post = null ) { // This is wrong. This function hooks into the 'wp' action. That action doesn't pass a post object or post_id. // The $post object set hwere is not even used. We only need the _POST[post] (post_id) variable from the form. if ( empty( $post ) ) { global $post; } if ( ( isset( $_POST['sfwd_mark_complete'] ) ) && ( ! empty( $_POST['sfwd_mark_complete'] ) ) && ( isset( $_POST['post'] ) ) && ( ! empty( $_POST['post'] ) ) ) { if ( empty( $post ) || empty( $post->ID ) ) { $post = get_post(); if ( empty( $post ) || empty( $post->ID ) ) { return; } } $post_id = intval( $_POST['post'] ); if ( isset( $_POST['course_id'] ) ) { $course_id = intval( $_POST['course_id'] ); } else { $course_id = learndash_get_course_id( $post_id ); } if ( isset( $_POST['userid'] ) ) { $userid = intval( $_POST['userid'] ); } else { if ( ! is_user_logged_in() ) { return; } $userid = get_current_user_id(); } /** * Verify the form is valid * * @since 2.2.1.2 */ if ( ! wp_verify_nonce( $_POST['sfwd_mark_complete'], 'sfwd_mark_complete_' . $userid . '_' . $post_id ) ) { return; } /** * Added logic to enroll the student in the course if the course price type is open and not a sample. * * @since 2.4.4 */ // $course_id = learndash_get_course_id( $post_id ); // if ( !empty( $course_id ) ) { // $user_course_access_time = get_user_meta( $userid, "course_".$course_id."_access_from", true ); // if ( empty( $user_course_access_time ) ) { // ld_update_course_access( $userid, $course_id ); // } // } $return = learndash_process_mark_complete( $userid, $post_id, false, $course_id ); if ( $return ) { // Remove the lesson/topic timer cookie once the step have been completed. $timer_cookie_key = learndash_forced_lesson_time_cookie_key( $post_id ); if ( ! empty( $timer_cookie_key ) ) { if ( isset( $_COOKIE[ 'learndash_timer_cookie_' . $timer_cookie_key ] ) ) { unset( $_COOKIE[ 'learndash_timer_cookie_' . $timer_cookie_key ] ); } // empty value and expiration one hour before $res = setcookie( 'learndash_timer_cookie_' . $timer_cookie_key, '', time() - 3600); } $nextlessonredirect = learndash_get_next_lesson_redirect(); } else { $nextlessonredirect = get_permalink(); } if ( ! empty( $nextlessonredirect ) ) { /** * Filter url to redirect to on next lesson * * @param string $nextlessonredirect */ $nextlessonredirect = apply_filters( 'learndash_completion_redirect', $nextlessonredirect, $post_id ); wp_redirect( $nextlessonredirect ); exit; } } } add_action( 'wp', 'learndash_mark_complete_process' ); /** * Get a courses permalink * * @since 2.1.0 * * @param int $id course, topic, lesson, quiz, etc. * @return string course permalink */ function learndash_get_course_url( $id = null ) { if ( empty( $id ) ) { $id = learndash_get_course_id(); } return get_permalink( $id ); } /** * Redirect user to next lesson * * @since 2.1.0 * * @param object $post */ function learndash_get_next_lesson_redirect( $post = null ) { if ( empty( $post->ID ) ) { global $post; } $next = learndash_next_post_link( '', true, $post ); if ( ! empty( $next ) ) { $link = $next; } else { if ( 'sfwd-topic' === $post->post_type ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $post->ID ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } $link = get_permalink( $lesson_id ); } else { $course_id = learndash_get_course_id( $post ); $link = learndash_next_global_quiz( true, null, $course_id ); } } if ( ! empty( $link ) ) { /** * Filter where user should be redirected to for next lesson * * @since 2.1.0 * * @var $link redirect url */ $link = apply_filters( 'learndash_completion_redirect', $link, @$post->ID ); wp_redirect( $link ); exit; } else { return ''; } } /** * Redirect user after quiz completion * * @since 2.1.0 */ function learndash_quiz_redirect() { global $post; $current_user = wp_get_current_user(); $user_id = $current_user->ID; if ( ! empty( $_GET['quiz_redirect'] ) && ! empty( $_GET['quiz_id'] ) && ! empty( $_GET['quiz_type'] ) && ! empty( $_GET['course_id'] ) && $_GET['quiz_type'] == 'global' ) { $quiz_id = intval( $_GET['quiz_id'] ); $can_attempt_again = learndash_can_attempt_again( $user_id, $quiz_id ); if ( $can_attempt_again ) { $link = learndash_next_global_quiz(); } else { $link = learndash_next_global_quiz( true, null, null, array( $quiz_id ) ); } learndash_update_completion( $user_id ); /** * Filter where user should be redirected * * @since 2.1.0 * * @var $link redirect url */ $link = apply_filters( 'learndash_completion_redirect', $link, $quiz_id ); wp_redirect( $link ); exit; } else { if ( ! empty( $_GET['quiz_redirect'] ) && ! empty( $_GET['quiz_id'] ) && ! empty( $_GET['quiz_type'] ) && ! empty( $_GET['lesson_id'] ) && $_GET['quiz_type'] == 'lesson' ) { $quiz_id = intval( $_GET['quiz_id'] ); $lesson_id = intval( $_GET['lesson_id'] ); // We don't need to check if the quiz can be retaken because the learndash_next_lesson_quiz() function does that for us. // if ( $can_attempt_again ) { // $link = learndash_next_lesson_quiz( true, $user_id, $lesson_id, null ); // } else { // $link = learndash_next_lesson_quiz( true, $user_id, $lesson_id, array($quiz_id) ); // } $link = learndash_next_lesson_quiz( true, $user_id, $lesson_id, null ); if ( empty( $link ) ) { $link = learndash_next_post_link( '', true ); } if ( empty( $link ) ) { $post = get_post( $lesson_id ); if ( $post->post_type == 'sfwd-topic' ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $post->ID ); $lesson = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson = learndash_get_setting( $post, 'lesson' ); } $link = get_permalink( $lesson ); } else { $link = learndash_next_global_quiz(); } } // v2.3: Removed this and moved to an earlier step // learndash_update_completion( $user_id ); if ( ! empty( $link ) ) { /** * Filter where user should be redirected * * @since 2.1.0 * * @var $link redirect url */ $link = apply_filters( 'learndash_completion_redirect', $link, $quiz_id ); wp_redirect( $link ); exit; } } } } add_action( 'wp', 'learndash_quiz_redirect' ); /** * Can the user attempt the quiz again * * @since 2.1.0 * * @param int $user_id * @param int $quiz_id * @return bool */ function learndash_can_attempt_again( $user_id, $quiz_id ) { $quizmeta = get_post_meta( $quiz_id, '_sfwd-quiz', true ); if ( isset( $quizmeta['sfwd-quiz_repeats'] ) ) { $repeats = $quizmeta['sfwd-quiz_repeats']; } else { $repeats = ''; } /** * Number of repeats for quiz * * @param int $repeats */ $repeats = apply_filters( 'learndash_allowed_repeats', $repeats, $user_id, $quiz_id ); if ( $repeats == '' ) { return true; } $quiz_results = get_user_meta( $user_id, '_sfwd-quizzes', true ); $count = 0; if ( ! empty( $quiz_results ) ) { foreach ( $quiz_results as $quiz ) { if ( $quiz['quiz'] == $quiz_id ) { $count++; } } } if ( $repeats > $count - 1 ) { return true; } else { return false; } } /** * Is previous topic, lesson complete * * @since 2.1.0 * * @param object $post WP_Post * @return bool */ function is_previous_complete( $post ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( empty( $progress ) ) { return 1; } if ( ! empty( $progress['prev'] ) && empty( $progress['prev']->completed ) ) { return 0; } else { return 1; } } /** * Returns the previous lesson/topic to be completed. * * @since 2.2.1.1 * * @param object $post WP_Post * @return object WP_Post object */ function learndash_get_previous( $post ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['prev'] ) ) { return $progress['prev']; } } /** * Update user meta with completion status for any resource * * @since 2.1.0 * * @param int $user_id * @param int $postid course, lesson, topic * @param boolean $onlycalculate * @return bool if user meta was updated */ function learndash_process_mark_complete( $user_id = null, $postid = null, $onlycalculate = false, $course_id = 0 ) { if ( empty( $user_id ) ) { if ( is_user_logged_in() ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } else { return false; } } else { $current_user = get_user_by( 'id', $user_id ); } $post = get_post( $postid ); if ( ! ( $post instanceof WP_Post ) ) { return false; } if ( ! $onlycalculate ) { /** * Filter if this should be marked completed * * @since 2.1.0 * * @param bool */ $process_completion = apply_filters( 'learndash_process_mark_complete', true, $post, $current_user ); if ( ! $process_completion ) { return false; } } if ( $post->post_type == 'sfwd-topic' ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $post->ID ); } $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } // $lesson_topics = learndash_get_topic_list( $lesson_id); } if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $postid ); } if ( empty( $course_id ) ) { return false; } $lessons = learndash_get_lesson_list( $course_id, array( 'num' => 0 ) ); if ( has_global_quizzes( $postid ) ) { $globalquiz = 1; } else { $globalquiz = 0; } if ( $globalquiz && is_all_global_quizzes_complete( $user_id, $postid ) ) { $globalquizcompleted = 1; } else { $globalquizcompleted = 0; } $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( ( empty( $course_progress ) ) || ( ! is_array( $course_progress ) ) ) { $course_progress = array(); } if ( ( ! isset( $course_progress[ $course_id ] ) ) || ( empty( $course_progress[ $course_id ] ) ) ) { $course_progress[ $course_id ] = array( 'lessons' => array(), 'topics' => array(), ); } if ( ( ! isset( $course_progress[ $course_id ]['lessons'] ) ) || ( empty( $course_progress[ $course_id ]['lessons'] ) ) ) { $course_progress[ $course_id ]['lessons'] = array(); } if ( ( ! isset( $course_progress[ $course_id ]['topics'] ) ) || ( empty( $course_progress[ $course_id ]['topics'] ) ) ) { $course_progress[ $course_id ]['topics'] = array(); } if ( $post->post_type == 'sfwd-topic' && empty( $course_progress[ $course_id ]['topics'][ $lesson_id ] ) ) { $course_progress[ $course_id ]['topics'][ $lesson_id ] = array(); } $lesson_completed = false; $topic_completed = false; if ( ! $onlycalculate && $post->post_type == 'sfwd-lessons' && empty( $course_progress[ $course_id ]['lessons'][ $postid ] ) ) { $course_progress[ $course_id ]['lessons'][ $postid ] = 1; $lesson_completed = true; } if ( ! $onlycalculate && $post->post_type == 'sfwd-topic' && empty( $course_progress[ $course_id ]['topics'][ $lesson_id ][ $postid ] ) ) { $course_progress[ $course_id ]['topics'][ $lesson_id ][ $postid ] = 1; $topic_completed = true; } $completed_old = isset( $course_progress[ $course_id ]['completed'] ) ? $course_progress[ $course_id ]['completed'] : 0; // $course_progress[ $course_id ]['completed'] = count( $course_progress[ $course_id ]['lessons'] ) + $globalquizcompleted; $completed = learndash_course_get_completed_steps( $user_id, $course_id, $course_progress[ $course_id ] ); $course_progress[ $course_id ]['completed'] = $completed; // 2016-07-16 v2.3 Changed the logic on the count here. In the previous logic the count of lessons and 1 or 0 for global quiz. // $course_progress[ $course_id ]['total'] = count( $lessons ) + $globalquiz; // New logic includes lessons and topics. $course_progress[ $course_id ]['total'] = learndash_get_course_steps_count( $course_id ); /** * Track the last post_id (Lesson, Topic, Quiz) seen by user. * * @since 2.1.0 */ $course_progress[ $course_id ]['last_id'] = $post->ID; $course_completed_time = time(); // If course is completed if ( ( $course_progress[ $course_id ]['completed'] >= $completed_old ) && ( $course_progress[ $course_id ]['completed'] >= $course_progress[ $course_id ]['total'] ) ) { /** * Run actions before course is completed * * @since 2.1.0 */ do_action( 'learndash_before_course_completed', array( 'user' => $current_user, 'course' => get_post( $course_id ), 'progress' => $course_progress, 'completed_time' => $course_completed_time, ) ); add_user_meta( $current_user->ID, 'course_completed_' . $course_id, $course_completed_time, true ); } else { delete_user_meta( $current_user->ID, 'course_completed_' . $course_id ); } update_user_meta( $user_id, '_sfwd-course_progress', $course_progress ); if ( ! empty( $topic_completed ) ) { /** * Run actions after topic is completed * * @since 2.1.0 */ do_action( 'learndash_topic_completed', array( 'user' => $current_user, 'course' => get_post( $course_id ), 'lesson' => get_post( $lesson_id ), 'topic' => $post, 'progress' => $course_progress, ) ); learndash_update_user_activity( array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $post->ID, 'activity_type' => 'topic', 'activity_status' => true, 'activity_completed' => time(), 'activity_meta' => array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], ), ) ); $course_args = array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', ); $course_activity = learndash_get_user_activity( $course_args ); if ( ! $course_activity ) { learndash_update_user_activity( array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', 'activity_status' => false, 'activity_meta' => array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], 'steps_last_id' => $post->ID, ), ) ); } else { learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_total', $course_progress[ $course_id ]['total'] ); learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_completed', $course_progress[ $course_id ]['completed'] ); learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_last_id', $post->ID ); } } if ( ! empty( $lesson_completed ) ) { /** * Run actions lesson is completed * * @since 2.1.0 */ do_action( 'learndash_lesson_completed', array( 'user' => $current_user, 'course' => get_post( $course_id ), 'lesson' => $post, 'progress' => $course_progress, ) ); learndash_update_user_activity( array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $post->ID, 'activity_type' => 'lesson', 'activity_status' => true, 'activity_completed' => time(), 'activity_meta' => array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], ), ) ); $course_args = array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', ); $course_activity = learndash_get_user_activity( $course_args ); if ( ! $course_activity ) { learndash_update_user_activity( array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', 'activity_status' => false, 'activity_meta' => array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], 'steps_last_id' => $post->ID, ), ) ); } else { learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_total', $course_progress[ $course_id ]['total'] ); learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_completed', $course_progress[ $course_id ]['completed'] ); learndash_update_user_activity_meta( $course_activity->activity_id, 'steps_last_id', $post->ID ); } } if ( $course_progress[ $course_id ]['completed'] >= $completed_old && $course_progress[ $course_id ]['total'] == $course_progress[ $course_id ]['completed'] ) { $do_course_complete_action = false; $course_args = array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', ); $course_activity = learndash_get_user_activity( $course_args ); if ( ! empty( $course_activity ) ) { $course_args = json_decode( json_encode( $course_activity ), true ); if ( $course_activity->activity_status != true ) { $course_args['activity_status'] = true; $course_args['activity_completed'] = time(); $course_args['activity_updated'] = time(); $do_course_complete_action = true; } } else { // If no activity record found. $course_args['activity_status'] = true; $course_args['activity_started'] = time(); $course_args['activity_completed'] = time(); $course_args['activity_updated'] = time(); $do_course_complete_action = true; } $course_args['activity_meta'] = array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], 'steps_last_id' => $post->ID, ); learndash_update_user_activity( $course_args ); if ( $do_course_complete_action == true ) { /** * Run actions after course is completed * * @since 2.1.0 */ do_action( 'learndash_course_completed', array( 'user' => $current_user, 'course' => get_post( $course_id ), 'progress' => $course_progress, 'course_completed' => $course_completed_time, ) ); } } else { $course_args = array( 'course_id' => $course_id, 'user_id' => $current_user->ID, 'post_id' => $course_id, 'activity_type' => 'course', ); $course_activity = learndash_get_user_activity( $course_args ); if ( $course_activity ) { $course_args['activity_completed'] = 0; $course_args['activity_status'] = false; if ( empty( $course_progress[ $course_id ]['completed'] ) ) { $course_args['activity_updated'] = 0; } $course_args['activity_meta'] = array( 'steps_total' => $course_progress[ $course_id ]['total'], 'steps_completed' => $course_progress[ $course_id ]['completed'], 'steps_last_id' => $post->ID, ); learndash_update_user_activity( $course_args ); } } return true; } /** * Helper to update completion resource * * @todo seems redundant, function already exists * * @since 2.1.0 * * @param int $user_id * @param int $postid * @return bool if user meta was updated */ function learndash_update_completion( $user_id = null, $postid = null ) { if ( empty( $postid ) ) { global $post; if ( ( $post ) && ( is_a( $post, 'WP_Post' ) ) ) { $postid = $post->ID; } } if ( ! empty( $postid ) ) { learndash_process_mark_complete( $user_id, $postid, true ); } } /** * Is quiz complete * * @since 2.1.0 * * @param int $user_id * @param int $quiz_id * @return bool */ function learndash_is_quiz_complete( $user_id = null, $quiz_id, $course_id = 0 ) { return ! learndash_is_quiz_notcomplete( $user_id, array( $quiz_id => 1 ), false, $course_id ); } /** * Is quiz not complete * * Checks against quizzes in user meta and passing percentage of the quiz itself * * @since 2.1.0 * * @param int $user_id User ID for quizzes. * @param array $quizes Quiz ID to search user quizzes. * @param bool $return_incomplete_quiz_ids if true will return the array of incomplete quizes. Default is false ( added v2.3.1 ). * @param integer $course_id match course id. If -1 is passed then course match is not performed. * * @return bool true is quiz(es) NOT complete. false is quiz(es) all complete */ function learndash_is_quiz_notcomplete( $user_id = null, $quizes = null, $return_incomplete_quiz_ids = false, $course_id = 0 ) { if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } $quiz_results = get_user_meta( $user_id, '_sfwd-quizzes', true ); if ( ! empty( $quiz_results ) && is_array( $quiz_results ) ) { foreach ( $quiz_results as $quiz ) { if ( ! empty( $quizes[ $quiz['quiz'] ] ) ) { if ( ( -1 !== $course_id ) && ( empty( $course_id ) ) ) { $course_id = learndash_get_course_id( intval( $quiz['quiz'] ) ); } if ( ! isset( $quiz['course'] ) ) { $quiz['course'] = $course_id; } $quiz['course'] = intval( $quiz['course'] ); if ( -1 !== $course_id ) { $course_id = intval( $course_id ); } $pass = false; if ( ( -1 === $course_id ) || ( $course_id == $quiz['course'] ) ) { if ( isset( $quiz['pass'] ) ) { $pass = ( $quiz['pass'] == 1 ) ? 1 : 0; } else { $quizmeta = get_post_meta( $quiz['quiz'], '_sfwd-quiz', true ); $passingpercentage = intVal( $quizmeta['sfwd-quiz_passingpercentage'] ); $pass = ( ! empty( $quiz['count'] ) && $quiz['score'] * 100 / $quiz['count'] >= $passingpercentage ) ? 1 : 0; } } if ( $pass ) { unset( $quizes[ $quiz['quiz'] ] ); } } } } if ( empty( $quizes ) ) { return 0; } else { if ( $return_incomplete_quiz_ids == true ) { return $quizes; } else { return 1; } } } /** * Return array of where the user currently is in course * * @since 2.1.0 * * @param int $user_id * @param int $postid * @param int $course_id * @return array list of courses, topics, lessons * current, previous, next */ function learndash_get_course_progress( $user_id = null, $postid = null, $course_id = null ) { if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); if ( empty( $current_user->ID ) ) { return null; } $user_id = $current_user->ID; } $posts = array(); $posts = array(); if ( is_null( $course_id ) ) { $course_id = learndash_get_course_id( $postid ); } $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); $this_post = get_post( $postid ); if ( empty( $course_progress ) ) { // learndash_update_completion( $user_id, $postid ); // $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); $course_progress = array(); } if ( $this_post->post_type == 'sfwd-lessons' ) { $posts = learndash_get_lesson_list( $postid, array( 'num' => 0 ) ); if ( empty( $course_progress ) || empty( $course_progress[ $course_id ]['lessons'] ) ) { $completed_posts = array(); } else { $completed_posts = $course_progress[ $course_id ]['lessons']; } } elseif ( $this_post->post_type == 'sfwd-topic' ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $lesson_id = learndash_course_get_single_parent_step( $course_id, $this_post->ID ); } else { $lesson_id = learndash_get_setting( $this_post, 'lesson' ); } $posts = learndash_get_topic_list( $lesson_id, $course_id ); if ( empty( $course_progress ) || empty( $course_progress[ $course_id ]['topics'][ $lesson_id ] ) ) { $completed_posts = array(); } else { $completed_posts = $course_progress[ $course_id ]['topics'][ $lesson_id ]; } } $temp = $prev_p = $next_p = $this_p = ''; if ( ! empty( $posts ) ) { foreach ( $posts as $k => $post ) { if ( $post instanceof WP_Post ) { if ( ! empty( $completed_posts[ $post->ID ] ) ) { $posts[ $k ]->completed = 1; } else { $posts[ $k ]->completed = 0; } if ( $post->ID == $postid ) { $this_p = $post; $prev_p = $temp; } if ( ! empty( $temp->ID ) && $temp->ID == $postid ) { $next_p = $post; } $temp = $post; } } } else { $posts = array(); } return array( 'posts' => $posts, 'this' => $this_p, 'prev' => $prev_p, 'next' => $next_p, ); } /** * Is lesson complete * * @since 2.1.0 * * @param int $user_id * @param int $lesson_id * @return bool */ function learndash_is_lesson_complete( $user_id = null, $lesson_id, $course_id = 0 ) { return ! learndash_is_lesson_notcomplete( $user_id, array( $lesson_id => 1 ), $course_id ); } /** * Is lesson not complete * * @since 2.1.0 * * @param int $user_id * @param int $lesson_id * @return bool */ function learndash_is_lesson_notcomplete( $user_id = null, $lessons, $course_id = 0 ) { if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( ! empty( $lessons ) ) { foreach ( $lessons as $lesson => $v ) { if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $lesson ); } if ( ! empty( $course_progress[ $course_id ] ) && ! empty( $course_progress[ $course_id ]['lessons'] ) && ! empty( $course_progress[ $course_id ]['lessons'][ $lesson ] ) ) { unset( $lessons[ $lesson ] ); } } } if ( empty( $lessons ) ) { return 0; } else { return 1; } } /** * Is topic complete * * @since 2.3.0.2 * * @param int $user_id * @param int $topic_id * @return bool */ function learndash_is_topic_complete( $user_id = null, $topic_id ) { return ! learndash_is_topic_notcomplete( $user_id, array( $topic_id => 1 ) ); } /** * Is topic not complete * * @since 2.1.0 * * @param int $user_id * @param int $lesson_id * @return bool */ function learndash_is_topic_notcomplete( $user_id = null, $topics ) { if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( ! empty( $topics ) ) { foreach ( $topics as $topic_id => $v ) { $course_id = learndash_get_course_id( $topic_id ); $lesson_id = learndash_get_lesson_id( $topic_id ); if ( ( isset( $course_progress[ $course_id ] ) ) && ( ! empty( $course_progress[ $course_id ] ) ) && ( isset( $course_progress[ $course_id ]['topics'] ) ) && ( ! empty( $course_progress[ $course_id ]['topics'] ) ) && ( isset( $course_progress[ $course_id ]['topics'][ $lesson_id ][ $topic_id ] ) ) && ( ! empty( $course_progress[ $course_id ]['topics'][ $lesson_id ][ $topic_id ] ) ) ) { unset( $topics[ $topic_id ] ); } } } if ( empty( $topics ) ) { return 0; } else { return 1; } } /** * Output current status of course * * @since 2.1.0 * @since 2.5.8 added $return_slug parameter * * @param int $id Course ID to get status of * @param int $user_id User ID * @param bool $return_slug If false will return transatable string. If false status slug. * * @return string output of current course status */ function learndash_course_status( $id, $user_id = null, $return_slug = false ) { $course_status_str = ''; if ( empty( $user_id ) ) { if ( ! is_user_logged_in() ) { return $course_status_str; } $user_id = get_current_user_id(); } else { $user_id = intval( $user_id ); } $completed_on = get_user_meta( $user_id, 'course_completed_' . $id, true ); if ( ! empty( $completed_on ) ) { if ( true === $return_slug ) { $course_status_str = 'completed'; } else { $course_status_str = esc_html__( 'Completed', 'learndash' ); } } else { $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); $has_completed_topic = false; if ( ! empty( $course_progress[ $id ] ) && ! empty( $course_progress[ $id ]['topics'] ) && is_array( $course_progress[ $id ]['topics'] ) ) { foreach ( $course_progress[ $id ]['topics'] as $lesson_topics ) { if ( ! empty( $lesson_topics ) && is_array( $lesson_topics ) ) { foreach ( $lesson_topics as $topic ) { if ( ! empty( $topic ) ) { $has_completed_topic = true; break; } } } if ( $has_completed_topic ) { break; } } } $quiz_notstarted = true; $quizzes = learndash_get_global_quiz_list( $id ); if ( ! empty( $quizzes ) ) { foreach ( $quizzes as $quiz ) { if ( ! learndash_is_quiz_notcomplete( $user_id, array( $quiz->ID => 1 ), false, $id ) ) { $quiz_notstarted = false; } } if ( false === $quiz_notstarted ) { $course_progress[ $id ]['completed'] += 1; } } if ( ( empty( $course_progress[ $id ] ) || empty( $course_progress[ $id ]['lessons'] ) && ! $has_completed_topic ) && $quiz_notstarted ) { if ( true === $return_slug ) { $course_status_str = 'not-started'; } else { $course_status_str = esc_html__( 'Not Started', 'learndash' ); } } elseif ( empty( $course_progress[ $id ] ) || @$course_progress[ $id ]['completed'] < @$course_progress[ $id ]['total'] ) { if ( true === $return_slug ) { $course_status_str = 'in-progress'; } else { $course_status_str = esc_html__( 'In Progress', 'learndash' ); } } elseif ( absint( $course_progress[ $id ]['completed'] ) == absint( $course_progress[ $id ]['total'] ) ) { if ( true === $return_slug ) { $course_status_str = 'completed'; } else { $course_status_str = esc_html__( 'Completed', 'learndash' ); } /** * We call the standard mark complete function so it triggers the notifications etc. */ learndash_process_mark_complete( $user_id, $id, false, $id ); } } if ( true === $return_slug ) { return $course_status_str; } else { return apply_filters( 'learndash_course_status', $course_status_str, $id, $user_id, isset( $course_progress[ $id ] ) ? $course_progress[ $id ] : array() ); } } /** * Get the course status idex from the course status label * * In various places with LD the course status is expressed as a string as in 'Not Started', 'In Progress' or 'Complete'. * the problem with using this string is it will be translated depending on the locale(). This means comparative logic can * possible fails. * * The purpose of this function is to help use an internal key to keep track of the course status value * * @since 2.3 * * @uses $learndash_course_statuses * @param string $course_status_label Current translatable text for Course Status * @return string The index/key of the course status string if found in the $learndash_course_statuses array */ function learndash_course_status_idx( $course_status_label = '' ) { global $learndash_course_statuses; return array_search( $course_status_label, $learndash_course_statuses ); } /** * Output HTML template of users course progress * * @since 2.1.0 * * @param array $atts shortcode attributes * @return string shortcode output */ function learndash_course_progress( $atts ) { global $learndash_shortcode_used; $learndash_shortcode_used = true; extract( shortcode_atts( array( 'course_id' => 0, 'user_id' => 0, 'array' => false, ), $atts ) ); if ( empty( $user_id ) ) { // $current_user = wp_get_current_user(); if ( is_user_logged_in() ) { $user_id = get_current_user_id(); } else { $user_id = 0; } } if ( empty( $course_id ) ) { $course_id = learndash_get_course_id(); } if ( empty( $course_id ) ) { return ''; } $completed = 0; $total = false; if ( ! empty( $user_id ) ) { $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); $percentage = 0; $message = ''; if ( ( ! empty( $course_progress ) ) && ( isset( $course_progress[ $course_id ] ) ) && ( ! empty( $course_progress[ $course_id ] ) ) ) { if ( isset( $course_progress[ $course_id ]['completed'] ) ) { $completed = absint( $course_progress[ $course_id ]['completed'] ); } if ( isset( $course_progress[ $course_id ]['total'] ) ) { $total = absint( $course_progress[ $course_id ]['total'] ); } } } // If $total is still false we calculate the total from course steps. if ( false === $total ) { $total = learndash_get_course_steps_count( $course_id ); } if ( $total > 0 ) { $percentage = intval( $completed * 100 / $total ); $percentage = ( $percentage > 100 ) ? 100 : $percentage; } else { $percentage = 0; } // translators: placeholder: completed steps, total steps. $message = sprintf( esc_html_x( '%1$d out of %2$d steps completed', 'placeholder: completed steps, total steps', 'learndash' ), $completed, $total ); if ( $array ) { return array( 'percentage' => isset( $percentage ) ? $percentage : 0, 'completed' => isset( $completed ) ? $completed : 0, 'total' => isset( $total ) ? $total : 0, ); } return SFWD_LMS::get_template( 'course_progress_widget', array( 'user_id' => $user_id, 'course_id' => $course_id, 'message' => $message, 'percentage' => isset( $percentage ) ? $percentage : 0, 'completed' => isset( $completed ) ? $completed : 0, 'total' => isset( $total ) ? $total : 0, ) ); } add_shortcode( 'learndash_course_progress', 'learndash_course_progress' ); /** * Is quiz accessible to user * * @since 2.1.0 * * @param int $user_id $user_id ID of User to check. * @param object $post WP_Post quiz. * @param boolean $return_incomplete default false. true to return last imcomplete step. * @return mixed boolean default. If $return_incomplete is true will return WP_Post object. */ function is_quiz_accessable( $user_id = null, $post = null, $return_incomplete = false, $course_id = 0 ) { // Allow using the legacy function in case of issues with new logic. if ( ( defined( 'LEARNDASH_IS_QUIZ_ACCESSABLE_LEGACY' ) && ( LEARNDASH_IS_QUIZ_ACCESSABLE_LEGACY === true ) ) ) { return is_quiz_accessable_legacy( $user_id, $post, $course_id ); } if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); if ( empty( $current_user->ID ) ) { return 1; } $user_id = $current_user->ID; } if ( learndash_is_admin_user( $user_id ) ) { $bypass_course_limits_admin_users = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_General_Admin_User', 'bypass_course_limits_admin_users' ); if ( 'yes' === $bypass_course_limits_admin_users ) { return 1; } } if ( ( empty( $post ) ) || ( ! is_a( $post, 'WP_Post' ) ) ) { return; } if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $post ); } $course_id = absint( $course_id ); // If we have a Quiz but the Quiz is not part of a course then return 1 for valid. if ( empty( $course_id ) ) { return 1; } if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $quiz_parent_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $quiz_parent_id = learndash_get_setting( $post, 'lesson' ); } $quiz_parent_id = absint( $quiz_parent_id ); if ( ! empty( $quiz_parent_id ) ) { $quiz_parent_post = get_post( $quiz_parent_id ); if ( is_a( $quiz_parent_post, 'WP_Post' ) ) { if ( $quiz_parent_post->post_type == learndash_get_post_type_slug( 'topic' ) ) { $quiz_parent_topic_post = $quiz_parent_post; $quiz_parent_lesson_id = learndash_get_setting( $quiz_parent_topic_post, 'lesson' ); $quiz_parent_lesson_post = get_post( $quiz_parent_lesson_id ); $parent_topic_quizzes = learndash_get_lesson_quiz_list( $quiz_parent_topic_post, $user_id, $course_id ); if ( ! empty( $parent_topic_quizzes ) ) { // loop until we get to the first status == 'notcompleted'. foreach ( $parent_topic_quizzes as $quiz ) { if ( $quiz['post']->ID === $post->ID ) { //return 1; break; } elseif ( 'completed' !== $quiz['status'] ) { if ( true === $return_incomplete ) { return $quiz['post']; } else { return 0; } } } } $lesson_topics_progress = learndash_get_course_progress( null, $quiz_parent_topic_post->ID ); if ( ( isset( $lesson_topics_progress['posts'] ) ) && ( ! empty( $lesson_topics_progress['posts'] ) ) ) { foreach ( $lesson_topics_progress['posts'] as $topic ) { if ( $topic->ID === $quiz_parent_topic_post->ID ) { break; } if ( empty( $topic->completed ) ) { if ( true === $return_incomplete ) { return $topic; } else { return 0; } break; } } } $lesson_progress = learndash_get_course_progress( null, $quiz_parent_lesson_post->ID ); if ( ( isset( $lesson_progress['posts'] ) ) && ( ! empty( $lesson_progress['posts'] ) ) ) { foreach ( $lesson_progress['posts'] as $lesson ) { if ( $lesson->ID === $quiz_parent_lesson_post->ID ) { break; } if ( empty( $lesson->completed ) ) { if ( true === $return_incomplete ) { return $lesson; } else { return 0; } break; } } } return 1; } elseif ( $quiz_parent_post->post_type == learndash_get_post_type_slug( 'lesson' ) ) { $quiz_parent_lesson_post = $quiz_parent_post; $lesson_topics = learndash_get_topic_list( $quiz_parent_lesson_post->ID ); if ( ! empty( $lesson_topics ) ) { $lesson_topics_progress = learndash_get_course_progress( null, $lesson_topics[0]->ID ); if ( ( isset( $lesson_topics_progress['posts'] ) ) && ( ! empty( $lesson_topics_progress['posts'] ) ) ) { foreach ( $lesson_topics_progress['posts'] as $topic ) { if ( empty( $topic->completed ) ) { if ( true === $return_incomplete ) { return $topic; } else { return 0; } break; } } } } $quizzes = learndash_get_lesson_quiz_list( $quiz_parent_lesson_post, $user_id, $course_id ); if ( ! empty( $quizzes ) ) { // loop until we get to the first status == 'notcompleted'. foreach( $quizzes as $quiz ) { if ( $quiz['post']->ID === $post->ID ) { break; } if ( 'completed' !== $quiz['status'] ) { if ( true === $return_incomplete ) { return $quiz['post']; } else { return 0; } } } } //$lessons = learndash_get_course_lessons_list( $course_id, $user_id, array( 'num' => 0 ) ); $lesson_progress = learndash_get_course_progress( null, $quiz_parent_lesson_post->ID ); if ( ( isset( $lesson_progress['posts'] ) ) && ( ! empty( $lesson_progress['posts'] ) ) ) { foreach ( $lesson_progress['posts'] as $lesson ) { if ( $lesson->ID === $quiz_parent_lesson_post->ID ) { break; } if ( empty( $lesson->completed ) ) { if ( true === $return_incomplete ) { return $lesson; } else { return 0; } break; } } } return 1; } } } else { // First we check if all course lessons are completed. $lessons = learndash_get_course_lessons_list( $course_id, $user_id, array( 'num' => 0 ) ); if ( ! empty( $lessons ) ) { foreach ( $lessons as $lesson ) { //if ( ( $lesson['sample'] === 'is_not_sample' ) && ( 'completed' !== $lesson['status'] ) ) { if ( 'completed' !== $lesson['status'] ) { if ( true === $return_incomplete ) { return $lesson['post']; } else { return 0; } } } } // Next we check if other global quizzes are completed. $quizzes = learndash_get_global_quiz_list( $course_id ); if ( ! empty( $quizzes ) ) { // loop until we get to the first status == 'notcompleted'. foreach( $quizzes as $quiz ) { if ( $quiz->ID === $post->ID ) { return 1; } elseif ( ! learndash_is_quiz_complete( $user_id, $quiz->ID, $course_id ) ) { if ( true === $return_incomplete ) { return $quiz; } else { return 0; } } } } } return 0; } function is_quiz_accessable_legacy( $user_id = null, $post = null, $course_id = 0 ) { if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); if ( empty( $current_user->ID ) ) { return 1; } $user_id = $current_user->ID; } if ( ( ! empty( $post ) ) && ( $post instanceof WP_Post ) ) { if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $post ); } $course_id = absint( $course_id ); if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $quiz_lesson = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $quiz_lesson = learndash_get_setting( $post, 'lesson' ); } if ( ! empty( $quiz_lesson ) ) { $quiz_lesson_post = get_post( $quiz_lesson ); if ( ( $quiz_lesson_post instanceof WP_Post ) && ( $quiz_lesson_post->post_type == 'sfwd-topic' ) ) { return 1; } elseif ( learndash_lesson_topics_completed( $quiz_lesson ) ) { return 1; } else { return 0; } } else { $course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( ! empty( $course_progress ) && ! empty( $course_progress[ $course_id ] ) && ! empty( $course_progress[ $course_id ]['total'] ) ) { $completed = intVal( $course_progress[ $course_id ]['completed'] ); $total = intVal( $course_progress[ $course_id ]['total'] ); if ( $completed >= $total - 1 ) { return 1; } } $lessons = learndash_get_lesson_list( $course_id, array( 'num' => 0 ) ); if ( empty( $lessons ) ) { return 1; } } } return 0; } /** * Check if all quizzes for course are complete for user * * @since 2.1.0 * * @param int $user_id * @param int $id * @return bool */ function is_all_global_quizzes_complete( $user_id = null, $id = null ) { $quizzes = learndash_get_global_quiz_list( $id ); $return = true; if ( ! empty( $quizzes ) ) { foreach ( $quizzes as $quiz ) { if ( learndash_is_quiz_notcomplete( $user_id, array( $quiz->ID => 1 ), false, $id ) ) { $return = false; } } } return $return; } /** * Get next quiz for course * * @since 2.1.0 * * @param bool $url return a url * @param int $user_id * @param int $id * @param array $exclude excluded quiz id's * @return int|string id of quiz or url of quiz */ function learndash_next_global_quiz( $url = true, $user_id = null, $id = null, $exclude = array() ) { if ( empty( $id ) ) { $id = learndash_get_course_id(); } if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } $quizzes = learndash_get_global_quiz_list( $id ); $return = get_permalink( $id ); if ( ! empty( $quizzes ) ) { foreach ( $quizzes as $quiz ) { if ( ! in_array( $quiz->ID, $exclude ) && learndash_is_quiz_notcomplete( $user_id, array( $quiz->ID => 1 ), false, $id ) && learndash_can_attempt_again( $user_id, $quiz->ID ) ) { if ( $url ) { return get_permalink( $quiz->ID ); } else { return $quiz->ID; } } } } /** * Filter return value of next global quiz * * @todo filter name does not seem correct * in context of function * * @since 2.1.0 * * @var id|string $return */ $return = apply_filters( 'learndash_course_completion_url', $return, $id ); return $return; } /** * Get next quiz for current lesson for current user * * @since 2.1.0 * * @param bool $url return a url * @param int $user_id * @param int $lesson_id * @param array $exclude excluded quiz id's * @return int|string id of quiz or url of quiz */ function learndash_next_lesson_quiz( $url = true, $user_id = null, $lesson_id = null, $exclude = array() ) { global $post; $return = false; if ( empty( $lesson_id ) ) { $lesson_id = $post->ID; } if ( empty( $exclude ) ) { $exclude = array(); } if ( empty( $user_id ) ) { $current_user = wp_get_current_user(); $user_id = $current_user->ID; } // Assumption here is the learndash_get_lesson_quiz_list returns the quizzes in the order they should be taken. $quizzes = learndash_get_lesson_quiz_list( $lesson_id, $user_id ); if ( ( ! empty( $quizzes ) ) && ( is_array( $quizzes ) ) ) { foreach ( $quizzes as $quiz ) { // The logic here is we need to check all the quizzes in this lesson. If all the quizzes are complete // (including the current one) then we set the parent (lesson) to complete. if ( $quiz['status'] == 'completed' ) { continue; } // If not complete AND the user CAN take the quiz again... if ( learndash_can_attempt_again( $user_id, $quiz['post']->ID ) ) { $return = ( $url ) ? get_permalink( $quiz['post']->ID ) : $quiz['post']->ID; break; } $return = ( $url ) ? get_permalink( $quiz['post']->ID ) : $quiz['post']->ID; // $return = ( $url ) ? get_permalink( $lesson_id ) : $lesson_id; break; } } if ( empty( $return ) ) { learndash_process_mark_complete( $user_id, $lesson_id ); } else { return $return; } } /** * Does resource have quizzes? * * @since 2.1.0 * * @param int $id * @return bool */ function has_global_quizzes( $id = null ) { $quizzes = learndash_get_global_quiz_list( $id ); return ! empty( $quizzes ); } /** * Course Progress Widget */ class LearnDash_Course_Progress_Widget extends WP_Widget { /** * Set up course project widget */ function __construct() { $widget_ops = array( 'classname' => 'widget_ldcourseprogress', 'description' => sprintf( esc_html_x( 'LearnDash %s progress bar', 'placeholders: course', 'learndash' ), learndash_get_custom_label_lower( 'course' ) ), ); $control_ops = array(); // 'width' => 400, 'height' => 350); parent::__construct( 'ldcourseprogress', sprintf( esc_html_x( '%s Progress Bar', 'Course Progress Bar Label', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' ) ), $widget_ops, $control_ops ); } /** * Displays widget * * @since 2.1.0 * * @param array $args widget arguments * @param array $instance widget instance * @return string widget output */ function widget( $args, $instance ) { global $learndash_shortcode_used; extract( $args ); $title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance ); if ( ! is_singular() ) { return; } $progressbar = learndash_course_progress( $args ); if ( empty( $progressbar ) ) { return; } echo $before_widget; if ( ! empty( $title ) ) { echo $before_title . $title . $after_title; } echo $progressbar; echo $after_widget; $learndash_shortcode_used = true; } /** * Handles widget updates in admin * * @since 2.1.0 * * @param array $new_instance * @param array $old_instance * @return array $instance */ function update( $new_instance, $old_instance ) { $instance = $old_instance; $instance['title'] = strip_tags( $new_instance['title'] ); return $instance; } /** * Display widget form in admin * * @since 2.1.0 * * @param array $instance widget instance */ function form( $instance ) { $instance = wp_parse_args( (array) $instance, array( 'title' => '' ) ); $title = strip_tags( $instance['title'] ); // $text = format_to_edit( $instance['text'] ); ?> <p><label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'learndash' ); ?></label> <input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p> <?php } } add_action( 'widgets_init', function() { return register_widget( 'LearnDash_Course_Progress_Widget' ); } ); /** * Output HTML of course progress for user * * @todo consider for deprecation, not in use * * @since 2.1.0 * * @param $atts */ function learndash_course_progress_widget( $atts ) { echo learndash_course_progress( $atts ); } /** * Is progression enabled for lesson * * @since 2.1.0 * * @since 2.5.9 * @param integer $course_id Course ID to check. * * @return bool */ function learndash_lesson_progression_enabled( $course_id = 0 ) { $course_id = intval( $course_id ); if ( empty( $course_id ) ) { $course_id = learndash_get_course_id(); } if ( ! empty( $course_id ) ) { $setting = learndash_get_setting( $course_id, 'course_disable_lesson_progression' ); return empty( $setting ); } } /** * Get lesson time for lesson if it exists * * @since 2.1.0 */ function learndash_forced_lesson_time( $lesson_topic_post = '' ) { if ( empty( $lesson_topic_post ) ) { global $post; $lesson_topic_post = $post; } if ( ! is_a( $lesson_topic_post, 'WP_Post' ) ) { $post_id = absint( $lesson_topic_post ); if ( empty( $post_id ) ) { return 0; } $lesson_topic_post = get_post( $post_id ); if ( ( ! $lesson_topic_post ) || ( ! is_a( $lesson_topic_post, 'WP_Post' ) ) ) { return 0; } } if ( ! in_array( $lesson_topic_post->post_type, array( learndash_get_post_type_slug( 'lesson' ), learndash_get_post_type_slug( 'topic' ) ) ) ) { return 0; } $meta = get_post_meta( $lesson_topic_post ->ID, '_' . $lesson_topic_post->post_type, true ); if ( ! isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] ) ) { if ( ( isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) && ( ! empty( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) ) { $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] = 'on'; } else { $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] = ''; } } if ( 'on' === $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] ) { if ( ( isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) && ( ! empty( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) ) { return $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ]; } } return 0; } /** * Get lesson time cookie key for lesson/topic * * @since 3.0 * @param WP_Post $lesson_topic_post WP_Post object or post_id. * @return string cookie key value or empty. */ function learndash_forced_lesson_time_cookie_key( $lesson_topic_post = '' ) { if ( empty( $lesson_topic_post ) ) { global $post; $lesson_topic_post = $post; } if ( ! is_a( $lesson_topic_post, 'WP_Post' ) ) { $post_id = absint( $lesson_topic_post ); if ( empty( $post_id ) ) { return 0; } $lesson_topic_post = get_post( $post_id ); if ( ( ! $lesson_topic_post ) || ( ! is_a( $lesson_topic_post, 'WP_Post' ) ) ) { return 0; } } if ( ! in_array( $lesson_topic_post->post_type, array( learndash_get_post_type_slug( 'lesson' ), learndash_get_post_type_slug( 'topic' ) ) ) ) { return 0; } $meta = get_post_meta( $lesson_topic_post ->ID, '_' . $lesson_topic_post->post_type, true ); if ( ! isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] ) ) { if ( ( isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) && ( ! empty( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) ) { $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] = 'on'; } else { $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] = ''; } } if ( 'on' === $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_enabled' ] ) { if ( ( isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) && ( ! empty( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time' ] ) ) ) { $cookie_key = get_current_user_id() . '_' . learndash_get_course_id( $lesson_topic_post ) . '_' . $lesson_topic_post->ID; if ( ( isset( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_cookie_key' ] ) ) && ( ! empty( $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_cookie_key' ] ) ) ) { $cookie_key .= '_' . $meta[ $lesson_topic_post->post_type . '_forced_lesson_time_cookie_key' ]; } return $cookie_key; } } return ''; } /** * Is course completed for user * * @since 2.1.0 * * @param int $user_id * @param int $course_id * @return bool */ function learndash_course_completed( $user_id, $course_id ) { if ( learndash_course_status( $course_id, $user_id ) == esc_html__( 'Completed', 'learndash' ) ) { return true; } else { return false; } } /** * Add course completion date to user meta * * @since 2.1.0 * * @param array $data */ function learndash_course_completed_store_time( $data ) { $user_id = $data['user']->ID; $course_id = $data['course']->ID; $meta_key = 'course_completed_' . $course_id; $meta_value = time(); $course_completed = get_user_meta( $user_id, $meta_key ); if ( empty( $course_completed ) ) { update_user_meta( $user_id, $meta_key, $meta_value ); } } add_action( 'learndash_before_course_completed', 'learndash_course_completed_store_time', 10, 1 ); /** * Delete course progress for user * * @since 2.1.0 * * @param int $course_id * @param int $user_id */ function learndash_delete_course_progress( $course_id, $user_id ) { global $wpdb; $usermeta = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( isset( $usermeta[ $course_id ] ) ) { unset( $usermeta[ $course_id ] ); update_user_meta( $user_id, '_sfwd-course_progress', $usermeta ); } delete_user_meta( $user_id, 'course_completed_' . $course_id ); // The reason we don't use the methods above is we want to ensure all old data is removed // from the quiz attempt history not just for quizzes currently associated with the course. $quizzes = array(); $usermeta_quizzes = get_user_meta( $user_id, '_sfwd-quizzes', true ); if ( ! is_array( $usermeta_quizzes ) ) { $usermeta_quizzes = array(); } if ( ! empty( $usermeta_quizzes ) ) { foreach ( $usermeta_quizzes as $quiz_item ) { if ( ( isset( $quiz_item['course'] ) ) && ( intval( $course_id ) == intval( $quiz_item['course'] ) ) ) { if ( isset( $quiz_item['quiz'] ) ) { $quiz_id = intval( $quiz_item['quiz'] ); $quizzes[ $quiz_id ] = $quiz_id; } } } } if ( ! empty( $quizzes ) ) { foreach ( $quizzes as $quiz_id ) { learndash_delete_quiz_progress( $user_id, $quiz_id ); } } } /** * Delete quiz progress for user * * @since 2.1.0 * * @param int $user_id * @param int $quiz_id */ function learndash_delete_quiz_progress( $user_id, $quiz_id ) { global $wpdb; // Clear User Meta $usermeta = get_user_meta( $user_id, '_sfwd-quizzes', true ); if ( ! empty( $usermeta ) && is_array( $usermeta ) ) { $usermeta_new = array(); foreach ( $usermeta as $key => $quizmeta ) { if ( $quizmeta['quiz'] != $quiz_id ) { $usermeta_new[] = $quizmeta; } } update_user_meta( $user_id, '_sfwd-quizzes', $usermeta_new ); } // Lesson/Topic /* $lesson_id = learndash_get_setting( $quiz_id, "lesson"); if(!empty( $lesson_id )) { $lesson_post = get_post( $lesson_id ); if( $lesson_post->post_type == "sfwd-lessons") learndash_specific_mark_lesson_incomplete( $user_id, $lesson_id ); else if( $lesson_post->post_type == "sfwd-topic") learndash_specific_mark_topic_incomplete( $user_id, $lesson_id ); }*/ // Pro Quiz Data $pro_quiz_id = learndash_get_setting( $quiz_id, 'quiz_pro' ); $ref_ids = $wpdb->get_col( $wpdb->prepare( 'SELECT statistic_ref_id FROM ' . LDLMS_DB::get_table_name( 'quiz_statistic_ref' ) . " WHERE user_id = '%d' AND quiz_id = '%d' ", $user_id, $pro_quiz_id ) ); if ( ! empty( $ref_ids[0] ) ) { $wpdb->delete( LDLMS_DB::get_table_name( 'quiz_statistic_ref' ), array( 'user_id' => $user_id, 'quiz_id' => $pro_quiz_id, ) ); $wpdb->query( 'DELETE FROM ' . LDLMS_DB::get_table_name( 'quiz_statistic' ) . ' WHERE statistic_ref_id IN (' . implode( ',', $ref_ids ) . ')' ); } // $wpdb->query("DELETE FROM ".$wpdb->usermeta." WHERE meta_key LIKE 'completed_%' AND user_id = '".$user->ID."'"); $wpdb->delete( LDLMS_DB::get_table_name( 'quiz_toplist' ), array( 'user_id' => $user_id, 'quiz_id' => $pro_quiz_id, ) ); } function learndash_quiz_remove_user_statistics_by_ref( $ref_id = 0 ) { global $wpdb; if ( ! empty( $ref_id ) ) { $wpdb->delete( LDLMS_DB::get_table_name( 'quiz_statistic_ref' ), array( 'statistic_ref_id' => $ref_id ) ); $wpdb->query( 'DELETE FROM ' . LDLMS_DB::get_table_name( 'quiz_statistic' ) . ' WHERE statistic_ref_id =' . $ref_id ); } } function learndash_quiz_remove_user_toplist( $user_id = 0, $quiz_time = 0, $pro_quizid = 0) { global $wpdb; if ( ( ! empty( $user_id ) ) && ( ! empty( $quiz_time ) ) && ( ! empty( $pro_quizid ) ) ) { return $wpdb->delete( LDLMS_DB::get_table_name( 'quiz_toplist' ), array( 'user_id' => $user_id, 'date' => $quiz_time, 'quiz_id' => $pro_quizid, ), array( '%d', '%d', '%d' ) ); } } // Used to set a Course step ( Lesson or Topic only ) back to NOT complete status function learndash_process_mark_incomplete( $user_id = 0, $course_id = 0, $step_id = 0, $step_complete = false ) { if ( empty( $user_id ) ) { return; } if ( empty( $course_id ) ) { return; } // Ensure the course is not completed // $course_status = learndash_course_status( $course_id, $user_id ); // if ( $course_status == esc_html__( 'Completed', 'learndash' ) ) { // return; // } if ( empty( $step_id ) ) { global $post; if ( ( isset( $post ) ) && ( $post instanceof WP_Post ) && ( ( in_array( $post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) ) ) { $step_id = $post->ID; } else { return; } } $subtracted_completed_steps = 0; $course_step_parents = learndash_course_get_all_parent_step_ids( $course_id, $step_id ); $user_course_progress = get_user_meta( $user_id, '_sfwd-course_progress', true ); $step_post_type = get_post_type( $step_id ); if ( $step_post_type === 'sfwd-quiz' ) { if ( ! empty( $course_step_parents ) ) { if ( ( sizeof( $course_step_parents ) == 2 ) && ( 'sfwd-lessons' == get_post_type( $course_step_parents[0] ) ) && ( 'sfwd-topic' == get_post_type( $course_step_parents[1] ) ) ) { $lesson_id = $course_step_parents[0]; $topic_id = $course_step_parents[1]; if ( ( isset( $user_course_progress[ $course_id ]['topics'][ $lesson_id ][ $topic_id ] ) ) && ( $user_course_progress[ $course_id ]['topics'][ $lesson_id ][ $topic_id ] == true ) ) { $user_course_progress[ $course_id ]['topics'][ $lesson_id ][ $topic_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $topic_id ); $topic_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $topic_id, 'activity_type' => 'topic', ); $topic_activity = learndash_get_user_activity( $topic_args ); if ( $topic_activity ) { $topic_activity = (array) $topic_activity; $topic_activity['activity_status'] = false; $topic_activity['activity_completed'] = false; learndash_update_user_activity( $topic_activity ); } } if ( ( isset( $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] ) ) && ( $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] == true ) ) { $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $lesson_id ); $lesson_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $lesson_id, 'activity_type' => 'lesson', ); $lesson_activity = learndash_get_user_activity( $lesson_args ); if ( $lesson_args ) { $lesson_args = (array) $lesson_args; $lesson_args['activity_status'] = false; $lesson_args['activity_completed'] = false; learndash_update_user_activity( $lesson_args ); } } } elseif ( ( sizeof( $course_step_parents ) == 1 ) && ( 'sfwd-lessons' == get_post_type( $course_step_parents[0] ) ) ) { $lesson_id = $course_step_parents[0]; if ( ( isset( $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] ) ) && ( $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] == true ) ) { $user_course_progress[ $course_id ]['lessons'][ $lesson_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $lesson_id ); $lesson_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $lesson_id, 'activity_type' => 'lesson', ); $lesson_activity = learndash_get_user_activity( $lesson_args ); if ( $lesson_args ) { $lesson_args = (array) $lesson_args; $lesson_args['activity_status'] = false; $lesson_args['activity_completed'] = false; learndash_update_user_activity( $lesson_args ); } } } } } elseif ( $step_post_type === 'sfwd-topic' ) { $step_parent_id = learndash_course_get_single_parent_step( $course_id, $step_id ); if ( ! empty( $step_parent_id ) ) { if ( ( isset( $user_course_progress[ $course_id ]['topics'][ $step_parent_id ][ $step_id ] ) ) && ( $user_course_progress[ $course_id ]['topics'][ $step_parent_id ][ $step_id ] == true ) ) { $user_course_progress[ $course_id ]['topics'][ $step_parent_id ][ $step_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $topic_id ); $topic_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $step_id, 'activity_type' => 'topic', ); $topic_activity = learndash_get_user_activity( $topic_args ); if ( $topic_activity ) { $topic_activity = (array) $topic_activity; $topic_activity['activity_status'] = false; $topic_activity['activity_completed'] = false; learndash_update_user_activity( $topic_activity ); } } if ( ( isset( $user_course_progress[ $course_id ]['lessons'][ $step_parent_id ] ) ) && ( $user_course_progress[ $course_id ]['lessons'][ $step_parent_id ] == true ) ) { $user_course_progress[ $course_id ]['lessons'][ $step_parent_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $step_parent_id ); $lesson_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $step_parent_id, 'activity_type' => 'topic', ); $lesson_activity = learndash_get_user_activity( $lesson_args ); if ( $lesson_args ) { $lesson_args = (array) $lesson_args; $lesson_args['activity_status'] = false; $lesson_args['activity_completed'] = false; learndash_update_user_activity( $lesson_args ); } } } } elseif ( $step_post_type === 'sfwd-lessons' ) { if ( ( isset( $user_course_progress[ $course_id ]['lessons'][ $step_id ] ) ) && ( $user_course_progress[ $course_id ]['lessons'][ $step_id ] == true ) ) { $user_course_progress[ $course_id ]['lessons'][ $step_id ] = 0; $user_course_progress[ $course_id ]['completed'] -= 1; do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $step_id ); $lesson_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $step_id, 'activity_type' => 'lesson', ); $lesson_activity = learndash_get_user_activity( $lesson_args ); if ( $lesson_args ) { $lesson_args = (array) $lesson_args; $lesson_args['activity_status'] = false; $lesson_args['activity_completed'] = false; learndash_update_user_activity( $lesson_args ); } } } $user_course_progress[ $course_id ]['completed'] = absint( $user_course_progress[ $course_id ]['completed'] ); $user_course_progress[ $course_id ]['total'] = absint( $user_course_progress[ $course_id ]['total'] ); if ( $user_course_progress[ $course_id ]['completed'] !== $user_course_progress[ $course_id ]['total'] ) { delete_user_meta( $user_id, 'course_completed_' . $course_id ); do_action( 'learndash_mark_incomplete_process', $user_id, $course_id, $course_id ); $course_args = array( 'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $course_id, 'activity_type' => 'course', ); $course_activity = learndash_get_user_activity( $course_args ); if ( $course_args ) { $course_args = (array) $course_args; $course_args['activity_status'] = false; $course_args['activity_completed'] = false; learndash_update_user_activity( $course_args ); } } return update_user_meta( $user_id, '_sfwd-course_progress', $user_course_progress ); } /** * Utility function to retreive a specific user quiz meta attempt. * * @param $args array of items to match. * * @since 2.5 */ function learndash_get_user_quiz_attempt( $user_id = 0, $args = array() ) { if ( ( ! empty( $user_id ) ) && ( ! empty( $args ) ) ) { $user_quizzes = get_user_meta( $user_id, '_sfwd-quizzes', true ); if ( ! empty( $user_quizzes ) ) { foreach ( $user_quizzes as $idx => $user_quiz ) { foreach ( $args as $arg_key => $arg_val ) { if ( ( ! isset( $user_quiz[ $arg_key ] ) ) || ( $user_quiz[ $arg_key ] != $arg_val ) ) { unset( $user_quizzes[ $idx ] ); } } } } return $user_quizzes; } } function learndash_remove_user_quiz_attempt( $user_id = 0, $args = array() ) { if ( ( ! empty( $user_id ) ) && ( ! empty( $args ) ) ) { $CHANGES = false; $user_quizzes = get_user_meta( $user_id, '_sfwd-quizzes', true ); if ( ! empty( $user_quizzes ) ) { $changed_user_quizzes = array(); foreach ( $user_quizzes as $idx => $user_quiz ) { $MATCH_FOUND = true; foreach ( $args as $arg_key => $arg_val ) { if ( ( ! isset( $user_quiz[ $arg_key ] ) ) || ( $user_quiz[ $arg_key ] != $arg_val ) ) { $MATCH_FOUND = false; break; } } if ( $MATCH_FOUND === true ) { if ( ( isset( $user_quiz['time'] ) ) && ( ! empty( $user_quiz['time'] ) ) ) { if ( ( isset( $user_quiz['pro_quizid'] ) ) && ( ! empty( $user_quiz['pro_quizid'] ) ) ) { learndash_quiz_remove_user_toplist( $user_id, $user_quiz['time'], $user_quiz['pro_quizid'] ); } } // If we have a statistics reference we need to remove this set of records. if ( ( isset( $user_quiz['statistic_ref_id'] ) ) && ( ! empty( $user_quiz['statistic_ref_id'] ) ) ) { learndash_quiz_remove_user_statistics_by_ref( $user_quiz['statistic_ref_id'] ); } if ( ( ! isset( $user_quiz['course'] ) ) || ( empty( $user_quiz['course'] ) ) ) { $user_quiz['course'] = learndash_get_course_id( $user_quiz['quiz'] ); } // If this quiz has graded items they all need to be moved to trash or deleted. if ( ( isset( $user_quiz['graded'] ) ) && ( ! empty( $user_quiz['graded'] ) ) ) { foreach ( $user_quiz['graded'] as $question_id => $graded_set ) { if ( ( isset( $graded_set['post_id'] ) ) && ( ! empty( $graded_set['post_id'] ) ) ) { wp_delete_post( $graded_set['post_id'], true ); } } } // Remove the user activity record. $quiz_args = array( 'course_id' => $user_quiz['course'], 'user_id' => $user_id, 'post_id' => $user_quiz['quiz'], 'activity_type' => 'quiz', 'activity_completed' => $user_quiz['completed'], ); $quiz_activity = learndash_get_user_activity( $quiz_args ); if ( ! empty( $quiz_activity ) ) { learndash_delete_user_activity( $quiz_activity->activity_id ); } $changed_user_quizzes[] = $user_quiz; unset( $user_quizzes[ $idx ] ); $CHANGES = true; } } if ( true === $CHANGES ) { // If not empty then we reset the keys. if ( ! empty( $user_quizzes ) ) { $user_quizzes = array_values( $user_quizzes ); } update_user_meta( $user_id, '_sfwd-quizzes', $user_quizzes ); if ( ! empty( $changed_user_quizzes ) ) { foreach ( $changed_user_quizzes as $user_quiz ) { if ( ! learndash_is_quiz_complete( $user_id, $user_quiz['quiz'], $user_quiz['course'] ) ) { learndash_process_mark_incomplete( $user_id, $user_quiz['course'], $user_quiz['quiz'], false ); } learndash_process_mark_complete( $user_id, $user_quiz['quiz'], false, $user_quiz['course'] ); } } } } return $user_quizzes; } } /** * Output HTML output to mark a step incomplete * * Must meet requirements of course * * @since 2.1.0 * * @param object $post WP_Post lesson, topic. * @return string HTML output to mark course complete */ function learndash_show_mark_incomplete( $post, $atts = array() ) { if ( ( ! defined( 'LEARNDASH_SHOW_MARK_INCOMPLETE' ) ) || ( true !== LEARNDASH_SHOW_MARK_INCOMPLETE ) ) { return ''; } if ( ! is_user_logged_in() ) { return ''; } $user_id = get_current_user_id(); $course_id = learndash_get_course_id( $post->ID ); if ( ! apply_filters( 'learndash_show_mark_incomplete_form', true, $course_id, $post, $atts ) ) { return ''; } $atts = apply_filters( 'learndash_mark_incomplete_form_atts', $atts, $post ); if ( isset( $atts['form']['id'] ) ) { $form_id = ' id="' . esc_attr( $atts['form']['id'] ) . '" '; } else { $form_id = ''; } if ( isset( $atts['form']['class'] ) ) { $form_class = ' class="sfwd-mark-incomplete sfwd-mark-complete ' . esc_attr( $atts['form']['class'] ) . '" '; } else { $form_class = ' class="sfwd-mark-incomplete sfwd-mark-complete" '; } if ( isset( $atts['button']['id'] ) ) { $button_id = ' id="' . esc_attr( $atts['button']['id'] ) . '" '; } else { $button_id = ''; } $button_disabled = ''; if ( isset( $atts['button']['class'] ) ) { $button_class = ' class="learndash_mark_incomplete_button learndash_mark_complete_button ' . esc_attr( $atts['button']['class'] ) . '" '; } else { $button_class = ' class="learndash_mark_incomplete_button learndash_mark_complete_button" '; } $button_label = LearnDash_Custom_Label::get_label( 'button_mark_incomplete' ); if ( empty( $button_label ) ) { $button_label = 'Mark Incomplete'; } $form_fields = '<input type="hidden" value="' . $post->ID . '" name="post" /> <input type="hidden" value="' . learndash_get_course_id( $post->ID ) . '" name="course_id" /> <input type="hidden" value="' . wp_create_nonce( 'sfwd_mark_incomplete_' . get_current_user_id() . '_' . $post->ID ) . '" name="sfwd_mark_incomplete" /> <input type="submit" ' . $button_id . ' value="' . esc_html( $button_label ) . '" ' . $button_class . ' ' . $button_disabled . '/>'; /** * Allow the outside world to filter the form fields. * * @since 3.0 * @param string $form_fields. * @param object $post WP_Post object being displayed. */ $form_fields = apply_filters( 'learndash_mark_complete_form_fields', $form_fields, $post ); $return = '<form ' . $form_id . ' ' . $form_class . ' method="post" action="">' . $form_fields . '</form>'; return $return; } /** * Process request to mark a course or step incomplete * * @since 2.1.0 * * @param int $post WP_Post object. */ function learndash_mark_incomplete_process( $post = null ) { // This is wrong. This function hooks into the 'wp' action. That action doesn't pass a post object or post_id. // The $post object set here is not even used. We only need the _POST[post] (post_id) variable from the form. if ( empty( $post ) ) { global $post; } if ( ( isset( $_POST['sfwd_mark_incomplete'] ) ) && ( ! empty( $_POST['sfwd_mark_incomplete'] ) ) && ( isset( $_POST['post'] ) ) && ( ! empty( $_POST['post'] ) ) ) { if ( empty( $post ) || empty( $post->ID ) ) { $post = get_post(); if ( empty( $post ) || empty( $post->ID ) ) { return; } } $post_id = intval( $_POST['post'] ); if ( isset( $_POST['course_id'] ) ) { $course_id = intval( $_POST['course_id'] ); } else { $course_id = learndash_get_course_id( $post_id ); } if ( isset( $_POST['userid'] ) ) { $user_id = intval( $_POST['userid'] ); } else { if ( ! is_user_logged_in() ) { return; } $user_id = get_current_user_id(); } /** * Verify the form is valid * * @since 2.2.1.2 */ if ( ! wp_verify_nonce( $_POST['sfwd_mark_incomplete'], 'sfwd_mark_incomplete_' . $user_id . '_' . $post_id ) ) { return; } $return = learndash_process_mark_incomplete( $user_id, $course_id, $post_id, false ); } } add_action( 'wp', 'learndash_mark_incomplete_process' ); ld-course-functions.php 0000666 00000274130 15214044143 0011171 0 ustar 00 <?php /** * Course Functions * * @since 2.1.0 * * @package LearnDash\Course */ /** * Get course ID for resource. * * Determine type of ID is being passed in. Should be the ID of * anything that belongs to a course (Lesson, Topic, Quiz, etc) * * @since 2.1.0 * * @param obj|int $id id of resource * @param bool $bypass_cb if true will bypass course_builder logic @since 2.5 * * @return string id of course */ function learndash_get_course_id( $id = null, $bypass_cb = false ) { //global $post; if ( is_object( $id ) && $id->ID ) { $p = $id; $id = $p->ID; } else if ( is_numeric( $id ) ) { $p = get_post( $id ); } if ( empty( $id ) ) { if ( defined( 'REST_REQUEST' ) && REST_REQUEST ) { //return false; } else { if ( is_admin() ) { global $parent_file, $post_type, $pagenow; if ( ( ! in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) || ( ! in_array( $post_type, array( 'sfwd-courses', 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) ) { return false; } } else if ( ! is_single() || is_home() ) { return false; } } $post = get_post( get_the_id() ); if ( ( $post ) && ( $post instanceof WP_Post ) ) { $id = $post->ID; $p = $post; } else { return false; } } if ( empty( $p->ID ) ) { return 0; } if ( $p->post_type == 'sfwd-courses' ) { return $p->ID; } // Somewhat a kludge. Here we try ans assume the course_id being handled. if ( ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) && ( $bypass_cb === false ) ) { if ( ! is_admin() ) { $course_slug = get_query_var( 'sfwd-courses' ); if ( ! empty( $course_slug ) ) { //$course_post = get_page_by_path( $course_slug, OBJECT, 'sfwd-courses' ); $course_post = learndash_get_page_by_path( $course_slug, 'sfwd-courses' ); if ( ( $course_post ) && ( $course_post instanceof WP_Post ) ) { return $course_post->ID; } } } if ( ( isset( $_GET['course_id'] ) ) && ( ! empty( $_GET['course_id'] ) ) ) { return intval( $_GET['course_id'] ); } else if ( ( isset( $_GET['course'] ) ) && ( ! empty( $_GET['course'] ) ) ) { return intval( $_GET['course'] ); } else if ( ( isset( $_POST['course_id'] ) ) && ( ! empty( $_POST['course_id'] ) ) ) { return intval( $_POST['course_id'] ); } else if ( ( isset( $_POST['course'] ) ) && ( ! empty( $_POST['course'] ) ) ) { return intval( $_POST['course'] ); } else if ( ( isset( $_GET['post'] ) ) && ( ! empty( $_GET['post'] ) ) ) { if ( get_post_type( intval( $_GET['post'] ) ) == 'sfwd-courses' ) { return intval( $_GET['post'] ); } } } return (int)get_post_meta( $id, 'course_id', true ); } /** * Get course ID for resource (legacy users) * * Determine type of ID is being passed in. Should be the ID of * anything that belongs to a course (Lesson, Topic, Quiz, etc) * * @since 2.1.0 * * @param obj|int $id id of resource * @return string id of course */ function learndash_get_legacy_course_id( $id = null ){ global $post; if ( empty( $id ) ) { if ( ! is_single() || is_home() ) { return false; } $id = $post->ID; } $terms = wp_get_post_terms( $id, 'courses' ); if ( empty( $terms) || empty( $terms[0] ) || empty( $terms[0]->slug) ) { return 0; } $courseslug = $terms[0]->slug; global $wpdb; $term_taxonomy_id = $wpdb->get_var( $wpdb->prepare( " SELECT `term_taxonomy_id` FROM $wpdb->term_taxonomy tt, $wpdb->terms t WHERE slug = %s AND t.term_id = tt.term_id AND tt.taxonomy = 'courses' ", $courseslug ) ); $course_id = $wpdb->get_var( $wpdb->prepare( " SELECT `ID` FROM $wpdb->term_relationships, $wpdb->posts WHERE `ID` = `object_id` AND `term_taxonomy_id` = %d AND `post_type` = 'sfwd-courses' AND `post_status` = 'publish' ", $term_taxonomy_id ) ); return $course_id; } /** * Get lesson id of resource * * @since 2.1.0 * * @param int $id post id of resource * @return string lesson id */ function learndash_get_lesson_id( $post_id = null, $course_id = null ) { global $post; if ( empty( $post_id ) ) { if ( ! is_single() || is_home() ) { return false; } $post_id = $post->ID; } if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $lesson_slug = get_query_var( 'sfwd-lessons' ); if ( !empty( $lesson_slug ) ) { //$lesson_post = get_page_by_path( $lesson_slug, OBJECT, 'sfwd-lessons' ); $lesson_post = learndash_get_page_by_path( $lesson_slug, 'sfwd-lessons' ); if ( ( $lesson_post ) && ( $lesson_post instanceof WP_Post ) ) { return $lesson_post->ID; } } else { if ( empty( $course_id ) ) { $course_id = learndash_get_course_id( $post_id ); } if ( !empty( $course_id ) ) { return learndash_course_get_single_parent_step( $course_id, $post_id ); } } } return get_post_meta( $post_id, 'lesson_id', true ); } /** * Get array of courses that user has access to * * @since 2.1.0 * * @param int $user_id * @param array array attributes ('order', 'orderby') * @return array array of courses that user has access to */ function ld_get_mycourses( $user_id = null, $atts = array() ) { $defaults = array( 'order' => 'DESC', 'orderby' => 'ID', 's' => '', ); $atts = wp_parse_args( $atts, $defaults ); return learndash_user_get_enrolled_courses( $user_id, $atts, true ); } /** * Does user have access to course (houses filter) * * @since 2.1.0 * * @param int $post_id id of resource * @param int $user_id * @return bool */ function sfwd_lms_has_access( $post_id, $user_id = null ) { /** * Filter if user has access to course * * Calls sfwd_lms_has_access_fn() to determine if user has access to course * * @since 2.1.0 * * @param bool */ return apply_filters( 'sfwd_lms_has_access', sfwd_lms_has_access_fn( $post_id, $user_id ), $post_id, $user_id ); } /** * Does user have access to course * * Check's if user has access to course when they try to access a resource that * belong to that course (Lesson, Topic, Quiz, etc.) * * @since 2.1.0 * * @param int $post_id id of resource * @param int $user_id * @return bool */ function sfwd_lms_has_access_fn( $post_id, $user_id = null ) { if ( empty( $user_id ) ) { $user_id = get_current_user_id(); } if ( learndash_is_admin_user( $user_id ) ) { /** * See example if 'learndash_override_course_auto_enroll' filter * https://bitbucket.org/snippets/learndash/kon6y * * @since 2.3 */ $course_autoenroll_admin = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_General_Admin_User', 'courses_autoenroll_admin_users' ); if ( $course_autoenroll_admin == 'yes' ) { $course_autoenroll_admin = true; } else { $course_autoenroll_admin = false; } if ( apply_filters('learndash_override_course_auto_enroll', $course_autoenroll_admin, $user_id ) ) { return true; } } $course_id = learndash_get_course_id( $post_id ); if ( empty( $course_id ) ) { return true; } if ( ! empty( $post_id ) && learndash_is_sample( $post_id ) ) { return true; } $meta = get_post_meta( $course_id, '_sfwd-courses', true ); if ( @$meta['sfwd-courses_course_price_type'] == 'open' || @$meta['sfwd-courses_course_price_type'] == 'paynow' && empty( $meta['sfwd-courses_course_join'] ) && empty( $meta['sfwd-courses_course_price'] ) ) { return true; } if ( empty( $user_id ) ) { return false; } if ( true === learndash_use_legacy_course_access_list() ) { if ( ! empty( $meta['sfwd-courses_course_access_list'] ) ) { //$course_access_list = explode( ',', $meta['sfwd-courses_course_access_list'] ); $course_access_list = learndash_convert_course_access_list( $meta['sfwd-courses_course_access_list'], true ); } else { $course_access_list = array(); } if ( ( in_array( $user_id, $course_access_list ) ) || ( learndash_user_group_enrolled_to_course( $user_id, $course_id ) ) ) { $expired = ld_course_access_expired( $course_id, $user_id ); return ! $expired; //True if not expired. } else { return false; } } else { $course_user_meta = get_user_meta( $user_id, 'course_' . $course_id . '_access_from', true ); if ( ( ! empty( $course_user_meta ) ) || ( learndash_user_group_enrolled_to_course( $user_id, $course_id ) ) ) { $expired = ld_course_access_expired( $course_id, $user_id ); return ! $expired; //True if not expired. } else { return false; } } } /** * Redirect user to course * * @since 2.1.0 * * @param int $post_id id of resource that belongs to a course */ function sfwd_lms_access_redirect( $post_id ) { $access = sfwd_lms_has_access( $post_id ); if ( $access === true ) { return true; } $link = get_permalink( learndash_get_course_id( $post_id ) ); $link = apply_filters( 'learndash_access_redirect' , $link, $post_id ); if ( !empty( $link ) ) { wp_redirect( $link ); exit(); } } /** * Is users access to course expired * * @since 2.1.0 * * @param int $course_id * @param int $user_id * @return bool */ function ld_course_access_expired( $course_id, $user_id ) { $course_access_upto = ld_course_access_expires_on( $course_id, $user_id ); if ( empty( $course_access_upto ) ) { return false; } else { if ( time() >= $course_access_upto ) { /** * Filter to control processing the user course expiration. * * @since 2.6.2 * @param boolean true. * @param integer $user_id User ID. * @param integer $course_id, Course ID. * @param integer $course_access_upto Timestamp when user course access is to expire. * * If return true then processing will continue. If false returned then abort and false returned to calling function. */ if ( apply_filters( 'learndash_process_user_course_access_expire', true, $user_id, $course_id, $course_access_upto ) ) { /** * As of LearnDash 2.3.0.3 we store the GMT timestamp as the meta value. In prior versions we stored 1 */ update_user_meta( $user_id, 'learndash_course_expired_' . $course_id, time() ); ld_update_course_access( $user_id, $course_id, true ); /** * Action fired when the user course access expired. * * @since 2.6.2 * * @param integer $user_id User ID. * @param integer $course_id, Course ID. */ do_action( 'learndash_user_course_access_expired', $user_id, $course_id ); $delete_course_progress = learndash_get_setting( $course_id, 'expire_access_delete_progress' ); if ( ! empty( $delete_course_progress) ) { learndash_delete_course_progress( $course_id, $user_id ); } return true; } else { return false; } } else { return false; } } } /** * Generate alert in wp_head that users access to course is expired * * @since 2.1.0 */ function ld_course_access_expired_alert() { global $post; if ( ! is_singular() || empty( $post->ID ) || $post->post_type != 'sfwd-courses' ) { return; } $user_id = get_current_user_id(); if ( empty( $user_id ) ) { return; } $expired = get_user_meta( $user_id, 'learndash_course_expired_'.$post->ID, true ); if ( empty( $expired) ) { return; } $has_access = sfwd_lms_has_access( $post->ID, $user_id ); if ( $has_access ) { delete_user_meta( $user_id, 'learndash_course_expired_'.$post->ID ); return; } else { ?> <script> setTimeout(function() { alert("<?php echo sprintf( esc_html_x( 'Your access to this %s has expired.', 'Your access to this course has expired.', 'learndash' ), LearnDash_Custom_Label::get_label( 'course' )); ?>") }, 2000); </script> <?php } } add_action( 'wp_head', 'ld_course_access_expired_alert', 1 ); /** * Get amount of time until users course access expires for user * * @since 2.1.0 * * @param int $course_id * @param int $user_id * @return int */ function ld_course_access_expires_on( $course_id, $user_id ) { // Set a default return var. $course_access_upto = 0; // Check access to course_id + user_id $courses_access_from = ld_course_access_from( $course_id, $user_id ); // If the course_id + user_id is not set we check the group courses. if ( empty( $courses_access_from ) ) { $courses_access_from = learndash_user_group_enrolled_to_course_from( $user_id, $course_id ); } // If we have a non-empty access from... if ( abs( intval( $courses_access_from ) ) ) { // Check the course is using expire access $expire_access = learndash_get_setting( $course_id, 'expire_access' ); // The value stored in the post meta for 'expire_access' is 'on' not true/false 1 or 0. The string 'on'. if ( !empty( $expire_access) ) { $expire_access_days = learndash_get_setting( $course_id, 'expire_access_days' ); if ( abs( intval( $expire_access_days ) ) > 0 ) { $course_access_upto = abs( intval( $courses_access_from ) ) + ( abs( intval( $expire_access_days ) ) * DAY_IN_SECONDS ); } } } /** * Filter for 'ld_course_access_expires_on'. * * @since 3.0.7 * @param integer $course_access_upto timestamp. * @param integer $course_id Course ID. * @param integer $user_id User ID. */ return apply_filters( 'ld_course_access_expires_on', $course_access_upto, $course_id, $user_id ); } /** * Get amount of time when lesson becomes available to user * * @since 2.1.0 * * @param int $course_id Course ID to check. * @param int $user_id User ID to check. * @return int */ function ld_course_access_from( $course_id = 0, $user_id = 0 ) { static $courses = array(); $course_id = absint( $course_id ); $user_id = absint( $user_id ); // If Shared Steps enabled we need to ensure both Course ID and User ID and not empty. if ( 'yes' === LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) ) { if ( ( empty( $course_id ) ) || ( empty( $user_id ) ) ) { return false; } } if ( ! isset( $courses[ $course_id ][ $user_id ] ) ) { if ( ! isset( $courses[ $course_id ] ) ) { $courses[ $course_id ] = array(); } $courses[ $course_id ][ $user_id ] = false; $courses[ $course_id ][ $user_id ] = (int) get_user_meta( $user_id, 'course_' . $course_id . '_access_from', true ); if ( empty( $courses[ $course_id ][ $user_id ] ) ) { if ( ( 'open' === learndash_get_course_meta_setting( $course_id, 'course_price_type' ) ) && ( apply_filters( 'learndash_course_open_set_user_access_from', true, $user_id, $course_id ) ) ) { $enrolled_groups = learndash_user_group_enrolled_to_course_from( $user_id, $course_id ); if ( ! empty( $enrolled_groups ) ) { $courses[ $course_id ][ $user_id ] = absint( $enrolled_groups ); } } } if ( empty( $courses[ $course_id ][ $user_id ] ) ) { $course_activity_args = array( //'course_id' => $course_id, 'user_id' => $user_id, 'post_id' => $course_id, 'activity_type' => 'access', ); $course_activity = learndash_get_user_activity( $course_activity_args ); if ( ( ! empty( $course_activity ) ) && ( is_object( $course_activity ) ) ) { if ( ( property_exists( $course_activity, 'activity_started' ) ) && ( ! empty( $course_activity->activity_started ) ) ) { $courses[ $course_id ][ $user_id ] = intval( $course_activity->activity_started ); update_user_meta( $user_id, 'course_' . $course_id . '_access_from', $courses[ $course_id ][ $user_id ] ); } } } } /** * Filter for 'ld_course_access_from'. * * @since 3.0.7 * @param integer timestamp * @param integer $course_id * @param integer $user_id */ return apply_filters( 'ld_course_access_from', $courses[ $course_id ][ $user_id ], $course_id, $user_id ); } /** * Update the course access time for a user. * * @since 2.6.0 * * @param int $course_id Course ID for update. * @param int $user_id User ID for update. * @param mixed $access Value can be a date string (YYYY-MM-DD hh:mm:ss or integer value. * @param bool $is_gmt If $access value is GMT (true) or relative to site timezone (false). * * @return bool Returns true if success. */ function ld_course_access_from_update( $course_id, $user_id, $access = '', $is_gmt = false ) { if ( ( ! empty( $course_id ) ) && ( ! empty( $user_id ) ) && ( ! empty( $access ) ) ) { if ( ! is_numeric( $access ) ) { // If we a non-numberic value like a date stamp Y-m-d hh:mm:ss we want to convert it to a GMT timestamp. $access_time = learndash_get_timestamp_from_date_string( $access, !$is_gmt ); } elseif ( is_string( $access ) ) { if ( ! $is_gmt ) { $access = get_gmt_from_date( $access, 'Y-m-d H:i:s' ); } $access_time = strtotime( $access ); } else { return false; } if ( ( ! empty( $access_time ) ) && ( $access_time > 0 ) ) { // We don't allow dates greater than now. if ( $access_time > time() ) { $access_time = time(); } $course_args = array( 'course_id' => $course_id, 'post_id' => $course_id, 'activity_type' => 'course', 'user_id' => $user_id, 'activity_started' => $access_time, ); $activity_id = learndash_update_user_activity( $course_args ); return update_user_meta( $user_id, 'course_' . $course_id . '_access_from', $access_time ); } } } /** * Update list of courses users has access to * * @since 2.1.0 * * @param int $user_id * @param int $course_id * @param bool $remove * @return array list of courses users has access to */ function ld_update_course_access( $user_id, $course_id, $remove = false ) { $action_success = false; $user_id = absint( $user_id ); $course_id = absint( $course_id ); $course_access_list = null; if ( ( empty( $user_id ) ) || ( empty( $course_id ) ) ) { return; } if ( true === learndash_use_legacy_course_access_list() ) { $course_access_list = learndash_get_setting( $course_id, 'course_access_list' ); $course_access_list = learndash_convert_course_access_list( $course_access_list, true ); if ( empty( $remove ) ) { $course_access_list[] = $user_id; $course_access_list = array_unique( $course_access_list ); $action_success = true; } else { $course_access_list = array_diff( $course_access_list, array( $user_id ) ); $action_success = true; } $course_access_list = learndash_convert_course_access_list( $course_access_list ); learndash_update_setting( $course_id, 'course_access_list', $course_access_list ); } $user_course_access_time = 0; if ( empty( $remove ) ) { $user_course_access_time = get_user_meta( $user_id, 'course_' . $course_id . '_access_from', true ); if ( empty( $user_course_access_time ) ) { $user_course_access_time = time(); update_user_meta( $user_id, 'course_' . $course_id . '_access_from', $user_course_access_time ); $action_success = true; } } else { delete_user_meta( $user_id, 'course_'. $course_id .'_access_from' ); $action_success = true; } $course_activity_args = array( 'activity_type' => 'access', 'user_id' => $user_id, 'post_id' => $course_id, 'course_id' => $course_id, ); $course_activity = learndash_get_user_activity( $course_activity_args ); if ( is_null( $course_activity ) ) { $course_activity_args['course_id'] = 0; $course_activity = learndash_get_user_activity( $course_activity_args ); } if ( is_object( $course_activity ) ) { $course_activity_args = json_decode( json_encode( $course_activity ), true ); $course_activity_args['changed'] = false; } else { $course_activity_args['changed'] = true; $course_activity_args['activity_started'] = 0; } if ( ( empty( $course_activity_args['course_id'] ) ) || ( $course_activity_args['course_id'] !== $course_activity_args['post_id'] ) ) { $course_activity_args['course_id'] = $course_activity_args['post_id']; $course_activity_args['changed'] = true; } if ( empty( $remove ) ) { if ( $user_course_access_time !== absint( $course_activity_args['activity_started'] ) ) { $course_activity_args['activity_started'] = $user_course_access_time; $course_activity_args['changed'] = true; } } else { $course_activity_args['activity_started'] = $user_course_access_time; $course_activity_args['changed'] = true; } if ( true === $course_activity_args['changed'] ) { $skip = false; if ( ( ! empty( $remove ) ) && ( ! isset( $course_activity_args['activity_id'] ) ) ) { $skip = true; } if ( true !== $skip ) { $course_activity_args['data_upgrade'] = true; learndash_update_user_activity( $course_activity_args ); } } /** * Run actions after a users list of courses is updated * * @since 2.1.0 * * @param int $user_id * @param int $course_id * @param array $course_access_list * @param bool $remove */ do_action( 'learndash_update_course_access', $user_id, $course_id, $course_access_list, $remove ); return $action_success; } /** * Get timestamp of when user has access to lesson * * @since 2.1.0 * * @param int $lesson_id * @param int $user_id * @return int timestamp */ function ld_lesson_access_from( $lesson_id, $user_id, $course_id = null ) { $return = null; if ( is_null( $course_id ) ) { $course_id = learndash_get_course_id( $lesson_id ); } $courses_access_from = ld_course_access_from( $course_id, $user_id ); if ( empty( $courses_access_from ) ) { $courses_access_from = learndash_user_group_enrolled_to_course_from( $user_id, $course_id ); } $visible_after = learndash_get_setting( $lesson_id, 'visible_after' ); if ( $visible_after > 0 ) { // Adjust the Course acces from by the number of days. Use abs() to ensure no negative days. $lesson_access_from = $courses_access_from + abs($visible_after) * 24 * 60 * 60; $lesson_access_from = apply_filters( 'ld_lesson_access_from__visible_after', $lesson_access_from, $lesson_id, $user_id ); $current_timestamp = time(); if ( $current_timestamp < $lesson_access_from ) { $return = $lesson_access_from; } } else { $visible_after_specific_date = learndash_get_setting( $lesson_id, 'visible_after_specific_date' ); if ( !empty( $visible_after_specific_date ) ) { if ( !is_numeric( $visible_after_specific_date ) ) { // If we a non-numberic value like a date stamp Y-m-d hh:mm:ss we want to convert it to a GMT timestamp $visible_after_specific_date = learndash_get_timestamp_from_date_string( $visible_after_specific_date, true ); } $current_time = time(); if ( $current_time < $visible_after_specific_date ) { $return = apply_filters( 'ld_lesson_access_from__visible_after_specific_date', $visible_after_specific_date, $lesson_id, $user_id ); } } } return apply_filters( 'ld_lesson_access_from', $return, $lesson_id, $user_id ); } /** * Display when lesson will be available * * @since 2.1.0 * * @param string $content content of lesson * @param object $post WP_Post object * @return string when lesson will be available */ function lesson_visible_after( $content, $post ) { if ( empty( $post->post_type ) ) { return $content; } if ( $post->post_type == 'sfwd-lessons' ) { $lesson_id = $post->ID; } else { if ( $post->post_type == 'sfwd-topic' || $post->post_type == 'sfwd-quiz' ) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_id = learndash_get_course_id( $post ); $lesson_id = learndash_course_get_single_parent_step( $course_id, $post->ID ); } else { $lesson_id = learndash_get_setting( $post, 'lesson' ); } } else { return $content; } } if ( empty( $lesson_id ) ) { return $content; } if ( is_user_logged_in() ) { $user_id = get_current_user_id(); } else { return $content; } if ( learndash_is_admin_user( $user_id ) ) { $bypass_course_limits_admin_users = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_General_Admin_User', 'bypass_course_limits_admin_users' ); if ( $bypass_course_limits_admin_users == 'yes' ) $bypass_course_limits_admin_users = true; else $bypass_course_limits_admin_users = false; } else { $bypass_course_limits_admin_users = false; } // For logged in users to allow an override filter. $bypass_course_limits_admin_users = apply_filters( 'learndash_prerequities_bypass', $bypass_course_limits_admin_users, $user_id, $post->ID, $post ); $lesson_access_from = ld_lesson_access_from( $lesson_id, get_current_user_id() ); if ( ( empty( $lesson_access_from ) ) || ( $bypass_course_limits_admin_users ) ) { return $content; } else { $content = SFWD_LMS::get_template( 'learndash_course_lesson_not_available', array( 'user_id' => get_current_user_id(), 'course_id' => learndash_get_course_id( $lesson_id ), 'lesson_id' => $lesson_id, 'lesson_access_from_int' => $lesson_access_from, 'lesson_access_from_date' => learndash_adjust_date_time_display( $lesson_access_from ), 'context' => 'lesson' ), false ); return $content; } return $content; } add_filter( 'learndash_content', 'lesson_visible_after', 1, 2 ); /** * Is users course prerequisites completed for a given course * * @since 2.1.0 * * @param int $id course id * @return boolean */ function is_course_prerequities_completed( $post_id = 0 ) { $course_pre_complete = true; if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( ( !empty( $course_id ) ) && ( learndash_get_course_prerequisite_enabled( $course_id ) ) ) { $course_pre = learndash_get_course_prerequisites( $course_id ); if ( ! empty( $course_pre ) ) { $course_pre_compare = learndash_get_course_prerequisite_compare( $course_id ); if ( $course_pre_compare == 'ANY' ) { $s_pre = array_search( true, $course_pre ); if ( $s_pre !== false ) $course_pre_complete = true; else $course_pre_complete = false; } else if ( $course_pre_compare == 'ALL' ) { $s_pre = array_search( false, $course_pre ); if ( array_search( false, $course_pre ) === false ) $course_pre_complete = true; else $course_pre_complete = false; } } } } return $course_pre_complete; } /** * Given a course ID will return an array of the prereq item and the status * * @since 2.4.0 * * @param int $id course id * @return array */ function learndash_get_course_prerequisites( $post_id = 0 ) { $courses_status_array = array(); if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( ( !empty( $course_id ) ) && ( learndash_get_course_prerequisite_enabled( $course_id ) ) ) { $course_pre = learndash_get_course_prerequisite( $course_id ); if ( ! empty( $course_pre ) ) { $course_pre_compare = learndash_get_course_prerequisite_compare( $course_id ); if ( is_string( $course_pre ) ) $course_pre = array( $course_pre ); foreach( $course_pre as $c_id ) { //Now check if the prerequities course is completed by user or not $course_status = learndash_course_status( $c_id, null ); if ( $course_status == esc_html__( 'Completed','learndash' ) ) { $courses_status_array[$c_id] = true; } else { $courses_status_array[$c_id] = false; } } } } } return $courses_status_array; } /** * Get list of course prerequisites for a given course * * @since 2.1.0 * * @param int $id course id * @return array list of courses */ function learndash_get_course_prerequisite( $course_id = 0 ) { $course_pre = learndash_get_setting( $course_id, 'course_prerequisite' ); if ( empty( $course_pre ) ) $course_pre = array(); return $course_pre; } function learndash_set_course_prerequisite( $course_id = 0, $course_prerequisites = array() ) { if ( !empty( $course_id ) ) { if ( ( !empty( $course_prerequisites ) ) && ( is_array( $course_prerequisites ) ) ) { $course_prerequisites = array_unique( $course_prerequisites ); } return learndash_update_setting( $course_id, 'course_prerequisite', (array)$course_prerequisites ); } } /** * Given a course ID will return true or false if prereq is enabled * * @since 2.4.0 * * @param int $id course id * @return bool true is prereq is enabled false if not */ function learndash_get_course_prerequisite_enabled( $course_id ) { $course_pre_enabled = false; $course_id = learndash_get_course_id( $course_id ); if (!empty( $course_id ) ) { $post_options = get_post_meta( $course_id, '_sfwd-courses', true ); if ( ( isset( $post_options['sfwd-courses_course_prerequisite_enabled'] ) ) && ( $post_options['sfwd-courses_course_prerequisite_enabled'] == 'on' ) ) { $course_pre_enabled = true; } else if ( !isset( $post_options['sfwd-courses_course_prerequisite_enabled'] ) ) { // If the 'course_prerequisite_enabled' setting is not found we check the 'sfwd-courses_course_prerequisite' if ( ( isset( $post_options['sfwd-courses_course_prerequisite'] ) ) && ( !empty( $post_options['sfwd-courses_course_prerequisite'] ) ) ) { $course_pre_enabled = true; $post_options['sfwd-courses_course_prerequisite_enabled'] = 'on'; } else { $post_options['sfwd-courses_course_prerequisite_enabled'] = ''; } update_post_meta( $course_id, '_sfwd-courses', $post_options ); } } return $course_pre_enabled; } function learndash_set_course_prerequisite_enabled( $course_id, $enabled = true ) { if ( $enabled === true ) $enabled = 'on'; if ( $enabled != 'on' ) $enabled = ''; return learndash_update_setting( $course_id, 'course_prerequisite_enabled', $enabled ); } /** * Given a course ID will return the compare value 'ALL' or 'ANY' (default) * * @since 2.4.0 * * @param int $id course id * @return string 'ALL' or 'ANY' default */ function learndash_get_course_prerequisite_compare( $post_id ) { $course_pre_compare = 'ANY'; if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( !empty( $course_id ) ) { $course_prerequisite_compare = learndash_get_setting( $course_id, 'course_prerequisite_compare' ); if ( ( $course_prerequisite_compare == 'ANY') || ( $course_prerequisite_compare == 'ALL' ) ) { $course_pre_compare = $course_prerequisite_compare; } } } return $course_pre_compare; } /** * Given a course ID will return true or false if course points enabled * * @since 2.4.0 * * @param int $id course id * @return bool true is prereq is enabled false if not */ function learndash_get_course_points_enabled( $post_id = 0 ) { $course_points_enabled = false; if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( !empty( $course_id ) ) { $course_points_enabled = learndash_get_setting( $course_id, 'course_points_enabled' ); if ( $course_points_enabled == 'on' ) $course_points_enabled = true; } } return $course_points_enabled; } /** * Given a course ID will return the course points * * @since 2.4.0 * * @param int $post_id Course Step ir Course post ID. * @param int $decimals Number of decimal places to round. * @return bool false - course points not enabled, int 0 or greater course points */ function learndash_get_course_points( $post_id = 0, $decimals = 1 ) { $course_points = false; if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( !empty( $course_id ) ) { if ( learndash_get_course_points_enabled( $course_id ) ) { $course_points = 0; $course_points = learndash_get_setting( $course_id, 'course_points' ); if ( !empty( $course_points ) ) { $course_points = learndash_format_course_points( $course_points, $decimals ); } } } } return $course_points; } /** * Given a course ID will return the course points for access * * @since 2.4.0 * * @param int $id course id * @return bool false - course point not enabled, int 0 or greater access points */ function learndash_get_course_points_access( $post_id = 0 ) { $course_points_access = false; if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( !empty( $course_id ) ) { if ( learndash_get_course_points_enabled( $course_id ) ) { $course_points_access = 0; $course_points_access = learndash_format_course_points( learndash_get_setting( $course_id, 'course_points_access' ) ); } } } return $course_points_access; } function learndash_check_user_course_points_access( $post_id, $user_id = 0 ) { $user_can_access = true; if ( empty( $user_id ) ) { if ( is_user_logged_in() ) { $user_id = get_current_user_id(); } else { return false; } } if ( !empty( $post_id ) ) { $course_id = learndash_get_course_id( $post_id ); if ( ( !empty( $course_id ) ) && ( !empty( $user_id ) ) ) { if ( learndash_get_course_points_enabled( $course_id ) ) { $course_access_points = learndash_get_course_points_access( $course_id ); if ( !empty( $course_access_points ) ) { $user_course_points = learndash_get_user_course_points( $user_id ); if ( floatval( $user_course_points ) >= floatval( $course_access_points ) ) return true; else return false; } } } } return true; } /** * Handles actions to be made when user joins a course * * Redirects user to login url, adds course access to user * * @since 2.1.0 */ function learndash_process_course_join(){ if ( ( ! isset( $_POST['course_join'] ) ) || ( ! isset( $_POST['course_id'] ) ) ) { return; } $user_id = get_current_user_id(); $course_id = intval( $_POST['course_id'] ); if ( empty( $user_id ) ) { $redirect_url = get_permalink( $course_id ); //$redirect_url = add_query_arg('course_join', $_POST['course_join'], $redirect_url ); //$redirect_url = add_query_arg('course_id', $course_id, $redirect_url ); $login_url = wp_login_url( $redirect_url ); /** * Filter URL of where user should be redirected to * * @since 2.1.0 * * @param login_url $login_url */ $login_url = apply_filters( 'learndash_course_join_redirect', $login_url, $course_id ); wp_redirect( $login_url ); exit; } /** * Verify the form is valid * @since 2.2.1.2 */ if ( !wp_verify_nonce( $_POST['course_join'], 'course_join_'. $user_id .'_'. $course_id ) ) { return; } $meta = get_post_meta( $course_id, '_sfwd-courses', true ); if ( @$meta['sfwd-courses_course_price_type'] == 'free' || @$meta['sfwd-courses_course_price_type'] == 'paynow' && empty( $meta['sfwd-courses_course_price'] ) && ! empty( $meta['sfwd-courses_course_join'] ) || sfwd_lms_has_access( $course_id, $user_id ) ) { ld_update_course_access( $user_id, $course_id ); } } add_action( 'wp', 'learndash_process_course_join' ); /* global $learndash_after_login; //$learndash_after_login = false; function learndash_wp_login_process_course_join( $user_login = '', $user = '' ) { if ( !empty( $user_login ) ) { if ( !( $user instanceof WP_User ) ) { $user = get_user_by('login', $user_login ); } if ( $user instanceof WP_User ) { global $learndash_after_login; $learndash_after_login = true; } } } add_action('wp_login', 'learndash_wp_login_process_course_join', 99, 2); */ /* function learndash_course_login_redirect( $redirect_to, $requested_redirect_to, $user ) { global $learndash_after_login; if ( $learndash_after_login ) { if ( ( isset( $redirect_to ) ) && ( !empty( $redirect_to ) ) ) { $url = parse_url( $redirect_to ); if ( ( isset( $url['query'] ) ) && ( !empty( $url['query'] ) ) ) { parse_str( $url['query'], $url_elements ); if ( ( isset( $url_elements['course_id'] ) ) && ( !empty( $url_elements['course_id'] ) ) && ( isset( $url_elements['course_join'] ) ) && ( !empty( $url_elements['course_join'] ) ) ) { // sort of a hack. If we are here then the user clicked on a Course 'Take This Course' form button. At the time the user was not known to WP which means // the nonce used in the form will be different than a nonce for an authentcated user. So we need to reseed the nonce so when we get to the form processing // in learndash_process_course_join() it will verify. $redirect_to = add_query_arg( 'course_join', wp_create_nonce( 'course_join_'. $user->ID .'_'. $url_elements['course_id'] ), $redirect_to ); } } } } return $redirect_to; } add_filter( 'login_redirect', 'learndash_course_login_redirect', 10, 3 ); */ /** * Shortcode to output course content * * @since 2.1.0 * * @param array $atts shortcode attributes * @return string output of shortcode */ function learndash_course_content_shortcode( $atts ) { global $learndash_shortcode_used; $atts_defaults = array( 'course_id' => 0, 'num' => false ); $atts = shortcode_atts( $atts_defaults, $atts ); if ( empty( $atts['course_id'] ) ) { $course_id = learndash_get_course_id(); if ( empty( $course_id ) ) { return ''; } $atts['course_id'] = intval( $course_id ); } if ( isset( $_GET['ld-courseinfo-lesson-page'] ) ) { $atts['paged'] = intval( $_GET['ld-courseinfo-lesson-page'] ); } $course_id = intval( $atts['course_id'] ); $course = $post = get_post( $course_id ); // if ( ! is_singular() || $post->post_type != 'sfwd-courses' ) { // return ''; // } if ( is_user_logged_in() ) $user_id = get_current_user_id(); else $user_id = 0; $logged_in = ! empty( $user_id ); $lesson_progression_enabled = false; $course_settings = learndash_get_setting( $course ); $lesson_progression_enabled = learndash_lesson_progression_enabled( $course_id ); $courses_options = learndash_get_option( 'sfwd-courses' ); $lessons_options = learndash_get_option( 'sfwd-lessons' ); $quizzes_options = learndash_get_option( 'sfwd-quiz' ); $course_status = learndash_course_status( $course_id, null ); $has_access = sfwd_lms_has_access( $course_id, $user_id ); $lessons = learndash_get_course_lessons_list( $course, $user_id, $atts ); $quizzes = learndash_get_course_quiz_list( $course ); $has_course_content = ( ! empty( $lessons ) || ! empty( $quizzes ) ); $has_topics = false; if ( ! empty( $lessons) ) { foreach ( $lessons as $lesson ) { $lesson_topics[ $lesson['post']->ID ] = learndash_topic_dots( $lesson['post']->ID, false, 'array', $user_id, $course_id ); if ( ! empty( $lesson_topics[ $lesson['post']->ID ] ) ) { $has_topics = true; } } } $level = ob_get_level(); ob_start(); $template_file = SFWD_LMS::get_template( 'course_content_shortcode', null, null, true ); if ( ! empty( $template_file ) ) { include $template_file; } $content = learndash_ob_get_clean( $level ); $content = str_replace( array("\n", "\r"), ' ', $content ); $user_has_access = $has_access? 'user_has_access':'user_has_no_access'; $learndash_shortcode_used = true; // Prevent the shortcoce page from showing when used on a course (sfwd-courses) single page // as it will conflict with pager from the templates/course.php output. $queried_object = get_queried_object(); if ( ( is_a( $queried_object, 'WP_Post' ) ) && ( $queried_object->post_type == 'sfwd-courses' ) ) { global $course_pager_results; $course_pager_results = null; } /** * Filter course content shortcode * * @since 2.1.0 */ return '<div class="learndash '.$user_has_access.'" id="learndash_post_'.$course_id.'">'.apply_filters( 'learndash_content', $content, $post ).'</div>'; } add_shortcode( 'course_content', 'learndash_course_content_shortcode' ); function learndash_update_user_activity( $args = array() ) { global $wpdb; $default_args = array( // Can be passed in if we are updating a specific existing activity row. 'activity_id' => 0, // Required. This is the ID of the Course. Unique key part 1/4 'course_id' => 0, // Required. This is the ID of the Course, Lesson, Topic, Quiz item. Unique key part 2/4 'post_id' => 0, // Optional. Will use get_current_user_id() if left 0. Unique key part 3/4 'user_id' => 0, // Will be the token stats that described the status_times array (next argument) Can be most anything. // From 'course', 'lesson', 'topic', 'access' or 'expired'. Unique key part 4/4. 'activity_type' => '', // true if the lesson, topic, course, quiz is complete. False if not complete. null if not started 'activity_status' => '', // Should be the timstamp when the 'status' started 'activity_started' => '', // Should be the timstamp when the 'status' completed 'activity_completed' => '', // Should be the timstamp when the activity record was last updated. Used as a sort column for ProPanel and other queries 'activity_updated' => '', // Flag to indicate what we are 'update', 'insert', 'delete'. The default action 'update' will cause this function // to check for an existing record to update (if found) 'activity_action' => 'update', 'activity_meta' => '' ); $args = wp_parse_args( $args, $default_args ); if ( empty( $args['activity_id'] ) ) { if ( ( empty( $args['post_id'] ) ) || ( empty( $args['activity_type'] ) ) ) { //error_log('ABORT #1'); return; } } //if ( empty( $args['course_id'] ) ) { // error_log('here'); //} if ( empty( $args['user_id'] ) ) { // If we don't have a user_id passed via args if ( !is_user_logged_in() ) return; // If not logged in, abort // Else use the logged in user ID as the args user_id $args['user_id'] = get_current_user_id(); } // End of args processing. Finally after we have applied all the logic we go out for filters. $args = apply_filters('learndash_update_user_activity_args', $args); if ( empty( $args ) ) return; $values_array = array( 'user_id' => $args['user_id'], 'course_id' => $args['course_id'], 'post_id' => $args['post_id'], 'activity_type' => $args['activity_type'], ); $types_array = array( '%d', // user_id '%d', // course_id '%d', // post_id '%s', // activity_type ); if ( ( $args['activity_status'] === true ) || ( $args['activity_status'] === false ) ) { $values_array['activity_status'] = $args['activity_status']; $types_array[] = '%d'; } //if ( ( $args['activity_status'] == true ) && ( !empty( $args['activity_completed'] ) ) ) { if ( $args['activity_completed'] !== '' ) { $values_array['activity_completed'] = $args['activity_completed']; $types_array[] = '%d'; } if ( $args['activity_started'] !== '' ) { $values_array['activity_started'] = $args['activity_started']; $types_array[] = '%d'; } if ( $args['activity_updated'] !== '' ) { $values_array['activity_updated'] = $args['activity_updated']; $types_array[] = '%d'; } else { if ( ( empty( $args['activity_started'] ) ) && ( empty( $args['activity_completed'] ) ) ) { if ( !isset( $args['data_upgrade'] ) ) { $values_array['activity_updated'] = time(); $types_array[] = '%d'; } } else if ( $args['activity_started'] == $args['activity_completed'] ) { $values_array['activity_updated'] = $args['activity_completed']; $types_array[] = '%d'; } else { if ( $args['activity_started'] > $args['activity_completed'] ) { $values_array['activity_updated'] = $args['activity_started']; $types_array[] = '%d'; } else if ( $args['activity_completed'] > $args['activity_started'] ) { $values_array['activity_updated'] = $args['activity_completed']; $types_array[] = '%d'; } } } $update_ret = false; if ( $args['activity_action'] == 'update' ) { if ( empty( $args['activity_id'] ) ) { $activity = learndash_get_user_activity( $args ); if ( null !== $activity ) { $args['activity_id'] = $activity->activity_id; } } if ( !empty( $args['activity_id'] ) ) { $update_values_array = $values_array; $update_types_array = $types_array; $update_ret = $wpdb->update( LDLMS_DB::get_table_name( 'user_activity' ), $update_values_array, array( 'activity_id' => $args['activity_id'] ), $update_types_array, array( '%d' // activity_id ) ); } else { $args['activity_action'] = 'insert'; } } if ( $args['activity_action'] == 'insert' ) { $values_array['activity_updated'] = time(); $types_array[] = '%d'; $insert_ret = $wpdb->insert( LDLMS_DB::get_table_name( 'user_activity' ), $values_array, $types_array ); if ( $insert_ret !== false) { $args['activity_id'] = $wpdb->insert_id; } } // Finally for the course we update the activity meta if ( ( !empty( $args['activity_id'] ) ) && ( !empty( $args['activity_meta'] ) ) ) { foreach( $args['activity_meta'] as $meta_key => $meta_value ) { learndash_update_user_activity_meta( $args['activity_id'], $meta_key, $meta_value); } } do_action( 'learndash_update_user_activity', $args ); return $args['activity_id']; } function learndash_get_user_activity( $args = array() ) { global $wpdb; if ( !isset( $args['course_id'] ) ) $args['course_id'] = 0; if ( $args['activity_type'] == 'quiz' ) { $data_settings_quizzes = learndash_data_upgrades_setting('user-meta-quizzes'); if ( version_compare( $data_settings_quizzes['version'], '2.5', '>=') ) { $sql_str = $wpdb->prepare("SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " WHERE user_id=%d AND course_id=%d AND post_id=%d AND activity_type=%s AND activity_completed=%d LIMIT 1", $args['user_id'], $args['course_id'], $args['post_id'], $args['activity_type'], $args['activity_completed'] ); } else { $sql_str = $wpdb->prepare("SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " WHERE user_id=%d AND post_id=%d AND activity_type=%s AND activity_completed=%d LIMIT 1", $args['user_id'], $args['post_id'], $args['activity_type'], $args['activity_completed'] ); } } else { $data_settings_courses = learndash_data_upgrades_setting('user-meta-courses'); if ( version_compare( $data_settings_courses['version'], '2.5', '>=') ) { $sql_str = $wpdb->prepare("SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " WHERE user_id=%d AND course_id=%d AND post_id=%d AND activity_type=%s LIMIT 1", $args['user_id'], $args['course_id'], $args['post_id'], $args['activity_type'] ); } else { $sql_str = $wpdb->prepare("SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " WHERE user_id=%d AND post_id=%d AND activity_type=%s LIMIT 1", $args['user_id'], $args['post_id'], $args['activity_type'] ); } } //error_log('sql_str['. $sql_str .']'); $activity = $wpdb->get_row( $sql_str ); if ( $activity ) { //error_log('activity<pre>'. print_r($activity, true) .'</pre>'); if ( property_exists( $activity, 'activity_status' ) ) { if ( $activity->activity_status == true ) $activity->activity_status = true; else if ( $activity->activity_status == false ) $activity->activity_status = false; } } return $activity; } function learndash_get_user_activity_meta( $activity_id = 0, $activity_meta_key = '', $return_activity_meta_value_only = true ) { global $wpdb; if ( empty( $activity_id ) ) return; if ( !empty( $activity_meta_key ) ) { $meta_sql_str = $wpdb->prepare("SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity_meta' ) . " WHERE activity_id=%d AND activity_meta_key=%s", $activity_id, $activity_meta_key); $activity_meta = $wpdb->get_row( $meta_sql_str ); if ( !empty($activity_meta ) ) { if ( $return_activity_meta_value_only == true ) { if ( property_exists( $activity_meta, 'activity_meta_value' ) ) { return $activity_meta->activity_meta_value; } } } return $activity_meta; } else { // Here we return ALL meta for the given activity_id $meta_sql_str = $wpdb->prepare( "SELECT * FROM " . LDLMS_DB::get_table_name( 'user_activity_meta' ) . " WHERE activity_id=%d", $activity_id); return $wpdb->get_results( $meta_sql_str ); } } function learndash_update_user_activity_meta( $activity_id = 0, $meta_key = '', $meta_value = null) { global $wpdb; if ( ( empty( $activity_id ) ) || ( empty( $meta_key ) ) || ( $meta_value === null ) ) return; $activity = learndash_get_user_activity_meta( $activity_id, $meta_key, false); if ( null !== $activity ) { $wpdb->update( LDLMS_DB::get_table_name( 'user_activity_meta' ), array( 'activity_id' => $activity_id, 'activity_meta_key' => $meta_key, 'activity_meta_value' => maybe_serialize( $meta_value ) ), array( 'activity_meta_id' => $activity->activity_meta_id ), array( '%d', // activity_id '%s', // meta_key '%s' // meta_value ), array( '%d' // activity_meta_id ) ); } else { $wpdb->insert( LDLMS_DB::get_table_name( 'user_activity_meta' ), array( 'activity_id' => $activity_id, 'activity_meta_key' => $meta_key, 'activity_meta_value' => maybe_serialize( $meta_value ) ), array( '%d', // activity_id '%s', // meta_key '%s' // meta_value ) ); } } function learndash_delete_user_activity( $activity_id = 0 ) { global $wpdb; if ( !empty( $activity_id ) ) { $wpdb->delete( LDLMS_DB::get_table_name( 'user_activity' ), array( 'activity_id' => $activity_id ), array( '%d' ) ); $wpdb->delete( LDLMS_DB::get_table_name( 'user_activity_meta' ), array( 'activity_id' => $activity_id ), array( '%d' ) ); } } /** * Utility function to return all the courses that are price_type: open * Logic for this query was taken from the sfwd_lms_has_access_fn() function * @since 2.3 * * @param bool $bypass_transient Set to true to bypass transient cache. * @return array array of post_ids (course ids) found */ function learndash_get_open_courses( $bypass_transient = false ) { global $wpdb; $transient_key = "learndash_open_courses"; if (!$bypass_transient) { $courses_ids_transient = LDLMS_Transients::get( $transient_key ); } else { $courses_ids_transient = false; } if ( $courses_ids_transient === false ) { $sql_str = "SELECT postmeta.post_id as post_id FROM ". $wpdb->postmeta ." as postmeta INNER JOIN ". $wpdb->posts ." as posts ON posts.ID = postmeta.post_id WHERE posts.post_status='publish' AND posts.post_type='sfwd-courses' AND postmeta.meta_key='_sfwd-courses' AND ( postmeta.meta_value REGEXP '\"sfwd-courses_course_price_type\";s:4:\"open\";' )"; $course_ids = $wpdb->get_col( $sql_str ); LDLMS_Transients::set( $transient_key, $course_ids, MINUTE_IN_SECONDS ); } else { $course_ids = $courses_ids_transient; } return $course_ids; } /** * Utility function to return all the courses that are price_type: paynow with empty price * Logic for this query was taken from the sfwd_lms_has_access_fn() function * @since 2.3 * * @param bool $bypass_transient Set to true to bypass transient cache. * @return array array of post_ids (course ids) found */ function learndash_get_paynow_courses( $bypass_transient = false ) { global $wpdb; $transient_key = "learndash_paynow_courses"; if (!$bypass_transient) { $courses_ids_transient = LDLMS_Transients::get( $transient_key ); } else { $courses_ids_transient = false; } if ( $courses_ids_transient === false ) { $sql_str = "SELECT postmeta.post_id FROM ". $wpdb->postmeta ." as postmeta INNER JOIN ". $wpdb->posts ." as posts ON posts.ID = postmeta.post_id WHERE posts.post_status='publish' AND posts.post_type='sfwd-courses' AND postmeta.meta_key='_sfwd-courses' AND (( postmeta.meta_value REGEXP 's:30:\"sfwd-courses_course_price_type\";s:6:\"paynow\";' ) AND ( postmeta.meta_value REGEXP 's:25:\"sfwd-courses_course_price\";s:0:\"\";' ))"; //error_log('sql_str['. $sql_str .']'); $course_ids = $wpdb->get_col( $sql_str ); LDLMS_Transients::set( $transient_key, $course_ids, MINUTE_IN_SECONDS ); } else { $course_ids = $courses_ids_transient; } return $course_ids; } // Gets ALL users that have access to given course_id. // Optional bool flag to exclude admin roles function learndash_get_users_for_course( $course_id = 0, $query_args = array(), $exclude_admin = true ) { $course_user_ids = array(); if ( empty( $course_id ) ) return $course_user_ids; $defaults = array( // By default WP_User_Query will return ALL users. Strange. 'fields' => 'ID', ); $query_args = wp_parse_args( $query_args, $defaults ); if ( $exclude_admin == true ) { $query_args['role__not_in'] = array('administrator'); } $course_price_type = learndash_get_course_meta_setting( $course_id, 'course_price_type' ); if ($course_price_type == 'open') { $user_query = new WP_User_Query( $query_args ); return $user_query; } else { $course_access_list = learndash_get_course_meta_setting( $course_id, 'course_access_list'); $course_user_ids = array_merge( $course_user_ids, $course_access_list ); $course_access_users = learndash_get_course_users_access_from_meta( $course_id ); $course_user_ids = array_merge( $course_user_ids, $course_access_users ); $course_groups_users = get_course_groups_users_access( $course_id ); $course_user_ids = array_merge( $course_user_ids, $course_groups_users ); if ( !empty( $course_user_ids ) ) $course_user_ids = array_unique( $course_user_ids ); $course_expired_access_users = learndash_get_course_expired_access_from_meta( $course_id ); if ( !empty( $course_expired_access_users ) ) $course_user_ids = array_diff( $course_access_list, $course_expired_access_users ); if ( !empty( $course_user_ids ) ) { $query_args['include'] = $course_user_ids; $user_query = new WP_User_Query( $query_args ); //$course_user_ids = $user_query->get_results(); return $user_query; } } /* if ( !empty( $course_user_ids ) ) { // Finally we spin through this list of user_ids and check for expired access. $course_expire_access = learndash_get_course_meta_setting( $course_id, 'expire_access' ); if ( !empty( $course_expire_access ) ) { $expired_user_ids = array(); foreach( $course_user_ids as $user_id ) { if ( ld_course_access_expired( $course_id, $user_id ) ) $expired_user_ids[] = $user_id; } if ( !empty( $expired_user_ids ) ) { $course_user_ids = array_diff( $course_user_ids, $expired_user_ids ); } } } */ return $course_user_ids; } function learndash_set_users_for_course( $course_id = 0, $course_users_new = array() ) { if (!empty( $course_id ) ) { if ( ! empty( $course_users_new ) ) { $course_users_new = learndash_convert_course_access_list( $course_users_new, true ); } else { $course_users_new = array(); } $course_users_old = learndash_get_course_users_access_from_meta( $course_id ); if ( ! empty( $course_users_old ) ) { $course_users_old = learndash_convert_course_access_list( $course_users_old, true ); } else { $course_users_old = array(); } $course_users_intersect = array_intersect( $course_users_new, $course_users_old ); $course_users_add = array_diff( $course_users_new, $course_users_intersect ); if ( ! empty( $course_users_add ) ) { foreach ( $course_users_add as $user_id ) { ld_update_course_access( $user_id, $course_id, false ); } } $course_users_remove = array_diff( $course_users_old, $course_users_intersect ); if ( ! empty( $course_users_remove ) ) { foreach ( $course_users_remove as $user_id ) { ld_update_course_access( $user_id, $course_id, true ); } } // Finally clear our cache for other services //$transient_key = "learndash_group_courses_" . $group_id; //delete_transient( $transient_key ); } } // Get all users with explicit 'course_XX_access_from' access function learndash_get_course_users_access_from_meta( $course_id = 0 ) { global $wpdb; $course_user_ids = array(); if ( !empty( $course_id ) ) { // We have to do it this was because WP_User_Query cannot handle on meta EXISTS and another 'NOT EXISTS' in the same query. $sql_str = $wpdb->prepare( "SELECT user_id FROM ". $wpdb->usermeta ." as usermeta WHERE meta_key = %s", 'course_'. $course_id .'_access_from'); $course_user_ids = $wpdb->get_col( $sql_str ); } return $course_user_ids; } // Get all the users for a given course_id that have 'learndash_course_expired_XX' user meta records. function learndash_get_course_expired_access_from_meta( $course_id = 0 ) { global $wpdb; $expired_user_ids = array(); if ( !empty( $course_id ) ) { $sql_str = $wpdb->prepare( "SELECT user_id FROM ". $wpdb->usermeta ." as usermeta WHERE meta_key = %s", 'learndash_course_expired_'. $course_id); $expired_user_ids = $wpdb->get_col( $sql_str ); } return $expired_user_ids; } // Utility function to att the course settings in meta. Better than having this over inline over and over again. // @TODO Need to convert all references to get_post_meta for '_sfwd-courses' to use this function. function learndash_get_course_meta_setting( $course_id = 0, $setting_key = '' ) { $course_settings = array(); if ( empty( $course_id ) ) return $course_settings; $meta = get_post_meta( $course_id, '_sfwd-courses', true ); if ( ( is_null( $meta ) ) || ( !is_array( $meta ) ) ) $meta = array(); // we only want/need to reformat the access list of we are returning ALL setting or just the access list if ( ( empty( $setting_key ) ) || ( $setting_key == 'course_access_list' ) ) { if ( !isset( $meta['sfwd-courses_course_access_list'] ) ) { $meta['sfwd-courses_course_access_list'] = ''; } $meta['sfwd-courses_course_access_list'] = array_map( 'intVal', explode( ',', $meta['sfwd-courses_course_access_list'] ) ); // Need to remove the empty '0' items $meta['sfwd-courses_course_access_list'] = array_diff($meta['sfwd-courses_course_access_list'], array(0, '')); } if ( empty( $setting_key ) ) { return $meta; } else if ( isset( $meta['sfwd-courses_'. $setting_key] ) ) { return $meta['sfwd-courses_'. $setting_key]; } } function learndash_get_course_steps_ORG( $course_id = 0, $include_post_types = array( 'sfwd-lessons', 'sfwd-topic' ) ) { $steps = array(); if ( ( !empty( $course_id ) ) && ( !empty( $include_post_types) ) ) { $steps_query_args = array( 'post_type' => $include_post_types, 'posts_per_page' => -1, 'post_status' => 'publish', 'fields' => 'ids', 'meta_query' => array( array( 'key' => 'course_id', 'value' => intval($course_id), 'compare' => '=', 'type' => 'NUMERIC' ) ) ); //error_log('steps_query_args<pre>'. print_r($steps_query_args, true) .'</pre>'); $steps_query = new WP_Query( $steps_query_args ); if ($steps_query->have_posts()) $steps = $steps_query->posts; } return $steps; } // Get the total number of Lessons + Topics for a given course_id. For now excludes quizzes at lesson and topic level. function learndash_get_course_steps( $course_id = 0, $include_post_types = array( 'sfwd-lessons', 'sfwd-topic' ) ) { // The steps array will hold all the individual step counts for each post_type. $steps = array(); // This will hold the combined steps post ids once we have run all queries. $steps_all = array(); if ( !empty( $course_id ) ) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { foreach( $include_post_types as $post_type ) { $steps[$post_type] = learndash_course_get_steps_by_type( $course_id, $post_type ); } } else { if ( ( in_array( 'sfwd-lessons', $include_post_types ) ) || ( in_array( 'sfwd-topic', $include_post_types ) ) ) { $lesson_steps_query_args = array( 'post_type' => 'sfwd-lessons', 'posts_per_page' => -1, 'post_status' => 'publish', 'fields' => 'ids', 'meta_query' => array( array( 'key' => 'course_id', 'value' => intval($course_id), 'compare' => '=', 'type' => 'NUMERIC' ) ) ); $lesson_steps_query = new WP_Query( $lesson_steps_query_args ); if ($lesson_steps_query->have_posts()) { $steps['sfwd-lessons'] = $lesson_steps_query->posts; } } // For Topics we still require the parent lessons items if ( in_array( 'sfwd-topic', $include_post_types ) ) { if ( !empty( $steps['sfwd-lessons'] ) ) { $topic_steps_query_args = array( 'post_type' => 'sfwd-topic', 'posts_per_page' => -1, 'post_status' => 'publish', 'fields' => 'ids', 'meta_query' => array( array( 'key' => 'course_id', 'value' => intval($course_id), 'compare' => '=', 'type' => 'NUMERIC' ) ) ); if ( ( isset( $steps['sfwd-lessons'] ) ) && ( !empty( $steps['sfwd-lessons'] ) ) ) { $topic_steps_query_args['meta_query'][] = array( 'key' => 'lesson_id', 'value' => $steps['sfwd-lessons'], 'compare' => 'IN', 'type' => 'NUMERIC' ); } $topic_steps_query = new WP_Query( $topic_steps_query_args ); if ($topic_steps_query->have_posts()) { $steps['sfwd-topic'] = $topic_steps_query->posts; } } else { $steps['sfwd-topic'] = array(); } } } } foreach( $include_post_types as $post_type ) { if ( ( isset( $steps[$post_type] ) ) && ( !empty( $steps[$post_type] ) ) ) { $steps_all = array_merge( $steps_all, $steps[$post_type] ); } } return $steps_all; } function learndash_get_course_steps_count( $course_id = 0 ) { $course_steps_count = 0; $course_steps = learndash_get_course_steps( $course_id ); if ( !empty( $course_steps ) ) $course_steps_count = count( $course_steps ); if ( has_global_quizzes( $course_id ) ) $course_steps_count += 1; return $course_steps_count; } // Get total completed steps for a given course_progress array structure. function learndash_course_get_completed_steps( $user_id = 0, $course_id = 0, $course_progress = array() ) { $steps_completed_count = 0; if ( ( !empty( $user_id ) ) && ( !empty( $course_id ) ) ) { if ( empty( $course_progress ) ) { $course_progress_all = get_user_meta( $user_id, '_sfwd-course_progress', true ); if ( isset( $course_progress_all[$course_id] ) ) $course_progress = $course_progress_all[$course_id]; } $course_lessons = learndash_course_get_steps_by_type( $course_id, 'sfwd-lessons' ); if ( !empty( $course_lessons ) ) { if ( isset( $course_progress['lessons'] ) ) { foreach( $course_progress['lessons'] as $lesson_id => $lesson_completed ) { if ( in_array( $lesson_id, $course_lessons ) ) { $steps_completed_count += intval($lesson_completed); } } } } $course_topics = learndash_course_get_steps_by_type( $course_id, 'sfwd-topic' ); if ( isset( $course_progress['topics'] ) ) { foreach( $course_progress['topics'] as $lesson_id => $lesson_topics ) { if ( in_array( $lesson_id, $course_lessons ) ) { if ( ( is_array( $lesson_topics ) ) && ( !empty( $lesson_topics ) ) ) { foreach( $lesson_topics as $topic_id => $topic_completed ) { if ( in_array( $topic_id, $course_topics ) ) { $steps_completed_count += intval($topic_completed); } } } } } } if ( has_global_quizzes( $course_id ) ) { if ( is_all_global_quizzes_complete( $user_id, $course_id ) ) { $steps_completed_count += 1; } } } return $steps_completed_count; } add_filter('sfwd-courses_display_options', function( $options, $location ) { if ( ( !isset( $options[$location.'_course_prerequisite_enabled'] ) ) || ( empty( $options[$location.'_course_prerequisite_enabled'] ) )) { global $post; if ( $post instanceof WP_Post ) { $settings = get_post_meta( $post->ID, '_sfwd-courses', true); if ( ( isset( $settings[$location .'_course_prerequisite'] ) ) && ( !empty( $settings[$location .'_course_prerequisite'] ) ) ) { $options[$location.'_course_prerequisite_enabled'] = 'on'; $settings[$location.'_course_prerequisite_enabled'] = 'on'; update_post_meta( $post->ID, '_sfwd-courses', $settings); } } } return $options; }, 1, 2); function learndash_update_course_users_groups( $user_id, $course_id, $access_list, $remove ) { if ( ( !empty( $user_id ) ) && ( !empty( $course_id ) ) && ( $remove !== true ) ) { $course_groups = learndash_get_course_groups( $course_id, true ); if ( !empty( $course_groups ) ) { foreach( $course_groups as $course_group_id ) { $ld_auto_enroll_group_courses = get_post_meta( $course_group_id, 'ld_auto_enroll_group_courses', true ); if ( $ld_auto_enroll_group_courses == 'yes' ) { ld_update_group_access( $user_id, $course_group_id ); } } } } } add_action( 'learndash_update_course_access', 'learndash_update_course_users_groups', 50, 4 ); function learndash_user_get_course_completed_date( $user_id = 0, $course_id = 0 ) { $completed_on_timestamp = 0; if ( ( ! empty( $user_id ) ) && ( !empty( $course_id ) ) ) { $completed_on_timestamp = get_user_meta( $user_id, 'course_completed_' . $course_id, true ); if ( empty( $completed_on_timestamp ) ) { $activity_query_args = array( 'post_ids' => $course_id, 'user_ids' => $user_id, 'activity_type' => 'course', 'per_page' => 1, ); $activity = learndash_reports_get_activity( $activity_query_args ); if ( ! empty( $activity['results'] ) ) { foreach( $activity['results'] as $activity_item ) { if ( property_exists( $activity_item, 'activity_completed' ) ) { $completed_on_timestamp = $activity_item->activity_completed; // To make the next check easier we update the user meta. update_user_meta( $user_id, 'course_completed_' . $course_id, $completed_on_timestamp ); break; } } } } } return $completed_on_timestamp; } function learndash_course_get_all_parent_step_ids( $course_id = 0, $step_id = 0 ) { $step_parents = array(); if ( ( !empty( $course_id ) ) && ( !empty( $step_id ) ) ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( intval( $course_id ) ); if ( $ld_course_steps_object ) { $step_parents = $ld_course_steps_object->get_item_parent_steps( $step_id ); if ( !empty( $step_parents ) ) { $step_parents_2 = array(); foreach( $step_parents as $step_parent ) { list( $parent_post_type, $parent_post_id ) = explode(':', $step_parent ); $step_parents_2[] = intval( $parent_post_id ); } $step_parents = array_reverse($step_parents_2); } } } else { $parent_step_id = get_post_meta( $step_id, 'lesson_id', true ); if ( ! empty( $parent_step_id ) ) { $step_parents[] = $parent_step_id; if ( 'sfwd-topic' === get_post_type( $parent_step_id ) ) { $parent_step_id = get_post_meta( $parent_step_id, 'lesson_id', true ); if ( ! empty( $parent_step_id ) ) { $step_parents[] = $parent_step_id; } } } if ( ! empty( $step_parents ) ) { $step_parents = array_reverse( $step_parents ); } } } if ( ! empty( $step_parents ) ) { $step_parents = array_map( 'intval', $step_parents ); } return $step_parents; } function learndash_course_get_single_parent_step( $course_id = 0, $step_id = 0, $step_type = '' ) { $parent_step_id = 0; if ( ( !empty( $course_id ) ) && ( !empty( $step_id ) ) ) { if ( LearnDash_Settings_Section::get_section_setting( 'LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( intval( $course_id ) ); if ( $ld_course_steps_object ) { $parent_step_id = $ld_course_steps_object->get_parent_step_id( $step_id, $step_type ); } } else { if ( empty( $step_type ) ) { $parent_step_id = get_post_meta( $step_id, 'lesson_id', true ); } else { // We only have two nested post types: Topics and quizzes. $step_id_post_type = get_post_type( $step_id ); // A topic only has one parent, a lesson. if ( $step_id_post_type == 'sfwd-topic' ) { $parent_step_id = get_post_meta( $step_id, 'lesson_id', true ); } else if ( $step_id_post_type == 'sfwd-quiz' ) { $lesson_id = $topic_id = 0; $parent_step_id = get_post_meta( $step_id, 'lesson_id', true ); if ( !empty( $parent_step_id ) ) { $parent_step_id_post_type = get_post_type( $parent_step_id ); if ( $parent_step_id_post_type == 'sfwd-topic' ) { $topic_id = $parent_step_id; $lesson_id = get_post_meta( $topic_id, 'lesson_id', true ); } else if ( $parent_step_id_post_type == 'sfwd-lessons' ) { $lesson_id = $parent_step_id; } if ( $step_type == 'sfwd-lessons' ) { $parent_step_id = $lesson_id; } else if ( $step_type == 'sfwd-topic' ) { $parent_step_id = $topic_id; } else { $parent_step_id = 0; } } } } } } return $parent_step_id; } function learndash_course_get_steps_by_type_ORG1( $course_id = 0, $step_type = '' ) { $course_steps_return = array(); if ( ( !empty( $course_id ) ) && ( !empty( $step_type ) ) ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( intval( $course_id ) ); if ( $ld_course_steps_object ) { $course_steps_t = $ld_course_steps_object->get_steps('t'); if ( ( isset( $course_steps_t[$step_type] ) ) && ( !empty( $course_steps_t[$step_type] ) ) ) { $course_steps_return = $course_steps_t[$step_type]; } } } return $course_steps_return; } function learndash_course_get_steps_by_type( $course_id = 0, $step_type = '' ) { $course_steps_return = array(); if ( ( !empty( $course_id ) ) && ( !empty( $step_type ) ) ) { if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( intval( $course_id ) ); if ( $ld_course_steps_object ) { $course_steps_t = $ld_course_steps_object->get_steps('t'); if ( ( isset( $course_steps_t[$step_type] ) ) && ( !empty( $course_steps_t[$step_type] ) ) ) { $course_steps_return = $course_steps_t[$step_type]; } } } else { $transient_key = "learndash_course_". $course_id .'_'. $step_type; $course_steps_return = LDLMS_Transients::get( $transient_key ); if ( $course_steps_return === false ) { $lesson_order = learndash_get_course_lessons_order( $course_id ); $steps_query_args = array( 'post_type' => $step_type, 'posts_per_page' => -1, 'post_status' => 'publish', 'fields' => 'ids', 'order' => isset( $lesson_order['order'] ) ? $lesson_order['order'] : false, 'orderby' => isset( $lesson_order['orderby'] ) ? $lesson_order['orderby'] : false, 'meta_query' => array( array( 'key' => 'course_id', 'value' => intval( $course_id ), 'compare' => '=', ) ) ); /** * Filter to allow override of query. * * @since 2.6.0 * * @param array $steps_query_args Array of WP_Query args. * @param integer $course_id Course ID to get steps for. * @param string $step_type Steps post type. Could be 'sfwd-lessons', 'sfwd-topics' etc. * * @return Array of query args. */ $steps_query_args = apply_filters( 'learndash_course_steps_by_type', $steps_query_args, $course_id, $step_type ); if ( ! empty( $steps_query_args ) ) { $steps_query = new WP_Query( $steps_query_args ); if ( $steps_query->have_posts() ) { $course_steps_return = $steps_query->posts; } else { $course_steps_return = array(); } LDLMS_Transients::set( $transient_key, $course_steps_return, MINUTE_IN_SECONDS ); } } } } return $course_steps_return; } function learndash_course_get_children_of_step( $course_id = 0, $step_id = 0, $child_type = '' ) { $children_steps = array(); if ( ( !empty( $course_id ) ) && ( !empty( $step_id ) ) ) { $ld_course_steps_object = LDLMS_Factory_Post::course_steps( intval( $course_id ) ); if ( $ld_course_steps_object ) { $children_steps = $ld_course_steps_object->get_children_steps( $step_id, $child_type ); } } return $children_steps; } function learndash_get_courses_for_step( $step_id = 0, $return_flat_array = false ) { global $wpdb; $course_ids = array(); if ( $return_flat_array !== true ) { $course_ids['primary'] = array(); $course_ids['secondary'] = array(); } if ( !empty( $step_id ) ) { $sql_str = $wpdb->prepare( "SELECT postmeta.meta_value as course_id, posts.post_title as course_title FROM ". $wpdb->postmeta ." AS postmeta INNER JOIN ". $wpdb->posts ." AS posts ON postmeta.meta_value = posts.ID WHERE postmeta.post_id = ". $step_id ." AND postmeta.meta_key LIKE %s ORDER BY course_title ASC", 'course_id' ); $course_ids_primary = $wpdb->get_results( $sql_str ); if ( !empty( $course_ids_primary ) ) { foreach( $course_ids_primary as $course_set ) { if ( $return_flat_array === true ) { $course_ids[$course_set->course_id] = $course_set->course_title; } else { $course_ids['primary'][$course_set->course_id] = $course_set->course_title; } } } $sql_str = $wpdb->prepare( "SELECT postmeta.meta_value as course_id, posts.post_title as course_title FROM ". $wpdb->postmeta ." AS postmeta INNER JOIN ". $wpdb->posts ." AS posts ON postmeta.meta_value = posts.ID WHERE postmeta.post_id = ". $step_id ." AND postmeta.meta_key LIKE %s ORDER BY course_title ASC", 'ld_course_%' ); //$sql_str = $wpdb->prepare( "SELECT meta_value as course_id FROM ". $wpdb->postmeta ." WHERE post_id = ". $step_id ." AND meta_key LIKE %s", 'ld_course_%' ); $course_ids_secondary = $wpdb->get_results( $sql_str ); if ( !empty( $course_ids_secondary ) ) { foreach( $course_ids_secondary as $course_set ) { if ( $return_flat_array === true ) { if ( !isset( $course_ids[$course_set->course_id] ) ) { $course_ids[$course_set->course_id] = $course_set->course_title; } } else { if ( ( !isset( $course_ids['primary'][$course_set->course_id] ) ) && ( !isset( $course_ids['secondary'][$course_set->course_id] ) ) ) { $course_ids['secondary'][$course_set->course_id] = $course_set->course_title; } } } } return $course_ids; } } function learndash_filter_lesson_options( $options, $location, $values ) { //error_log('options<pre>'. print_r($options, true) .'</pre>'); //error_log('location<pre>'. print_r($location, true) .'</pre>'); //error_log('values<pre>'. print_r($values, true) .'</pre>'); if ( ( isset( $_GET['course_id'] ) ) && ( !empty( $_GET['course_id'] ) ) ) { $viewed_course_id = intval( $_GET['course_id'] ); if ( ( isset( $values[$location .'_course' ] ) ) && ( !empty( $values[$location .'_course' ] ) ) && ( intval( $values[$location .'_course' ] ) !== intval( $_GET['course_id'] ) ) ) { if ( isset( $options[$location .'_course'] ) ) unset( $options[$location .'_course'] ); if ( isset( $options[$location .'_lesson'] ) ) unset( $options[$location .'_lesson'] ); } } return $options; } //add_filter( 'sfwd-lessons_display_settings', 'learndash_filter_lesson_options', 10, 3 ); //add_filter( 'sfwd-topic_display_settings', 'learndash_filter_lesson_options', 10, 3 ); //add_filter( 'sfwd-quiz_display_settings', 'learndash_filter_lesson_options', 10, 3 ); /** * Action hook called when a post is moved to trash or untrashed. * * @since 2.5.0 * * @param int $post_id */ function learndash_transition_course_step_post_status( $new_status, $old_status, $post ) { global $wpdb; if ( $new_status !== $old_status ) { if ( ( !empty( $post ) ) && ( is_a( $post, 'WP_Post' ) ) && ( in_array( $post->post_type, array( 'sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) ) === true ) { $sql_str = "SELECT meta_value FROM " . $wpdb->postmeta . " WHERE post_id = " . $post->ID . " AND (meta_key = 'course_id' OR meta_key LIKE 'ld_course_%')"; $course_ids = $wpdb->get_col( $sql_str ); if ( !empty( $course_ids ) ) { $course_ids = array_unique( $course_ids ); foreach( $course_ids as $course_id ) { $course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); if ( ( is_object( $course_steps_object ) ) && (is_a( $course_steps_object, 'LDLMS_Course_Steps' ) ) ) { $course_steps_object->set_steps_dirty(); } } } } } } add_action( 'transition_post_status', 'learndash_transition_course_step_post_status', 10, 3 ); /** * Need to validate URL requests when Nested URL permalinks are used. * @since 2.5 */ function learndash_check_course_step( $wp ) { if ( is_single() ) { global $post; if ( ( in_array( $post->post_type, array('sfwd-lessons', 'sfwd-topic', 'sfwd-quiz' ) ) === true ) && ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Section_Permalinks', 'nested_urls' ) == 'yes' ) ) { $course_slug = get_query_var('sfwd-courses'); // Check first if there is an existing course part of the URL. Maybe the student is trying to user a lesson URL part // for a differen course. if ( ! empty( $course_slug ) ) { $course_post = learndash_get_page_by_path( $course_slug, 'sfwd-courses' ); if ( ( ! empty( $course_post ) ) && ( is_a( $course_post, 'WP_Post' ) ) && ( 'sfwd-courses' === $course_post->post_type ) ) { $step_courses = learndash_get_courses_for_step( $post->ID, true ); if ( ( !empty( $step_courses ) ) && ( isset( $step_courses[$course_post->ID] ) ) ) { if ( in_array( $post->post_type, array( 'sfwd-topic', 'sfwd-quiz' ) ) === true ) { $parent_steps = learndash_course_get_all_parent_step_ids( $course_post->ID, $post->ID ); if ( 'sfwd-quiz' === $post->post_type ) { $topic_slug = get_query_var( 'sfwd-topic' ); if ( ! empty( $topic_slug ) ) { $topic_post = learndash_get_page_by_path( $topic_slug, 'sfwd-topic' ); if ( ( ! empty( $topic_post ) ) && ( is_a( $topic_post, 'WP_Post' ) ) && ( 'sfwd-topic' === $topic_post->post_type ) ) { if ( ! in_array( $topic_post->ID, $parent_steps ) ) { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } else { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } $lesson_slug = get_query_var( 'sfwd-lessons' ); if ( ! empty( $lesson_slug ) ) { $lesson_post = learndash_get_page_by_path( $lesson_slug, 'sfwd-lessons' ); if ( ( ! empty( $lesson_post ) ) && ( is_a( $lesson_post, 'WP_Post' ) ) && ( 'sfwd-lessons' === $lesson_post->post_type ) ) { if ( ! in_array( $lesson_post->ID, $parent_steps ) ) { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } else { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } } else if ( 'sfwd-topic' === $post->post_type ) { $lesson_slug = get_query_var( 'sfwd-lessons' ); if ( ! empty( $lesson_slug ) ) { $lesson_post = learndash_get_page_by_path( $lesson_slug, 'sfwd-lessons' ); if ( ( ! empty( $lesson_post ) ) && ( is_a( $lesson_post, 'WP_Post' ) ) && ( 'sfwd-lessons' === $lesson_post->post_type ) ) { if ( ! in_array( $lesson_post->ID, $parent_steps ) ) { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } else { $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } } } // All is ok to return. return; } else { //global $wp_query; //$wp_query->is_404 = true; $course_link = get_permalink( $course_post->ID ); wp_redirect( $course_link ); die(); } } else { // If we don't have a valid Course post global $wp_query; $wp_query->set_404(); // 3. Throw 404 //status_header( 404 ); //nocache_headers(); // 4. Show 404 template require get_404_template(); // 5. Stop execution exit; } } else { if ( learndash_is_admin_user() ) { return; } else { // If we don't have a course part of the URL then we check if the step has a primary (legacy) course $step_courses = learndash_get_courses_for_step( $post->ID, false ); // If we do have a primary (legacy) then we redirect the user there. if ( !empty( $step_courses['primary'] ) ) { $primary_courses = array_keys($step_courses['primary'] ); $step_permalink = learndash_get_step_permalink( $post->ID, $primary_courses[0] ); if ( !empty( $step_permalink ) ) { wp_redirect( $step_permalink ); die(); } else { //global $wp_query; //$wp_query->is_404 = true; $courses_archive_link = get_post_type_archive_link( 'sfwd-courses' ); wp_redirect( $courses_archive_link ); die(); } } else { if ( learndash_is_admin_user() ) { // Alow the admin to view the lesson/topic before it is added to a course return; } else if ( ( $post->post_type == 'sfwd-quiz' ) && ( empty( $step_courses['secondary'] ) ) ) { // If here we have a quiz with no primary or secondary courses. So it is standalone and allowed. return; } else { //global $wp_query; //$wp_query->is_404 = true; $courses_archive_link = get_post_type_archive_link( 'sfwd-courses' ); wp_redirect( $courses_archive_link ); die(); } } } } } } } add_action( 'wp', 'learndash_check_course_step' ); function learndash_get_page_by_path( $slug = '', $post_type = '' ) { $course_post = null; if ( ( !empty( $slug ) ) && ( !empty( $post_type ) ) ) { $course_post = get_page_by_path( $slug, OBJECT, $post_type ); if ( ( defined( 'ICL_LANGUAGE_CODE' ) ) && ( ICL_LANGUAGE_CODE != '' ) ) { if ( function_exists( 'icl_object_id' ) ) { $course_post = get_page( icl_object_id( $course_post->ID, $post_type, true, ICL_LANGUAGE_CODE ) ); } } } return $course_post; } /** * Utility function to get the Course Lessons per page setting. This function * will initially source the per_page from the course. But if we are using the * default lessons options setting we will use that. Then if the lessons options * is not set for some reason we use the default system option 'posts_per_page'. * * @param $course_id int the course_id to get the per_page value from * @return $course_lessons_per_page int will be the calculated lessons per page or zero * * @since 2.5.4 */ function learndash_get_course_lessons_per_page( $course_id = 0 ) { $course_lessons_per_page = 0; $lessons_options = learndash_get_option( 'sfwd-lessons' ); if ( isset( $lessons_options['posts_per_page'] ) ) { $course_lessons_per_page = intval( $lessons_options['posts_per_page'] ); } if ( !empty( $course_id ) ) { $course_settings = learndash_get_setting( intval( $course_id ) ); if ( ( isset( $course_settings['course_lesson_per_page'] ) ) && ( $course_settings['course_lesson_per_page'] == 'CUSTOM' ) && ( isset( $course_settings['course_lesson_per_page_custom'] ) ) ) { $course_lessons_per_page = intval( $course_settings['course_lesson_per_page_custom'] ); } else { if ( ( ! isset( $lessons_options['posts_per_page'] ) ) || ( is_null( $lessons_options['posts_per_page'] ) ) ) { $course_lessons_per_page = get_option( 'posts_per_page' ); } else { $course_lessons_per_page = intval( $lessons_options['posts_per_page'] ) ; } } } return $course_lessons_per_page; } /** * When Course Lessons pagnination is enabled we want to advance the page to the next avaailable lesson page. * * For example we have a course with 100 lessons and the course has per page set to 10. The student can completed * up to lesson 73. When the student returns to the course we don't want to default to show the first page * (lessons 1-10). Instead we want to redirect the user to page 7 showing lessons 71-80. * * @since 2.5.4 */ function learndash_course_set_lessons_start_page( ) { // Last minute change to not use this for the v2.5.5 release. return; if ( ( !is_admin() ) && ( is_single() ) ) { $queried_object = get_queried_object(); if ( ( is_a( $queried_object, 'WP_Post' ) ) && ( is_user_logged_in() ) && ( !isset( $_GET['ld-lesson-page'] ) ) ) { if ( $queried_object->post_type == 'sfwd-courses' ) { if ( apply_filters( 'learndash_course_lessons_advance_progress_page', true, $queried_object->ID, get_current_user_id() ) ) { $course_lessons_per_page = learndash_get_course_lessons_per_page( $queried_object->ID ); if ( $course_lessons_per_page > 0 ) { $user_courses = get_user_meta( get_current_user_id(), '_sfwd-course_progress', true ); if ( ( isset( $user_courses[$queried_object->ID]['lessons'] ) ) && ( !empty( $user_courses[$queried_object->ID]['lessons'] ) ) ) { $lesson_paged = ceil( ( count( $user_courses[$queried_object->ID]['lessons'] ) + 1 ) / $course_lessons_per_page ); if ( $lesson_paged > 1 ) { $redirect_url = add_query_arg( 'ld-lesson-page', $lesson_paged ); wp_redirect( $redirect_url ); die(); } } } } } } } } //add_action( 'wp', 'learndash_course_set_lessons_start_page', 1 ); /** * Called from within the Coure Lessons List processing query SFWD_CPT::loop_shortcode. * This action will setup a global pager array to be used in templates. */ $course_pager_results = array( 'pager' => array( ) ); global $course_pager_results; function learndash_course_lessons_list_pager( $query_result = null, $pager_context = '' ) { global $course_pager_results; $course_pager_results['pager']['paged'] = 1; if ( ( isset( $query_result->query_vars['paged'] ) ) && ( $query_result->query_vars['paged'] > 1 ) ) { $course_pager_results['pager']['paged'] = $query_result->query_vars['paged']; } $course_pager_results['pager']['total_items'] = absint( $query_result->found_posts ); $course_pager_results['pager']['total_pages'] = absint( $query_result->max_num_pages ); } add_action( 'learndash_course_lessons_list_pager', 'learndash_course_lessons_list_pager', 10, 2 ); /** * Determine pager settings based on _GET vars */ function learndash_get_lesson_topic_paged_values() { $paged_values = array( 'lesson' => 0, 'paged' => 1 ); if ( ( isset( $_GET['ld-topic-page'] ) ) && ( ! empty( $_GET['ld-topic-page'] ) ) ) { list( $paged_values['lesson'], $paged_values['paged'] ) = explode( '-', $_GET['ld-topic-page'] ); $paged_values['lesson'] = absint( $paged_values['lesson'] ); $paged_values['paged'] = absint( $paged_values['paged'] ); if ( $paged_values['paged'] < 1 ) { $paged_values['paged'] = 1; } if ( ( empty( $paged_values['lesson'] ) ) || ( empty( $paged_values['paged'] ) ) ) { $paged_values = array( 'lesson' => 0, 'paged' => 1 ); } } return $paged_values; } function learndash_process_lesson_topics_pager( $topics = array(), $args = array() ) { global $course_pager_results; $paged_values = learndash_get_lesson_topic_paged_values(); if ( ! empty( $topics ) ) { $topics_per_page = learndash_get_course_topics_per_page( $args['course_id'], $args['lesson_id'] ); if ( ( $topics_per_page > 0 ) && ( count( $topics ) > $topics_per_page ) ) { $topics_chunks = array_chunk( $topics, $topics_per_page ); $course_pager_results[ $args['lesson_id'] ] = array(); $course_pager_results[ $args['lesson_id'] ]['pager'] = array(); $topics_paged = 1; if ( ( ! empty($paged_values['lesson'] ) ) && ( $paged_values['lesson'] == $args['lesson_id'] ) ) { $topics_paged = $paged_values['paged']; } else if ( get_post_type() === learndash_get_post_type_slug( 'topic' ) ) { /** * If we are viewing a Topic and the page is empty we load the * paged set to show the current topic item. */ foreach( $topics_chunks as $topics_chunk_page => $topics_chunk_set ) { $topics_ids = array_values( wp_list_pluck( $topics_chunk_set, 'ID' ) ); if ( ( ! empty( $topics_ids ) ) && ( in_array( get_the_ID(), $topics_ids ) ) ) { $topics_paged = ++$topics_chunk_page; break; } } } $course_pager_results[ $args['lesson_id'] ]['pager']['paged'] = $topics_paged; $course_pager_results[ $args['lesson_id'] ]['pager']['total_items'] = count( $topics ); $course_pager_results[ $args['lesson_id'] ]['pager']['total_pages'] = count( $topics_chunks ); $topics = $topics_chunks[ $topics_paged - 1 ]; } } return $topics; } /** * Utility function to get the Course Lessons order. * The course lessons order can be set in the course or globally defined in * the lesson options. This function will check all logic and return the * correct setting. * * @param $course_id int the course_id to get the per_page value from * @return $course_lessons_order int will be the calculated lessons per page or zero * * @since 2.5.4 */ function learndash_get_course_lessons_order( $course_id = 0 ) { $course_lessons_args = array( 'order' => '', 'orderby' => '' ); if ( LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) == 'yes' ) { $course_lessons_args['orderby'] = 'post__in'; return $course_lessons_args; } else { $lessons_options = learndash_get_option( 'sfwd-lessons' ); if ( ( isset( $lessons_options['order'] ) ) && ( !empty( $lessons_options['order'] ) ) ) $course_lessons_args['order'] = $lessons_options['order']; if ( ( isset( $lessons_options['orderby'] ) ) && ( !empty( $lessons_options['orderby'] ) ) ) $course_lessons_args['orderby'] = $lessons_options['orderby']; } if ( !empty( $course_id ) ) { $course_settings = learndash_get_setting( $course_id ); if ( ( isset( $course_settings['course_lesson_order'] ) ) && ( !empty( $course_settings['course_lesson_order'] ) ) ) $course_lessons_args['order'] = $course_settings['course_lesson_order']; if ( ( isset( $course_settings['course_lesson_orderby'] ) ) && ( !empty( $course_settings['course_lesson_orderby'] ) ) ) $course_lessons_args['orderby'] = $course_settings['course_lesson_orderby']; } return apply_filters( 'learndash_course_lessons_order', $course_lessons_args, $course_id ); } /** * Utility function to convert the standard comma separated list of user IDs * used for the course_access_list field. The conversion is to trim and ensure * the values are integer and not empty. * * @since 2.5.9 * @param string $course_access_list_str String of comma separated user IDs. * @param boolean $return_array True/False bool to return string or array. * * @return string $course_access_list_str */ function learndash_convert_course_access_list( $course_access_list = '', $return_array = false ) { if ( ! empty( $course_access_list ) ) { // Convert the comma separated list into an array. if ( is_string( $course_access_list ) ) { $course_access_list = explode( ',', $course_access_list ); } // Now normalize the array elements. if ( is_array( $course_access_list ) ) { $course_access_list = array_map( 'intval', $course_access_list ); $course_access_list = array_unique( $course_access_list, SORT_NUMERIC ); $course_access_list = array_diff( $course_access_list, array( 0 ) ); } // Prepare the return value. if ( true !== $return_array ) { $course_access_list = implode( ',', $course_access_list ); } } else if ( true === $return_array ) { $course_access_list = array(); } return $course_access_list; } /** * Utility function to determine the number of lesson topics to display per page. * * @since 3.0 * @param integer $course_id Parent Course ID. * @param integer $lesson_id Parent Lesson ID. */ function learndash_get_course_topics_per_page( $course_id = 0, $lesson_id = 0 ) { $course_topics_per_page = 0; $lessons_options = learndash_get_option( 'sfwd-lessons' ); if ( isset( $lessons_options['posts_per_page'] ) ) { $course_topics_per_page = intval( $lessons_options['posts_per_page'] ); } if ( !empty( $course_id ) ) { $course_settings = learndash_get_setting( intval( $course_id ) ); if ( ( isset( $course_settings['course_lesson_per_page'] ) ) && ( $course_settings['course_lesson_per_page'] == 'CUSTOM' ) && ( isset( $course_settings['course_topic_per_page_custom'] ) ) ) { $course_topics_per_page = intval( $course_settings['course_topic_per_page_custom'] ); } } return $course_topics_per_page; } /** * Transition the Course steps logic from using Shared Steps to legacy. * * @since 3.0 * @param integer $course_id Course ID to process. */ function learndash_transition_course_shared_steps( $course_id = 0 ) { if ( ! empty( $course_id ) ) { if ( 'yes' !== LearnDash_Settings_Section::get_section_setting('LearnDash_Settings_Courses_Builder', 'shared_steps' ) ) { $course_steps = get_post_meta( $course_id, 'ld_course_steps', true ); if ( isset( $course_steps['h'] ) ) { // If here then Shared Steps was enabled $ld_course_steps_object = LDLMS_Factory_Post::course_steps( $course_id ); $ld_course_steps_object->set_steps( $course_steps['h'] ); } } } } function learndash_use_legacy_course_access_list() { $use_legacy_course_access_list = true; $data_course_access_convert = learndash_data_upgrades_setting( 'course-access-lists-convert' ); if ( $data_course_access_convert ) { $use_legacy_course_access_list = false; } return apply_filters( 'learndash_use_legacy_course_access_list', $use_legacy_course_access_list ); } /** * Get the user's last active (last updated) course_id * * @since 2.1.3 * @param interger $user_id User ID. * @return integer Course ID. */ function learndash_get_last_active_course( $user_id = 0 ) { global $wpdb; $last_course_id = 0; if ( empty( $user_id ) ) { $user_id = get_current_user_id(); } if ( ! empty( $user_id ) ) { $query_str = $wpdb->prepare( "SELECT post_id FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " WHERE user_id=%d AND activity_type='course' AND activity_status = 0 AND activity_completed = '' ORDER BY activity_updated DESC", $user_id); $query_result = $wpdb->get_var( $query_str ); $last_course_id = absint( $query_result ); } return $last_course_id; } /** * Get the user's last active step within a course_id * * @since 2.1.3 * @param interger $user_id User ID. * @param interger $course_id Course ID. * @return integer Course Step ID. */ function learndash_user_course_last_step( $user_id = 0, $course_id = 0 ) { global $wpdb; $last_course_step_id = 0; if ( empty( $user_id ) ) { $user_id = get_current_user_id(); } if ( ! empty( $user_id ) ) { if ( empty( $course_id ) ) { $course_id = learndash_get_last_active_course( $user_id ); } if ( ! empty( $course_id ) ) { $query_str = $wpdb->prepare( "SELECT user_activity_meta.activity_meta_value FROM " . LDLMS_DB::get_table_name( 'user_activity' ) . " as user_activity INNER JOIN " . LDLMS_DB::get_table_name( 'user_activity_meta' ) . " as user_activity_meta ON user_activity.activity_id = user_activity_meta.activity_id WHERE user_activity.user_id=%d AND user_activity.post_id=%d AND user_activity.activity_type='course' AND user_activity_meta.activity_meta_key= 'steps_last_id' ORDER BY activity_updated DESC", $user_id, $course_id ); $query_result = $wpdb->get_var( $query_str ); $last_course_step_id = absint( $query_result ); } } return $last_course_step_id; } ld-course-video.php 0000666 00000074070 15214044143 0010270 0 ustar 00 <?php if (!class_exists('Learndash_Course_Video' ) ) { class Learndash_Course_Video { private static $instance; private $video_data = array( 'videos_found_provider' => false, 'videos_found_type' => false, 'videos_auto_start' => false, 'videos_show_controls' => false, 'videos_auto_complete' => true, 'videos_auto_complete_delay' => 0, 'videos_auto_complete_delay_message' => '', 'videos_hide_complete_button' => false, 'videos_shown' => false, 'video_debug' => false, ); private $video_content = ''; function __construct() { add_action( 'wp_footer', array( $this, 'action_wp_footer' ), 1 ); add_filter( 'learndash_post_args', array( $this, 'filter_post_args' ) ); add_filter( 'learndash_process_mark_complete', array( $this, 'process_mark_complete' ), 99, 3 ); add_action( 'save_post', array( $this, 'save_post_data') ); } public static function get_instance() { if ( null === self::$instance ) { self::$instance = new static(); } return self::$instance; } function filter_post_args( $post_args = array() ) { if ( isset( $post_args['sfwd-lessons']['fields'] ) ) { $post_args['sfwd-lessons']['fields'] = array_merge( $post_args['sfwd-lessons']['fields'], array( 'lesson_video_enabled' => array( 'name' => esc_html__( 'Enable Video Progression', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this if you want to show a video as part of the progression.', 'learndash' ), 'default' => 0, ), 'lesson_video_url' => array( 'name' => esc_html__( 'Video URL', 'learndash' ), 'type' => 'text', 'help_text' => sprintf( esc_html_x( 'URL to video. The video will be added above the %s content. Use the shortcode %s to position the player within content. Supported URL formats are YouTube (youtu.be, youtube.com), Vimeo (vimeo.com), Wistia (wistia.com), or Local videos. The value for this field can be a simple URL to the video, an iframe or either [video] or [embed] shortcodes.', 'placeholder: Lesson, admin URL to [ld_video] shortcode.', 'learndash' ), LearnDash_Custom_Label::get_label( 'lesson' ), '<a href="'. admin_url('admin.php?page=courses-shortcodes#shortcode_ld_video' ) .'">[ld_video]</a>' ), 'default' => '', ), 'lesson_video_auto_start' => array( 'name' => esc_html__( 'Auto Start Video', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this if you want the video to auto-start on page load.', 'learndash' ), 'default' => 0, ), 'lesson_video_show_controls' => array( 'name' => esc_html__( 'Show Video Controls', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Show Video Controls. By default controls are disabled. Only used for YouTube and local videos.', 'learndash' ), 'default' => 0, ), 'lesson_video_shown' => array( 'name' => esc_html__( 'When to show video', 'learndash' ), 'type' => 'select', 'initial_options' => array( 'BEFORE' => esc_html__( 'Before (default) - Video is shown before completing sub-steps', 'learndash' ), 'AFTER' => esc_html__( 'After - Video is shown after completing sub-steps', 'learndash' ), ), 'default' => 'BEFORE', 'help_text' => esc_html__( 'Select when to show video in relation to sub-steps.', 'learndash' ) ), 'lesson_video_auto_complete' => array( 'name' => sprintf( esc_html_x( 'Auto Complete %s', 'placeholder: Lesson', 'learndash' ), LearnDash_Custom_Label::get_label( 'lesson' ) ), 'type' => 'checkbox', 'help_text' => sprintf( esc_html_x( 'Check this if you want the %s to auto-complete after the video completes.', 'placeholder: Lesson', 'learndash' ), LearnDash_Custom_Label::get_label( 'lesson' ) ), 'default' => 0, ), 'lesson_video_auto_complete_delay' => array( 'name' => esc_html__( 'Auto Complete Delay', 'learndash' ), 'type' => 'number', 'class' => 'small-text', 'min' => '0', 'help_text' => esc_html__( 'Time delay in second between the time the video finishes and the auto complete occurs. Example 0 no delay, 5 for five seconds.', 'learndash' ), 'default' => 0, ), 'lesson_video_hide_complete_button' => array( 'name' => esc_html__( 'Hide Complete Button', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this to hide the complete button.', 'learndash' ), 'default' => 0, ), ) ); } if ( isset( $post_args['sfwd-topic']['fields'] ) ) { $post_args['sfwd-topic']['fields'] = array_merge( $post_args['sfwd-topic']['fields'], array( 'lesson_video_enabled' => array( 'name' => esc_html__( 'Enable Video Progression', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this if you want to show a video as part of the progression.', 'learndash' ), 'default' => 0, ), 'lesson_video_url' => array( 'name' => esc_html__( 'Video URL', 'learndash' ), 'type' => 'text', 'help_text' => sprintf( esc_html_x( 'URL to video. The video will be added above the %s content. Use the shortcode %s to position the player within content. Supported URL formats are YouTube (youtu.be, youtube.com), Vimeo (vimeo.com), Wistia (wistia.com), or Local videos. The value for this field can be a simple URL to the video, an iframe or either [video] or [embed] shortcodes.', 'placeholder: Topic, admin URL to [ld_video] shortcode.', 'learndash' ), LearnDash_Custom_Label::get_label( 'topic' ), '<a href="'. admin_url('admin.php?page=courses-shortcodes#shortcode_ld_video' ) .'">[ld_video]</a>' ), 'default' => '', ), 'lesson_video_auto_start' => array( 'name' => esc_html__( 'Auto Start Video', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this if you want the video to auto-start on page load.', 'learndash' ), 'default' => 0, ), 'lesson_video_show_controls' => array( 'name' => esc_html__( 'Show Video Controls', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Show Video Controls. By default controls are disabled. Only used for YouTube and local videos.', 'learndash' ), 'default' => 0, ), 'lesson_video_shown' => array( 'name' => esc_html__( 'When to show video', 'learndash' ), 'type' => 'select', 'initial_options' => array( 'AFTER' => esc_html__( 'After (default) - Video is shown after completing sub-steps', 'learndash' ), 'BEFORE' => esc_html__( 'Before - Video is shown before completing sub-steps', 'learndash' ), ), 'default' => '', 'help_text' => esc_html__( 'Select when to show video in relation to sub-steps.', 'learndash' ) ), 'lesson_video_auto_complete' => array( 'name' => sprintf( esc_html_x( 'Auto Complete %s', 'placeholder: Topic', 'learndash' ), LearnDash_Custom_Label::get_label( 'topic' ) ), 'type' => 'checkbox', 'help_text' => sprintf( esc_html_x( 'Check this if you want the %s to auto-complete after the video completes.', 'placeholder: Topic', 'learndash' ), LearnDash_Custom_Label::get_label( 'topic' ) ), 'default' => 0, ), 'lesson_video_auto_complete_delay' => array( 'name' => esc_html__( 'Auto Complete Delay', 'learndash' ), 'type' => 'number', 'class' => 'small-text', 'min' => '0', 'help_text' => esc_html__( 'Time delay in second between the time the video finishes and the auto complete occurs. Example 0 no delay, 5 for five seconds.', 'learndash' ), 'default' => 0, ), 'lesson_video_hide_complete_button' => array( 'name' => esc_html__( 'Hide Complete Button', 'learndash' ), 'type' => 'checkbox', 'help_text' => esc_html__( 'Check this to hide the complete button.', 'learndash' ), 'default' => 0, ), ) ); } return $post_args; } function add_video_to_content( $content = '', $post, $settings = array() ) { if ( is_user_logged_in() ) { $user_id = get_current_user_id(); } else { $user_id = 0; } // Do we show the video. In some cases we do. But in others like when the setting is to show AFTER completing other steps then we set to false. $show_video = false; // In the initial flow we do apply the video restiction logic. But then in other if the user is an admin or the student has completed the lesson // we don't apply the video logic. $logic_video = false; if ( ( isset( $settings['lesson_video_enabled'] ) ) && ( $settings['lesson_video_enabled'] == 'on' ) ) { if ( ( isset( $settings['lesson_video_url'] ) ) && ( !empty( $settings['lesson_video_url'] ) ) ) { // Because some copy/paste can result in leading whitespace. LEARNDASH-3819 $settings['lesson_video_url'] = trim( $settings['lesson_video_url'] ); $settings['lesson_video_url'] = html_entity_decode( $settings['lesson_video_url'] ); // Just to ensure the proper settings are available if ( ( !isset( $settings['lesson_video_shown'] ) ) || ( empty( $settings['lesson_video_shown'] ) ) ) { $settings['lesson_video_shown'] = 'BEFORE'; } $bypass_course_limits_admin_users = false; if ( !empty( $user_id ) ) { if ( learndash_is_admin_user( $user_id ) ) { $bypass_course_limits_admin_users = LearnDash_Settings_Section::get_section_setting('LearnDash_Settings _Section_General_Admin_User', 'bypass_course_limits_admin_users' ); if ( $bypass_course_limits_admin_users == 'yes' ) $bypass_course_limits_admin_users = true; else $bypass_course_limits_admin_users = false; } else { $bypass_course_limits_admin_users = false; } // For logged in users to allow an override filter. $bypass_course_limits_admin_users = apply_filters( 'learndash_prerequities_bypass', $bypass_course_limits_admin_users, $user_id, $post->ID, $post ); } if ( !$bypass_course_limits_admin_users ) { if ( $post->post_type == 'sfwd-lessons' ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( ( !empty( $progress['this'] ) ) && ( $progress['this'] instanceof WP_Post ) && ( $progress['this']->completed == true ) ) { // The student has completes this step so we show the video but don't apply the logic $show_video = true; $logic_video = false; } else { if ( $settings['lesson_video_shown'] == 'BEFORE' ) { $show_video = true; $logic_video = true; $topics = learndash_get_topic_list( $post->ID ); if ( !empty( $topics ) ) { $progress = learndash_get_course_progress( null, $topics[0]->ID ); if ( !empty( $progress ) ) { $topics_completed = 0; foreach ( $progress['posts'] as $topic ) { if ( $topic->completed == true ) { $topics_completed += 1; break; } } if ( !empty( $topics_completed ) ) { $logic_video = false; } } } } else if ( $settings['lesson_video_shown'] == 'AFTER' ) { if ( learndash_lesson_topics_completed( $post->ID ) ) { $quizzes_completed = true; $lesson_quizzes_list = learndash_get_lesson_quiz_list( $post->ID ); if ( !empty( $lesson_quizzes_list ) ) { foreach( $lesson_quizzes_list as $quiz ) { if ( $quiz['status'] != 'completed') { $quizzes_completed = false; break; } } } if ( $quizzes_completed == true ) { $show_video = true; $logic_video = true; } } else { $show_video = false; $logic_video = false; } } } } else if ( $post->post_type == 'sfwd-topic' ) { $progress = learndash_get_course_progress( null, $post->ID ); if ( ( !empty( $progress['this'] ) ) && ( $progress['this'] instanceof WP_Post ) && ( $progress['this']->completed == true ) ) { // The student has completes this step so we show the video but don't apply the logic $show_video = true; $logic_video = false; } else { if ( $settings['lesson_video_shown'] == 'BEFORE' ) { $show_video = true; $logic_video = true; } else if ( $settings['lesson_video_shown'] == 'AFTER' ) { $quizzes_completed = true; $lesson_quizzes_list = learndash_get_lesson_quiz_list( $post->ID ); if ( !empty( $lesson_quizzes_list ) ) { foreach( $lesson_quizzes_list as $quiz ) { if ( $quiz['status'] != 'completed') { $quizzes_completed = false; break; } } } if ( $quizzes_completed == true ) { $show_video = true; $logic_video = true; } } else { $show_video = false; $logic_video = false; } } /* // Lessons are always 'BEFORE' $settings['lesson_video_shown'] = 'AFTER'; $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['this']->completed ) ) { $show_video = true; $logic_video = false; } else { // are we the first item in the list. No prev if ( ( empty( $progress['prev'] ) ) && ( $progress['this']->ID == $progress['posts'][0]->ID ) ) { $show_video = true; $logic_video = true; // Should not be here. } else if ( ( ! empty( $progress['prev'] ) ) && ( $progress['prev']->completed == true ) ) { $show_video = true; $logic_video = true; } } */ } } else { $progress = learndash_get_course_progress( null, $post->ID ); if ( ! empty( $progress['this']->completed ) ) { //return str_replace( '[ld_video]', '', $content ); $show_video = true; $logic_video = false; } } if ( $show_video == true ) { if ( ( isset( $settings['lesson_video_shown'] ) ) && ( !empty( $settings['lesson_video_shown'] ) ) ) { $this->video_data['videos_shown'] = $settings['lesson_video_shown']; } else { $this->video_data['videos_shown'] = 'AFTER'; } if (( strpos( $settings['lesson_video_url'], 'youtu.be' ) !== false ) || ( strpos( $settings['lesson_video_url'], 'youtube.com' ) !== false )) { $this->video_data['videos_found_provider'] = 'youtube'; } else if ( strpos( $settings['lesson_video_url'], 'vimeo.com' ) !== false ) { $this->video_data['videos_found_provider'] = 'vimeo'; } else if ( ( strpos( $settings['lesson_video_url'], 'wistia.com' ) !== false ) || ( strpos( $settings['lesson_video_url'], 'wistia.net' ) !== false ) ) { $this->video_data['videos_found_provider'] = 'wistia'; } else if ( strpos( $settings['lesson_video_url'], 'amazonaws.com' ) !== false ) { $this->video_data['videos_found_provider'] = 'local'; } else if ( strpos( $settings['lesson_video_url'], 'vooplayer' ) !== false ) { $this->video_data['videos_found_provider'] = 'vooplayer'; } else if ( strpos( $settings['lesson_video_url'], trailingslashit( get_home_url() ) ) !== false ) { $this->video_data['videos_found_provider'] = 'local'; } else { $this->video_data['videos_found_provider'] = apply_filters('ld_video_provider', '', $settings ); } if ( ( substr( $settings['lesson_video_url'], 0, strlen('http://') ) == 'http://' ) || ( substr( $settings['lesson_video_url'], 0, strlen('https://') ) == 'https://' ) ) { if ( $this->video_data['videos_found_provider'] == 'local' ) { $this->video_data['videos_found_type'] = 'video_shortcode'; $settings['lesson_video_url'] = '[video src="'. $settings['lesson_video_url'] .'"][/video]'; } else if ( ( $this->video_data['videos_found_provider'] == 'youtube' ) || ( $this->video_data['videos_found_provider'] == 'vimeo' ) ) { $this->video_data['videos_found_type'] = 'embed_shortcode'; $settings['lesson_video_url'] = '[embed]'. $settings['lesson_video_url'] .'[/embed]'; } else if ( $this->video_data['videos_found_provider'] == 'wistia' ) { $this->video_data['videos_found_type'] = 'embed_shortcode'; $settings['lesson_video_url'] = '[embed]'. $settings['lesson_video_url'] .'[/embed]'; } } else if ( substr( $settings['lesson_video_url'], 0, strlen('[embed') ) == '[embed' ) { $this->video_data['videos_found_type'] = 'embed_shortcode'; } else if ( substr( $settings['lesson_video_url'], 0, strlen('[video') ) == '[video' ) { $this->video_data['videos_found_type'] = 'video_shortcode'; } else if ( substr( $settings['lesson_video_url'], 0, strlen('<iframe') ) == '<iframe' ) { $this->video_data['videos_found_type'] = 'iframe'; } else { if ( $this->video_data['videos_found_provider'] == 'vooplayer' ) { if ( substr( $settings['lesson_video_url'], 0, strlen('[vooplayer') ) == '[vooplayer' ) { $this->video_data['videos_found_type'] = 'vooplayer_shortcode'; } else { $this->video_data['videos_found_type'] = 'iframe'; } } } if ( ( $this->video_data['videos_found_provider'] !== false ) && ( $this->video_data['videos_found_type'] !== false ) ) { if ( $this->video_data['videos_found_provider'] == 'local' ) { if ( $this->video_data['videos_found_type'] == 'video_url' ) { //$this->video_content = wp_video_shortcode( // apply_filters( // 'ld_video_shortcode_args', // array( // 'src' => $settings['lesson_video_url'], // ), // $post->ID, $settings // ) //); } else if ( $this->video_data['videos_found_type'] == 'embed_shortcode' ) { global $wp_embed; $video_content = $wp_embed->run_shortcode( $settings['lesson_video_url'] ); $this->video_content = do_shortcode( $video_content ); } else if ( $this->video_data['videos_found_type'] == 'video_shortcode' ) { $this->video_content = do_shortcode( $settings['lesson_video_url'] ); } else if ( $this->video_data['videos_found_type'] == 'iframe' ) { $this->video_content = $settings['lesson_video_url']; } } else if ( ( $this->video_data['videos_found_provider'] == 'youtube' ) || ( $this->video_data['videos_found_provider'] == 'vimeo' ) || ( $this->video_data['videos_found_provider'] == 'wistia' ) ) { //$this->video_content = wp_oembed_get( $settings['lesson_video_url'], apply_filters( 'learndash_video_oembed_args', array(), $settings['lesson_video_url'], $post->ID, $settings ) ); if ( $this->video_data['videos_found_type'] == 'embed_shortcode' ) { global $wp_embed; $this->video_content = $wp_embed->run_shortcode( $settings['lesson_video_url'] ); } else if ( $this->video_data['videos_found_type'] == 'video_shortcode' ) { $this->video_content = do_shortcode( $settings['lesson_video_url'] ); } else if ( $this->video_data['videos_found_type'] == 'iframe' ) { $this->video_content = $settings['lesson_video_url']; } } else if ( $this->video_data['videos_found_provider'] == 'vooplayer' ) { if ( $this->video_data['videos_found_type'] == 'vooplayer_shortcode' ) { $this->video_content = do_shortcode( $settings['lesson_video_url'] ); } else if ( $this->video_data['videos_found_type'] == 'iframe' ) { //if ( strpos( $settings['lesson_video_url'], '</script>' ) === false ) { // $settings['lesson_video_url'] = '<script src="https://codehooligans.cdn.vooplayer.com/assets/vooplayer.js"></script>' . $settings['lesson_video_url']; //} $this->video_content = $settings['lesson_video_url']; } } if ( !empty( $this->video_content ) ) { if ( $logic_video ) { if (( isset( $settings['lesson_video_show_controls'] ) ) && ( $settings['lesson_video_show_controls'] == 'on' )) { $this->video_data['videos_show_controls'] = 1; } else { $this->video_data['videos_show_controls'] = 0; } if (( isset( $settings['lesson_video_auto_start'] ) ) && ( $settings['lesson_video_auto_start'] == 'on' )) { $this->video_data['videos_auto_start'] = 1; } else { $this->video_data['videos_auto_start'] = 0; } $video_preg_pattern = ''; if ( strstr( $this->video_content, ' src="' ) ) { $video_preg_pattern = '/<iframe.*src=\"(.*)\".*><\/iframe>/isU'; } else if ( strstr( $this->video_content, " src='" ) ) { $video_preg_pattern = "/<iframe.*src=\'(.*)\'.*><\/iframe>/isU"; } if ( ! empty( $video_preg_pattern ) ) { preg_match( $video_preg_pattern, $this->video_content, $matches ); if ( ( is_array( $matches ) ) && ( isset( $matches[1] ) ) && ( !empty( $matches[1] ) ) ) { // Next we need to check if the video is YouTube, Vimeo, etc. so we check the matches[1] if ( $this->video_data['videos_found_provider'] == 'youtube' ) { $ld_video_params = apply_filters( 'ld_video_params', array( 'controls' => $this->video_data['videos_show_controls'], 'autoplay' => $this->video_data['videos_auto_start'], 'modestbranding' => 1, 'showinfo' => 0, 'rel' => 0 ), 'youtube', $this->video_content, $post, $settings ); // Regardless of the filter we set this param because we need it! $ld_video_params['enablejsapi'] = '1'; $matches_1_new = add_query_arg( $ld_video_params, $matches[1] ); $this->video_content = str_replace( $matches[1], $matches_1_new, $this->video_content ); //$this->video_content = str_replace('<iframe ', '<iframe id="ld-video-player" ', $this->video_content ); } else if ( $this->video_data['videos_found_provider'] == 'vimeo' ) { if ( ( ! $this->video_data['videos_show_controls'] ) && ( ! $this->video_data['videos_auto_start'] ) ) { $this->video_data['videos_show_controls'] = true; } $ld_video_params = apply_filters( 'ld_video_params', array( 'controls' => $this->video_data['videos_show_controls'], 'autoplay' => $this->video_data['videos_auto_start'], ), 'vimeo', $this->video_content, $post, $settings ); // Regardless of the filter we set this param because we need it! $ld_video_params['api'] = '1'; $matches_1_new = add_query_arg( $ld_video_params, $matches[1] ); $this->video_content = str_replace( $matches[1], $matches_1_new, $this->video_content ); } else if ( $this->video_data['videos_found_provider'] == 'wistia' ) { // } else if ( $this->video_data['videos_found_provider'] == 'local' ) { // } } } $this->video_content = '<div class="ld-video" data-video-progression="true" data-video-provider="'. $this->video_data['videos_found_provider'] .'">'. $this->video_content .'</div>'; if ( $this->video_data['videos_found_provider'] == 'local' ) { if ( $this->video_data['videos_found_provider'] == 'local' ) { $ld_video_params = apply_filters( 'ld_video_params', array( 'controls' => $this->video_data['videos_show_controls'], ), 'local', $this->video_content, $post, $settings ); } if ( $ld_video_params['controls'] != true ) { $this->video_content .="<style>.ld-video .mejs-controls { display: none !important; visibility: hidden !important;}</style>"; } } $this->video_data['videos_auto_complete'] = false; if (( isset( $settings['lesson_video_shown'] ) ) && ( $settings['lesson_video_shown'] == 'AFTER' )) { if ( ( isset( $settings['lesson_video_auto_complete'] ) ) && ( $settings['lesson_video_auto_complete'] == 'on' ) ) { $this->video_data['videos_auto_complete'] = true; if ( ( isset( $settings['lesson_video_hide_complete_button'] ) ) && ( $settings['lesson_video_hide_complete_button'] == 'on' ) ) { $this->video_data['videos_hide_complete_button'] = true; } if ( isset( $settings['lesson_video_auto_complete_delay'] ) ) { $this->video_data['videos_auto_complete_delay'] = intval( $settings['lesson_video_auto_complete_delay'] ); $post_type_obj = get_post_type_object( $post->post_type ); $post_type_name = $post_type_obj->labels->name; $this->video_data['videos_auto_complete_delay_message'] = sprintf( wp_kses_post( _x('<p class="ld-video-delay-message">%s will auto complete in %s seconds</p>', 'placeholders: 1. Lesson or Topic label, 2. span for counter', 'learndash' ) ), $post_type_obj->labels->singular_name, '<span class="time-countdown">'. $this->video_data['videos_auto_complete_delay'] . '</span>' ); } } } } else { $this->video_data['videos_found_provider'] = false; $this->video_content = '<div class="ld-video" data-video-progression="false">'. $this->video_content .'</div>'; } } } } } } if ( isset( $_GET['ld_debug'] ) ) { $this->video_data['video_debug'] = true; } if ( !empty( $this->video_content ) ) { $this->video_data = apply_filters('learndash_lesson_video_data', $this->video_data, $settings ); } $content = SFWD_LMS::get_template( 'learndash_lesson_video', array( 'content' => $content, 'video_content' => $this->video_content, 'video_settings' => $settings, 'video_data' => $this->video_data ) ); return $content; } function action_wp_footer() { if ( $this->video_data['videos_found_provider'] !== false ) { wp_enqueue_script( 'learndash_video_script_js', LEARNDASH_LMS_PLUGIN_URL . 'assets/js/learndash_video_script'. leardash_min_asset() .'.js', array( 'jquery' ), LEARNDASH_SCRIPT_VERSION_TOKEN, true ); $learndash_assets_loaded['scripts']['learndash_video_script_js'] = __FUNCTION__; wp_localize_script( 'learndash_video_script_js', 'learndash_video_data', $this->video_data ); if ( $this->video_data['videos_found_provider'] == 'youtube' ) { wp_enqueue_script( 'youtube_iframe_api', 'https://www.youtube.com/iframe_api', array( 'learndash_video_script_js' ), '1.0', true ); } else if ( $this->video_data['videos_found_provider'] == 'vimeo' ) { wp_enqueue_script( 'vimeo_iframe_api', 'https://player.vimeo.com/api/player.js', array( 'learndash_video_script_js' ), null, true ); } } } function process_mark_complete( $process_complete = true, $post, $current_user ) { if ( ( isset( $_GET['quiz_redirect'] ) ) && ( !empty( $_GET['quiz_redirect'] ) ) && ( isset( $_GET['quiz_type'] ) ) && ( $_GET['quiz_type'] == 'lesson' ) ) { $lesson_id = 0; $quiz_id = 0; if ( isset( $_GET['lesson_id'] ) ) $lesson_id = intval( $_GET['lesson_id'] ); if ( isset( $_GET['quiz_id'] ) ) $quiz_id = intval( $_GET['quiz_id'] ); if ( ( !empty( $lesson_id ) ) && ( !empty( $quiz_id ) ) ) { $lesson_settings = learndash_get_setting( $lesson_id ); if ( ( isset( $lesson_settings['lesson_video_enabled'] ) ) && ( $lesson_settings['lesson_video_enabled'] == 'on' ) ) { if ( ( isset( $lesson_settings['lesson_video_shown'] ) ) && ( $lesson_settings['lesson_video_shown'] == 'AFTER' ) ) { $process_complete = false; add_filter( 'learndash_completion_redirect', array( $this, 'learndash_completion_redirect' ), 99 ); } } } } return $process_complete; } function learndash_completion_redirect( $link ) { if ( ( isset( $_GET['quiz_redirect'] ) ) && ( !empty( $_GET['quiz_redirect'] ) ) && ( isset( $_GET['quiz_type'] ) ) && ( $_GET['quiz_type'] == 'lesson' ) ) { $lesson_id = 0; $quiz_id = 0; if ( isset( $_GET['lesson_id'] ) ) $lesson_id = intval( $_GET['lesson_id'] ); if ( isset( $_GET['quiz_id'] ) ) $quiz_id = intval( $_GET['quiz_id'] ); if ( ( !empty( $lesson_id ) ) && ( !empty( $quiz_id ) ) ) { $lesson_settings = learndash_get_setting( $lesson_id ); if ( ( isset( $lesson_settings['lesson_video_enabled'] ) ) && ( $lesson_settings['lesson_video_enabled'] == 'on' ) ) { if ( ( isset( $lesson_settings['lesson_video_shown'] ) ) && ( $lesson_settings['lesson_video_shown'] == 'AFTER' ) ) { $link = get_permalink( $lesson_id ); remove_filter( 'learndash_completion_redirect', array( $this, 'learndash_completion_redirect' ), 99 ); } } } } return $link; } function save_post_data( $post_id = 0 ) { if ( !empty( $post_id ) ) { if ( ( isset( $_POST['post_type'] ) ) && ( ( $_POST['post_type'] === 'sfwd-lessons') || ( $_POST['post_type'] === 'sfwd-topic') ) ) { $post_type = esc_attr( $_POST['post_type'] ); if ( ( isset( $_POST[ $post_type . '_lesson_video_enabled'] ) ) && ( $_POST[ $post_type . '_lesson_video_enabled'] === 'on' ) ) { if ( ( isset( $_POST[ $post_type . '_lesson_video_url'] ) ) && ( !empty( $_POST[ $post_type . '_lesson_video_url'] ) ) ) { global $wpdb; $sql_str = $wpdb->prepare( "DELETE FROM " . $wpdb->postmeta ." WHERE post_id=%d AND meta_key LIKE %s", intval( $post_id ), '_oembed_%' ); $wpdb->query( $sql_str ); } } } } } } } add_action( 'learndash_init', function() { Learndash_Course_Video::get_instance(); } );
| ver. 1.4 |
Github
|
.
| PHP 7.0.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings