woothemes /
sensei
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
||
| 3 | |||
| 4 | /** |
||
| 5 | * Grading User Profile in Sensei. |
||
| 6 | * |
||
| 7 | * @package Assessment |
||
| 8 | * @author Automattic |
||
| 9 | * |
||
| 10 | * @since 1.3.0 |
||
| 11 | */ |
||
| 12 | class Sensei_Grading_User_Quiz { |
||
| 13 | public $user_id; |
||
| 14 | public $lesson_id; |
||
| 15 | public $quiz_id; |
||
| 16 | |||
| 17 | /** |
||
| 18 | * Constructor |
||
| 19 | * @since 1.3.0 |
||
| 20 | */ |
||
| 21 | public function __construct ( $user_id = 0, $quiz_id = 0 ) { |
||
| 22 | $this->user_id = intval( $user_id ); |
||
| 23 | $this->quiz_id = intval( $quiz_id ); |
||
| 24 | $this->lesson_id = get_post_meta( $this->quiz_id, '_quiz_lesson', true ); |
||
| 25 | } // End __construct() |
||
| 26 | |||
| 27 | /** |
||
| 28 | * build_data_array builds the data for use on the page |
||
| 29 | * Overloads the parent method |
||
| 30 | * @since 1.3.0 |
||
| 31 | * @return array |
||
| 32 | */ |
||
| 33 | public function build_data_array() { |
||
| 34 | $data_array = Sensei_Utils::sensei_get_quiz_questions( $this->quiz_id ); |
||
| 35 | return $data_array; |
||
| 36 | } // End build_data_array() |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Display output to the admin view |
||
| 40 | * |
||
| 41 | * This view is shown when grading a quiz for a single user in admin under grading |
||
| 42 | * |
||
| 43 | * @since 1.3.0 |
||
| 44 | * @return html |
||
| 45 | */ |
||
| 46 | public function display() { |
||
| 47 | // Get data for the user |
||
| 48 | $questions = $this->build_data_array(); |
||
| 49 | |||
| 50 | |||
| 51 | $count = 0; |
||
| 52 | $graded_count = 0; |
||
| 53 | $user_quiz_grade_total = 0; |
||
| 54 | $quiz_grade_total = 0; |
||
| 55 | $quiz_grade = 0; |
||
| 56 | $lesson_id = $this->lesson_id; |
||
| 57 | $user_id = $this->user_id; |
||
| 58 | |||
| 59 | ?><form name="<?php esc_attr_e( 'quiz_' . $this->quiz_id ); ?>" action="" method="post"> |
||
| 60 | <?php wp_nonce_field( 'sensei_manual_grading', '_wp_sensei_manual_grading_nonce' ); ?> |
||
| 61 | <input type="hidden" name="sensei_manual_grade" value="<?php esc_attr_e( $this->quiz_id ); ?>" /> |
||
| 62 | <input type="hidden" name="sensei_grade_next_learner" value="<?php esc_attr_e( $this->user_id ); ?>" /> |
||
| 63 | <div class="total_grade_display"> |
||
| 64 | <span><?php esc_attr_e( __( 'Grade:', 'woothemes-sensei' ) ); ?></span> |
||
| 65 | <span class="total_grade_total"><?php echo $user_quiz_grade_total; ?></span> / <span class="quiz_grade_total"><?php echo $quiz_grade_total; ?></span> (<span class="total_grade_percent"><?php echo $quiz_grade; ?></span>%) |
||
| 66 | </div> |
||
| 67 | <div class="buttons"> |
||
| 68 | <input type="submit" value="<?php esc_attr_e( __( 'Save', 'woothemes-sensei' ) ); ?>" class="grade-button button-primary" title="Saves grades as currently marked on this page" /> |
||
| 69 | <input type="button" value="<?php esc_attr_e( __( 'Auto grade', 'woothemes-sensei' ) ); ?>" class="autograde-button button-secondary" title="Where possible, automatically grades questions that have not yet been graded" /> |
||
| 70 | <input type="reset" value="<?php esc_attr_e( __( 'Reset', 'woothemes-sensei' ) ); ?>" class="reset-button button-secondary" title="Resets all questions to ungraded and total grade to 0" /> |
||
| 71 | </div> |
||
| 72 | <div class="clear"></div><br/><?php |
||
| 73 | |||
| 74 | $lesson_status_id = Sensei_Utils::sensei_get_activity_value( array( 'post_id' => $this->lesson_id, 'user_id' => $this->user_id, 'type' => 'sensei_lesson_status', 'field' => 'comment_ID' ) ); |
||
| 75 | $user_quiz_grade = get_comment_meta( $lesson_status_id, 'grade', true ); |
||
| 76 | $correct_answers = 0; |
||
| 77 | |||
| 78 | foreach( $questions as $question ) { |
||
| 79 | $question_id = $question->ID; |
||
| 80 | ++$count; |
||
| 81 | |||
| 82 | $type = false; |
||
| 83 | $type_name = ''; |
||
| 84 | |||
| 85 | $type = Sensei()->question->get_question_type( $question_id ); |
||
| 86 | |||
| 87 | $question_answer_notes = Sensei()->quiz->get_user_question_feedback( $lesson_id, $question_id, $user_id ); |
||
| 88 | |||
| 89 | |||
| 90 | $question_grade_total = Sensei()->question->get_question_grade( $question_id ); |
||
| 91 | $quiz_grade_total += $question_grade_total; |
||
| 92 | |||
| 93 | $right_answer = get_post_meta( $question_id, '_question_right_answer', true ); |
||
| 94 | $user_answer_content = Sensei()->quiz->get_user_question_answer( $lesson_id, $question_id, $user_id ); |
||
| 95 | $type_name = __( 'Multiple Choice', 'woothemes-sensei' ); |
||
| 96 | $grade_type = 'manual-grade'; |
||
| 97 | |||
| 98 | switch( $type ) { |
||
| 99 | case 'boolean': |
||
| 100 | $type_name = __( 'True/False', 'woothemes-sensei' ); |
||
| 101 | $right_answer = ucfirst( $right_answer ); |
||
| 102 | $user_answer_content = ucfirst( $user_answer_content ); |
||
| 103 | $grade_type = 'auto-grade'; |
||
| 104 | break; |
||
| 105 | case 'multiple-choice': |
||
| 106 | $type_name = __( 'Multiple Choice', 'woothemes-sensei' ); |
||
| 107 | $grade_type = 'auto-grade'; |
||
| 108 | break; |
||
| 109 | case 'gap-fill': |
||
| 110 | $type_name = __( 'Gap Fill', 'woothemes-sensei' ); |
||
| 111 | |||
| 112 | $right_answer_array = explode( '||', $right_answer ); |
||
| 113 | if ( isset( $right_answer_array[0] ) ) { $gapfill_pre = $right_answer_array[0]; } else { $gapfill_pre = ''; } |
||
| 114 | if ( isset( $right_answer_array[1] ) ) { $gapfill_gap = $right_answer_array[1]; } else { $gapfill_gap = ''; } |
||
| 115 | if ( isset( $right_answer_array[2] ) ) { $gapfill_post = $right_answer_array[2]; } else { $gapfill_post = ''; } |
||
| 116 | |||
| 117 | if( ! $user_answer_content ) { |
||
|
0 ignored issues
–
show
|
|||
| 118 | $user_answer_content = '______'; |
||
| 119 | } |
||
| 120 | |||
| 121 | $right_answer = $gapfill_pre . ' <span class="highlight">' . $gapfill_gap . '</span> ' . $gapfill_post; |
||
| 122 | $user_answer_content = $gapfill_pre . ' <span class="highlight">' . $user_answer_content . '</span> ' . $gapfill_post; |
||
| 123 | $grade_type = 'auto-grade'; |
||
| 124 | |||
| 125 | break; |
||
| 126 | case 'multi-line': |
||
| 127 | $type_name = __( 'Multi Line', 'woothemes-sensei' ); |
||
| 128 | $grade_type = 'manual-grade'; |
||
| 129 | break; |
||
| 130 | case 'single-line': |
||
| 131 | $type_name = __( 'Single Line', 'woothemes-sensei' ); |
||
| 132 | $grade_type = 'manual-grade'; |
||
| 133 | break; |
||
| 134 | case 'file-upload': |
||
| 135 | $type_name = __( 'File Upload', 'woothemes-sensei' ); |
||
| 136 | $grade_type = 'manual-grade'; |
||
| 137 | |||
| 138 | // Get uploaded file |
||
| 139 | if( $user_answer_content ) { |
||
| 140 | $attachment_id = $user_answer_content; |
||
| 141 | $answer_media_url = $answer_media_filename = ''; |
||
| 142 | if( 0 < intval( $attachment_id ) ) { |
||
| 143 | $answer_media_url = wp_get_attachment_url( $attachment_id ); |
||
| 144 | $answer_media_filename = basename( $answer_media_url ); |
||
| 145 | if( $answer_media_url && $answer_media_filename ) { |
||
| 146 | $user_answer_content = sprintf( __( 'Submitted file: %1$s', 'woothemes-sensei' ), '<a href="' . esc_url( $answer_media_url ) . '" target="_blank">' . esc_html( $answer_media_filename ) . '</a>' ); |
||
| 147 | } |
||
| 148 | } |
||
| 149 | } else { |
||
| 150 | $user_answer_content = ''; |
||
| 151 | } |
||
| 152 | break; |
||
| 153 | default: |
||
| 154 | // Nothing |
||
| 155 | break; |
||
| 156 | } |
||
| 157 | $user_answer_content = (array) $user_answer_content; |
||
| 158 | $right_answer = (array) $right_answer; |
||
| 159 | $question_title = sprintf( __( 'Question %d: ', 'woothemes-sensei' ), $count ) . $type_name; |
||
| 160 | |||
| 161 | $graded_class = ''; |
||
| 162 | $user_question_grade = Sensei()->quiz->get_user_question_grade( $lesson_id, $question_id, $user_id ); |
||
| 163 | $graded_class = 'ungraded'; |
||
| 164 | if ( 0 == $question_grade_total && 0 == intval( $user_question_grade ) ) { |
||
| 165 | // Question skips grading |
||
| 166 | $grade_type = 'zero-graded'; |
||
| 167 | $graded_class = ''; |
||
| 168 | ++$correct_answers; |
||
| 169 | ++$graded_count; |
||
| 170 | $user_question_grade = 0; |
||
| 171 | } |
||
| 172 | elseif( intval( $user_question_grade ) > 0 ) { |
||
| 173 | $graded_class = 'user_right'; |
||
| 174 | ++$correct_answers; |
||
| 175 | $user_quiz_grade_total += $user_question_grade; |
||
| 176 | ++$graded_count; |
||
| 177 | } else { |
||
| 178 | if( ! is_string( $user_question_grade ) && intval( $user_question_grade ) == 0 ) { |
||
| 179 | $graded_class = 'user_wrong'; |
||
| 180 | ++$graded_count; |
||
| 181 | } |
||
| 182 | $user_question_grade = 0; |
||
| 183 | } |
||
| 184 | |||
| 185 | ?><div class="postbox question_box <?php esc_attr_e( $type ); ?> <?php esc_attr_e( $grade_type ); ?> <?php esc_attr_e( $graded_class ); ?>" id="<?php esc_attr_e( 'question_' . $question_id . '_box' ); ?>"> |
||
| 186 | <div class="handlediv" title="Click to toggle"><br></div> |
||
| 187 | <h3 class="hndle"><span><?php echo $question_title; ?></span></h3> |
||
| 188 | <div class="inside"> |
||
| 189 | <div class="sensei-grading-actions"> |
||
| 190 | <div class="actions"> |
||
| 191 | <input type="hidden" class="question_id" value="<?php esc_attr_e( $question_id ); ?>" /> |
||
| 192 | <input type="hidden" class="question_total_grade" name="question_total_grade" value="<?php echo esc_attr( $question_grade_total ); ?>" /> |
||
| 193 | <span class="grading-mark icon_right"><input type="radio" class="<?php esc_attr_e( 'question_' . $question_id . '_right_option' ); ?>" name="<?php esc_attr_e( 'question_' . $question_id ); ?>" value="right" <?php checked( $graded_class, 'user_right', true ); ?> /></span> |
||
| 194 | <span class="grading-mark icon_wrong"><input type="radio" class="<?php esc_attr_e( 'question_' . $question_id . '_wrong_option' ); ?>" name="<?php esc_attr_e( 'question_' . $question_id ); ?>" value="wrong" <?php checked( $graded_class, 'user_wrong', true ); ?> /></span> |
||
| 195 | <input type="number" class="question-grade" name="<?php esc_attr_e( 'question_' . $question_id . '_grade' ); ?>" id="<?php esc_attr_e( 'question_' . $question_id . '_grade' ); ?>" value="<?php echo esc_attr( $user_question_grade ); ?>" min="0" max="<?php echo esc_attr( $question_grade_total ); ?>" /> |
||
| 196 | <span class="question-grade-total"><?php echo $question_grade_total; ?></span> |
||
| 197 | </div> |
||
| 198 | </div> |
||
| 199 | <div class="sensei-grading-answer"> |
||
| 200 | <h4><?php echo apply_filters( 'sensei_question_title', $question->post_title ); ?></h4> |
||
| 201 | <?php echo apply_filters( 'the_content', $question->post_content );?> |
||
| 202 | <p class="user-answer"><?php |
||
| 203 | foreach ( $user_answer_content as $_user_answer ) { |
||
| 204 | |||
| 205 | if( 'multi-line' == Sensei()->question->get_question_type( $question->ID ) ){ |
||
| 206 | |||
| 207 | $_user_answer = htmlspecialchars_decode( nl2br( esc_html($_user_answer) ) ); |
||
| 208 | |||
| 209 | } |
||
| 210 | |||
| 211 | echo apply_filters( 'sensei_answer_text', $_user_answer ) . "<br>"; |
||
| 212 | } |
||
| 213 | ?></p> |
||
| 214 | <div class="right-answer"> |
||
| 215 | <h5><?php _e( 'Correct answer', 'woothemes-sensei' ) ?></h5> |
||
| 216 | <span class="correct-answer"><?php |
||
| 217 | foreach ( $right_answer as $_right_answer ) { |
||
| 218 | |||
| 219 | echo apply_filters( 'sensei_answer_text', $_right_answer ) . "<br>"; |
||
| 220 | |||
| 221 | } |
||
| 222 | ?></span> |
||
| 223 | </div> |
||
| 224 | <div class="answer-notes"> |
||
| 225 | <h5><?php _e( 'Grading Notes', 'woothemes-sensei' ) ?></h5> |
||
| 226 | <textarea class="correct-answer" name="questions_feedback[<?php esc_attr_e( $question_id ); ?>]" placeholder="<?php _e( 'Add notes here...', 'woothemes-sensei' ) ?>"><?php echo $question_answer_notes; ?></textarea> |
||
| 227 | </div> |
||
| 228 | </div> |
||
| 229 | </div> |
||
| 230 | </div><?php |
||
| 231 | } |
||
| 232 | |||
| 233 | $quiz_grade = intval( $user_quiz_grade ); |
||
| 234 | $all_graded = 'no'; |
||
| 235 | if( intval( $count ) == intval( $graded_count ) ) { |
||
| 236 | $all_graded = 'yes'; |
||
| 237 | } |
||
| 238 | |||
| 239 | ?> <input type="hidden" name="total_grade" id="total_grade" value="<?php esc_attr_e( $user_quiz_grade_total ); ?>" /> |
||
| 240 | <input type="hidden" name="total_questions" id="total_questions" value="<?php esc_attr_e( $count ); ?>" /> |
||
| 241 | <input type="hidden" name="quiz_grade_total" id="quiz_grade_total" value="<?php esc_attr_e( $quiz_grade_total ); ?>" /> |
||
| 242 | <input type="hidden" name="total_graded_questions" id="total_graded_questions" value="<?php esc_attr_e( $graded_count ); ?>" /> |
||
| 243 | <input type="hidden" name="all_questions_graded" id="all_questions_graded" value="<?php esc_attr_e( $all_graded ); ?>" /> |
||
| 244 | <div class="total_grade_display"> |
||
| 245 | <span><?php esc_attr_e( __( 'Grade:', 'woothemes-sensei' ) ); ?></span> |
||
| 246 | <span class="total_grade_total"><?php echo $user_quiz_grade_total; ?></span> / <span class="quiz_grade_total"><?php echo $quiz_grade_total; ?></span> (<span class="total_grade_percent"><?php echo $quiz_grade; ?></span>%) |
||
| 247 | </div> |
||
| 248 | <div class="buttons"> |
||
| 249 | <input type="submit" value="<?php esc_attr_e( 'Save' ); ?>" class="grade-button button-primary" title="Saves grades as currently marked on this page" /> |
||
| 250 | <input type="button" value="<?php esc_attr_e( __( 'Auto grade', 'woothemes-sensei' ) ); ?>" class="autograde-button button-secondary" title="Where possible, automatically grades questions that have not yet been graded" /> |
||
| 251 | <input type="reset" value="<?php esc_attr_e( __( 'Reset', 'woothemes-sensei' ) ); ?>" class="reset-button button-secondary" title="Resets all questions to ungraded and total grade to 0" /> |
||
| 252 | </div> |
||
| 253 | <div class="clear"></div> |
||
| 254 | <script type="text/javascript"> |
||
| 255 | jQuery( window ).load( function() { |
||
| 256 | // Calculate total grade on page load to make sure everything is set up correctly |
||
| 257 | jQuery.fn.autoGrade(); |
||
| 258 | }); |
||
| 259 | </script> |
||
| 260 | </form><?php |
||
| 261 | } // End display() |
||
| 262 | |||
| 263 | } // End Class |
||
| 264 | |||
| 265 | /** |
||
| 266 | * Class WooThemes_Sensei_Grading_User_Quiz |
||
| 267 | * @ignore only for backward compatibility |
||
| 268 | * @since 1.9.0 |
||
| 269 | */ |
||
| 270 | class WooThemes_Sensei_Grading_User_Quiz extends Sensei_Grading_User_Quiz{} |
||
| 271 |
If an expression can have both
false, andnullas possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.