1: <?php
2: if ( ! defined( 'ABSPATH' ) ) exit;
3:
4: 5: 6: 7: 8: 9: 10: 11:
12: class Sensei_Grading_User_Quiz {
13: public $user_id;
14: public $lesson_id;
15: public $quiz_id;
16:
17: 18: 19: 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: }
26:
27: 28: 29: 30: 31: 32:
33: public function build_data_array() {
34: $data_array = Sensei_Utils::sensei_get_quiz_questions( $this->quiz_id );
35: return $data_array;
36: }
37:
38: 39: 40: 41: 42: 43: 44: 45:
46: public function display() {
47:
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 ) {
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:
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:
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:
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:
257: jQuery.fn.autoGrade();
258: });
259: </script>
260: </form><?php
261: }
262:
263: }
264:
265: 266: 267: 268: 269:
270: class WooThemes_Sensei_Grading_User_Quiz extends Sensei_Grading_User_Quiz{}
271: