Exemple #1
0
 /**
  * Testing the is lesson pre-requisite completed function.
  *
  * @since 1.9.0
  */
 public function testIsPreRequisiteComplete()
 {
     // does this function add_user_data exist?
     $this->assertTrue(method_exists('WooThemes_Sensei_Lesson', 'is_prerequisite_complete'), 'The lesson class function `is_prerequisite_complete` does not exist ');
     // falsy state
     $user_id = 0;
     $lesson_id = 0;
     $this->assertFalse(WooThemes_Sensei_Lesson::is_prerequisite_complete($lesson_id, $user_id), 'None existing lesson or user should return false');
     $test_user_id = wp_create_user('studentPrerequisite', 'studentPrerequisite', '*****@*****.**');
     $test_lesson = $this->factory->get_lessons();
     $test_lesson_id = $test_lesson[0];
     // truthy state
     $course_id = $this->factory->get_random_course_id();
     $lessons = $this->factory->get_lessons();
     $test_lesson_prerequisite_id = $lessons[1];
     // add lesson to random course
     update_post_meta($test_lesson_prerequisite_id, '_lesson_course', $course_id);
     update_post_meta($test_lesson_id, '_lesson_course', $course_id);
     // setup prerequisite
     update_post_meta($test_lesson_id, '_lesson_prerequisite', $test_lesson_prerequisite_id);
     Sensei_Utils::user_start_lesson($test_user_id, $test_lesson_prerequisite_id);
     $this->assertFalse(WooThemes_Sensei_Lesson::is_prerequisite_complete($test_lesson_id, $test_user_id), 'Users that has NOT completeded prerequisite should return false.');
     Sensei_Utils::user_start_lesson($test_user_id, $test_lesson_prerequisite_id, true);
     $this->assertTrue(Sensei_Lesson::is_prerequisite_complete($test_lesson_id, $test_user_id), 'Users that has completeded prerequisite should return true.');
 }
 /**
  * trigger function.
  *
  * @access public
  *
  * @param int $user_id
  * @param int $course_id
  *
  * @return void
  */
 function trigger($user_id = 0, $course_id = 0)
 {
     global $sensei_email_data;
     // Get learner user object
     $this->user = new WP_User($user_id);
     // Get passed status
     $passed = __('passed', 'woothemes-sensei');
     if (!Sensei_Utils::sensei_user_passed_course($course_id, $user_id)) {
         $passed = __('failed', 'woothemes-sensei');
     }
     // Construct data array
     $sensei_email_data = apply_filters('sensei_email_data', array('template' => $this->template, 'heading' => $this->heading, 'user_id' => $user_id, 'course_id' => $course_id, 'passed' => $passed), $this->template);
     // Set recipient (learner)
     $this->recipient = stripslashes($this->user->user_email);
     // Send mail
     Sensei()->emails->send($this->recipient, $this->subject, Sensei()->emails->get_content($this->template));
 }
 /**
  * Sets up the object course query
  * that will be used int he render method.
  *
  * @since 1.9.0
  */
 protected function setup_course_query()
 {
     // course query parameters to be used for all courses
     $query_args = array('post_type' => 'course', 'post_status' => 'publish', 'posts_per_page' => 1000, 'orderby' => $this->orderby, 'order' => $this->order);
     // get all the courses that has a product attached
     $all_courses_query = new WP_Query($query_args);
     $paid_courses_not_taken = array();
     // look through all course and find the purchasable ones that user has not purchased
     foreach ($all_courses_query->posts as $course) {
         // only keep the courses with a product including only  courses that the user not taking
         $course_product_id = get_post_meta($course->ID, '_course_woocommerce_product', true);
         if (is_numeric($course_product_id) && !Sensei_Utils::user_started_course($course->ID, get_current_user_id())) {
             $paid_courses_not_taken[] = $course->ID;
         }
     }
     // end foreach
     // setup the course query again and only use the course the user has not purchased.
     // this query will be loaded into the global WP_Query in the render function.
     $query_args['post__in'] = $paid_courses_not_taken;
     $query_args['posts_per_page'] = $this->number;
     $this->query = new WP_Query($query_args);
 }
    /**
     * Print a single course markup
     *
     * @param $course_id
     */
    public static function the_course($course_id)
    {
        // Get meta data
        $course = get_post($course_id);
        $user_info = get_userdata(absint($course->post_author));
        $author_link = get_author_posts_url(absint($course->post_author));
        $author_display_name = $user_info->display_name;
        $author_id = $course->post_author;
        $category_output = get_the_term_list($course_id, 'course-category', '', ', ', '');
        $preview_lesson_count = intval(Sensei()->course->course_lesson_preview_count($course_id));
        $is_user_taking_course = Sensei_Utils::user_started_course($course_id, get_current_user_id());
        ?>

        <article class="<?php 
        echo esc_attr(join(' ', get_post_class(array('course', 'post'), $course_id)));
        ?>
">
            <?php 
        // so that legacy shortcodes work with the party plugins that wants to hook in
        do_action('sensei_course_content_before', $course->ID);
        ?>
            <div class="course-content">

                <?php 
        Sensei()->course->course_image($course_id);
        ?>

                <header>

                    <h2><a href="<?php 
        echo get_permalink($course_id);
        ?>
" title="<?php 
        echo $course->post_title;
        ?>
"><?php 
        echo $course->post_title;
        ?>
</a></h2>

                </header>

                <section class="entry">

                    <p class="sensei-course-meta">

                        <?php 
        if (isset(Sensei()->settings->settings['course_author']) && Sensei()->settings->settings['course_author']) {
            ?>
                            <span class="course-author"><?php 
            _e('by ', 'woothemes-sensei');
            ?>
<a href="<?php 
            echo $author_link;
            ?>
" title="<?php 
            echo esc_attr($author_display_name);
            ?>
"><?php 
            echo esc_html($author_display_name);
            ?>
</a></span>
                        <?php 
        }
        // End If Statement
        ?>

                        <span class="course-lesson-count">
                                    <?php 
        echo Sensei()->course->course_lesson_count($course_id) . '&nbsp;' . __('Lessons', 'woothemes-sensei');
        ?>
                                </span>

                        <?php 
        if ('' != $category_output) {
            ?>
                            <span class="course-category"><?php 
            echo sprintf(__('in %s', 'woothemes-sensei'), $category_output);
            ?>
</span>
                        <?php 
        }
        // End If Statement
        ?>

                        <?php 
        sensei_simple_course_price($course_id);
        ?>

                    </p>

                    <p class="course-excerpt"><?php 
        echo $course->post_excerpt;
        ?>

                    </p>

                    <?php 
        if (0 < $preview_lesson_count && !$is_user_taking_course) {
            $preview_lessons = sprintf(__('(%d preview lessons)', 'woothemes-sensei'), $preview_lesson_count);
            ?>
                        <p class="sensei-free-lessons">
                            <a href="<?php 
            echo get_permalink($course_id);
            ?>
"><?php 
            _e('Preview this course', 'woothemes-sensei');
            ?>
                            </a> - <?php 
            echo $preview_lessons;
            ?>
                        </p>
                    <?php 
        }
        ?>

                </section>

            </div>
            <?php 
        // so that legacy shortcodes work with thir party plugins that wants to hook in
        do_action('sensei_course_content_after', $course->ID);
        ?>

        </article>

        <?php 
    }
 /**
  * Limit the analysis view to only the users taking courses belong to this teacher
  *
  * Hooked into sensei_analysis_get_learners
  * @param array $args WP_User_Query arguments
  * @return array $learners_query_results
  */
 public function limit_analysis_learners($args)
 {
     // show default for none teachers
     if (!Sensei()->teacher->is_admin_teacher()) {
         return $args;
     }
     // for teachers all courses only return those which belong to the teacher
     // as they don't have access to course belonging to other users
     $teacher_courses = Sensei()->course->get_all_courses();
     // if the user has no courses they should see no users
     if (empty($teacher_courses) || !is_array($teacher_courses)) {
         // tell the query to return 0 students
         $args['include'] = array(0);
         return $args;
     }
     $learner_ids_for_teacher_courses = array();
     foreach ($teacher_courses as $course) {
         $course_learner_ids = array();
         $activity_comments = Sensei_Utils::sensei_check_for_activity(array('post_id' => $course->ID, 'type' => 'sensei_course_status', 'field' => 'user_id'), true);
         if (empty($activity_comments) || is_array($activity_comments) && !(count($activity_comments) > 0)) {
             continue;
             // skip to the next course as there are no users on this course
         }
         // it could be an array of comments or a single comment
         if (is_array($activity_comments)) {
             foreach ($activity_comments as $comment) {
                 $user = get_userdata($comment->user_id);
                 if (empty($user)) {
                     // next comment in this array
                     continue;
                 }
                 $course_learner_ids[] = $user->ID;
             }
         } else {
             $user = get_userdata($activity_comments->user_id);
             $course_learner_ids[] = $user->ID;
         }
         // add learners on this course to the all courses learner list
         $learner_ids_for_teacher_courses = array_merge($learner_ids_for_teacher_courses, $course_learner_ids);
     }
     // if there are no students taking the courses by this teacher don't show them any of the other users
     if (empty($learner_ids_for_teacher_courses)) {
         $args['include'] = array(0);
     } else {
         $args['include'] = $learner_ids_for_teacher_courses;
     }
     // return the WP_Use_Query arguments
     return $args;
 }
Exemple #6
0
 /**
  * Runs when an order is cancelled.
  * @since   1.2.0
  * @access  public
  * @param   integer $order_id order ID
  * @return  void
  */
 public function sensei_woocommerce_cancel_order($order_id)
 {
     // Get order object
     $order = new WC_Order($order_id);
     // Run through each product ordered
     if (0 < sizeof($order->get_items())) {
         // Get order user
         $user_id = $order->__get('user_id');
         foreach ($order->get_items() as $item) {
             $product_type = '';
             if (isset($item['variation_id']) && 0 < $item['variation_id']) {
                 $item_id = $item['variation_id'];
                 $product_type = 'variation';
             } else {
                 $item_id = $item['product_id'];
             }
             // End If Statement
             $_product = $this->sensei_get_woocommerce_product_object($item_id, $product_type);
             // Get courses that use the WC product
             $courses = array();
             $courses = $this->post_types->course->get_product_courses($item_id);
             // Loop and update those courses
             foreach ($courses as $course_item) {
                 // Check and Remove course from courses user meta
                 $dataset_changes = Sensei_Utils::sensei_remove_user_from_course($course_item->ID, $user_id);
             }
             // End For Loop
         }
         // End For Loop
     }
     // End If Statement
 }
Exemple #7
0
    /**
     * This hook fire inside learner-profile.php inside directly before the content
     *
     * @since 1.9.0
     *
     * @param integer $course_id
     *
     * @hooked Sensei_Course_Results::course_info() - 20
     */
    do_action('sensei_course_results_content_inside_before_lessons', $course->ID);
    ?>


            <section class="course-results-lessons">
                <?php 
    $started_course = Sensei_Utils::user_started_course($course->ID, get_current_user_id());
    if ($started_course) {
        sensei_the_course_results_lessons();
    }
    ?>
            </section>

        <?php 
}
?>

        <?php 
/**
 * This hook fire inside learner-profile.php inside directly after the content
 *
 * @since 1.9.0
 /**
  * Add text to the certificate
  *
  * @access public
  * @since  1.0.0
  * @return void
  */
 public function certificate_text($pdf_certificate, $fpdf)
 {
     $show_border = apply_filters('woothemes_sensei_certificates_show_border', 0);
     $start_position = 200;
     // Find certificate based on hash
     $args = array('post_type' => 'certificate', 'meta_key' => 'certificate_hash', 'meta_value' => $pdf_certificate->hash);
     $query = new WP_Query($args);
     $certificate_id = 0;
     if ($query->have_posts()) {
         $query->the_post();
         $certificate_id = $query->posts[0]->ID;
     }
     // End If Statement
     wp_reset_query();
     if (0 < intval($certificate_id)) {
         // Get Student Data
         $user_id = get_post_meta($certificate_id, 'learner_id', true);
         $student = get_userdata($user_id);
         $student_name = $student->display_name;
         $fname = $student->first_name;
         $lname = $student->last_name;
         if ('' != $fname && '' != $lname) {
             $student_name = $fname . ' ' . $lname;
         }
         // Get Course Data
         $course_id = get_post_meta($certificate_id, 'course_id', true);
         $course = Sensei()->course->course_query(-1, 'usercourses', $course_id);
         $course = $course[0];
         $course_end = Sensei_Utils::sensei_check_for_activity(array('post_id' => intval($course_id), 'user_id' => intval($user_id), 'type' => 'sensei_course_status'), true);
         $course_end_date = $course_end->comment_date;
         // Get the certificate template
         $certificate_template_id = get_post_meta($course_id, '_course_certificate_template', true);
         $certificate_template_custom_fields = get_post_custom($certificate_template_id);
         // Define the data we're going to load: Key => Default value
         $load_data = array('certificate_font_style' => array(), 'certificate_font_color' => array(), 'certificate_font_size' => array(), 'certificate_font_family' => array(), 'image_ids' => array(), 'certificate_template_fields' => array());
         // Load the data from the custom fields
         foreach ($load_data as $key => $default) {
             // set value from db (unserialized if needed) or use default
             $this->{$key} = isset($certificate_template_custom_fields['_' . $key][0]) && '' !== $certificate_template_custom_fields['_' . $key][0] ? is_array($default) ? maybe_unserialize($certificate_template_custom_fields['_' . $key][0]) : $certificate_template_custom_fields['_' . $key][0] : $default;
         }
         // End For Loop
         // Set default fonts
         if (isset($this->certificate_font_color) && '' != $this->certificate_font_color) {
             $pdf_certificate->certificate_pdf_data['font_color'] = $this->certificate_font_color;
         }
         if (isset($this->certificate_font_size) && '' != $this->certificate_font_size) {
             $pdf_certificate->certificate_pdf_data['font_size'] = $this->certificate_font_size;
         }
         if (isset($this->certificate_font_family) && '' != $this->certificate_font_family) {
             $pdf_certificate->certificate_pdf_data['font_family'] = $this->certificate_font_family;
         }
         if (isset($this->certificate_font_style) && '' != $this->certificate_font_style) {
             $pdf_certificate->certificate_pdf_data['font_style'] = $this->certificate_font_style;
         }
         // Set default fonts
         setlocale(LC_TIME, get_locale());
         if (false !== strpos(get_locale(), 'en')) {
             $date_format = apply_filters('sensei_certificate_date_format', 'jS F Y');
             $date = date($date_format, strtotime($course_end_date));
         } else {
             $date_format = apply_filters('sensei_certificate_date_format', '%Y %B %e');
             $date = strftime($date_format, strtotime($course_end_date));
         }
         $certificate_heading = __('Certificate of Completion', 'sensei-certificates');
         // Certificate of Completion
         if (isset($this->certificate_template_fields['certificate_heading']['text']) && '' != $this->certificate_template_fields['certificate_heading']['text']) {
             $certificate_heading = $this->certificate_template_fields['certificate_heading']['text'];
             $certificate_heading = str_replace(array('{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}'), array($student_name, $course->post_title, $date, get_bloginfo('name')), $certificate_heading);
         }
         // End If Statement
         $certificate_message = __('This is to certify that', 'sensei-certificates') . " \r\n\r\n" . $student_name . " \r\n\r\n" . __('has completed the course', 'sensei-certificates');
         // This is to certify that {{learner}} has completed the course
         if (isset($this->certificate_template_fields['certificate_message']['text']) && '' != $this->certificate_template_fields['certificate_message']['text']) {
             $certificate_message = $this->certificate_template_fields['certificate_message']['text'];
             $certificate_message = str_replace(array('{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}'), array($student_name, $course->post_title, $date, get_bloginfo('name')), $certificate_message);
         }
         // End If Statement
         $certificate_course = $course->post_title;
         // {{course_title}}
         if (isset($this->certificate_template_fields['certificate_course']['text']) && '' != $this->certificate_template_fields['certificate_course']['text']) {
             $certificate_course = $this->certificate_template_fields['certificate_course']['text'];
             $certificate_course = str_replace(array('{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}'), array($student_name, $course->post_title, $date, get_bloginfo('name')), $certificate_course);
         }
         // End If Statement
         $certificate_completion = $date;
         // {{completion_date}}
         if (isset($this->certificate_template_fields['certificate_completion']['text']) && '' != $this->certificate_template_fields['certificate_completion']['text']) {
             $certificate_completion = $this->certificate_template_fields['certificate_completion']['text'];
             $certificate_completion = str_replace(array('{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}'), array($student_name, $course->post_title, $date, get_bloginfo('name')), $certificate_completion);
         }
         // End If Statement
         $certificate_place = sprintf(__('At %s', 'sensei-certificates'), get_bloginfo('name'));
         // At {{course_place}}
         if (isset($this->certificate_template_fields['certificate_place']['text']) && '' != $this->certificate_template_fields['certificate_place']['text']) {
             $certificate_place = $this->certificate_template_fields['certificate_place']['text'];
             $certificate_place = str_replace(array('{{learner}}', '{{course_title}}', '{{completion_date}}', '{{course_place}}'), array($student_name, $course->post_title, $date, get_bloginfo('name')), $certificate_place);
         }
         // End If Statement
         $output_fields = array('certificate_heading' => 'text_field', 'certificate_message' => 'textarea_field', 'certificate_course' => 'text_field', 'certificate_completion' => 'text_field', 'certificate_place' => 'text_field');
         foreach ($output_fields as $meta_key => $function_name) {
             // Check if the field has a set position
             if (isset($this->certificate_template_fields[$meta_key]['position']['x1'])) {
                 $font_settings = $this->get_certificate_font_settings($meta_key);
                 call_user_func_array(array($pdf_certificate, $function_name), array($fpdf, ${$meta_key}, $show_border, array($this->certificate_template_fields[$meta_key]['position']['x1'], $this->certificate_template_fields[$meta_key]['position']['y1'], $this->certificate_template_fields[$meta_key]['position']['width'], $this->certificate_template_fields[$meta_key]['position']['height']), $font_settings));
             }
             // End If Statement
         }
         // End For Loop
     } else {
         wp_die(__('The certificate you are searching for does not exist.', 'sensei-certificates'), __('Certificate Error', 'sensei-certificates'));
     }
     // End If Statement
 }
Exemple #9
0
 /**
  * Checks the cart to see if a course is in the cart.
  *
  * @param $course_id
  * @return bool
  */
 public static function is_course_in_cart($course_id)
 {
     $wc_post_id = absint(get_post_meta($course_id, '_course_woocommerce_product', true));
     $user_course_status_id = Sensei_Utils::user_started_course($course_id, get_current_user_id());
     if (0 < intval($wc_post_id) && !$user_course_status_id) {
         if (self::is_product_in_cart($wc_post_id)) {
             return true;
         }
     }
     return false;
 }
 /**
  * Sets the stats boxes to render
  * @since  1.2.0
  * @return array $stats_to_render of stats boxes and values
  */
 public function stats_boxes()
 {
     // Get the data required
     $user_count = count_users();
     $user_count = apply_filters('sensei_analysis_total_users', $user_count['total_users'], $user_count);
     $total_courses = Sensei()->course->course_count(array('publish', 'private'));
     $total_lessons = Sensei()->lesson->lesson_count(array('publish', 'private'));
     /**
      * filter the analysis tot grades query args
      */
     $grade_args = apply_filters('sensei_analysis_total_quiz_grades', array('type' => 'sensei_lesson_status', 'status' => 'any', 'meta_key' => 'grade'));
     $total_grade_count = Sensei_Grading::get_graded_lessons_count();
     $total_grade_total = Sensei_Grading::get_graded_lessons_sum();
     $total_average_grade = 0;
     if ($total_grade_total > 0 && $total_grade_count > 0) {
         $total_average_grade = abs(round(doubleval($total_grade_total / $total_grade_count), 2));
     }
     $course_args = array('type' => 'sensei_course_status', 'status' => 'any');
     $total_courses_started = Sensei_Utils::sensei_check_for_activity(apply_filters('sensei_analysis_total_courses_started', $course_args));
     $course_args = array('type' => 'sensei_course_status', 'status' => 'complete');
     $total_courses_ended = Sensei_Utils::sensei_check_for_activity(apply_filters('sensei_analysis_total_courses_ended', $course_args));
     $average_courses_per_learner = abs(round(doubleval($total_courses_started / $user_count), 2));
     // Setup the boxes to render
     $stats_to_render = array(__('Total Courses', 'woothemes-sensei') => $total_courses, __('Total Lessons', 'woothemes-sensei') => $total_lessons, __('Total Learners', 'woothemes-sensei') => $user_count, __('Average Courses per Learner', 'woothemes-sensei') => $average_courses_per_learner, __('Average Grade', 'woothemes-sensei') => $total_average_grade . '%', __('Total Completed Courses', 'woothemes-sensei') => $total_courses_ended);
     return apply_filters('sensei_analysis_stats_boxes', $stats_to_render);
 }
Exemple #11
0
 /**
  * Check if the prerequisite course is completed
  * Courses with no pre-requisite should always return true
  *
  * @since 1.9.0
  * @param $course_id
  * @return bool
  */
 public static function is_prerequisite_complete($course_id)
 {
     $course_prerequisite_id = get_post_meta($course_id, '_course_prerequisite', true);
     // if it has a pre requisite course check it
     if (!empty($course_prerequisite_id)) {
         return Sensei_Utils::user_completed_course($course_prerequisite_id, get_current_user_id());
     }
     return true;
 }
Exemple #12
0
 /**
  * check_user_permissions function.
  *
  * @access public
  * @param string $page (default: '')
  *
  * @return bool
  */
 public function check_user_permissions($page = '')
 {
     global $current_user, $post;
     // if user is not logged in skipped for single lesson
     if (empty($current_user->caps) && Sensei()->settings->get('access_permission') && 'lesson-single' != $page) {
         $this->permissions_message['title'] = __('Restricted Access:', 'woothemes-sensei');
         $this->permissions_message['message'] = sprintf(__('You must be logged in to view this %s'), get_post_type());
         return false;
     }
     $user_allowed = false;
     switch ($page) {
         case 'course-single':
             // check for prerequisite course or lesson,
             $course_prerequisite_id = (int) get_post_meta($post->ID, '_course_prerequisite', true);
             $update_course = Sensei_WC::course_update($post->ID);
             // Count completed lessons
             if (0 < absint($course_prerequisite_id)) {
                 $prerequisite_complete = Sensei_Utils::user_completed_course($course_prerequisite_id, $current_user->ID);
             } else {
                 $prerequisite_complete = true;
             }
             // End If Statement
             // Handles restrictions
             if (!$prerequisite_complete && 0 < absint($course_prerequisite_id)) {
                 $this->permissions_message['title'] = get_the_title($post->ID) . ': ' . __('Restricted Access', 'woothemes-sensei');
                 $course_link = '<a href="' . esc_url(get_permalink($course_prerequisite_id)) . '">' . __('course', 'woothemes-sensei') . '</a>';
                 $this->permissions_message['message'] = sprintf(__('Please complete the previous %1$s before taking this course.', 'woothemes-sensei'), $course_link);
             } else {
                 $user_allowed = true;
             }
             // End If Statement
             break;
         case 'lesson-single':
             // Check for WC purchase
             $lesson_course_id = get_post_meta($post->ID, '_lesson_course', true);
             $update_course = Sensei_WC::course_update($lesson_course_id);
             $is_preview = Sensei_Utils::is_preview_lesson($post->ID);
             if ($this->access_settings() && Sensei_Utils::user_started_course($lesson_course_id, $current_user->ID)) {
                 $user_allowed = true;
             } elseif ($this->access_settings() && false == $is_preview) {
                 $user_allowed = true;
             } else {
                 $this->permissions_message['title'] = get_the_title($post->ID) . ': ' . __('Restricted Access', 'woothemes-sensei');
                 $course_link = '<a href="' . esc_url(get_permalink($lesson_course_id)) . '">' . __('course', 'woothemes-sensei') . '</a>';
                 $wc_post_id = get_post_meta($lesson_course_id, '_course_woocommerce_product', true);
                 if (Sensei_WC::is_woocommerce_active() && 0 < $wc_post_id) {
                     if ($is_preview) {
                         $this->permissions_message['message'] = sprintf(__('This is a preview lesson. Please purchase the %1$s to access all lessons.', 'woothemes-sensei'), $course_link);
                     } else {
                         $this->permissions_message['message'] = sprintf(__('Please purchase the %1$s before starting this Lesson.', 'woothemes-sensei'), $course_link);
                     }
                 } else {
                     if ($is_preview) {
                         $this->permissions_message['message'] = sprintf(__('This is a preview lesson. Please sign up for the %1$s to access all lessons.', 'woothemes-sensei'), $course_link);
                     } else {
                         /** This filter is documented in class-woothemes-sensei-frontend.php */
                         $this->permissions_message['message'] = sprintf(__('Please sign up for the %1$s before starting the lesson.', 'woothemes-sensei'), $course_link);
                     }
                 }
                 // End If Statement
             }
             // End If Statement
             break;
         case 'quiz-single':
             $lesson_id = get_post_meta($post->ID, '_quiz_lesson', true);
             $lesson_course_id = get_post_meta($lesson_id, '_lesson_course', true);
             $update_course = Sensei_WC::course_update($lesson_course_id);
             if ($this->access_settings() && Sensei_Utils::user_started_course($lesson_course_id, $current_user->ID) || sensei_all_access()) {
                 // Check for prerequisite lesson for this quiz
                 $lesson_prerequisite_id = (int) get_post_meta($lesson_id, '_lesson_prerequisite', true);
                 $user_lesson_prerequisite_complete = Sensei_Utils::user_completed_lesson($lesson_prerequisite_id, $current_user->ID);
                 // Handle restrictions
                 if (sensei_all_access()) {
                     $user_allowed = true;
                 } else {
                     if (0 < absint($lesson_prerequisite_id) && !$user_lesson_prerequisite_complete) {
                         $this->permissions_message['title'] = get_the_title($post->ID) . ': ' . __('Restricted Access', 'woothemes-sensei');
                         $lesson_link = '<a href="' . esc_url(get_permalink($lesson_prerequisite_id)) . '">' . __('lesson', 'woothemes-sensei') . '</a>';
                         $this->permissions_message['message'] = sprintf(__('Please complete the previous %1$s before taking this Quiz.', 'woothemes-sensei'), $lesson_link);
                     } else {
                         $user_allowed = true;
                     }
                     // End If Statement
                 }
                 // End If Statement
             } elseif ($this->access_settings()) {
                 // Check if the user has started the course
                 if (is_user_logged_in() && !Sensei_Utils::user_started_course($lesson_course_id, $current_user->ID) && (isset($this->settings->settings['access_permission']) && true == $this->settings->settings['access_permission'])) {
                     $user_allowed = false;
                     $this->permissions_message['title'] = get_the_title($post->ID) . ': ' . __('Restricted Access', 'woothemes-sensei');
                     $course_link = '<a href="' . esc_url(get_permalink($lesson_course_id)) . '">' . __('course', 'woothemes-sensei') . '</a>';
                     $wc_post_id = get_post_meta($lesson_course_id, '_course_woocommerce_product', true);
                     if (Sensei_WC::is_woocommerce_active() && 0 < $wc_post_id) {
                         $this->permissions_message['message'] = sprintf(__('Please purchase the %1$s before starting this Quiz.', 'woothemes-sensei'), $course_link);
                     } else {
                         $this->permissions_message['message'] = sprintf(__('Please sign up for the %1$s before starting this Quiz.', 'woothemes-sensei'), $course_link);
                     }
                     // End If Statement
                 } else {
                     $user_allowed = true;
                 }
                 // End If Statement
             } else {
                 $this->permissions_message['title'] = get_the_title($post->ID) . ': ' . __('Restricted Access', 'woothemes-sensei');
                 $course_link = '<a href="' . esc_url(get_permalink(get_post_meta(get_post_meta($post->ID, '_quiz_lesson', true), '_lesson_course', true))) . '">' . __('course', 'woothemes-sensei') . '</a>';
                 $this->permissions_message['message'] = sprintf(__('Please sign up for the %1$s before taking this Quiz.', 'woothemes-sensei'), $course_link);
             }
             // End If Statement
             break;
         default:
             $user_allowed = true;
             break;
     }
     // End Switch Statement
     /**
      * filter the permissions message shown on sensei post types.
      *
      * @since 1.8.7
      *
      * @param array $permissions_message{
      *
      *   @type string $title
      *   @type string $message
      *
      * }
      * @param string $post_id
      */
     $this->permissions_message = apply_filters('sensei_permissions_message', $this->permissions_message, $post->ID);
     if (sensei_all_access() || Sensei_Utils::is_preview_lesson($post->ID)) {
         $user_allowed = true;
     }
     /**
      * Filter the permissions check final result. Which determines if the user has
      * access to the given page.
      *
      * @since 1.0
      *
      * @param boolean $user_allowed
      * @param integer $user_id
      *
      */
     return apply_filters('sensei_access_permissions', $user_allowed, $current_user->ID);
 }
 /**
  * Add a the user status class for the given course.
  *
  * @since 1.9
  *
  * @param array $classes
  * @param WP_Post $course
  * @return array $classes
  */
 public function course_status_class_tagging($classes, $course)
 {
     if (Sensei_Utils::user_completed_course($course, get_current_user_id())) {
         $classes[] = 'user-completed';
     } else {
         $classes[] = 'user-active';
     }
     return $classes;
 }
Exemple #14
0
 /**
  * Test the array zip utility function
  * @since 1.9.0
  */
 public function testArrayZipMerge()
 {
     $this->assertTrue(method_exists('Sensei_Utils', 'array_zip_merge'), 'Sensei_Utils::array_zip_merge does not exist.');
     // test if the function works
     $array_1 = array(1, 2, 3);
     $array_2 = array(5, 6, 7, 8, 9);
     $array_zipped = Sensei_Utils::array_zip_merge($array_1, $array_2);
     $expected = array(1, 5, 2, 6, 3, 7, 8, 9);
     $this->assertEquals($expected, $array_zipped);
 }
 public function add_new_learners()
 {
     $result = false;
     if (!isset($_POST['add_learner_submit'])) {
         return $result;
     }
     if (!isset($_POST['add_learner_nonce']) || !wp_verify_nonce($_POST['add_learner_nonce'], 'add_learner_to_sensei')) {
         return $result;
     }
     if (!isset($_POST['add_user_id']) || '' == $_POST['add_user_id'] || !isset($_POST['add_post_type']) || !isset($_POST['add_course_id']) || !isset($_POST['add_lesson_id'])) {
         return $result;
     }
     $post_type = $_POST['add_post_type'];
     $user_id = absint($_POST['add_user_id']);
     $course_id = absint($_POST['add_course_id']);
     switch ($post_type) {
         case 'course':
             $result = Sensei_Utils::user_start_course($user_id, $course_id);
             // Complete each lesson if course is set to be completed
             if (isset($_POST['add_complete_course']) && 'yes' == $_POST['add_complete_course']) {
                 $lesson_ids = Sensei()->course->course_lessons($course_id, 'any', 'ids');
                 foreach ($lesson_ids as $id) {
                     Sensei_Utils::sensei_start_lesson($id, $user_id, true);
                 }
                 // Updates the Course status and it's meta data
                 Sensei_Utils::user_complete_course($course_id, $user_id);
                 do_action('sensei_user_course_end', $user_id, $course_id);
             }
             break;
         case 'lesson':
             $lesson_id = absint($_POST['add_lesson_id']);
             $complete = false;
             if (isset($_POST['add_complete_lesson']) && 'yes' == $_POST['add_complete_lesson']) {
                 $complete = true;
             }
             $result = Sensei_Utils::sensei_start_lesson($lesson_id, $user_id, $complete);
             // Updates the Course status and it's meta data
             Sensei_Utils::user_complete_course($course_id, $user_id);
             break;
     }
     // Set redirect URL after adding user to course/lesson
     $query_args = array('page' => $this->page_slug, 'view' => 'learners');
     if ($result) {
         if ($course_id) {
             $query_args['course_id'] = $course_id;
         }
         if ($lesson_id) {
             $query_args['lesson_id'] = $lesson_id;
         }
         $query_args['message'] = 'success';
     } else {
         $query_args['message'] = 'error';
     }
     $redirect_url = apply_filters('sensei_learners_add_learner_redirect_url', add_query_arg($query_args, admin_url('admin.php')));
     wp_safe_redirect(esc_url_raw($redirect_url));
     exit;
 }
 /**
  * Sets the stats boxes to render
  * @since  1.2.0
  * @return array $stats_to_render of stats boxes and values
  */
 public function stats_boxes()
 {
     // Get the data required
     $user_count = count_users();
     $user_count = apply_filters('sensei_analysis_total_users', $user_count['total_users'], $user_count);
     $total_courses = Sensei()->course->course_count(array('publish', 'private'));
     $total_lessons = Sensei()->lesson->lesson_count(array('publish', 'private'));
     $grade_args = array('type' => 'sensei_lesson_status', 'status' => 'any', 'meta_key' => 'grade');
     add_filter('comments_clauses', array('WooThemes_Sensei_Utils', 'comment_total_sum_meta_value_filter'));
     $total_quiz_grades = Sensei_Utils::sensei_check_for_activity(apply_filters('sensei_analysis_total_quiz_grades', $grade_args), true);
     remove_filter('comments_clauses', array('WooThemes_Sensei_Utils', 'comment_total_sum_meta_value_filter'));
     $total_grade_count = !empty($total_quiz_grades->total) ? $total_quiz_grades->total : 1;
     $total_grade_total = !empty($total_quiz_grades->meta_sum) ? doubleval($total_quiz_grades->meta_sum) : 0;
     $total_average_grade = abs(round(doubleval($total_grade_total / $total_grade_count), 2));
     $course_args = array('type' => 'sensei_course_status', 'status' => 'any');
     $total_courses_started = Sensei_Utils::sensei_check_for_activity(apply_filters('sensei_analysis_total_courses_started', $course_args));
     $course_args = array('type' => 'sensei_course_status', 'status' => 'complete');
     $total_courses_ended = Sensei_Utils::sensei_check_for_activity(apply_filters('sensei_analysis_total_courses_ended', $course_args));
     $average_courses_per_learner = abs(round(doubleval($total_courses_started / $user_count), 2));
     // Setup the boxes to render
     $stats_to_render = array(__('Total Courses', 'woothemes-sensei') => $total_courses, __('Total Lessons', 'woothemes-sensei') => $total_lessons, __('Total Learners', 'woothemes-sensei') => $user_count, __('Average Courses per Learner', 'woothemes-sensei') => $average_courses_per_learner, __('Average Grade', 'woothemes-sensei') => $total_average_grade . '%', __('Total Completed Courses', 'woothemes-sensei') => $total_courses_ended);
     return apply_filters('sensei_analysis_stats_boxes', $stats_to_render);
 }
 /**
  * Return array of lesson statuses
  * @since  1.7.0
  * @return array statuses
  */
 private function get_lesson_statuses($args)
 {
     $activity_args = array('post_id' => $this->lesson_id, 'type' => 'sensei_lesson_status', 'number' => $args['number'], 'offset' => $args['offset'], 'orderby' => $args['orderby'], 'order' => $args['order'], 'status' => 'any');
     // Searching users on statuses requires sub-selecting the statuses by user_ids
     if ($this->search) {
         $user_args = array('search' => '*' . $this->search . '*', 'fields' => 'ID');
         // Filter for extending
         $user_args = apply_filters('sensei_analysis_lesson_search_users', $user_args);
         if (!empty($user_args)) {
             $learners_search = new WP_User_Query($user_args);
             // Store for reuse on counts
             $activity_args['user_id'] = (array) $learners_search->get_results();
         }
     }
     // End If Statement
     $activity_args = apply_filters('sensei_analysis_lesson_filter_statuses', $activity_args);
     // WP_Comment_Query doesn't support SQL_CALC_FOUND_ROWS, so instead do this twice
     $this->total_items = Sensei_Utils::sensei_check_for_activity(array_merge($activity_args, array('count' => true, 'offset' => 0, 'number' => 0)));
     // Ensure we change our range to fit (in case a search threw off the pagination) - Should this be added to all views?
     if ($this->total_items < $activity_args['offset']) {
         $new_paged = floor($total_statuses / $activity_args['number']);
         $activity_args['offset'] = $new_paged * $activity_args['number'];
     }
     $statuses = Sensei_Utils::sensei_check_for_activity($activity_args, true);
     // Need to always return an array, even with only 1 item
     if (!is_array($statuses)) {
         $statuses = array($statuses);
     }
     return $statuses;
 }
 /**
  * Load course results info
  * @since  1.4.0
  * @return void
  */
 public function course_info()
 {
     global $course;
     $course_status = Sensei_Utils::sensei_user_course_status_message($course->ID, get_current_user_id());
     echo '<div class="sensei-message ' . $course_status['box_class'] . '">' . $course_status['message'] . '</div>';
     sensei_do_deprecated_action('sensei_course_results_lessons', '1.9.', 'sensei_course_results_content_inside_after', $course);
     sensei_do_deprecated_action('sensei_course_results_bottom', '1.9.', 'sensei_course_results_content_inside_after', $course->ID);
 }
 /**
  * Activate single course if already purchases
  * @return void
  */
 public function activate_purchased_single_course()
 {
     global $post, $current_user;
     if (Sensei_WC::is_woocommerce_active()) {
         if (!is_user_logged_in()) {
             return;
         }
         if (!isset($post->ID)) {
             return;
         }
         $user_id = $current_user->ID;
         $course_id = $post->ID;
         $course_product_id = (int) get_post_meta($course_id, '_course_woocommerce_product', true);
         if (!$course_product_id) {
             return;
         }
         $user_course_status = Sensei_Utils::user_course_status(intval($course_id), $user_id);
         // Ignore course if already completed
         if (Sensei_Utils::user_completed_course($user_course_status)) {
             return;
         }
         // Ignore course if already started
         if ($user_course_status) {
             return;
         }
         // Get all user's orders
         $order_args = array('post_type' => 'shop_order', 'posts_per_page' => -1, 'post_status' => array('wc-processing', 'wc-completed'), 'meta_query' => array(array('key' => '_customer_user', 'value' => $user_id)), 'fields' => 'ids');
         $orders = get_posts($order_args);
         foreach ($orders as $order_post_id) {
             // Get course product IDs from order
             $order = new WC_Order($order_post_id);
             $items = $order->get_items();
             foreach ($items as $item) {
                 $product = wc_get_product($item['product_id']);
                 // handle product bundles
                 if (is_object($product) && $product->is_type('bundle')) {
                     $bundled_product = new WC_Product_Bundle($product->id);
                     $bundled_items = $bundled_product->get_bundled_items();
                     foreach ($bundled_items as $bundled_item) {
                         if ($bundled_item->product_id == $course_product_id) {
                             Sensei_Utils::user_start_course($user_id, $course_id);
                             return;
                         }
                     }
                 } else {
                     // handle regular products
                     if ($item['product_id'] == $course_product_id) {
                         Sensei_Utils::user_start_course($user_id, $course_id);
                         return;
                     }
                 }
             }
         }
     }
 }
    /**
     * Load the desired component, if a method is available for it.
     * @param  string $component The component to potentially be loaded.
     *
     * @since  1.0.0
     * @return void
     */
    protected function load_component($instance)
    {
        global $current_user;
        $course_ids = array();
        if ('activecourses' == esc_attr($instance['component'])) {
            $courses = Sensei_Utils::sensei_check_for_activity(array('user_id' => $current_user->ID, 'type' => 'sensei_course_status', 'status' => 'in-progress'), true);
            // Need to always return an array, even with only 1 item
            if (!is_array($courses)) {
                $courses = array($courses);
            }
            foreach ($courses as $course) {
                $course_ids[] = $course->comment_post_ID;
            }
        } elseif ('completedcourses' == esc_attr($instance['component'])) {
            $courses = Sensei_Utils::sensei_check_for_activity(array('user_id' => $current_user->ID, 'type' => 'sensei_course_status', 'status' => 'complete'), true);
            // Need to always return an array, even with only 1 item
            if (!is_array($courses)) {
                $courses = array($courses);
            }
            foreach ($courses as $course) {
                $course_ids[] = $course->comment_post_ID;
            }
        }
        // End If Statement
        $posts_array = array();
        // course_query() is buggy, it doesn't honour the 1st arg if includes are provided, so instead slice the includes
        if (!empty($instance['limit']) && intval($instance['limit']) >= 1 && intval($instance['limit']) < count($course_ids)) {
            $course_ids = array_slice($course_ids, 0, intval($instance['limit']));
            // This does mean the order by is effectively ignored
        }
        if (!empty($course_ids)) {
            $posts_array = Sensei()->course->course_query(intval($instance['limit']), esc_attr($instance['component']), $course_ids);
        } else {
            if ('activecourses' == esc_attr($instance['component']) || 'completedcourses' == esc_attr($instance['component'])) {
                $posts_array = array();
            } else {
                $course_args = array('post_type' => 'course', 'orderby' => 'date', 'order' => 'DESC', 'post_status' => 'publish', 'posts_per_page' => $instance['limit']);
                $posts_array = get_posts($course_args);
            }
        }
        // End If Statement
        if (count($posts_array) > 0) {
            ?>
			<ul>
			<?php 
            foreach ($posts_array as $post_item) {
                $post_id = absint($post_item->ID);
                $post_title = $post_item->post_title;
                $user_info = get_userdata(absint($post_item->post_author));
                $author_link = get_author_posts_url(absint($post_item->post_author));
                $author_display_name = $user_info->display_name;
                $author_id = $post_item->post_author;
                ?>
		    	<li class="fix">
		    		<?php 
                do_action('sensei_course_image', $post_id);
                ?>
		    		<a href="<?php 
                echo esc_url(get_permalink($post_id));
                ?>
" title="<?php 
                echo esc_attr($post_title);
                ?>
"><?php 
                echo $post_title;
                ?>
</a>
		    		<br />
		    		<?php 
                if (isset(Sensei()->settings->settings['course_author']) && Sensei()->settings->settings['course_author']) {
                    ?>
    					<span class="course-author"><?php 
                    _e('by ', 'woothemes-sensei');
                    ?>
<a href="<?php 
                    echo esc_url($author_link);
                    ?>
" title="<?php 
                    echo esc_attr($author_display_name);
                    ?>
"><?php 
                    echo esc_html($author_display_name);
                    ?>
</a></span>
    					<br />
    				<?php 
                }
                // End If Statement
                ?>
    				<span class="course-lesson-count"><?php 
                echo Sensei()->course->course_lesson_count($post_id) . '&nbsp;' . __('Lessons', 'woothemes-sensei');
                ?>
</span>
    				<br />
    				<?php 
                sensei_simple_course_price($post_id);
                ?>
		    	</li>
		    <?php 
            }
            // End For Loop
            ?>
		    <?php 
            if ('activecourses' == esc_attr($instance['component']) || 'completedcourses' == esc_attr($instance['component'])) {
                $my_account_page_id = intval(Sensei()->settings->settings['my_course_page']);
                echo '<li class="my-account fix"><a href="' . esc_url(get_permalink($my_account_page_id)) . '">' . __('My Courses', 'woothemes-sensei') . ' <span class="meta-nav"></span></a></li>';
            }
            // End If Statement
            ?>
		</ul>
		<?php 
        } else {
            // No posts returned. This means the user either has no active or no completed courses.
            if (isset($instance['component'])) {
                if ('featuredcourses' == $instance['component']) {
                    _e('You have no featured courses.', 'woothemes-sensei');
                } elseif ('activecourses' == $instance['component']) {
                    _e('You have no active courses.', 'woothemes-sensei');
                } elseif ('completedcourses' == $instance['component']) {
                    _e('You have no completed courses.', 'woothemes-sensei');
                } else {
                    _e('You have no courses.', 'woothemes-sensei');
                }
            }
            // end if compoenetn status instance
        }
        // End If Statement
    }
 /**
  * Deprecate the hook sensei_lesson_course_signup.
  *
  * The hook content will be linked directly on the recommended
  * sensei_single_lesson_content_inside_after
  *
  * @deprecated since 1.9.0
  */
 public static function deprecate_sensei_lesson_course_signup_hook()
 {
     $lesson_course_id = get_post_meta(get_the_ID(), '_lesson_course', true);
     $user_taking_course = Sensei_Utils::user_started_course($lesson_course_id, get_current_user_id());
     if (!$user_taking_course) {
         sensei_do_deprecated_action('sensei_lesson_course_signup', '1.9.0', 'sensei_single_lesson_content_inside_after', $lesson_course_id);
     }
 }
 /**
  * Display the leeson quiz status if it should be shown
  *
  * @param int $lesson_id defaults to the global lesson id
  * @param int $user_id defaults to the current user id
  *
  * @since 1.9.0
  */
 public static function user_lesson_quiz_status_message($lesson_id = 0, $user_id = 0)
 {
     $lesson_id = empty($lesson_id) ? get_the_ID() : $lesson_id;
     $user_id = empty($lesson_id) ? get_current_user_id() : $user_id;
     $lesson_course_id = (int) get_post_meta($lesson_id, '_lesson_course', true);
     $quiz_id = Sensei()->lesson->lesson_quizzes($lesson_id);
     $has_user_completed_lesson = Sensei_Utils::user_completed_lesson(intval($lesson_id), $user_id);
     if ($quiz_id && is_user_logged_in() && Sensei_Utils::user_started_course($lesson_course_id, $user_id)) {
         $no_quiz_count = 0;
         $has_quiz_questions = get_post_meta($lesson_id, '_quiz_has_questions', true);
         // Display lesson quiz status message
         if ($has_user_completed_lesson || $has_quiz_questions) {
             $status = Sensei_Utils::sensei_user_quiz_status_message($lesson_id, $user_id, true);
             echo '<div class="sensei-message ' . $status['box_class'] . '">' . $status['message'] . '</div>';
             if ($has_quiz_questions) {
                 // echo $status['extra'];
             }
             // End If Statement
         }
         // End If Statement
     }
 }
 /**
  * Grade quiz automatically
  *
  * This function grades each question automatically if there all questions are auto gradable. If not
  * the quiz will not be auto gradable.
  *
  * @since 1.7.4
  *
  * @param  integer $quiz_id         ID of quiz
  * @param  array $submitted questions id ans answers {
  *          @type int $question_id
  *          @type mixed $answer
  * }
  * @param  integer $total_questions Total questions in quiz (not used)
  * @param string $quiz_grade_type Optional defaults to auto
  *
  * @return int $quiz_grade total sum of all question grades
  */
 public static function grade_quiz_auto($quiz_id = 0, $submitted = array(), $total_questions = 0, $quiz_grade_type = 'auto')
 {
     if (!(intval($quiz_id) > 0) || !$submitted || $quiz_grade_type != 'auto') {
         return false;
         // exit early
     }
     $user_id = get_current_user_id();
     $lesson_id = Sensei()->quiz->get_lesson_id($quiz_id);
     $quiz_autogradable = true;
     /**
      * Filter the types of question types that can be automatically graded.
      *
      * This filter fires inside the auto grade quiz function and provides you with the default list.
      *
      * @param array {
      *      'multiple-choice',
      *      'boolean',
      *      'gap-fill'.
      * }
      */
     $autogradable_question_types = apply_filters('sensei_autogradable_question_types', array('multiple-choice', 'boolean', 'gap-fill'));
     $grade_total = 0;
     $all_question_grades = array();
     foreach ($submitted as $question_id => $answer) {
         // check if the question is autogradable, either by type, or because the grade is 0
         $question_type = Sensei()->question->get_question_type($question_id);
         $achievable_grade = Sensei()->question->get_question_grade($question_id);
         // Question has a zero grade, so skip grading
         if (0 == $achievable_grade) {
             $all_question_grades[$question_id] = $achievable_grade;
         } elseif (in_array($question_type, $autogradable_question_types)) {
             // Get user question grade
             $question_grade = Sensei_Utils::sensei_grade_question_auto($question_id, $question_type, $answer, $user_id);
             $all_question_grades[$question_id] = $question_grade;
             $grade_total += $question_grade;
         } else {
             // There is a question that cannot be autograded
             $quiz_autogradable = false;
         }
         // end if in_array( $question_type...
     }
     // end for each question
     // Only if the whole quiz was autogradable do we set a grade
     if ($quiz_autogradable) {
         $quiz_total = Sensei_Utils::sensei_get_quiz_total($quiz_id);
         // Check for zero total from grades
         if (0 < $quiz_total) {
             $grade = abs(round(doubleval($grade_total) * 100 / $quiz_total, 2));
         } else {
             $grade = 0;
         }
         Sensei_Utils::sensei_grade_quiz($quiz_id, $grade, $user_id, $quiz_grade_type);
     } else {
         $grade = new WP_Error('autograde', __('This quiz is not able to be automatically graded.', 'woothemes-sensei'));
     }
     // store the auto gradable grades. If the quiz is not auto gradable the grades can be use as the default
     // when doing manual grading.
     Sensei()->quiz->set_user_grades($all_question_grades, $lesson_id, $user_id);
     return $grade;
 }
Exemple #24
0
 /**
  * Delete all user activity when user is deleted
  * @param  integer $user_id User ID
  * @return void
  */
 public function delete_user_activity($user_id = 0)
 {
     if ($user_id) {
         Sensei_Utils::delete_all_user_activity($user_id);
     }
 }
Exemple #25
0
 /**
  * Sets the statuses for the Course
  *
  * @access public
  * @since  1.7.0
  * @param int $user_id
  * @param int $course_id
  * @param string $status
  * @param array $metadata
  * @return mixed false or comment_ID
  */
 public static function update_course_status($user_id, $course_id, $status = 'in-progress', $metadata = array())
 {
     $comment_id = false;
     if (!empty($status)) {
         $args = array('user_id' => $user_id, 'post_id' => $course_id, 'status' => $status, 'type' => 'sensei_course_status', 'action' => 'update', 'keep_time' => true);
         if ('in-progress' == $status) {
             unset($args['keep_time']);
             // Keep updating what's happened
         }
         $comment_id = Sensei_Utils::sensei_log_activity($args);
         if ($comment_id && !empty($metadata)) {
             foreach ($metadata as $key => $value) {
                 update_comment_meta($comment_id, $key, $value);
             }
         }
         do_action('sensei_course_status_updated', $status, $user_id, $course_id, $comment_id);
     }
     return $comment_id;
 }
/**
 * Returns the lesson status class
 *
 * must be used in the loop.
 * @since 1.9.0
 *
 * @return string $status_class
 */
function get_the_lesson_status_class()
{
    $status_class = '';
    $lesson_completed = Sensei_Utils::user_completed_lesson(get_the_ID(), get_current_user_id());
    if ($lesson_completed) {
        $status_class = 'completed';
    }
    return $status_class;
}
 /**
  * Calculate module progess for user
  *
  * @since 1.8.0
  *
  * @param  integer $user_id ID of user
  * @param  integer $module_id ID of module
  * @param  integer $course_id ID of course
  * @return integer            Module progress percentage
  */
 public function calculate_user_module_progress($user_id = 0, $module_id = 0, $course_id = 0)
 {
     $args = array('post_type' => 'lesson', 'post_status' => 'publish', 'posts_per_page' => -1, 'tax_query' => array(array('taxonomy' => $this->taxonomy, 'field' => 'id', 'terms' => $module_id)), 'meta_query' => array(array('key' => '_lesson_course', 'value' => $course_id)), 'fields' => 'ids');
     $lessons = get_posts($args);
     if (is_wp_error($lessons) || 0 >= count($lessons)) {
         return 0;
     }
     $completed = false;
     $lesson_count = 0;
     $completed_count = 0;
     foreach ($lessons as $lesson_id) {
         $completed = Sensei_Utils::user_completed_lesson($lesson_id, $user_id);
         ++$lesson_count;
         if ($completed) {
             ++$completed_count;
         }
     }
     $module_progress = $completed_count / $lesson_count * 100;
     return (double) $module_progress;
 }
 /**
  * Prepare the table with different parameters, pagination, columns and table elements
  * @since  1.7.0
  * @return void
  */
 public function prepare_items()
 {
     global $per_page, $wp_version;
     // Handle orderby
     $orderby = '';
     if (!empty($_GET['orderby'])) {
         if (array_key_exists(esc_html($_GET['orderby']), $this->get_sortable_columns())) {
             $orderby = esc_html($_GET['orderby']);
         }
         // End If Statement
     }
     // Handle order
     $order = 'DESC';
     if (!empty($_GET['order'])) {
         $order = 'ASC' == strtoupper($_GET['order']) ? 'ASC' : 'DESC';
     }
     // Handle search
     $search = false;
     if (!empty($_GET['s'])) {
         $search = esc_html($_GET['s']);
     }
     // End If Statement
     $this->search = $search;
     // Searching users on statuses requires sub-selecting the statuses by user_ids
     if ($this->search) {
         $user_args = array('search' => '*' . $this->search . '*', 'fields' => 'ID');
         // Filter for extending
         $user_args = apply_filters('sensei_grading_search_users', $user_args);
         if (!empty($user_args)) {
             $learners_search = new WP_User_Query($user_args);
             // Store for reuse on counts
             $this->user_ids = $learners_search->get_results();
         }
     }
     // End If Statement
     $per_page = $this->get_items_per_page('sensei_comments_per_page');
     $per_page = apply_filters('sensei_comments_per_page', $per_page, 'sensei_comments');
     $paged = $this->get_pagenum();
     $offset = 0;
     if (!empty($paged)) {
         $offset = $per_page * ($paged - 1);
     }
     // End If Statement
     $activity_args = array('type' => 'sensei_lesson_status', 'number' => $per_page, 'offset' => $offset, 'orderby' => $orderby, 'order' => $order, 'status' => 'any');
     if ($this->lesson_id) {
         $activity_args['post_id'] = $this->lesson_id;
     } elseif ($this->course_id) {
         // Currently not possible to restrict to a single Course, as that requires WP_Comment to support multiple
         // post_ids (i.e. every lesson within the Course), WP 4.1 ( https://core.trac.wordpress.org/changeset/29808 )
         if (version_compare($wp_version, '4.1', '>=')) {
             $activity_args['post__in'] = Sensei()->course->course_lessons($this->course_id, 'any', 'ids');
         }
     }
     // Sub select to group of learners
     if ($this->user_ids) {
         $activity_args['user_id'] = (array) $this->user_ids;
     }
     // Restrict to a single Learner
     if ($this->user_id) {
         $activity_args['user_id'] = $this->user_id;
     }
     switch ($this->view) {
         case 'in-progress':
             $activity_args['status'] = 'in-progress';
             break;
         case 'ungraded':
             $activity_args['status'] = 'ungraded';
             break;
         case 'graded':
             $activity_args['status'] = array('graded', 'passed', 'failed');
             break;
         case 'all':
         default:
             $activity_args['status'] = 'any';
             break;
     }
     // End switch
     $activity_args = apply_filters('sensei_grading_filter_statuses', $activity_args);
     // WP_Comment_Query doesn't support SQL_CALC_FOUND_ROWS, so instead do this twice
     $total_statuses = Sensei_Utils::sensei_check_for_activity(array_merge($activity_args, array('count' => true, 'offset' => 0, 'number' => 0)));
     // Ensure we change our range to fit (in case a search threw off the pagination) - Should this be added to all views?
     if ($total_statuses < $activity_args['offset']) {
         $new_paged = floor($total_statuses / $activity_args['number']);
         $activity_args['offset'] = $new_paged * $activity_args['number'];
     }
     $statuses = Sensei_Utils::sensei_check_for_activity($activity_args, true);
     // Need to always return an array, even with only 1 item
     if (!is_array($statuses)) {
         $statuses = array($statuses);
     }
     $this->total_items = $total_statuses;
     $this->items = $statuses;
     $total_items = $this->total_items;
     $total_pages = ceil($total_items / $per_page);
     $this->set_pagination_args(array('total_items' => $total_items, 'total_pages' => $total_pages, 'per_page' => $per_page));
 }
Exemple #29
0
        <?php 
    }
    // lessons count > 0
    ?>


        <h2 class="total-grade">

            <?php 
    _e('Total Grade', 'woothemes-sensei');
    ?>
            <span class="lesson-grade">

                <?php 
    $course_user_grade = Sensei_Utils::sensei_course_user_grade($course->ID, get_current_user_id());
    echo $course_user_grade . '%';
    ?>

            </span>

        </h2>

    </article>

    <?php 
    /**
     * Fires inside course-results/lessons.php after the
     * is uer logged check, at the bottom of all lessons.
     *
     * @since 1.4.0
Exemple #30
-1
 /**
  * Compare the user's subscriptions end date with the date
  * the user was added to the course. If the user was added after
  * the subscription ended they were manually added and this will return
  * true.
  *
  * Important to note that all subscriptions for the user is compared.
  *
  * @since 1.9.0
  *
  * @param $user_id
  * @param $product_id
  * @param $course_id
  *
  * @return bool
  */
 public static function was_user_added_without_subscription($user_id, $product_id, $course_id)
 {
     $course_start_date = '';
     $subscription_start_date = '';
     $is_a_subscription = '';
     $was_user_added_without_subscription = true;
     // if user is not on the course they were not added
     if (!Sensei_Utils::user_started_course($course_id, $user_id)) {
         return false;
     }
     // if user doesn't have a subscription and is taking the course
     // they were added manually
     if (!wcs_user_has_subscription($user_id, $product_id) && Sensei_Utils::user_started_course($course_id, get_current_user_id())) {
         return true;
     }
     $course_status = Sensei_Utils::user_course_status($course_id, $user_id);
     // comparing dates setup data
     $course_start_date = date_create($course_status->comment_date);
     $subscriptions = wcs_get_users_subscriptions($user_id);
     // comparing every subscription
     foreach ($subscriptions as $subscription) {
         // for the following statuses we know the user was not added
         // manually
         $status = $subscription->get_status();
         if (in_array($status, array('pending-canceled', 'active', 'on-hold', 'pending'))) {
             continue;
         }
         $current_subscription_start_date = date_create($subscription->modified_date);
         // is the last updated subscription date newer than course start date
         if ($current_subscription_start_date > $course_start_date) {
             return false;
         }
     }
     return $was_user_added_without_subscription;
 }