/** * 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); }
/** * 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 } }
/** * Start course for user * @since 1.4.8 * @param integer $user_id User ID * @param integer $course_id Course ID * @return mixed boolean or comment_ID */ public static function user_start_course($user_id = 0, $course_id = 0) { $activity_logged = false; if ($user_id && $course_id) { // Check if user is already on the Course $activity_logged = Sensei_Utils::user_started_course($course_id, $user_id); if (!$activity_logged) { // Add user to course $course_metadata = array('start' => current_time('mysql'), 'percent' => 0, 'complete' => 0); $activity_logged = Sensei_Utils::update_course_status($user_id, $course_id, $course_status = 'in-progress', $course_metadata); // Allow further actions if ($activity_logged) { do_action('sensei_user_course_start', $user_id, $course_id); } } } return $activity_logged; }
/** * Ouput the single lesson meta * * The function should only be called on the single lesson * */ function sensei_the_single_lesson_meta() { // if the lesson meta is included within theme load that instead of the function content $template = Sensei_Templates::locate_template('single-lesson/lesson-meta.php'); if (!empty($template)) { Sensei_Templates::get_template('single-lesson/lesson-meta.php'); return; } // Get the meta info $lesson_course_id = absint(get_post_meta(get_the_ID(), '_lesson_course', true)); $is_preview = Sensei_Utils::is_preview_lesson(get_the_ID()); // Complete Lesson Logic do_action('sensei_complete_lesson'); // Check that the course has been started if (Sensei()->access_settings() || Sensei_Utils::user_started_course($lesson_course_id, get_current_user_id()) || $is_preview) { ?> <section class="lesson-meta"> <?php if (apply_filters('sensei_video_position', 'top', get_the_ID()) == 'bottom') { do_action('sensei_lesson_video', get_the_ID()); } ?> <?php do_action('sensei_frontend_messages'); ?> <?php if (!$is_preview || Sensei_Utils::user_started_course($lesson_course_id, get_current_user_id())) { sensei_do_deprecated_action('sensei_lesson_quiz_meta', '1.9.0', 'sensei_single_lesson_content_inside_before', array(get_the_ID(), get_current_user_id())); } ?> </section> <?php do_action('sensei_lesson_back_link', $lesson_course_id); ?> <?php } do_action('sensei_lesson_meta_extra', get_the_ID()); }
/** * 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; }
/** * 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) . ' ' . __('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 }
/** * This function shows the WooCommerce cart notice if the user has * added the current course to cart. It does not show if the user is already taking * the course. * * @since 1.0.2 * @return void; */ public function sensei_woocommerce_in_cart_message() { global $post, $woocommerce; $wc_post_id = absint(get_post_meta($post->ID, '_course_woocommerce_product', true)); $user_course_status_id = Sensei_Utils::user_started_course($post->ID, get_current_user_id()); if (0 < intval($wc_post_id) && !$user_course_status_id) { if (Sensei_WC::is_product_in_cart($wc_post_id)) { echo '<div class="sensei-message info">' . sprintf(__('You have already added this Course to your cart. Please %1$s to access the course.', 'woothemes-sensei') . '</div>', '<a class="cart-complete" href="' . $woocommerce->cart->get_checkout_url() . '" title="' . __('complete the purchase', 'woothemes-sensei') . '">' . __('complete the purchase', 'woothemes-sensei') . '</a>'); } // End If Statement } // End If Statement }
/** * check_user_permissions function. * * @access public * @param string $page (default: '') * * @return bool */ public function check_user_permissions($page = '') { // REFACTOR global $current_user, $post; // if use 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 = $this->woocommerce_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 = $this->woocommerce_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 = $this->woocommerce_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; } return apply_filters('sensei_access_permissions', $user_allowed); }
/** * 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
/** * Output the course actions like start taking course, register, add to cart etc. * * @since 1.9.0 */ public static function the_course_enrolment_actions() { ?> <section class="course-meta course-enrolment"> <?php global $post, $current_user; $is_user_taking_course = Sensei_Utils::user_started_course($post->ID, $current_user->ID); if (is_user_logged_in() && !$is_user_taking_course) { // Get the product ID $wc_post_id = absint(get_post_meta($post->ID, '_course_woocommerce_product', true)); // Check for woocommerce if (Sensei_WC::is_woocommerce_active() && 0 < intval($wc_post_id)) { sensei_wc_add_to_cart($post->ID); } else { sensei_start_course_form($post->ID); } // End If Statement } elseif (is_user_logged_in()) { // Check if course is completed $user_course_status = Sensei_Utils::user_course_status($post->ID, $current_user->ID); $completed_course = Sensei_Utils::user_completed_course($user_course_status); // Success message if ($completed_course) { ?> <div class="status completed"><?php _e('Completed', 'woothemes-sensei'); ?> </div> <?php $has_quizzes = Sensei()->course->course_quizzes($post->ID, true); if (has_filter('sensei_results_links') || $has_quizzes) { ?> <p class="sensei-results-links"> <?php $results_link = ''; if ($has_quizzes) { $results_link = '<a class="view-results" href="' . Sensei()->course_results->get_permalink($post->ID) . '">' . __('View results', 'woothemes-sensei') . '</a>'; } /** * Filter documented in Sensei_Course::the_course_action_buttons */ $results_link = apply_filters('sensei_results_links', $results_link, $post->ID); echo $results_link; ?> </p> <?php } ?> <?php } else { ?> <div class="status in-progress"><?php echo __('In Progress', 'woothemes-sensei'); ?> </div> <?php } } else { // Get the product ID $wc_post_id = absint(get_post_meta($post->ID, '_course_woocommerce_product', true)); // Check for woocommerce if (Sensei_WC::is_woocommerce_active() && 0 < intval($wc_post_id)) { sensei_wc_add_to_cart($post->ID); } else { if (get_option('users_can_register')) { $my_courses_page_id = ''; /** * Filter to force Sensei to output the default WordPress user * registration link. * * @since 1.9.0 * @param bool $wp_register_link default false */ $wp_register_link = apply_filters('sensei_use_wp_register_link', false); $settings = Sensei()->settings->get_settings(); if (isset($settings['my_course_page']) && 0 < intval($settings['my_course_page'])) { $my_courses_page_id = $settings['my_course_page']; } // If a My Courses page was set in Settings, and 'sensei_use_wp_register_link' // is false, link to My Courses. If not, link to default WordPress registration page. if (!empty($my_courses_page_id) && $my_courses_page_id && !$wp_register_link) { $my_courses_url = get_permalink($my_courses_page_id); $register_link = '<a href="' . $my_courses_url . '">' . __('Register', 'woothemes-sensei') . '</a>'; echo '<div class="status register">' . $register_link . '</div>'; } else { wp_register('<div class="status register">', '</div>'); } } // end if user can register } // End If Statement } // End If Statement ?> </section><?php }
/** * 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); } }
/** * The quiz action buttons needed to ouput quiz * action such as reset complete and save. * * @since 1.3.0 */ public static function action_buttons() { global $post, $current_user; $lesson_id = (int) get_post_meta($post->ID, '_quiz_lesson', true); $lesson_course_id = (int) get_post_meta($lesson_id, '_lesson_course', true); $lesson_prerequisite = (int) get_post_meta($lesson_id, '_lesson_prerequisite', true); $show_actions = true; $user_lesson_status = Sensei_Utils::user_lesson_status($lesson_id, $current_user->ID); //setup quiz grade $user_quiz_grade = ''; if (!empty($user_lesson_status)) { $user_quiz_grade = get_comment_meta($user_lesson_status->comment_ID, 'grade', true); } if (intval($lesson_prerequisite) > 0) { // If the user hasn't completed the prereq then hide the current actions $show_actions = Sensei_Utils::user_completed_lesson($lesson_prerequisite, $current_user->ID); } if ($show_actions && is_user_logged_in() && Sensei_Utils::user_started_course($lesson_course_id, $current_user->ID)) { // Get Reset Settings $reset_quiz_allowed = get_post_meta($post->ID, '_enable_quiz_reset', true); ?> <!-- Action Nonce's --> <input type="hidden" name="woothemes_sensei_complete_quiz_nonce" id="woothemes_sensei_complete_quiz_nonce" value="<?php echo esc_attr(wp_create_nonce('woothemes_sensei_complete_quiz_nonce')); ?> " /> <input type="hidden" name="woothemes_sensei_reset_quiz_nonce" id="woothemes_sensei_reset_quiz_nonce" value="<?php echo esc_attr(wp_create_nonce('woothemes_sensei_reset_quiz_nonce')); ?> " /> <input type="hidden" name="woothemes_sensei_save_quiz_nonce" id="woothemes_sensei_save_quiz_nonce" value="<?php echo esc_attr(wp_create_nonce('woothemes_sensei_save_quiz_nonce')); ?> " /> <!--#end Action Nonce's --> <?php if ('' == $user_quiz_grade) { ?> <span><input type="submit" name="quiz_complete" class="quiz-submit complete" value="<?php _e('Complete Quiz', 'woothemes-sensei'); ?> "/></span> <span><input type="submit" name="quiz_save" class="quiz-submit save" value="<?php _e('Save Quiz', 'woothemes-sensei'); ?> "/></span> <?php } // End If Statement ?> <?php if (isset($reset_quiz_allowed) && $reset_quiz_allowed) { ?> <span><input type="submit" name="quiz_reset" class="quiz-submit reset" value="<?php _e('Reset Quiz', 'woothemes-sensei'); ?> "/></span> <?php } ?> <?php } }
<a href="<?php the_permalink(); ?> " title="<?php the_title_attribute(); ?> " > <?php the_title(); ?> <?php $course_id = Sensei()->lesson->get_course_id(get_the_ID()); if (Sensei_Utils::is_preview_lesson(get_the_ID()) && !Sensei_Utils::user_started_course($course_id, get_current_user_id())) { ?> <span class="preview-label"><?php _e('Free Preview', 'woothemes-sensei'); ?> </span> <?php } ?> </a> </li>
/** * 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; }