• When the user fails the assessment, everything that should bring up the assessment to take again, instead just goes to the finalization page. And the retry count adds up. I’ve set the retries to unlimited. But the student is not able to retake the exam, it only keeps the previously answered state instead.

    • This topic was modified 7 years, 3 months ago by shiftlessatol.

    The page I need help with: [log in to see the link]

Viewing 6 replies - 1 through 6 (of 6 total)
  • Plugin Support Williams – WPMU DEV Support

    (@wpmudev-support8)

    Hey @shiftlessatol,

    Hope you’re well.

    I can confirm the bug on my test site too. So I reported it to developers. I am sure it will be fixed one of the next releases. Thank you for informing us.

    Cheers,
    Oguz

    Thread Starter shiftlessatol

    (@shiftlessatol)

    Thanks for the confirmation; eagerly awaiting the update. I appreciate your response and update.

    Thread Starter shiftlessatol

    (@shiftlessatol)

    I’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;
    	}
    }
    
    
    Plugin Support Dimitris – WPMU DEV Support

    (@wpmudev-support6)

    Hello there @shiftlessatol,

    I’m sorry for the long delay here and really appreciate that you shared your custom solution on this.

    I’ve already informed our developers about your fix, hopefully next release will include a fix for this.

    Warm regards,
    Dimitris

    Thread Starter shiftlessatol

    (@shiftlessatol)

    Still doesn’t work on Latest Version ( May 28th, 2018) | Version 2.2.0 |
    I’m including the updated file below

    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', '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 6 years, 9 months ago by shiftlessatol.
    Plugin Support Williams – WPMU DEV Support

    (@wpmudev-support8)

    Hey @shiftlessatol,

    Hope you’re well.

    Thank you for continuing to follow this thread and update with the new codes. I forward them to our developers too. Thank you for your effort!

    Cheers,
    Oguz

Viewing 6 replies - 1 through 6 (of 6 total)
  • The topic ‘Cannot Retry or Retake Assessments’ is closed to new replies.