shiftlessatol
Forum Replies Created
Viewing 3 replies - 1 through 3 (of 3 total)
-
Forum: Plugins
In reply to: [CoursePress Learning Management System] Cannot Retry or Retake AssessmentsStill doesn’t work on Latest Version ( May 28th, 2018) | Version 2.2.0 |
I’m including the updated file belowwp-content/plugins/coursepress/2.0/include/coursepress/template/class-module.php
<?php /** * Use to print the different modules. * * @package WordPress * @subpackage CoursePress **/ class CoursePress_Template_Module { private static $args = array(); protected static $student_progress = array(); /** * Helper function get module attributes. **/ protected static function attributes( $module_id ) { return CoursePress_Data_Module::attributes( $module_id ); } /** * Helper function to quickly retrieve student response **/ protected static function get_response( $module_id, $student_id, $all = false ) { $unit_id = get_post_field( 'post_parent', $module_id ); $course_id = get_post_field( 'post_parent', $unit_id ); $response = CoursePress_Data_Student::get_response( $student_id, $course_id, $unit_id, $module_id ); if ( false === $all && isset( $response['response'] ) ) { $response = $response['response']; } return $response; } public static function get_student_answer( $module_id, $student_id ) { $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $unit_id = get_post_field( 'post_parent', $module_id ); $course_id = get_post_field( 'post_parent', $unit_id ); $content = ''; $response = self::get_response( $module_id, $student_id ); switch ( $module_type ) { case 'input-checkbox': case 'input-radio': case 'input-select': $answers = $attributes['answers']; $selected = $attributes['answers_selected']; $content .= '<ul class="cp-answers">'; // $selected is of string type, change it to int $ints = array_fill( 0, 10, true ); if ( ! is_array( $selected ) && ! empty( $ints[ $selected ] ) ) { $selected = (int) $selected; } foreach ( $answers as $key => $answer ) { if ( 'input-checkbox' !== $module_type ) { $the_answer = $selected === $key || $selected === $answer; $student_answer = $response == $key || $response === $answer; } else { $the_answer = in_array( $key, $selected ); $student_answer = is_array( $response ) ? in_array( $key, $response ) : $response == $key; } if ( $student_answer ) { if ( $the_answer ) { $answer = '<span class="chosen-answer correct"></span>' . $answer; } else { $answer = '<span class="chosen-answer incorrect"></span>' . $answer; } $content .= sprintf( '<li>%s</li>', $answer ); } } $content .= '</ul>'; break; case 'input-textarea': case 'input-text': if ( ! empty( $response ) ) { $content .= sprintf( '<div class="cp-answer-box">%s</div>', $response ); } break; case 'input-upload': if ( ! empty( $response['url'] ) ) { $url = $response['url']; $filename = basename( $url ); $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?fdcpf=' . $url; $content .= sprintf( '<a href="%s" class="button-primary cp-download">%s</a>', esc_url( $url ), $filename ); } break; case 'input-quiz': if ( is_admin() ) { if ( ! empty( $attributes['questions'] ) ) { $questions = $attributes['questions']; foreach ( $questions as $q_index => $question ) { $options = (array) $question['options']; $checked = (array) $options['checked']; $checked = array_filter( $checked ); $student_response = $response[ $q_index ]; $content .= sprintf( '<div class="cp-q"><hr /><p class="description cp-question">%s</p><ul>', esc_html( $question['question'] ) ); foreach ( $options['answers'] as $p_index => $answer ) { $the_answer = isset( $checked[ $p_index ] ) ? $checked[ $p_index ] : false; $student_answer = ''; if ( isset( $student_response[ $p_index ] ) && $student_response[ $p_index ] ) { $student_answer = $student_response[ $p_index ]; if ( $the_answer ) { $student_answer = '<span class="chosen-answer correct"></span>'; } else { $student_answer = '<span class="chosen-answer incorrect"></span>'; } $content .= '<li>' . $student_answer . esc_html( $answer ) . '</li>'; } } $content .= '</ul></div>'; } } } else { $content .= self::quiz_result_content( $student_id, $course_id, $unit_id, $module_id ); } break; case 'input-form': if ( ! empty( $attributes['questions'] ) ) { $questions = $attributes['questions']; foreach ( $questions as $q_index => $question ) { $student_response = ! empty( $response[ $q_index ] ) ? $response[ $q_index ] : ''; $format = '<div class="cp-q"><hr /><p class="description cp-question">%s</p>'; $content .= sprintf( $format, esc_html( $question['question'] ) ); $content .= '<ul>'; if ( 'selectable' == $question['type'] ) { $options = $question['options']['answers']; $checked = $question['options']['checked']; foreach ( $options as $ai => $answer ) { if ( $student_response == $ai ) { $the_answer = ! empty( $checked[ $ai ] ); if ( $the_answer === $student_response ) { $student_answer = '<span class="chosen-answer correct"></span>'; } else { $student_answer = '<span class="chosen-answer incorrect"></span>'; } $content .= sprintf( '<li>%s %s</li>', $student_answer, $answer ); } } } else { $content .= sprintf( '<li>%s</li>', esc_html( $student_response ) ); } $content .= '</ul></div>'; } } break; } /** * Filter the student response template. **/ $content = apply_filters( 'coursepress_student_reponse_template', $content, $module_id, $module_type ); return $content; } public static function get_module_status( $module_id, $student_id ) { $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $assessables = array( 'input-text', 'input-textarea', 'input-upload', 'input-form' ); $response = self::get_response( $module_id, $student_id, true ); $grades = (array) CoursePress_Helper_Utility::get_array_val( $response, 'grades' ); $grades = array_pop( $grades ); $grade = (int) CoursePress_Helper_Utility::get_array_val( $grades, 'grade' ); $minimum_grade = (int) $attributes['minimum_grade']; $require_assessment = false; $pass = $grade >= $minimum_grade; $status = ''; if ( in_array( $module_type, $assessables ) ) { if ( ! empty( $attributes['assessable'] ) ) { $graded_by = CoursePress_Helper_Utility::get_array_val( $grades, 'graded_by' ); if ( 'auto' === $graded_by || empty( $grades ) ) { $status = __( 'Pending', 'coursepress' ); } elseif ( $pass ) { $status = __( 'Pass', 'coursepress' ); } else { $status = __( 'Failed', 'coursepress' ); } } else { $status = __( 'Non Gradable', 'coursepress' ); } } else { $status = $pass ? __( 'Pass', 'coursepress' ) : __( 'Fail', 'coursepress' ); } return $status; } /** * * @param integer $module_id Modile ID. * @param boolean $is_focus Is in focus mode? * @param string $view_type View type, possible values "normal", "preview" @since 2.0.4 */ public static function template( $module_id = 0, $is_focus = false, $view_type = 'normal' ) { if ( empty( $module_id ) ) { return ''; // Nothing to process, bail! } $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $is_required = ! empty( $attributes['mandatory'] ); $method = 'render_' . str_replace( '-', '_', $module_type ); $module = get_post( $module_id ); $unit_id = $module->post_parent; $course_id = get_post_field( 'post_parent', $unit_id ); $course_status = CoursePress_Data_Course::get_course_status( $course_id ); $is_module_answerable = preg_match( '%input-%', $module_type ) || 'video' === $module_type; $disabled = false; $element_class = array(); $student_id = get_current_user_id(); $content = '<div class="module-container">'; /** * Fire before the module template is printed * * @since 2.0 * * @param (int) $module_id The WP_Post object ID. * @param (int) $student_id Current user ID. **/ do_action( 'coursepress_module_view', $module_id, $student_id ); // Marked module and page as visited $module_page = get_post_meta( $module_id, 'module_page', true ); CoursePress_Data_Student::visited_module( $student_id, $course_id, $unit_id, $module_id ); CoursePress_Data_Student::visited_page( $student_id, $course_id, $unit_id, $module_page ); $content .= sprintf( '<input type="hidden" name="course_id" value="%s" />', $course_id ); $content .= sprintf( '<input type="hidden" name="unit_id" value="%s" />', $unit_id ); $content .= sprintf( '<input type="hidden" name="student_id" value="%s" />', $student_id ); $content .= sprintf( '<input type="hidden" name="module_id[]" value="%s" />', $module_id ); if ( $is_focus ) { $content .= wp_nonce_field( 'coursepress_submit_modules', '_wpnonce', true, false ); $content .= sprintf( '<div class="cp-error">%s</div>', apply_filters( 'coursepress_before_unit_modules', '' ) ); } // Module header $content .= self::render_module_head( $module, $attributes ); // The question or text content $content .= self::_wrap_content( $module->post_content ); if ( method_exists( __CLASS__, $method ) ) { // Get student progress if it is not retrieve yet if ( empty( self::$student_progress ) ) { $student_progress = self::$student_progress = CoursePress_Data_Student::get_completion_data( $student_id, $course_id ); } else { $student_progress = self::$student_progress; } // Record module visit CoursePress_Data_Student::visited_module( $student_id, $course_id, $unit_id, $module_id, self::$student_progress ); $retry = 'TRY'; $element_class = array( 'module-elements' ); if ( $is_module_answerable ) { $responses = CoursePress_Data_Student::get_responses( $student_id, $course_id, $unit_id, $module_id, true, $student_progress ); $last_response = self::get_response( $module_id, $student_id ); if ( ! empty( $responses ) ) { $element_class[] = 'hide'; } // Set value to 1 only if not attempted this module. $is_module_hidden = empty( $responses ) ? 0 : 1; // Add a hidden field to track if student really submitted the form. $content .= sprintf( '<input type="hidden" class="cp-is-hidden-module" name="is_module_hidden[%s]" value="%s" />', $module_id, $is_module_hidden ); $response_count = ! empty( $responses ) ? count( $responses ) : 0; // Get recorded time lapsed $keys = array( $course_id, $unit_id, $module_id, $student_id ); $key = 'response_' . implode( '_', $keys ); $lapses = (int) get_user_meta( $student_id, $key, true ); $response_count += $lapses; $try_again_label = __( 'Try Again', 'coursepress' ); switch ( $module_type ) { case 'input-upload': $try_again_label = __( 'Upload a different file', 'coursepress' ); break; } $retry = sprintf( '<p class="cp-try-again"><a data-module="%s" onclick="javascript:ShowQuiz(%s);" class="button module-submit-action button-reload-module">%s</a></p>', $module_id,$module_id, $try_again_label ); // Check if retry is disabled if ( empty( $attributes['allow_retries'] ) ) { $retry = ''; } elseif ( ! empty( $attributes['retry_attempts'] ) && 0 < $response_count ) { $attempts = (int) $attributes['retry_attempts']; // Retries + 1 normal attempt. if ( $response_count > $attempts ) { $disabled = true; $retry = ''; } else { $retry .= sprintf( '<p class="number-of-fails">%s</p>', sprintf( __( 'Number of failed attempts: %d', 'coursepress' ), $response_count ) ); } } if ( ! empty( $attributes['use_timer'] ) && ! empty( $attributes['duration'] ) ) { $allow_retry = true; $attempts = (int) $attributes['retry_attempts']; $duration = $attributes['duration']; $dur = explode( ':', $duration ); /** * sanitize time format */ switch ( sizeof( $dur ) ) { case 1: $duration = sprintf( '00:%02d', $dur[0] ); break; case 2: $duration = sprintf( '%02d:%02d', $dur[0], $dur[1] ); break; case 3: $duration = sprintf( '%02d:%02d:%02d', $dur[0], $dur[1], $dur[2] ); break; } $format = '<span class="quiz_timer" data-limit="%1$s" data-retry="%2$s">%1$s</span><span class="quiz_timer_info">%3$s</span>'; if ( empty( $retry ) ) { $attempts = 'no'; if ( $response_count > 0 ) { $duration = '00:00:00'; } } $timer_info = __( 'Session Expired', 'coursepress' ) . $retry; $content .= sprintf( $format, $duration, $attempts, $timer_info ); } } if ( 'closed' == $course_status ) { $disabled = true; $retry = ''; } $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $module_elements = call_user_func( array( __CLASS__, $method ), $module, $attributes, $student_progress ); if ( $is_module_answerable && 'preview' == $view_type ) { $module_elements = ''; } switch ( $module_type ) { case 'input-quiz'; $module_elements = sprintf( '<div class="module-quiz-questions">%s</div>', $module_elements ); break; } $element_class[] = sprintf( 'module-type-%s', $module_type ); $module_elements = sprintf( '<div id="cp-element-%s" class="%s" data-type="%s" data-required="%s">%s</div>', $module_id, implode( ' ', $element_class ), $module_type, $is_required, $module_elements ); if ( $is_module_answerable && ! empty( $responses ) ) { $status = self::get_module_status( $module->ID, $student_id ); if ( 'Pass' == $status ) { $retry = ''; } $student_answers = sprintf( '<span class="cp-status status-%s">%s</span>', strtolower( $status ), $status ); $student_answers = sprintf( '<div class="cp-student-status">%s</div>', $student_answers ); $student_answers .= self::get_student_answer( $module->ID, $student_id ); $student_answers .= $retry; $module_elements .= sprintf( '<div id="cp-response-%s" class="module-response">%s</div>', $module_id, $student_answers ); } if ( 'closed' == $course_status ) { $format = '<div class="module-warnings"><p>%s</p></div>'; $module_warning = sprintf( $format, esc_html__( 'This course is completed, you can not submit answers anymore.', 'coursepress' ) ); /** * Filter the warning message. * * @since 2.0 **/ $module_elements .= apply_filters( 'coursepress_course_readonly_message', $module_warning, $module_id, $course_id ); } /** * custom wrappers */ switch ( $module_type ) { case 'discussion': $module_elements = sprintf( '<div id="comments" class="comments-area"><div class="comments-list-container">%s</div></div>', $module_elements ); break; } /** * Filter the module elements template. * * @since 2.0 **/ $content .= apply_filters( 'coursepress_module_template', $module_elements, $module_type, $module_id ); /** * Filter the module container classes * * @since 2.0.6 **/ $module_container_classes = apply_filters( 'coursepress_module_container_classes', array( 'cp-module-content' ), $module_type, $module_id ); $content = sprintf( '<div class="%4$s" data-type="%1$s" data-id="%2$s" id="cp-module-%2$s">%3$s</div>', esc_attr( $module_type ), esc_attr( $module_id ), $content, esc_attr( implode( ' ', $module_container_classes ) ) ); } /** * div.module-container */ $content .= '</div>'; return $content; } /** * Module header **/ private static function render_module_head( $module, $attributes = false ) { if ( false === $module || empty( $module ) ) { return; // Bail } $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $content = ''; $show_title = ! empty( $attributes['show_title'] ); $mandatory = ! empty( $attributes['mandatory'] ); if ( $show_title ) { $content .= '<h4 class="module-title">'; $content .= $module->post_title; if ( $mandatory ) { $content .= sprintf( '<span class="is-mandatory">%s</span>', __( 'Required', 'coursepress' ) ); } $content .= '</h4>'; } else if ( $mandatory ) { $content .= sprintf( '<div class="is-mandatory">%s</div>', __( 'Required', 'coursepress' ) ); } $format = '<div class="module-header module %1$s module-%2$s %3$s" data-type="%1$s" data-module="%2$s">%4$s</div>'; $content = sprintf( $format, $attributes['module_type'], $module->ID, $attributes['mode'], $content ); /** * Filter the module header template. * * @since 2.0 **/ $content = apply_filters( 'coursepress_module_header', $content, $module ); return $content; } public static function render_image( $module, $attributes = false ) { $content = self::do_caption_media( $attributes ); return $content; } /** * @param $data * @param null|WP_Post $module * @return string */ private static function do_caption_media( $data, $module = null ) { if ( empty( $data['image_url'] ) && empty( $data['video_url'] ) ) { return ''; } $the_caption = ''; $alt_text = ''; $media_width = ''; $type = $data['module_type']; if ( 'video' === $type ) { $url = $data['video_url']; } if ( 'image' === $type ) { $url = $data['image_url']; } $caption_source = isset( $data['caption_field'] ) ? $data['caption_field'] : 'media'; $attachment = CoursePress_Helper_Utility::attachment_from_url( $url ); if ( 'media' === $caption_source ) { if ( ! empty( $attachment ) ) { $alt_text = CoursePress_Helper_Utility::filter_content( get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ) ); if ( empty( $alt_text ) ) { $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } $meta = wp_get_attachment_metadata( $attachment->ID ); $media_width = $meta['width']; $the_caption = $attachment->post_excerpt; } else { $the_caption = ''; $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } } else { $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; global $content_width; if ( ! empty( $content_width ) ) { $media_width = $content_width; } else { $media_width = get_option( 'large_size_w' ); } // Get the custom caption text $the_caption = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } $html = ''; $show_caption = isset( $data['show_media_caption'] ) ? cp_is_true( $data['show_media_caption'] ) : false; if ( ! empty( $attachment ) ) { $attachment_id = ' id="attachment_' . $attachment->ID . '" '; } else { $attachment_id = ' id="attachment_' . time() . '" '; } if ( 'image' === $type ) { if ( $show_caption ) { $html .= '<div class="image_holder">'; $img = '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $alt_text ) . '" />'; $html .= do_shortcode( '[caption width="' . $media_width . '"' . $attachment_id . ']' . $img . ' ' . $the_caption . '[/caption]' ); $html .= '</div>'; } else { $html .= '<div class="image_holder">'; $html .= '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $alt_text ) . '" />'; $html .= '</div>'; } } if ( 'video' === $type ) { $player_width = CoursePress_Helper_Utility::get_array_val( $data, 'video_player_width' ); $player_width = $player_width ? $player_width : '640'; $player_height = CoursePress_Helper_Utility::get_array_val( $data, 'video_player_height' ); $player_height = $player_height ? $player_height : '360'; $autoplay = CoursePress_Helper_Utility::get_array_val( $data, 'video_autoplay' ) ? 'autoplay' : ''; $loop = CoursePress_Helper_Utility::get_array_val( $data, 'video_loop' ) ? 'loop' : ''; $controls = CoursePress_Helper_Utility::get_array_val( $data, 'video_hide_controls' ) ? '' : 'controls'; $module_video_id = isset( $module->ID ) ? 'module-video-' . $module->ID : ''; ob_start(); ?> <video id="<?php echo $module_video_id; ?>" class="video-js vjs-default-skin vjs-big-play-centered" width="<?php echo $player_width; ?>" height="<?php echo $player_height; ?>" src="<?php echo $url; ?>" data-setup='<?php echo CoursePress_Helper_Utility::create_video_js_setup_data( $url, $data ); ?>' <?php echo $controls; ?> <?php echo $autoplay; ?> <?php echo $loop; ?>> </video> <?php $video = ob_get_clean(); if ( $show_caption ) { $html .= '<div class="video_holder">'; $html .= '<figure ' . $attachment_id . ' class="wp-caption" style="width: ' . $media_width . 'px;">'; $html .= '<div class="video_player">'; $html .= $video; $html .= '</div>'; if ( ! empty( $the_caption ) ) { $html .= '<figcaption class="wp-caption-text">' . $the_caption . '</figcaption>'; } $html .= '</figure>'; $html .= '</div>'; } else { $html .= '<div class="video_player">'; $html .= $video; $html .= '</div>'; } } return $html; } public static function render_video( $module, $attributes = false ) { $content = self::do_caption_media( $attributes, $module ); return $content; } public static function render_audio( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['audio_url'] ) ) { $loop = isset( $attributes['loop'] ) ? cp_is_true( $attributes['loop'] ) : false; $autoplay = isset( $attributes['autoplay'] ) ? cp_is_true( $attributes['autoplay'] ) : false; $attr = array( 'src' => $attributes['audio_url'], 'loop' => $loop, 'autoplay' => $autoplay, ); $content .= '<div class="module-content"> <div class="audio_player"> ' . wp_audio_shortcode( $attr ) . ' </div> </div> '; } return $content; } public static function render_download( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['file_url'] ) ) { $url = $attributes['file_url']; $file_size = CoursePress_Helper_Utility::get_file_size( $url ); if ( $file_size > 0 ) { $filesize = '<small>(' . esc_html( $file_size ) . ')</small>'; } else { $filesize = ''; } $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?fdcpf=' . $url; $link_text = isset( $attributes['link_text'] ) ? $attributes['link_text'] : $module->post_title; $after_content = sprintf( '<div class="file_holder"><a href="%s">%s <span class="file-size">%s</span></a></div>', esc_url( $url ), esc_html( $link_text ), CoursePress_Helper_Utility::filter_content( $filesize ) ); $content .= $after_content; } return $content; } public static function render_zipped( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['zip_url'] ) && ! empty( $attributes['primary_file'] ) ) { $url = $attributes['zip_url']; $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?oacpf=' . $url . '&module=' . $module->ID . '&file=' . $attributes['primary_file']; $link_text = isset( $attributes['link_text'] ) ? $attributes['link_text'] : $module->post_title; $after_content = sprintf( '<div class="zip_holder"><a href="%s">%s</a></div>', esc_url( $url ), esc_html( $link_text ) ); $content .= $after_content; } elseif ( empty( $attributes['primary_file'] ) ) { $content .= sprintf( '<div class="zip_holder error">%s</div>', __( 'Primary File not set, please come back later.', 'coursepress' ) ); } return $content; } public static function render_section( $module, $attributes = false ) { return '<hr />'; } private static function comment_form( $post_id, $attributes = false ) { if ( ! is_user_logged_in() ) { return ''; } $enrolled = false; $student_id = get_current_user_id(); $course_id = CoursePress_Data_Module::get_course_id_by_module( $post_id ); $enrolled = CoursePress_Data_Course::student_enrolled( $student_id, $course_id ); /** * Instructor as enrolled user. */ if ( false == $enrolled ) { $instructors = array_filter( CoursePress_Data_Course::get_instructors( $course_id ) ); if ( in_array( $student_id, $instructors ) ) { $enrolled = true; } } /** * Author as enrolled user. */ if ( false == $enrolled ) { $enrolled = CoursePress_Data_Capabilities::can_update_course( $course_id ); } if ( false == $enrolled ) { return ''; } $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; ob_start(); $form_class = array( 'comment-form', 'cp-comment-form' ); $comment_order = get_option( 'comment_order' ); $form_class[] = 'comment-form-' . $comment_order; $args = array( 'class_form' => implode( ' ', $form_class ), 'title_reply' => __( 'Post Here', 'coursepress' ), 'label_submit' => __( 'Post', 'coursepress' ), 'must_log_in' => '', 'logged_in_as' => '', 'action' => '', 'class_submit' => 'submit cp-comment-submit', 'comment_field' => '<p class="comment-form-comment"><textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525"></textarea></p>', ); /** * Comment form args filter. * * @since 2.0.8 */ $args = apply_filters( 'coursepress_comment_form_args', false ); add_filter( 'comment_form_submit_button', array( 'CoursePress_Template_Discussion', 'add_subscribe_button' ) ); comment_form( $args, $post_id ); $comment_form = ob_get_clean(); $comment_form = str_replace( array( '<form', '</form>' ), array( '<div', '</div>' ), $comment_form ); /** * remove required="required" from textarea */ $mandatory = false; if ( isset( $attributes['mandatory'] ) ) { $mandatory = cp_is_true( $attributes['mandatory'] ); } if ( false === $mandatory ) { $pattern = '/(<textarea[^>]+>)/'; preg_match( $pattern, $comment_form, $matches ); if ( 2 == sizeof( $matches ) ) { $replacement = $matches[1]; $replacement = preg_replace( '/ required(="[^"]+")?/', '', $replacement ); $replacement = preg_replace( '/ aria-required="true"/', '', $replacement ); $comment_form = preg_replace( $pattern, $replacement, $comment_form ); } } remove_filter( 'comment_form_submit_button', array( 'CoursePress_Template_Discussion', 'add_subscribe_button' ) ); return $comment_form; } public static function comment_list( $module_id ) { ob_start(); $comments = get_comments( array( 'post_id' => $module_id, ) ); $args = array( 'style' => 'ol', 'short_ping' => true, 'avatar_size' => 42, ); /** * Comment list arguments filter. * * @since 2.0.8 */ $args = apply_filters( 'coursepress_comment_list_args', $args ); ?> <ol class="comment-list"> <?php wp_list_comments( $args, $comments ); ?> </ol><!-- .comment-list --> <?php $comment_list = ob_get_clean(); return $comment_list; } public static function discussion_url( $post_id ) { $unit_id = get_post_field( 'post_parent', $post_id ); $unit_url = CoursePress_Data_Unit::get_unit_url( $unit_id ); $page_number = get_post_meta( $post_id, 'page_number', true ); $page_number = max( $page_number, 1 ); $url = sprintf( '%spage/%s/module_id/%s', $unit_url, $page_number, $post_id ); return $url; } public static function comment_reply_link( $link, $args, $comment, $post ) { $discussion_link = self::discussion_url( $post->ID ); $discussion_link = add_query_arg( 'replytocom', $comment->comment_ID, $discussion_link ); $discussion_link .= '#respond'; $link = preg_replace( '%href=([\'"])(.*?)([\'"])%', 'href=$1' . $discussion_link . '$3', $link ); $link = sprintf( '<div data-comid="%s" data-parentid="%s">%s</div>', $comment->comment_ID, $post->ID, $link ); return $link; } public static function render_discussion( $module, $attributes = false ) { global $post; $post = $module; // Add comment filters add_filter( 'comments_open', '__return_true' ); add_filter( 'comment_reply_link', array( __CLASS__, 'comment_reply_link' ), 10, 4 ); setup_postdata( $module ); $content = ''; $content .= self::comment_form( $module->ID, $attributes ); $content .= self::comment_list( $module->ID ); // Remove comment filters, etc wp_reset_postdata(); remove_filter( 'comments_open', '__return_true' ); remove_filter( 'comment_reply_link', array( __CLASS__, 'comment_reply_link' ), 10, 4 ); return $content; } public static function render_input_checkbox( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = true === $disabled ? 'disabled="disabled"' : ''; $oddeven = 'odd'; $alt = ''; $response = self::get_response( $module->ID, get_current_user_id() ); $content .= '<ul class="quiz-question quiz-question-checkbox">'; foreach ( $attributes['answers'] as $key => $answer ) { $checked = ' ' . checked( 1, is_array( $response ) && in_array( $key, $response ), false ); $format = '<li class="%1$s %2$s"><input type="checkbox" value="%5$s" name="module[%3$s][]" id="module-%3$s-%5$s" %6$s /> <label for="module-%3$s-%5$s">%4$s</label></li>'; $content .= sprintf( $format, $oddeven, $alt, $module->ID, $answer, esc_attr( $key ), $disabled_attr . $checked ); $oddeven = 'odd' === $oddeven ? 'even' : 'odd'; } $content .= '</ul>'; } return $content; } public static function render_input_radio( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $oddeven = 'odd'; $alt = ''; $response = self::get_response( $module->ID, get_current_user_id() ); $content .= '<ul class="quiz-question quiz-question-radio">'; foreach ( $attributes['answers'] as $key => $answer ) { $checked = '' !== $response ? ' ' . checked( 1, '' != $response && (int) $response === $key, false ) : ''; $format = '<li class="%1$s %2$s"><input type="radio" value="%5$s" name="module[%3$s]" id="module-%3$s-%5$s" %6$s /> <label for="module-%3$s-%5$s">%4$s</label> </li>'; $content .= sprintf( $format, $oddeven, $alt, $module->ID, $answer, esc_attr( $key ), $disabled_attr . $checked ); $oddeven = 'odd' === $oddeven ? 'even' : 'odd'; $alt = empty( $alt ) ? 'alt' : ''; } $content .= '</ul>'; } return $content; } public static function render_input_select( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $options = ''; $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['answers'] as $key => $answer ) { $options .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( 1, $response == $key, false ), esc_html( $answer ) ); } $content .= sprintf( '<select class="wide" name="module[%s]" %s>%s</select>', $module->ID, $disabled_attr, $options ); } return $content; } public static function render_input_text( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $placeholder_text = get_post_meta( $module->ID, 'placeholder_text', true ); $placeholder_text = ! empty( $placeholder_text ) ? $placeholder_text : ''; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<input type="text" name="module[%s]" placeholder="%s" value="%s" %s />'; $content = sprintf( $format, $module->ID, esc_attr( $placeholder_text ), esc_attr( $response ), $disabled_attr ); return $content; } public static function render_input_textarea( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $placeholder_text = get_post_meta( $module->ID, 'placeholder_text', true ); $placeholder_text = ! empty( $placeholder_text ) ? $placeholder_text : ''; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<textarea name="module[%s]" placeholder="%s" %s rows="3">%s</textarea>'; $content = sprintf( $format, $module->ID, esc_attr( $placeholder_text ), $disabled_attr, esc_textarea( $response ) ); return $content; } public static function render_input_upload( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<label class="file"><input type="file" name="module[%s]" %s /><span class="button" data-change="%s" data-upload="%s">%s <span class="upload-progress"></span></label>'; $content = sprintf( $format, $module->ID, $disabled_attr, __( 'Change File', 'coursepress' ), __( 'Upload File', 'coursepress' ), __( 'Upload File', 'coursepress' ) ); $upload_types = CoursePress_Helper_Utility::allowed_student_mimes(); $upload_types = array_map( 'strtoupper', array_keys( $upload_types ) ); $format = '<div class="cp-sub"><p>%s %s</p><p>%s %s</p></div>'; $content .= sprintf( $format, __( 'Accepted File Format: ', 'coursepress' ), implode( ' ', $upload_types ), __( 'Max File Size:', 'coursepress' ), ini_get( 'upload_max_filesize' ) ); return $content; } public static function render_input_quiz( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $content = ''; if ( ! empty( $attributes['questions'] ) ) { $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['questions'] as $qi => $question ) { $questions = '<ul class="quiz-question quiz-question-input">'; foreach ( $question['options']['answers'] as $ai => $answer ) { $module_name = sprintf( 'module[%s][%s]', $module->ID, $qi ); $quiz_id = 'quiz-module-' . $module->ID . '-' . $qi . '-' . $ai; $type = 'radio'; if ( 'multiple' == $question['type'] ) { $type = 'checkbox'; $module_name .= '[]'; } $checked = ' '; if ( is_array( $response ) && ! empty( $response[ $qi ] ) ) { $checked .= checked( 1, ! empty( $response[ $qi ][ $ai ] ), false ); } $format = '<li><input type="%3$s" id="%1$s" name="%4$s" value="%5$s" %6$s/> <label for="%1$s">%2$s</label></li>'; $questions .= sprintf( $format, $quiz_id, esc_html( $answer ), $type, $module_name, $ai, $disabled_attr . $checked ); } $questions .= '</ul>'; $questions = sprintf( '<p class="question">%s</p>%s', esc_html( $question['question'] ), $questions ); $container_format = '<div class="module-quiz-question question-%s" data-type="%s">%s</div>'; $content .= sprintf( $container_format, $qi, $question['type'], $questions ); } } /** * Filter allow to cange questions in input quiz. * * @since 2.0.6 * * @param string $questions Quiz module questions. */ $content = apply_filters( 'coursepress_template_module_render_input_quiz_content', $content ); return $content; } public static function render_input_form( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $content = ''; $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['questions'] as $qi => $question ) { $field_id = 'form-module-' . $module->ID . '-' . $qi; $label = sprintf( '<label for="%s">%s</label>', $field_id, esc_html( $question['question'] ) ); switch ( $question['type'] ) { case 'short': $value = ! empty( $response[ $qi ] ) ? $response[ $qi ] : ''; $field = '<input type="text" name="module[%s][%s]" placeholder="%s" id="%s" value="%s" %s />'; $field = sprintf( $field, $module->ID, $qi, esc_attr( $question['placeholder'] ), $field_id, esc_attr( $value ), $disabled_attr ); break; case 'long': $value = ! empty( $response[ $qi ] ) ? $response[ $qi ] : ''; $field = '<textarea name="module[%s][%s]" placeholder="%s" id="%s" %s>%s</textarea>'; $field = sprintf( $field, $module->ID, $qi, esc_attr( $question['placeholder'] ), $field_id, $disabled_attr, esc_textarea( $value ) ); break; case 'selectable': $options = ''; foreach ( $question['options']['answers'] as $ai => $answer ) { $selected = selected( 1, isset( $response[ $qi ] ) && $response[ $qi ] == $ai, false ); $options .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $ai ), $selected, $answer ); } $field = '<select class="wide" name="module[%s][%s]" id="%s" %s>%s</select>'; $field = sprintf( $field, $module->ID, $qi, $field_id, $disabled_attr, $options ); break; } $container_format = '<div class="module-quiz-question question-%s" data-type="%s">%s</div>'; $content .= sprintf( $container_format, $qi, $question['type'], $label . $field ); } return $content; } /** * Chat Module **/ public static function render_chat( $module, $attributes = false, $student_progress = false, $disabled = false ) { if ( cp_is_chat_plugin_active() ) { $content = sprintf( '<div class="cp-chat-module">[chat id="%s"]</div>', $module->ID ); $content = do_shortcode( $content ); return $content; } return ''; } /** * Wrap Content by div, apply filter and shortcodes. * * @access private * * @since 2.0.0 * * @param string $content Content to wrap. * @param string $after_content String to paste after content, but before * wrapper. * @return string Wrapped and processed content. */ private static function _wrap_content( $content, $after_content = '' ) { return sprintf( '<div class="module-content">%s%s</div>', do_shortcode( apply_filters( 'the_content', $content ) ), $after_content ); } public static function quiz_result_content( $student_id, $course_id, $unit_id, $module_id, $quiz_result = false ) { // Get last submitted result if ( empty( $quiz_result ) ) { $quiz_result = CoursePress_Data_Module::get_quiz_results( $student_id, $course_id, $unit_id, $module_id ); } $quiz_passed = ! empty( $quiz_result['passed'] ); $passed_class = $quiz_passed ? 'passed' : 'not-passed'; $passed_message = ! empty( $quiz_result['passed'] ) ? __( 'You have successfully passed the quiz. Here are your results.', 'coursepress' ) : __( 'You did not pass the quiz this time. Here are your results.', 'coursepress' ); $template = '<div class="module-quiz-questions"> <div class="coursepress-quiz-results ' . esc_attr( $passed_class ) . '"> <div class="quiz-message"><p class="result-message">' . $passed_message . '</p></div> <div class="quiz-results"> <table> <tr><th>' . esc_html__( 'Total Questions', 'coursepress' ) . '</th><td>' . esc_html( $quiz_result['total_questions'] ) . '</td></tr> <tr><th>' . esc_html__( 'Correct', 'coursepress' ) . '</th><td>' . esc_html( $quiz_result['correct'] ) . '</td></tr> <tr><th>' . esc_html__( 'Incorrect', 'coursepress' ) . '</th><td>' . esc_html( $quiz_result['wrong'] ) . '</td></tr> <tr><th>' . esc_html__( 'Grade', 'coursepress' ) . '</th><td>' . esc_html( $quiz_result['grade'] ) . '%</td></tr> </table> </div> </div> </div> <script> function ShowQuiz(id){ document.getElementById("cp-element-"+id).classList.remove("hide"); } </script>'; $attributes = array( 'course_id' => $course_id, 'unit_id' => $unit_id, 'module_id' => $module_id, 'student_id' => $student_id, 'quiz_result' => $quiz_result, ); // Can't use shortcodes this time as this also loads via AJAX $template = apply_filters( 'coursepress_template_quiz_results', $template, $attributes ); return $template; } public static function oembed_result_add_autoplay( $html, $url, $attr ) { wp_parse_str( $url, $attr ); if ( isset( $attr['autoplay'] ) && $attr['autoplay'] ) { preg_match( '/src="([^"]+)"/', $html, $matches ); if ( 1 < sizeof( $matches ) ) { $url = add_query_arg( array( 'autoplay' => 1, ), $matches[1] ); $src = sprintf( 'src="%s"', esc_url( $url ) ); $html = preg_replace( '/src="[^"]+"/', $src, $html ); } } return $html; } /** * Check and show form input results. * * @since 2.0.6 * * @param integer $student_id student ID. * @param integer $course_id Course ID. * @param integer $unit_id Unit ID. * @param integer $module_id Modue ID. * @param array $form_result Result of rorm input. * * @return array */ public static function form_result_content( $student_id, $course_id, $unit_id, $module_id, $form_result = false ) { // Get last submitted result if ( empty( $form_result ) ) { $form_result = CoursePress_Data_Module::get_form_results( $student_id, $course_id, $unit_id, $module_id ); } if ( ! empty( $form_result['pending'] ) ) { $template = sprintf( '<div class="module-form-message">%s</div>', $form_result['message'] ); } else { /* $form_passed = !empty($form_result['passed']); $passed_class = $form_passed ? 'passed' : 'not-passed'; $passed_message = !empty($form_result['passed']) ? __('You have successfully passed the form. Here are your results.', 'coursepress') : __('You did not pass the form this time. Here are your results.', 'coursepress'); $template = '<div class="module-form-questions"> <div class="coursepress-form-results ' . esc_attr($passed_class) . '"> <div class="form-message"><p class="result-message">' . $passed_message . '</p></div> <div class="form-results"> <table> <tr><th>' . esc_html__('Total Questions', 'coursepress') . '</th><td>' . esc_html($form_result['total_questions']) . '</td></tr> <tr><th>' . esc_html__('Correct', 'coursepress') . '</th><td>' . esc_html($form_result['correct']) . '</td></tr> <tr><th>' . esc_html__('Incorrect', 'coursepress') . '</th><td>' . esc_html($form_result['wrong']) . '</td></tr> <tr><th>' . esc_html__('Grade', 'coursepress') . '</th><td>' . esc_html($form_result['grade']) . '%</td></tr> </table> </div> </div> </div>'; */ } $attributes = array( 'course_id' => $course_id, 'unit_id' => $unit_id, 'module_id' => $module_id, 'student_id' => $student_id, 'form_result' => $form_result, ); // Can't use shortcodes this time as this also loads via AJAX $template = apply_filters( 'coursepress_template_form_results', $template, $attributes ); return $template; } }- This reply was modified 7 years, 10 months ago by shiftlessatol.
Forum: Plugins
In reply to: [CoursePress Learning Management System] Cannot Retry or Retake AssessmentsI’ve applied a fix for now
replace this file with code content below.
File::wp-content/plugins/coursepress/2.0/include/coursepress/template/class-module.php
<?php /** * Use to print the different modules. * * @package WordPress * @subpackage CoursePress **/ class CoursePress_Template_Module { private static $args = array(); protected static $student_progress = array(); /** * Helper function get module attributes. **/ protected static function attributes( $module_id ) { return CoursePress_Data_Module::attributes( $module_id ); } /** * Helper function to quickly retrieve student response **/ protected static function get_response( $module_id, $student_id, $all = false ) { $unit_id = get_post_field( 'post_parent', $module_id ); $course_id = get_post_field( 'post_parent', $unit_id ); $response = CoursePress_Data_Student::get_response( $student_id, $course_id, $unit_id, $module_id ); if ( false === $all && isset( $response['response'] ) ) { $response = $response['response']; } return $response; } public static function get_student_answer( $module_id, $student_id ) { $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $unit_id = get_post_field( 'post_parent', $module_id ); $course_id = get_post_field( 'post_parent', $unit_id ); $content = ''; $response = self::get_response( $module_id, $student_id ); switch ( $module_type ) { case 'input-checkbox': case 'input-radio': case 'input-select': $answers = $attributes['answers']; $selected = $attributes['answers_selected']; $content .= '<ul class="cp-answers">'; // $selected is of string type, change it to int $ints = array_fill( 0, 10, true ); if ( ! is_array( $selected ) && ! empty( $ints[ $selected ] ) ) { $selected = (int) $selected; } foreach ( $answers as $key => $answer ) { if ( 'input-checkbox' !== $module_type ) { $the_answer = $selected === $key || $selected === $answer; $student_answer = $response == $key || $response === $answer; } else { $the_answer = in_array( $key, $selected ); $student_answer = is_array( $response ) ? in_array( $key, $response ) : $response == $key; } if ( $student_answer ) { if ( $the_answer ) { $answer = '<span class="chosen-answer correct"></span>' . $answer; } else { $answer = '<span class="chosen-answer incorrect"></span>' . $answer; } $content .= sprintf( '<li>%s</li>', $answer ); } } $content .= '</ul>'; break; case 'input-textarea': case 'input-text': if ( ! empty( $response ) ) { $content .= sprintf( '<div class="cp-answer-box">%s</div>', $response ); } break; case 'input-upload': if ( ! empty( $response['url'] ) ) { $url = $response['url']; $filename = basename( $url ); $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?fdcpf=' . $url; $content .= sprintf( '<a href="%s" class="button-primary cp-download">%s</a>', esc_url( $url ), $filename ); } break; case 'input-quiz': if ( is_admin() ) { if ( ! empty( $attributes['questions'] ) ) { $questions = $attributes['questions']; foreach ( $questions as $q_index => $question ) { $options = (array) $question['options']; $checked = (array) $options['checked']; $checked = array_filter( $checked ); $student_response = $response[ $q_index ]; $content .= sprintf( '<div class="cp-q"><hr /><p class="description cp-question">%s</p><ul>', esc_html( $question['question'] ) ); foreach ( $options['answers'] as $p_index => $answer ) { $the_answer = isset( $checked[ $p_index ] ) ? $checked[ $p_index ] : false; $student_answer = ''; if ( isset( $student_response[ $p_index ] ) && $student_response[ $p_index ] ) { $student_answer = $student_response[ $p_index ]; if ( $the_answer ) { $student_answer = '<span class="chosen-answer correct"></span>'; } else { $student_answer = '<span class="chosen-answer incorrect"></span>'; } $content .= '<li>' . $student_answer . esc_html( $answer ) . '</li>'; } } $content .= '</ul></div>'; } } } else { $content .= self::quiz_result_content( $student_id, $course_id, $unit_id, $module_id ); } break; case 'input-form': if ( ! empty( $attributes['questions'] ) ) { $questions = $attributes['questions']; foreach ( $questions as $q_index => $question ) { $student_response = ! empty( $response[ $q_index ] ) ? $response[ $q_index ] : ''; $format = '<div class="cp-q"><hr /><p class="description cp-question">%s</p>'; $content .= sprintf( $format, esc_html( $question['question'] ) ); $content .= '<ul>'; if ( 'selectable' == $question['type'] ) { $options = $question['options']['answers']; $checked = $question['options']['checked']; foreach ( $options as $ai => $answer ) { if ( $student_response == $ai ) { $the_answer = ! empty( $checked[ $ai ] ); if ( $the_answer === $student_response ) { $student_answer = '<span class="chosen-answer correct"></span>'; } else { $student_answer = '<span class="chosen-answer incorrect"></span>'; } $content .= sprintf( '<li>%s %s</li>', $student_answer, $answer ); } } } else { $content .= sprintf( '<li>%s</li>', esc_html( $student_response ) ); } $content .= '</ul></div>'; } } break; } /** * Filter the student response template. **/ $content = apply_filters( 'coursepress_student_reponse_template', $content, $module_id, $module_type ); return $content; } public static function get_module_status( $module_id, $student_id ) { $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $assessables = array( 'input-text', 'input-textarea', 'input-upload', 'input-form' ); $response = self::get_response( $module_id, $student_id, true ); $grades = (array) CoursePress_Helper_Utility::get_array_val( $response, 'grades' ); $grades = array_pop( $grades ); $grade = (int) CoursePress_Helper_Utility::get_array_val( $grades, 'grade' ); $minimum_grade = (int) $attributes['minimum_grade']; $require_assessment = false; $pass = $grade >= $minimum_grade; $status = ''; if ( in_array( $module_type, $assessables ) ) { if ( ! empty( $attributes['assessable'] ) ) { $graded_by = CoursePress_Helper_Utility::get_array_val( $grades, 'graded_by' ); if ( 'auto' === $graded_by || empty( $grades ) ) { $status = __( 'Pending', 'cp' ); } elseif ( $pass ) { $status = __( 'Pass', 'cp' ); } else { $status = __( 'Failed', 'cp' ); } } else { $status = __( 'Non Gradable', 'cp' ); } } else { $status = $pass ? __( 'Pass', 'cp' ) : __( 'Fail', 'cp' ); } return $status; } /** * * @param integer $module_id Modile ID. * @param boolean $is_focus Is in focus mode? * @param string $view_type View type, possible values "normal", "preview" @since 2.0.4 */ public static function template( $module_id = 0, $is_focus = false, $view_type = 'normal' ) { if ( empty( $module_id ) ) { return ''; // Nothing to process, bail! } $attributes = self::attributes( $module_id ); $module_type = $attributes['module_type']; $is_required = ! empty( $attributes['mandatory'] ); $method = 'render_' . str_replace( '-', '_', $module_type ); $module = get_post( $module_id ); $unit_id = $module->post_parent; $course_id = get_post_field( 'post_parent', $unit_id ); $course_status = CoursePress_Data_Course::get_course_status( $course_id ); $is_module_answerable = preg_match( '%input-%', $module_type ) || 'video' === $module_type; $disabled = false; $element_class = array(); $student_id = get_current_user_id(); $content = '<div class="module-container">'; /** * Fire before the module template is printed * * @since 2.0 * * @param (int) $module_id The WP_Post object ID. * @param (int) $student_id Current user ID. **/ do_action( 'coursepress_module_view', $module_id, $student_id ); // Marked module and page as visited $module_page = get_post_meta( $module_id, 'module_page', true ); CoursePress_Data_Student::visited_module( $student_id, $course_id, $unit_id, $module_id ); CoursePress_Data_Student::visited_page( $student_id, $course_id, $unit_id, $module_page ); $content .= sprintf( '<input type="hidden" name="course_id" value="%s" />', $course_id ); $content .= sprintf( '<input type="hidden" name="unit_id" value="%s" />', $unit_id ); $content .= sprintf( '<input type="hidden" name="student_id" value="%s" />', $student_id ); $content .= sprintf( '<input type="hidden" name="module_id[]" value="%s" />', $module_id ); if ( $is_focus ) { $content .= wp_nonce_field( 'coursepress_submit_modules', '_wpnonce', true, false ); $content .= sprintf( '<div class="cp-error">%s</div>', apply_filters( 'coursepress_before_unit_modules', '' ) ); } // Module header $content .= self::render_module_head( $module, $attributes ); // The question or text content $content .= self::_wrap_content( $module->post_content ); if ( method_exists( __CLASS__, $method ) ) { // Get student progress if it is not retrieve yet if ( empty( self::$student_progress ) ) { $student_progress = self::$student_progress = CoursePress_Data_Student::get_completion_data( $student_id, $course_id ); } else { $student_progress = self::$student_progress; } // Record module visit CoursePress_Data_Student::visited_module( $student_id, $course_id, $unit_id, $module_id, self::$student_progress ); $retry = 'TRY'; $element_class = array( 'module-elements' ); if ( $is_module_answerable ) { $responses = CoursePress_Data_Student::get_responses( $student_id, $course_id, $unit_id, $module_id, true, $student_progress ); $last_response = self::get_response( $module_id, $student_id ); if ( ! empty( $responses ) ) { $element_class[] = 'hide'; } // Set value to 1 only if not attempted this module. $is_module_hidden = empty( $responses ) ? 0 : 1; // Add a hidden field to track if student really submitted the form. $content .= sprintf( '<input type="hidden" class="cp-is-hidden-module" name="is_module_hidden[%s]" value="%s" />', $module_id, $is_module_hidden ); $response_count = ! empty( $responses ) ? count( $responses ) : 0; // Get recorded time lapsed $keys = array( $course_id, $unit_id, $module_id, $student_id ); $key = 'response_' . implode( '_', $keys ); $lapses = (int) get_user_meta( $student_id, $key, true ); $response_count += $lapses; $try_again_label = __( 'Try Again', 'cp' ); switch ( $module_type ) { case 'input-upload': $try_again_label = __( 'Upload a different file', 'cp' ); break; } $retry = sprintf( '<p class="cp-try-again"><a data-module="%s" onclick="javascript:ShowQuiz(%s);" class="button module-submit-action button-reload-module">%s</a></p>', $module_id,$module_id, $try_again_label ); // Check if retry is disabled if ( empty( $attributes['allow_retries'] ) ) { $retry = ''; } elseif ( ! empty( $attributes['retry_attempts'] ) && 0 < $response_count ) { $attempts = (int) $attributes['retry_attempts']; // Retries + 1 normal attempt. if ( $response_count > $attempts ) { $disabled = true; $retry = ''; } else { $retry .= sprintf( '<p class="number-of-fails">%s</p>', sprintf( __( 'Number of failed attempts: %d', 'cp' ), $response_count ) ); } } if ( ! empty( $attributes['use_timer'] ) && ! empty( $attributes['duration'] ) ) { $allow_retry = true; $attempts = (int) $attributes['retry_attempts']; $duration = $attributes['duration']; $dur = explode( ':', $duration ); /** * sanitize time format */ switch ( sizeof( $dur ) ) { case 1: $duration = sprintf( '00:%02d', $dur[0] ); break; case 2: $duration = sprintf( '%02d:%02d', $dur[0], $dur[1] ); break; case 3: $duration = sprintf( '%02d:%02d:%02d', $dur[0], $dur[1], $dur[2] ); break; } $format = '<span class="quiz_timer" data-limit="%1$s" data-retry="%2$s">%1$s</span><span class="quiz_timer_info">%3$s</span>'; if ( empty( $retry ) ) { $attempts = 'no'; if ( $response_count > 0 ) { $duration = '00:00:00'; } } $timer_info = __( 'Session Expired', 'cp' ) . $retry; $content .= sprintf( $format, $duration, $attempts, $timer_info ); } } if ( 'closed' == $course_status ) { $disabled = true; $retry = ''; } $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $module_elements = call_user_func( array( __CLASS__, $method ), $module, $attributes, $student_progress ); if ( $is_module_answerable && 'preview' == $view_type ) { $module_elements = ''; } switch ( $module_type ) { case 'input-quiz'; $module_elements = sprintf( '<div class="module-quiz-questions">%s</div>', $module_elements ); break; } $element_class[] = sprintf( 'module-type-%s', $module_type ); $module_elements = sprintf( '<div id="cp-element-%s" class="%s" data-type="%s" data-required="%s">%s</div>', $module_id, implode( ' ', $element_class ), $module_type, $is_required, $module_elements ); if ( $is_module_answerable && ! empty( $responses ) ) { $status = self::get_module_status( $module->ID, $student_id ); if ( 'Pass' == $status ) { $retry = ''; } $student_answers = sprintf( '<span class="cp-status status-%s">%s</span>', strtolower( $status ), $status ); $student_answers = sprintf( '<div class="cp-student-status">%s</div>', $student_answers ); $student_answers .= self::get_student_answer( $module->ID, $student_id ); $student_answers .= $retry; $module_elements .= sprintf( '<div id="cp-response-%s" class="module-response">%s</div>', $module_id, $student_answers ); } if ( 'closed' == $course_status ) { $format = '<div class="module-warnings"><p>%s</p></div>'; $module_warning = sprintf( $format, esc_html__( 'This course is completed, you can not submit answers anymore.', 'cp' ) ); /** * Filter the warning message. * * @since 2.0 **/ $module_elements .= apply_filters( 'coursepress_course_readonly_message', $module_warning, $module_id, $course_id ); } /** * custom wrappers */ switch ( $module_type ) { case 'discussion': $module_elements = sprintf( '<div id="comments" class="comments-area"><div class="comments-list-container">%s</div></div>', $module_elements ); break; } /** * Filter the module elements template. * * @since 2.0 **/ $content .= apply_filters( 'coursepress_module_template', $module_elements, $module_type, $module_id ); /** * Filter the module container classes * * @since 2.0.6 **/ $module_container_classes = apply_filters( 'coursepress_module_container_classes', array( 'cp-module-content' ), $module_type, $module_id ); $content = sprintf( '<div class="%4$s" data-type="%1$s" data-id="%2$s" id="cp-module-%2$s">%3$s</div>', esc_attr( $module_type ), esc_attr( $module_id ), $content, esc_attr( implode( ' ', $module_container_classes ) ) ); } /** * div.module-container */ $content .= '</div>'; return $content; } /** * Module header **/ private static function render_module_head( $module, $attributes = false ) { if ( false === $module || empty( $module ) ) { return; // Bail } $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $content = ''; $show_title = ! empty( $attributes['show_title'] ); $mandatory = ! empty( $attributes['mandatory'] ); if ( $show_title ) { $content .= '<h4 class="module-title">'; $content .= $module->post_title; if ( $mandatory ) { $content .= sprintf( '<span class="is-mandatory">%s</span>', __( 'Required', 'cp' ) ); } $content .= '</h4>'; } else if ( $mandatory ) { $content .= sprintf( '<div class="is-mandatory">%s</div>', __( 'Required', 'cp' ) ); } $format = '<div class="module-header module %1$s module-%2$s %3$s" data-type="%1$s" data-module="%2$s">%4$s</div>'; $content = sprintf( $format, $attributes['module_type'], $module->ID, $attributes['mode'], $content ); /** * Filter the module header template. * * @since 2.0 **/ $content = apply_filters( 'coursepress_module_header', $content, $module ); return $content; } public static function render_image( $module, $attributes = false ) { $content = self::do_caption_media( $attributes ); return $content; } /** * @param $data * @param null|WP_Post $module * @return string */ private static function do_caption_media( $data, $module = null ) { if ( empty( $data['image_url'] ) && empty( $data['video_url'] ) ) { return ''; } $the_caption = ''; $alt_text = ''; $media_width = ''; $type = $data['module_type']; if ( 'video' === $type ) { $url = $data['video_url']; } if ( 'image' === $type ) { $url = $data['image_url']; } $caption_source = isset( $data['caption_field'] ) ? $data['caption_field'] : 'media'; $attachment = CoursePress_Helper_Utility::attachment_from_url( $url ); if ( 'media' === $caption_source ) { if ( ! empty( $attachment ) ) { $alt_text = CoursePress_Helper_Utility::filter_content( get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ) ); if ( empty( $alt_text ) ) { $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } $meta = wp_get_attachment_metadata( $attachment->ID ); $media_width = $meta['width']; $the_caption = $attachment->post_excerpt; } else { $the_caption = ''; $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } } else { $alt_text = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; global $content_width; if ( ! empty( $content_width ) ) { $media_width = $content_width; } else { $media_width = get_option( 'large_size_w' ); } // Get the custom caption text $the_caption = isset( $data['caption_custom_text'] ) ? CoursePress_Helper_Utility::filter_content( $data['caption_custom_text'] ) : ''; } $html = ''; $show_caption = isset( $data['show_media_caption'] ) ? cp_is_true( $data['show_media_caption'] ) : false; if ( ! empty( $attachment ) ) { $attachment_id = ' id="attachment_' . $attachment->ID . '" '; } else { $attachment_id = ' id="attachment_' . time() . '" '; } if ( 'image' === $type ) { if ( $show_caption ) { $html .= '<div class="image_holder">'; $img = '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $alt_text ) . '" />'; $html .= do_shortcode( '[caption width="' . $media_width . '"' . $attachment_id . ']' . $img . ' ' . $the_caption . '[/caption]' ); $html .= '</div>'; } else { $html .= '<div class="image_holder">'; $html .= '<img src="' . esc_url( $url ) . '" alt="' . esc_attr( $alt_text ) . '" />'; $html .= '</div>'; } } if ( 'video' === $type ) { $player_width = CoursePress_Helper_Utility::get_array_val( $data, 'video_player_width' ); $player_width = $player_width ? $player_width : '640'; $player_height = CoursePress_Helper_Utility::get_array_val( $data, 'video_player_height' ); $player_height = $player_height ? $player_height : '360'; $autoplay = CoursePress_Helper_Utility::get_array_val( $data, 'video_autoplay' ) ? 'autoplay' : ''; $loop = CoursePress_Helper_Utility::get_array_val( $data, 'video_loop' ) ? 'loop' : ''; $controls = CoursePress_Helper_Utility::get_array_val( $data, 'video_hide_controls' ) ? '' : 'controls'; $module_video_id = isset( $module->ID ) ? 'module-video-' . $module->ID : ''; ob_start(); ?> <video id="<?php echo $module_video_id; ?>" class="video-js vjs-default-skin vjs-big-play-centered" width="<?php echo $player_width; ?>" height="<?php echo $player_height; ?>" src="<?php echo $url; ?>" data-setup='<?php echo CoursePress_Helper_Utility::create_video_js_setup_data( $url, $data ); ?>' <?php echo $controls; ?> <?php echo $autoplay; ?> <?php echo $loop; ?>> </video> <?php $video = ob_get_clean(); if ( $show_caption ) { $html .= '<div class="video_holder">'; $html .= '<figure ' . $attachment_id . ' class="wp-caption" style="width: ' . $media_width . 'px;">'; $html .= '<div class="video_player">'; $html .= $video; $html .= '</div>'; if ( ! empty( $the_caption ) ) { $html .= '<figcaption class="wp-caption-text">' . $the_caption . '</figcaption>'; } $html .= '</figure>'; $html .= '</div>'; } else { $html .= '<div class="video_player">'; $html .= $video; $html .= '</div>'; } } return $html; } public static function render_video( $module, $attributes = false ) { $content = self::do_caption_media( $attributes, $module ); return $content; } public static function render_audio( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['audio_url'] ) ) { $loop = isset( $attributes['loop'] ) ? cp_is_true( $attributes['loop'] ) : false; $autoplay = isset( $attributes['autoplay'] ) ? cp_is_true( $attributes['autoplay'] ) : false; $attr = array( 'src' => $attributes['audio_url'], 'loop' => $loop, 'autoplay' => $autoplay, ); $content .= '<div class="module-content"> <div class="audio_player"> ' . wp_audio_shortcode( $attr ) . ' </div> </div> '; } return $content; } public static function render_download( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['file_url'] ) ) { $url = $attributes['file_url']; $file_size = CoursePress_Helper_Utility::get_file_size( $url ); if ( $file_size > 0 ) { $filesize = '<small>(' . esc_html( $file_size ) . ')</small>'; } else { $filesize = ''; } $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?fdcpf=' . $url; $link_text = isset( $attributes['link_text'] ) ? $attributes['link_text'] : $module->post_title; $after_content = sprintf( '<div class="file_holder"><a href="%s">%s <span class="file-size">%s</span></a></div>', esc_url( $url ), esc_html( $link_text ), CoursePress_Helper_Utility::filter_content( $filesize ) ); $content .= $after_content; } return $content; } public static function render_zipped( $module, $attributes = false ) { $content = ''; if ( isset( $attributes['zip_url'] ) && ! empty( $attributes['primary_file'] ) ) { $url = $attributes['zip_url']; $url = CoursePress_Helper_Utility::encode( $url ); $url = trailingslashit( home_url() ) . '?oacpf=' . $url . '&module=' . $module->ID . '&file=' . $attributes['primary_file']; $link_text = isset( $attributes['link_text'] ) ? $attributes['link_text'] : $module->post_title; $after_content = sprintf( '<div class="zip_holder"><a href="%s">%s</a></div>', esc_url( $url ), esc_html( $link_text ) ); $content .= $after_content; } elseif ( empty( $attributes['primary_file'] ) ) { $content .= sprintf( '<div class="zip_holder error">%s</div>', __( 'Primary File not set, please come back later.', 'cp' ) ); } return $content; } public static function render_section( $module, $attributes = false ) { return '<hr />'; } private static function comment_form( $post_id, $attributes = false ) { if ( ! is_user_logged_in() ) { return ''; } $enrolled = false; $student_id = get_current_user_id(); $course_id = CoursePress_Data_Module::get_course_id_by_module( $post_id ); $enrolled = CoursePress_Data_Course::student_enrolled( $student_id, $course_id ); /** * Instructor as enrolled user. */ if ( false == $enrolled ) { $instructors = array_filter( CoursePress_Data_Course::get_instructors( $course_id ) ); if ( in_array( $student_id, $instructors ) ) { $enrolled = true; } } /** * Author as enrolled user. */ if ( false == $enrolled ) { $enrolled = CoursePress_Data_Capabilities::can_update_course( $course_id ); } if ( false == $enrolled ) { return ''; } $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; ob_start(); $form_class = array( 'comment-form', 'cp-comment-form' ); $comment_order = get_option( 'comment_order' ); $form_class[] = 'comment-form-' . $comment_order; $args = array( 'class_form' => implode( ' ', $form_class ), 'title_reply' => __( 'Post Here', 'cp' ), 'label_submit' => __( 'Post', 'cp' ), 'must_log_in' => '', 'logged_in_as' => '', 'action' => '', 'class_submit' => 'submit cp-comment-submit', 'comment_field' => '<p class="comment-form-comment"><textarea id="comment" name="comment" cols="45" rows="8" maxlength="65525"></textarea></p>', ); /** * Comment form args filter. * * @since 2.0.8 */ $args = apply_filters( 'coursepress_comment_form_args', false ); add_filter( 'comment_form_submit_button', array( 'CoursePress_Template_Discussion', 'add_subscribe_button' ) ); comment_form( $args, $post_id ); $comment_form = ob_get_clean(); $comment_form = str_replace( array( '<form', '</form>' ), array( '<div', '</div>' ), $comment_form ); /** * remove required="required" from textarea */ $mandatory = false; if ( isset( $attributes['mandatory'] ) ) { $mandatory = cp_is_true( $attributes['mandatory'] ); } if ( false === $mandatory ) { $pattern = '/(<textarea[^>]+>)/'; preg_match( $pattern, $comment_form, $matches ); if ( 2 == sizeof( $matches ) ) { $replacement = $matches[1]; $replacement = preg_replace( '/ required(="[^"]+")?/', '', $replacement ); $replacement = preg_replace( '/ aria-required="true"/', '', $replacement ); $comment_form = preg_replace( $pattern, $replacement, $comment_form ); } } remove_filter( 'comment_form_submit_button', array( 'CoursePress_Template_Discussion', 'add_subscribe_button' ) ); return $comment_form; } public static function comment_list( $module_id ) { ob_start(); $comments = get_comments( array( 'post_id' => $module_id, ) ); $args = array( 'style' => 'ol', 'short_ping' => true, 'avatar_size' => 42, ); /** * Comment list arguments filter. * * @since 2.0.8 */ $args = apply_filters( 'coursepress_comment_list_args', $args ); ?> <ol class="comment-list"> <?php wp_list_comments( $args, $comments ); ?> </ol><!-- .comment-list --> <?php $comment_list = ob_get_clean(); return $comment_list; } public static function discussion_url( $post_id ) { $unit_id = get_post_field( 'post_parent', $post_id ); $unit_url = CoursePress_Data_Unit::get_unit_url( $unit_id ); $page_number = get_post_meta( $post_id, 'page_number', true ); $page_number = max( $page_number, 1 ); $url = sprintf( '%spage/%s/module_id/%s', $unit_url, $page_number, $post_id ); return $url; } public static function comment_reply_link( $link, $args, $comment, $post ) { $discussion_link = self::discussion_url( $post->ID ); $discussion_link = add_query_arg( 'replytocom', $comment->comment_ID, $discussion_link ); $discussion_link .= '#respond'; $link = preg_replace( '%href=([\'"])(.*?)([\'"])%', 'href=$1' . $discussion_link . '$3', $link ); $link = sprintf( '<div data-comid="%s" data-parentid="%s">%s</div>', $comment->comment_ID, $post->ID, $link ); return $link; } public static function render_discussion( $module, $attributes = false ) { global $post; $post = $module; // Add comment filters add_filter( 'comments_open', '__return_true' ); add_filter( 'comment_reply_link', array( __CLASS__, 'comment_reply_link' ), 10, 4 ); setup_postdata( $module ); $content = ''; $content .= self::comment_form( $module->ID, $attributes ); $content .= self::comment_list( $module->ID ); // Remove comment filters, etc wp_reset_postdata(); remove_filter( 'comments_open', '__return_true' ); remove_filter( 'comment_reply_link', array( __CLASS__, 'comment_reply_link' ), 10, 4 ); return $content; } public static function render_input_checkbox( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = true === $disabled ? 'disabled="disabled"' : ''; $oddeven = 'odd'; $alt = ''; $response = self::get_response( $module->ID, get_current_user_id() ); $content .= '<ul class="quiz-question quiz-question-checkbox">'; foreach ( $attributes['answers'] as $key => $answer ) { $checked = ' ' . checked( 1, is_array( $response ) && in_array( $key, $response ), false ); $format = '<li class="%1$s %2$s"><input type="checkbox" value="%5$s" name="module[%3$s][]" id="module-%3$s-%5$s" %6$s /> <label for="module-%3$s-%5$s">%4$s</label></li>'; $content .= sprintf( $format, $oddeven, $alt, $module->ID, $answer, esc_attr( $key ), $disabled_attr . $checked ); $oddeven = 'odd' === $oddeven ? 'even' : 'odd'; } $content .= '</ul>'; } return $content; } public static function render_input_radio( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $oddeven = 'odd'; $alt = ''; $response = self::get_response( $module->ID, get_current_user_id() ); $content .= '<ul class="quiz-question quiz-question-radio">'; foreach ( $attributes['answers'] as $key => $answer ) { $checked = '' !== $response ? ' ' . checked( 1, '' != $response && (int) $response === $key, false ) : ''; $format = '<li class="%1$s %2$s"><input type="radio" value="%5$s" name="module[%3$s]" id="module-%3$s-%5$s" %6$s /> <label for="module-%3$s-%5$s">%4$s</label> </li>'; $content .= sprintf( $format, $oddeven, $alt, $module->ID, $answer, esc_attr( $key ), $disabled_attr . $checked ); $oddeven = 'odd' === $oddeven ? 'even' : 'odd'; $alt = empty( $alt ) ? 'alt' : ''; } $content .= '</ul>'; } return $content; } public static function render_input_select( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $content = ''; if ( ! empty( $attributes['answers'] ) ) { $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $options = ''; $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['answers'] as $key => $answer ) { $options .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $key ), selected( 1, $response == $key, false ), esc_html( $answer ) ); } $content .= sprintf( '<select class="wide" name="module[%s]" %s>%s</select>', $module->ID, $disabled_attr, $options ); } return $content; } public static function render_input_text( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $placeholder_text = get_post_meta( $module->ID, 'placeholder_text', true ); $placeholder_text = ! empty( $placeholder_text ) ? $placeholder_text : ''; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<input type="text" name="module[%s]" placeholder="%s" value="%s" %s />'; $content = sprintf( $format, $module->ID, esc_attr( $placeholder_text ), esc_attr( $response ), $disabled_attr ); return $content; } public static function render_input_textarea( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $placeholder_text = get_post_meta( $module->ID, 'placeholder_text', true ); $placeholder_text = ! empty( $placeholder_text ) ? $placeholder_text : ''; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<textarea name="module[%s]" placeholder="%s" %s rows="3">%s</textarea>'; $content = sprintf( $format, $module->ID, esc_attr( $placeholder_text ), $disabled_attr, esc_textarea( $response ) ); return $content; } public static function render_input_upload( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $response = self::get_response( $module->ID, get_current_user_id() ); $format = '<label class="file"><input type="file" name="module[%s]" %s /><span class="button" data-change="%s" data-upload="%s">%s <span class="upload-progress"></span></label>'; $content = sprintf( $format, $module->ID, $disabled_attr, __( 'Change File', 'cp' ), __( 'Upload File', 'cp' ), __( 'Upload File', 'cp' ) ); $upload_types = CoursePress_Helper_Utility::allowed_student_mimes(); $upload_types = array_map( 'strtoupper', array_keys( $upload_types ) ); $format = '<div class="cp-sub"><p>%s %s</p><p>%s %s</p></div>'; $content .= sprintf( $format, __( 'Accepted File Format: ', 'cp' ), implode( ' ', $upload_types ), __( 'Max File Size:', 'cp' ), ini_get( 'upload_max_filesize' ) ); return $content; } public static function render_input_quiz( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $content = ''; if ( ! empty( $attributes['questions'] ) ) { $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['questions'] as $qi => $question ) { $questions = '<ul class="quiz-question quiz-question-input">'; foreach ( $question['options']['answers'] as $ai => $answer ) { $module_name = sprintf( 'module[%s][%s]', $module->ID, $qi ); $quiz_id = 'quiz-module-' . $module->ID . '-' . $qi . '-' . $ai; $type = 'radio'; if ( 'multiple' == $question['type'] ) { $type = 'checkbox'; $module_name .= '[]'; } $checked = ' '; if ( is_array( $response ) && ! empty( $response[ $qi ] ) ) { $checked .= checked( 1, ! empty( $response[ $qi ][ $ai ] ), false ); } $format = '<li><input type="%3$s" id="%1$s" name="%4$s" value="%5$s" %6$s/> <label for="%1$s">%2$s</label></li>'; $questions .= sprintf( $format, $quiz_id, esc_html( $answer ), $type, $module_name, $ai, $disabled_attr . $checked ); } $questions .= '</ul>'; $questions = sprintf( '<p class="question">%s</p>%s', esc_html( $question['question'] ), $questions ); $container_format = '<div class="module-quiz-question question-%s" data-type="%s">%s</div>'; $content .= sprintf( $container_format, $qi, $question['type'], $questions ); } } /** * Filter allow to cange questions in input quiz. * * @since 2.0.6 * * @param string $questions Quiz module questions. */ $content = apply_filters( 'coursepress_template_module_render_input_quiz_content', $content ); return $content; } public static function render_input_form( $module, $attributes = false, $student_progress = false, $disabled = false ) { $attributes = false === $attributes ? self::attributes( $module->ID ) : $attributes; $student_progress = false === $student_progress ? self::$student_progress : $student_progress; $disabled_attr = $disabled ? 'disabled="disabled"' : ''; $content = ''; $response = self::get_response( $module->ID, get_current_user_id() ); foreach ( $attributes['questions'] as $qi => $question ) { $field_id = 'form-module-' . $module->ID . '-' . $qi; $label = sprintf( '<label for="%s">%s</label>', $field_id, esc_html( $question['question'] ) ); switch ( $question['type'] ) { case 'short': $value = ! empty( $response[ $qi ] ) ? $response[ $qi ] : ''; $field = '<input type="text" name="module[%s][%s]" placeholder="%s" id="%s" value="%s" %s />'; $field = sprintf( $field, $module->ID, $qi, esc_attr( $question['placeholder'] ), $field_id, esc_attr( $value ), $disabled_attr ); break; case 'long': $value = ! empty( $response[ $qi ] ) ? $response[ $qi ] : ''; $field = '<textarea name="module[%s][%s]" placeholder="%s" id="%s" %s>%s</textarea>'; $field = sprintf( $field, $module->ID, $qi, esc_attr( $question['placeholder'] ), $field_id, $disabled_attr, esc_textarea( $value ) ); break; case 'selectable': $options = ''; foreach ( $question['options']['answers'] as $ai => $answer ) { $selected = selected( 1, isset( $response[ $qi ] ) && $response[ $qi ] == $ai, false ); $options .= sprintf( '<option value="%s" %s>%s</option>', esc_attr( $ai ), $selected, $answer ); } $field = '<select class="wide" name="module[%s][%s]" id="%s" %s>%s</select>'; $field = sprintf( $field, $module->ID, $qi, $field_id, $disabled_attr, $options ); break; } $container_format = '<div class="module-quiz-question question-%s" data-type="%s">%s</div>'; $content .= sprintf( $container_format, $qi, $question['type'], $label . $field ); } return $content; } /** * Chat Module **/ public static function render_chat( $module, $attributes = false, $student_progress = false, $disabled = false ) { if ( cp_is_chat_plugin_active() ) { $content = sprintf( '<div class="cp-chat-module">[chat id="%s"]</div>', $module->ID ); $content = do_shortcode( $content ); return $content; } return ''; } /** * Wrap Content by div, apply filter and shortcodes. * * @access private * * @since 2.0.0 * * @param string $content Content to wrap. * @param string $after_content String to paste after content, but before * wrapper. * @return string Wrapped and processed content. */ private static function _wrap_content( $content, $after_content = '' ) { return sprintf( '<div class="module-content">%s%s</div>', do_shortcode( apply_filters( 'the_content', $content ) ), $after_content ); } public static function quiz_result_content( $student_id, $course_id, $unit_id, $module_id, $quiz_result = false ) { // Get last submitted result if ( empty( $quiz_result ) ) { $quiz_result = CoursePress_Data_Module::get_quiz_results( $student_id, $course_id, $unit_id, $module_id ); } $quiz_passed = ! empty( $quiz_result['passed'] ); $passed_class = $quiz_passed ? 'passed' : 'not-passed'; $passed_message = ! empty( $quiz_result['passed'] ) ? __( 'You have successfully passed the quiz. Here are your results.', 'cp' ) : __( 'You did not pass the quiz this time. Here are your results.', 'cp' ); $template = '<div class="module-quiz-questions"> <div class="coursepress-quiz-results ' . esc_attr( $passed_class ) . '"> <div class="quiz-message"><p class="result-message">' . $passed_message . '</p></div> <div class="quiz-results"> <table> <tr><th>' . esc_html__( 'Total Questions', 'cp' ) . '</th><td>' . esc_html( $quiz_result['total_questions'] ) . '</td></tr> <tr><th>' . esc_html__( 'Correct', 'cp' ) . '</th><td>' . esc_html( $quiz_result['correct'] ) . '</td></tr> <tr><th>' . esc_html__( 'Incorrect', 'cp' ) . '</th><td>' . esc_html( $quiz_result['wrong'] ) . '</td></tr> <tr><th>' . esc_html__( 'Grade', 'cp' ) . '</th><td>' . esc_html( $quiz_result['grade'] ) . '%</td></tr> </table> </div> </div> </div> <script> function ShowQuiz(id){ document.getElementById("cp-element-"+id).classList.remove("hide"); } </script>'; $attributes = array( 'course_id' => $course_id, 'unit_id' => $unit_id, 'module_id' => $module_id, 'student_id' => $student_id, 'quiz_result' => $quiz_result, ); // Can't use shortcodes this time as this also loads via AJAX $template = apply_filters( 'coursepress_template_quiz_results', $template, $attributes ); return $template; } public static function oembed_result_add_autoplay( $html, $url, $attr ) { wp_parse_str( $url, $attr ); if ( isset( $attr['autoplay'] ) && $attr['autoplay'] ) { preg_match( '/src="([^"]+)"/', $html, $matches ); if ( 1 < sizeof( $matches ) ) { $url = add_query_arg( array( 'autoplay' => 1, ), $matches[1] ); $src = sprintf( 'src="%s"', esc_url( $url ) ); $html = preg_replace( '/src="[^"]+"/', $src, $html ); } } return $html; } /** * Check and show form input results. * * @since 2.0.6 * * @param integer $student_id student ID. * @param integer $course_id Course ID. * @param integer $unit_id Unit ID. * @param integer $module_id Modue ID. * @param array $form_result Result of rorm input. * * @return array */ public static function form_result_content( $student_id, $course_id, $unit_id, $module_id, $form_result = false ) { // Get last submitted result if ( empty( $form_result ) ) { $form_result = CoursePress_Data_Module::get_form_results( $student_id, $course_id, $unit_id, $module_id ); } if ( ! empty( $form_result['pending'] ) ) { $template = sprintf( '<div class="module-form-message">%s</div>', $form_result['message'] ); } else { /* $form_passed = !empty($form_result['passed']); $passed_class = $form_passed ? 'passed' : 'not-passed'; $passed_message = !empty($form_result['passed']) ? __('You have successfully passed the form. Here are your results.', 'cp') : __('You did not pass the form this time. Here are your results.', 'cp'); $template = '<div class="module-form-questions"> <div class="coursepress-form-results ' . esc_attr($passed_class) . '"> <div class="form-message"><p class="result-message">' . $passed_message . '</p></div> <div class="form-results"> <table> <tr><th>' . esc_html__('Total Questions', 'cp') . '</th><td>' . esc_html($form_result['total_questions']) . '</td></tr> <tr><th>' . esc_html__('Correct', 'cp') . '</th><td>' . esc_html($form_result['correct']) . '</td></tr> <tr><th>' . esc_html__('Incorrect', 'cp') . '</th><td>' . esc_html($form_result['wrong']) . '</td></tr> <tr><th>' . esc_html__('Grade', 'cp') . '</th><td>' . esc_html($form_result['grade']) . '%</td></tr> </table> </div> </div> </div>'; */ } $attributes = array( 'course_id' => $course_id, 'unit_id' => $unit_id, 'module_id' => $module_id, 'student_id' => $student_id, 'form_result' => $form_result, ); // Can't use shortcodes this time as this also loads via AJAX $template = apply_filters( 'coursepress_template_form_results', $template, $attributes ); return $template; } }- This reply was modified 8 years, 2 months ago by shiftlessatol.
- This reply was modified 8 years, 2 months ago by shiftlessatol.
- This reply was modified 8 years, 2 months ago by shiftlessatol.
- This reply was modified 8 years, 2 months ago by shiftlessatol.
Forum: Plugins
In reply to: [CoursePress Learning Management System] Cannot Retry or Retake AssessmentsThanks for the confirmation; eagerly awaiting the update. I appreciate your response and update.
Viewing 3 replies - 1 through 3 (of 3 total)