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 | * Sensei Grading Class |
||
6 | * |
||
7 | * All functionality pertaining to the Admin Grading in Sensei. |
||
8 | * |
||
9 | * @package Assessment |
||
10 | * @author Automattic |
||
11 | * |
||
12 | * @since 1.3.0 |
||
13 | */ |
||
14 | class Sensei_Grading { |
||
15 | |||
16 | public $name; |
||
17 | public $file; |
||
18 | public $page_slug; |
||
19 | |||
20 | /** |
||
21 | * Constructor |
||
22 | * @since 1.3.0 |
||
23 | * |
||
24 | * @param $file |
||
25 | */ |
||
26 | public function __construct ( $file ) { |
||
27 | $this->name = __( 'Grading', 'woothemes-sensei' ); |
||
28 | $this->file = $file; |
||
29 | $this->page_slug = 'sensei_grading'; |
||
30 | |||
31 | // Admin functions |
||
32 | View Code Duplication | if ( is_admin() ) { |
|
33 | add_action( 'admin_menu', array( $this, 'grading_admin_menu' ), 20); |
||
34 | add_action( 'grading_wrapper_container', array( $this, 'wrapper_container' ) ); |
||
35 | if ( isset( $_GET['page'] ) && ( $_GET['page'] == $this->page_slug ) ) { |
||
36 | add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) ); |
||
37 | add_action( 'admin_print_styles', array( $this, 'enqueue_styles' ) ); |
||
38 | } |
||
39 | |||
40 | add_action( 'admin_init', array( $this, 'admin_process_grading_submission' ) ); |
||
41 | |||
42 | add_action( 'admin_notices', array( $this, 'add_grading_notices' ) ); |
||
43 | // add_action( 'sensei_grading_notices', array( $this, 'sensei_grading_notices' ) ); |
||
44 | } // End If Statement |
||
45 | |||
46 | // Ajax functions |
||
47 | if ( is_admin() ) { |
||
48 | add_action( 'wp_ajax_get_lessons_dropdown', array( $this, 'get_lessons_dropdown' ) ); |
||
49 | add_action( 'wp_ajax_get_redirect_url', array( $this, 'get_redirect_url' ) ); |
||
50 | } // End If Statement |
||
51 | } // End __construct() |
||
52 | |||
53 | /** |
||
54 | * grading_admin_menu function. |
||
55 | * @since 1.3.0 |
||
56 | * @access public |
||
57 | * @return void |
||
58 | */ |
||
59 | View Code Duplication | public function grading_admin_menu() { |
|
60 | global $menu; |
||
61 | |||
62 | if ( current_user_can( 'manage_sensei_grades' ) ) { |
||
63 | $grading_page = add_submenu_page('sensei', __('Grading', 'woothemes-sensei'), __('Grading', 'woothemes-sensei') , 'manage_sensei_grades', $this->page_slug, array( $this, 'grading_page' ) ); |
||
64 | } |
||
65 | |||
66 | } // End grading_admin_menu() |
||
67 | |||
68 | /** |
||
69 | * enqueue_scripts function. |
||
70 | * |
||
71 | * @description Load in JavaScripts where necessary. |
||
72 | * @access public |
||
73 | * @since 1.3.0 |
||
74 | * @return void |
||
75 | */ |
||
76 | public function enqueue_scripts () { |
||
77 | |||
78 | $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min'; |
||
79 | |||
80 | // Load Grading JS |
||
81 | wp_enqueue_script( 'sensei-grading-general', Sensei()->plugin_url . 'assets/js/grading-general' . $suffix . '.js', array( 'jquery' ), Sensei()->version ); |
||
82 | |||
83 | } // End enqueue_scripts() |
||
84 | |||
85 | /** |
||
86 | * enqueue_styles function. |
||
87 | * |
||
88 | * @description Load in CSS styles where necessary. |
||
89 | * @access public |
||
90 | * @since 1.0.0 |
||
91 | * @return void |
||
92 | */ |
||
93 | public function enqueue_styles () { |
||
94 | |||
95 | wp_enqueue_style( Sensei()->token . '-admin' ); |
||
96 | |||
97 | wp_enqueue_style( 'woothemes-sensei-settings-api', Sensei()->plugin_url . 'assets/css/settings.css', '', Sensei()->version ); |
||
98 | |||
99 | } // End enqueue_styles() |
||
100 | |||
101 | /** |
||
102 | * load_data_table_files loads required files for Grading |
||
103 | * @since 1.3.0 |
||
104 | * @return void |
||
105 | */ |
||
106 | public function load_data_table_files() { |
||
107 | |||
108 | // Load Grading Classes |
||
109 | $classes_to_load = array( 'list-table', |
||
110 | 'grading-main', |
||
111 | 'grading-user-quiz' |
||
112 | ); |
||
113 | foreach ( $classes_to_load as $class_file ) { |
||
114 | Sensei()->load_class( $class_file ); |
||
115 | } // End For Loop |
||
116 | } // End load_data_table_files() |
||
117 | |||
118 | /** |
||
119 | * load_data_object creates new instance of class |
||
120 | * @since 1.3.0 |
||
121 | * @param string $name Name of class |
||
122 | * @param integer $data constructor arguments |
||
123 | * @param undefined $optional_data optional constructor arguments |
||
124 | * @return object class instance object |
||
125 | */ |
||
126 | View Code Duplication | public function load_data_object( $name = '', $data = 0, $optional_data = null ) { |
|
127 | // Load Analysis data |
||
128 | $object_name = 'WooThemes_Sensei_Grading_' . $name; |
||
129 | if ( is_null($optional_data) ) { |
||
130 | $sensei_grading_object = new $object_name( $data ); |
||
131 | } |
||
132 | else { |
||
133 | $sensei_grading_object = new $object_name( $data, $optional_data ); |
||
134 | } // End If Statement |
||
135 | if ( 'Main' == $name ) { |
||
136 | $sensei_grading_object->prepare_items(); |
||
137 | } // End If Statement |
||
138 | return $sensei_grading_object; |
||
139 | } // End load_data_object() |
||
140 | |||
141 | /** |
||
142 | * grading_page function. |
||
143 | * @since 1.3.0 |
||
144 | * @access public |
||
145 | * @return void |
||
146 | */ |
||
147 | public function grading_page() { |
||
148 | |||
149 | if ( isset( $_GET['quiz_id'] ) && 0 < intval( $_GET['quiz_id'] ) && isset( $_GET['user'] ) && 0 < intval( $_GET['user'] ) ) { |
||
150 | $this->grading_user_quiz_view(); |
||
151 | } |
||
152 | else { |
||
153 | $this->grading_default_view(); |
||
154 | } // End If Statement |
||
155 | } // End grading_page() |
||
156 | |||
157 | /** |
||
158 | * grading_default_view default view for grading page |
||
159 | * @since 1.3.0 |
||
160 | * @return void |
||
161 | */ |
||
162 | public function grading_default_view() { |
||
163 | |||
164 | // Load Grading data |
||
165 | if( !empty( $_GET['course_id'] ) ) { |
||
166 | $course_id = intval( $_GET['course_id'] ); |
||
167 | } |
||
168 | if( !empty( $_GET['lesson_id'] ) ) { |
||
169 | $lesson_id = intval( $_GET['lesson_id'] ); |
||
170 | } |
||
171 | if( !empty( $_GET['user_id'] ) ) { |
||
172 | $user_id = intval( $_GET['user_id'] ); |
||
173 | } |
||
174 | if( !empty( $_GET['view'] ) ) { |
||
175 | $view = esc_html( $_GET['view'] ); |
||
176 | } |
||
177 | $sensei_grading_overview = $this->load_data_object( 'Main', compact( 'course_id', 'lesson_id', 'user_id', 'view' ) ); |
||
178 | |||
179 | // Wrappers |
||
180 | do_action( 'grading_before_container' ); |
||
181 | do_action( 'grading_wrapper_container', 'top' ); |
||
182 | $this->grading_headers(); |
||
183 | ?> |
||
184 | <div id="poststuff" class="sensei-grading-wrap"> |
||
185 | <div class="sensei-grading-main"> |
||
186 | <?php $sensei_grading_overview->display(); ?> |
||
187 | </div> |
||
188 | <div class="sensei-grading-extra"> |
||
189 | <?php do_action( 'sensei_grading_extra' ); ?> |
||
190 | </div> |
||
191 | </div> |
||
192 | <?php |
||
193 | do_action( 'grading_wrapper_container', 'bottom' ); |
||
194 | do_action( 'grading_after_container' ); |
||
195 | } // End grading_default_view() |
||
196 | |||
197 | /** |
||
198 | * grading_user_quiz_view user quiz answers view for grading page |
||
199 | * @since 1.2.0 |
||
200 | * @return void |
||
201 | */ |
||
202 | View Code Duplication | public function grading_user_quiz_view() { |
|
203 | |||
204 | // Load Grading data |
||
205 | $user_id = 0; |
||
206 | $quiz_id = 0; |
||
207 | if( isset( $_GET['user'] ) ) { |
||
208 | $user_id = intval( $_GET['user'] ); |
||
209 | } |
||
210 | if( isset( $_GET['quiz_id'] ) ) { |
||
211 | $quiz_id = intval( $_GET['quiz_id'] ); |
||
212 | } |
||
213 | $sensei_grading_user_profile = $this->load_data_object( 'User_Quiz', $user_id, $quiz_id ); |
||
214 | // Wrappers |
||
215 | do_action( 'grading_before_container' ); |
||
216 | do_action( 'grading_wrapper_container', 'top' ); |
||
217 | $this->grading_headers( array( 'nav' => 'user_quiz' ) ); |
||
218 | ?> |
||
219 | <div id="poststuff" class="sensei-grading-wrap user-profile"> |
||
220 | <div class="sensei-grading-main"> |
||
221 | <?php // do_action( 'sensei_grading_notices' ); ?> |
||
222 | <?php $sensei_grading_user_profile->display(); ?> |
||
223 | </div> |
||
224 | </div> |
||
225 | <?php |
||
226 | do_action( 'grading_wrapper_container', 'bottom' ); |
||
227 | do_action( 'grading_after_container' ); |
||
228 | } // End grading_user_quiz_view() |
||
229 | |||
230 | /** |
||
231 | * Outputs Grading general headers |
||
232 | * @since 1.3.0 |
||
233 | * @param array $args |
||
234 | * @return void |
||
235 | */ |
||
236 | View Code Duplication | public function grading_headers( $args = array( 'nav' => 'default' ) ) { |
|
237 | |||
238 | $function = 'grading_' . $args['nav'] . '_nav'; |
||
239 | $this->$function(); |
||
240 | ?> |
||
241 | <p class="powered-by-woo"><?php _e( 'Powered by', 'woothemes-sensei' ); ?><a href="http://www.woothemes.com/" title="WooThemes"><img src="<?php echo Sensei()->plugin_url; ?>assets/images/woothemes.png" alt="WooThemes" /></a></p> |
||
242 | <?php |
||
243 | do_action( 'sensei_grading_after_headers' ); |
||
244 | } // End grading_headers() |
||
245 | |||
246 | /** |
||
247 | * wrapper_container wrapper for Grading area |
||
248 | * @since 1.3.0 |
||
249 | * @param $which string |
||
250 | * @return void |
||
251 | */ |
||
252 | public function wrapper_container( $which ) { |
||
253 | if ( 'top' == $which ) { |
||
254 | ?><div id="woothemes-sensei" class="wrap woothemes-sensei"><?php |
||
255 | } elseif ( 'bottom' == $which ) { |
||
256 | ?></div><!--/#woothemes-sensei--><?php |
||
257 | } // End If Statement |
||
258 | } // End wrapper_container() |
||
259 | |||
260 | /** |
||
261 | * Default nav area for Grading |
||
262 | * @since 1.3.0 |
||
263 | * @return void |
||
264 | */ |
||
265 | public function grading_default_nav() { |
||
266 | global $wp_version; |
||
267 | |||
268 | $title = sprintf( '<a href="%s">%s</a>', esc_url(add_query_arg( array( 'page' => $this->page_slug ), admin_url( 'admin.php' ) ) ), esc_html( $this->name ) ); |
||
269 | if ( isset( $_GET['course_id'] ) ) { |
||
270 | $course_id = intval( $_GET['course_id'] ); |
||
271 | View Code Duplication | if ( version_compare($wp_version, '4.1', '>=') ) { |
|
272 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
273 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) ); |
||
274 | } |
||
275 | else { |
||
276 | $title .= sprintf( ' <span class="course-title">> %s</span>', get_the_title( $course_id ) ); |
||
277 | } |
||
278 | } |
||
279 | View Code Duplication | if ( isset( $_GET['lesson_id'] ) ) { |
|
280 | $lesson_id = intval( $_GET['lesson_id'] ); |
||
281 | $title .= ' <span class="lesson-title">> ' . get_the_title( intval( $lesson_id ) ) . '</span>'; |
||
282 | } |
||
283 | View Code Duplication | if ( isset( $_GET['user_id'] ) && 0 < intval( $_GET['user_id'] ) ) { |
|
284 | |||
285 | $user_name = Sensei_Learner::get_full_name( $_GET['user_id'] ); |
||
286 | $title .= ' <span class="user-title">> ' . $user_name . '</span>'; |
||
287 | |||
288 | } // End If Statement |
||
289 | ?> |
||
290 | <h2><?php echo apply_filters( 'sensei_grading_nav_title', $title ); ?></h2> |
||
291 | <?php |
||
292 | } // End grading_default_nav() |
||
293 | |||
294 | /** |
||
295 | * Nav area for Grading specific users' quiz answers |
||
296 | * @since 1.3.0 |
||
297 | * @return void |
||
298 | */ |
||
299 | public function grading_user_quiz_nav() { |
||
300 | global $wp_version; |
||
301 | |||
302 | $title = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'page' => $this->page_slug ), admin_url( 'admin.php' ) ), esc_html( $this->name ) ); |
||
303 | if ( isset( $_GET['quiz_id'] ) ) { |
||
304 | $quiz_id = intval( $_GET['quiz_id'] ); |
||
305 | $lesson_id = get_post_meta( $quiz_id, '_quiz_lesson', true ); |
||
306 | $course_id = get_post_meta( $lesson_id, '_lesson_course', true ); |
||
307 | View Code Duplication | if ( version_compare($wp_version, '4.1', '>=') ) { |
|
308 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
309 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) ); |
||
310 | } |
||
311 | else { |
||
312 | $title .= sprintf( ' <span class="course-title">> %s</span>', get_the_title( $course_id ) ); |
||
313 | } |
||
314 | $url = add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $lesson_id ), admin_url( 'admin.php' ) ); |
||
315 | $title .= sprintf( ' <span class="lesson-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $lesson_id ) ); |
||
316 | } |
||
317 | View Code Duplication | if ( isset( $_GET['user'] ) && 0 < intval( $_GET['user'] ) ) { |
|
318 | |||
319 | $user_name = Sensei_Learner::get_full_name( $_GET['user'] ); |
||
320 | $title .= ' <span class="user-title">> ' . $user_name . '</span>'; |
||
321 | |||
322 | } // End If Statement |
||
323 | ?> |
||
324 | <h2><?php echo apply_filters( 'sensei_grading_nav_title', $title ); ?></h2> |
||
325 | <?php |
||
326 | } // End grading_user_quiz_nav() |
||
327 | |||
328 | /** |
||
329 | * Return array of valid statuses for either Course or Lesson |
||
330 | * @since 1.7.0 |
||
331 | * @return array |
||
332 | */ |
||
333 | public function get_stati( $type ) { |
||
334 | $statuses = array(); |
||
335 | switch( $type ) { |
||
336 | case 'course' : |
||
337 | $statuses = array( |
||
338 | 'in-progress', |
||
339 | 'complete', |
||
340 | ); |
||
341 | break; |
||
342 | |||
343 | case 'lesson' : |
||
344 | $statuses = array( |
||
345 | 'in-progress', |
||
346 | 'complete', |
||
347 | 'ungraded', |
||
348 | 'graded', |
||
349 | 'passed', |
||
350 | 'failed', |
||
351 | ); |
||
352 | break; |
||
353 | |||
354 | } |
||
355 | return $statuses; |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Count the various statuses for Course or Lesson |
||
360 | * Very similar to get_comment_count() |
||
361 | * @since 1.7.0 |
||
362 | * @param array $args (default: array()) |
||
363 | * @return object |
||
364 | */ |
||
365 | public function count_statuses( $args = array() ) { |
||
366 | global $wpdb; |
||
367 | |||
368 | /** |
||
369 | * Filter fires inside Sensei_Grading::count_statuses |
||
370 | * |
||
371 | * Alter the the post_in array to determine which posts the |
||
372 | * comment query should be limited to. |
||
373 | * @since 1.8.0 |
||
374 | * @param array $args |
||
375 | */ |
||
376 | $args = apply_filters( 'sensei_count_statuses_args', $args ); |
||
377 | |||
378 | if ( 'course' == $args['type'] ) { |
||
379 | $type = 'sensei_course_status'; |
||
380 | } |
||
381 | else { |
||
382 | $type = 'sensei_lesson_status'; |
||
383 | } |
||
384 | $cache_key = 'sensei-' . $args['type'] . '-statuses'; |
||
385 | |||
386 | $query = "SELECT comment_approved, COUNT( * ) AS total FROM {$wpdb->comments} WHERE comment_type = %s "; |
||
387 | |||
388 | // Restrict to specific posts |
||
389 | View Code Duplication | if ( isset( $args['post__in'] ) && !empty( $args['post__in'] ) && is_array( $args['post__in'] ) ) { |
|
0 ignored issues
–
show
|
|||
390 | $query .= ' AND comment_post_ID IN (' . implode( ',', array_map( 'absint', $args['post__in'] ) ) . ')'; |
||
391 | } |
||
392 | elseif ( !empty( $args['post_id'] ) ) { |
||
393 | $query .= $wpdb->prepare( ' AND comment_post_ID = %d', $args['post_id'] ); |
||
394 | } |
||
395 | // Restrict to specific users |
||
396 | View Code Duplication | if ( isset( $args['user_id'] ) && is_array( $args['user_id'] ) ) { |
|
397 | $query .= ' AND user_id IN (' . implode( ',', array_map( 'absint', $args['user_id'] ) ) . ')'; |
||
398 | } |
||
399 | elseif ( !empty( $args['user_id'] ) ) { |
||
400 | $query .= $wpdb->prepare( ' AND user_id = %d', $args['user_id'] ); |
||
401 | } |
||
402 | $query .= ' GROUP BY comment_approved'; |
||
403 | |||
404 | $counts = wp_cache_get( $cache_key, 'counts' ); |
||
405 | if ( false === $counts ) { |
||
406 | $sql = $wpdb->prepare( $query, $type ); |
||
407 | $results = (array) $wpdb->get_results( $sql, ARRAY_A ); |
||
408 | $counts = array_fill_keys( $this->get_stati( $type ), 0 ); |
||
409 | |||
410 | foreach ( $results as $row ) { |
||
411 | $counts[ $row['comment_approved'] ] = $row['total']; |
||
412 | } |
||
413 | wp_cache_set( $cache_key, $counts, 'counts' ); |
||
414 | } |
||
415 | |||
416 | if( ! isset( $counts['graded'] ) ) { |
||
417 | $counts['graded'] = 0; |
||
418 | } |
||
419 | |||
420 | if( ! isset( $counts['ungraded'] ) ) { |
||
421 | $counts['ungraded'] = 0; |
||
422 | } |
||
423 | |||
424 | if( ! isset( $counts['passed'] ) ) { |
||
425 | $counts['passed'] = 0; |
||
426 | } |
||
427 | |||
428 | if( ! isset( $counts['failed'] ) ) { |
||
429 | $counts['failed'] = 0; |
||
430 | } |
||
431 | |||
432 | if( ! isset( $counts['in-progress'] ) ) { |
||
433 | $counts['in-progress'] = 0; |
||
434 | } |
||
435 | |||
436 | if( ! isset( $counts['complete'] ) ) { |
||
437 | $counts['complete'] = 0; |
||
438 | } |
||
439 | |||
440 | return apply_filters( 'sensei_count_statuses', $counts, $type ); |
||
441 | } // End sensei_count_statuses() |
||
442 | |||
443 | /** |
||
444 | * Build the Courses dropdown for return in AJAX |
||
445 | * @since 1.7.0 |
||
446 | * @return string |
||
447 | */ |
||
448 | public function courses_drop_down_html( $selected_course_id = 0 ) { |
||
449 | |||
450 | $html = ''; |
||
451 | |||
452 | $course_args = array( 'post_type' => 'course', |
||
453 | 'posts_per_page' => -1, |
||
454 | 'orderby' => 'title', |
||
455 | 'order' => 'ASC', |
||
456 | 'post_status' => 'any', |
||
457 | 'suppress_filters' => 0, |
||
458 | 'fields' => 'ids', |
||
459 | ); |
||
460 | $courses = get_posts( apply_filters( 'sensei_grading_filter_courses', $course_args ) ); |
||
461 | |||
462 | $html .= '<option value="">' . __( 'Select a course', 'woothemes-sensei' ) . '</option>'; |
||
463 | View Code Duplication | if ( count( $courses ) > 0 ) { |
|
464 | foreach ($courses as $course_id){ |
||
465 | $html .= '<option value="' . esc_attr( absint( $course_id ) ) . '" ' . selected( $course_id, $selected_course_id, false ) . '>' . esc_html( get_the_title( $course_id ) ) . '</option>' . "\n"; |
||
466 | } // End For Loop |
||
467 | } // End If Statement |
||
468 | |||
469 | return $html; |
||
470 | } // End lessons_drop_down_html() |
||
471 | |||
472 | /** |
||
473 | * Build the Lessons dropdown for return in AJAX |
||
474 | * @since 1.? |
||
475 | * @return string |
||
476 | */ |
||
477 | public function get_lessons_dropdown() { |
||
478 | |||
479 | $posts_array = array(); |
||
480 | |||
481 | // Parse POST data |
||
482 | $data = $_POST['data']; |
||
483 | $course_data = array(); |
||
484 | parse_str($data, $course_data); |
||
485 | |||
486 | $course_id = intval( $course_data['course_id'] ); |
||
487 | |||
488 | $html = $this->lessons_drop_down_html( $course_id ); |
||
489 | |||
490 | echo $html; |
||
491 | die(); // WordPress may print out a spurious zero without this can be particularly bad if using JSON |
||
492 | } |
||
493 | |||
494 | public function lessons_drop_down_html( $course_id = 0, $selected_lesson_id = 0 ) { |
||
495 | |||
496 | $html = ''; |
||
497 | if ( 0 < intval( $course_id ) ) { |
||
498 | |||
499 | $lesson_args = array( 'post_type' => 'lesson', |
||
500 | 'posts_per_page' => -1, |
||
501 | 'orderby' => 'title', |
||
502 | 'order' => 'ASC', |
||
503 | 'meta_key' => '_lesson_course', |
||
504 | 'meta_value' => $course_id, |
||
505 | 'post_status' => 'publish', |
||
506 | 'suppress_filters' => 0, |
||
507 | 'fields' => 'ids', |
||
508 | ); |
||
509 | $lessons = get_posts( apply_filters( 'sensei_grading_filter_lessons', $lesson_args ) ); |
||
510 | |||
511 | $html .= '<option value="">' . __( 'Select a lesson', 'woothemes-sensei' ) . '</option>'; |
||
512 | View Code Duplication | if ( count( $lessons ) > 0 ) { |
|
513 | foreach ( $lessons as $lesson_id ){ |
||
514 | $html .= '<option value="' . esc_attr( absint( $lesson_id ) ) . '" ' . selected( $lesson_id, $selected_lesson_id, false ) . '>' . esc_html( get_the_title( $lesson_id ) ) . '</option>' . "\n"; |
||
515 | } // End For Loop |
||
516 | } // End If Statement |
||
517 | |||
518 | } // End If Statement |
||
519 | |||
520 | return $html; |
||
521 | } // End lessons_drop_down_html() |
||
522 | |||
523 | /** |
||
524 | * The process grading function handles admin grading submissions. |
||
525 | * |
||
526 | * This function is hooked on to admin_init. It simply accepts |
||
527 | * the grades as the Grader selected theme and saves the total grade and |
||
528 | * individual question grades. |
||
529 | * |
||
530 | * @return bool |
||
531 | */ |
||
532 | public function admin_process_grading_submission() { |
||
533 | |||
534 | // NEEDS REFACTOR/OPTIMISING, such as combining the various meta data stored against the sensei_user_answer entry |
||
535 | if( ! isset( $_POST['sensei_manual_grade'] ) |
||
536 | || ! wp_verify_nonce( $_POST['_wp_sensei_manual_grading_nonce'], 'sensei_manual_grading' ) |
||
537 | || ! isset( $_GET['quiz_id'] ) |
||
538 | || $_GET['quiz_id'] != $_POST['sensei_manual_grade'] ) { |
||
539 | |||
540 | return false; //exit and do not grade |
||
541 | |||
542 | } |
||
543 | |||
544 | $quiz_id = $_GET['quiz_id']; |
||
545 | $user_id = $_GET['user']; |
||
546 | |||
547 | |||
548 | $questions = Sensei_Utils::sensei_get_quiz_questions( $quiz_id ); |
||
549 | $quiz_lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ); |
||
550 | $quiz_grade = 0; |
||
551 | $count = 0; |
||
552 | $quiz_grade_total = $_POST['quiz_grade_total']; |
||
553 | $all_question_grades = array(); |
||
554 | $all_answers_feedback = array(); |
||
555 | |||
556 | foreach( $questions as $question ) { |
||
557 | |||
558 | ++$count; |
||
559 | $question_id = $question->ID; |
||
560 | |||
561 | if( isset( $_POST[ 'question_' . $question_id ] ) ) { |
||
562 | |||
563 | $question_grade = 0; |
||
564 | if( $_POST[ 'question_' . $question_id ] == 'right' ) { |
||
565 | |||
566 | $question_grade = $_POST[ 'question_' . $question_id . '_grade' ]; |
||
567 | |||
568 | } |
||
569 | |||
570 | // add data to the array that will, after the loop, be stored on the lesson status |
||
571 | $all_question_grades[ $question_id ] = $question_grade; |
||
572 | |||
573 | // tally up the total quiz grade |
||
574 | $quiz_grade += $question_grade; |
||
575 | |||
576 | } // endif |
||
577 | |||
578 | // Question answer feedback / notes |
||
579 | $question_feedback = ''; |
||
580 | if( isset( $_POST[ 'questions_feedback' ][ $question_id ] ) ){ |
||
581 | |||
582 | $question_feedback = wp_unslash( $_POST[ 'questions_feedback' ][ $question_id ] ); |
||
583 | |||
584 | } |
||
585 | $all_answers_feedback[ $question_id ] = $question_feedback; |
||
586 | |||
587 | } // end for each $questions |
||
588 | |||
589 | //store all question grades on the lesson status |
||
590 | Sensei()->quiz->set_user_grades( $all_question_grades, $quiz_lesson_id , $user_id ); |
||
591 | |||
592 | //store the feedback from grading |
||
593 | Sensei()->quiz->save_user_answers_feedback( $all_answers_feedback, $quiz_lesson_id , $user_id ); |
||
594 | |||
595 | // $_POST['all_questions_graded'] is set when all questions have been graded |
||
596 | // in the class sensei grading user quiz -> display() |
||
597 | if( $_POST['all_questions_graded'] == 'yes' ) { |
||
598 | |||
599 | // set the users total quiz grade |
||
600 | if ( 0 < intval( $quiz_grade_total ) ) { |
||
601 | $grade = abs( round( ( doubleval( $quiz_grade ) * 100 ) / ( $quiz_grade_total ), 2 ) ); |
||
602 | } |
||
603 | else { |
||
604 | $grade = 0; |
||
605 | } |
||
606 | Sensei_Utils::sensei_grade_quiz( $quiz_id, $grade, $user_id ); |
||
607 | |||
608 | // Duplicating what Frontend->sensei_complete_quiz() does |
||
609 | $pass_required = get_post_meta( $quiz_id, '_pass_required', true ); |
||
610 | $quiz_passmark = abs( round( doubleval( get_post_meta( $quiz_id, '_quiz_passmark', true ) ), 2 ) ); |
||
611 | $lesson_metadata = array(); |
||
612 | View Code Duplication | if ( $pass_required ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
613 | // Student has reached the pass mark and lesson is complete |
||
614 | if ( $quiz_passmark <= $grade ) { |
||
615 | $lesson_status = 'passed'; |
||
616 | } |
||
617 | else { |
||
618 | $lesson_status = 'failed'; |
||
619 | } // End If Statement |
||
620 | } |
||
621 | // Student only has to partake the quiz |
||
622 | else { |
||
623 | $lesson_status = 'graded'; |
||
624 | } |
||
625 | $lesson_metadata['grade'] = $grade; // Technically already set as part of "WooThemes_Sensei_Utils::sensei_grade_quiz()" above |
||
626 | |||
627 | Sensei_Utils::update_lesson_status( $user_id, $quiz_lesson_id, $lesson_status, $lesson_metadata ); |
||
628 | |||
629 | if( in_array( $lesson_status, array( 'passed', 'graded' ) ) ) { |
||
630 | |||
631 | /** |
||
632 | * Summary. |
||
633 | * |
||
634 | * Description. |
||
635 | * |
||
636 | * @since 1.7.0 |
||
637 | * |
||
638 | * @param int $user_id |
||
639 | * @param int $quiz_lesson_id |
||
640 | */ |
||
641 | do_action( 'sensei_user_lesson_end', $user_id, $quiz_lesson_id ); |
||
642 | |||
643 | } // end if in_array |
||
644 | |||
645 | }// end if $_POST['all_que... |
||
646 | |||
647 | if( isset( $_POST['sensei_grade_next_learner'] ) && strlen( $_POST['sensei_grade_next_learner'] ) > 0 ) { |
||
648 | |||
649 | $load_url = add_query_arg( array( 'message' => 'graded' ) ); |
||
650 | |||
651 | } elseif ( isset( $_POST['_wp_http_referer'] ) ) { |
||
652 | |||
653 | $load_url = add_query_arg( array( 'message' => 'graded' ), $_POST['_wp_http_referer'] ); |
||
654 | |||
655 | } else { |
||
656 | |||
657 | $load_url = add_query_arg( array( 'message' => 'graded' ) ); |
||
658 | |||
659 | } |
||
660 | |||
661 | wp_safe_redirect( esc_url_raw( $load_url ) ); |
||
662 | exit; |
||
663 | |||
664 | } // end admin_process_grading_submission |
||
665 | |||
666 | public function get_redirect_url() { |
||
667 | // Parse POST data |
||
668 | $data = $_POST['data']; |
||
669 | $lesson_data = array(); |
||
670 | parse_str($data, $lesson_data); |
||
671 | |||
672 | $lesson_id = intval( $lesson_data['lesson_id'] ); |
||
673 | $course_id = intval( $lesson_data['course_id'] ); |
||
674 | $grading_view = sanitize_text_field( $lesson_data['view'] ); |
||
675 | |||
676 | $redirect_url = ''; |
||
677 | if ( 0 < $lesson_id && 0 < $course_id ) { |
||
678 | $redirect_url = esc_url_raw( apply_filters( 'sensei_ajax_redirect_url', add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $lesson_id, 'course_id' => $course_id, 'view' => $grading_view ), admin_url( 'admin.php' ) ) ) ); |
||
679 | } // End If Statement |
||
680 | |||
681 | echo $redirect_url; |
||
682 | die(); |
||
683 | } |
||
684 | |||
685 | public function add_grading_notices() { |
||
686 | if( isset( $_GET['page'] ) && $this->page_slug == $_GET['page'] && isset( $_GET['message'] ) && $_GET['message'] ) { |
||
687 | if( 'graded' == $_GET['message'] ) { |
||
688 | $msg = array( |
||
689 | 'updated', |
||
690 | __( 'Quiz Graded Successfully!', 'woothemes-sensei' ), |
||
691 | ); |
||
692 | } |
||
693 | ?> |
||
694 | <div class="grading-notice <?php echo $msg[0]; ?>"> |
||
695 | <p><?php echo $msg[1]; ?></p> |
||
696 | </div> |
||
697 | <?php |
||
698 | } |
||
699 | } |
||
700 | |||
701 | public function sensei_grading_notices() { |
||
702 | if ( isset( $_GET['action'] ) && 'graded' == $_GET['action'] ) { |
||
703 | echo '<div class="grading-notice updated">'; |
||
704 | echo '<p>' . __( 'Quiz Graded Successfully!', 'woothemes-sensei' ) . '</p>'; |
||
705 | echo '</div>'; |
||
706 | } // End If Statement |
||
707 | } // End sensei_grading_notices() |
||
708 | |||
709 | /** |
||
710 | * Grade quiz automatically |
||
711 | * |
||
712 | * This function grades each question automatically if there all questions are auto gradable. If not |
||
713 | * the quiz will not be auto gradable. |
||
714 | * |
||
715 | * @since 1.7.4 |
||
716 | * |
||
717 | * @param integer $quiz_id ID of quiz |
||
718 | * @param array $submitted questions id ans answers { |
||
719 | * @type int $question_id |
||
720 | * @type mixed $answer |
||
721 | * } |
||
722 | * @param integer $total_questions Total questions in quiz (not used) |
||
723 | * @param string $quiz_grade_type Optional defaults to auto |
||
724 | * |
||
725 | * @return int $quiz_grade total sum of all question grades |
||
726 | */ |
||
727 | public static function grade_quiz_auto( $quiz_id = 0, $submitted = array(), $total_questions = 0, $quiz_grade_type = 'auto' ) { |
||
0 ignored issues
–
show
|
|||
728 | |||
729 | if( ! ( intval( $quiz_id ) > 0 ) || ! $submitted |
||
0 ignored issues
–
show
The expression
$submitted of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
730 | || $quiz_grade_type != 'auto' ) { |
||
731 | return false; // exit early |
||
732 | } |
||
733 | |||
734 | |||
735 | $user_id = get_current_user_id(); |
||
736 | $lesson_id = Sensei()->quiz->get_lesson_id( $quiz_id ) ; |
||
737 | $quiz_autogradable = true; |
||
738 | |||
739 | /** |
||
740 | * Filter the types of question types that can be automatically graded. |
||
741 | * |
||
742 | * This filter fires inside the auto grade quiz function and provides you with the default list. |
||
743 | * |
||
744 | * @param array { |
||
745 | * 'multiple-choice', |
||
746 | * 'boolean', |
||
747 | * 'gap-fill'. |
||
748 | * } |
||
749 | */ |
||
750 | $autogradable_question_types = apply_filters( 'sensei_autogradable_question_types', array( 'multiple-choice', 'boolean', 'gap-fill' ) ); |
||
751 | |||
752 | $grade_total = 0; |
||
753 | $all_question_grades = array(); |
||
754 | foreach( $submitted as $question_id => $answer ) { |
||
755 | |||
756 | // check if the question is autogradable, either by type, or because the grade is 0 |
||
757 | $question_type = Sensei()->question->get_question_type( $question_id ); |
||
758 | $achievable_grade = Sensei()->question->get_question_grade( $question_id ); |
||
759 | // Question has a zero grade, so skip grading |
||
760 | if ( 0 == $achievable_grade ) { |
||
761 | $all_question_grades[ $question_id ] = $achievable_grade; |
||
762 | } |
||
763 | elseif ( in_array( $question_type, $autogradable_question_types ) ) { |
||
764 | // Get user question grade |
||
765 | $question_grade = Sensei_Utils::sensei_grade_question_auto( $question_id, $question_type, $answer, $user_id ); |
||
0 ignored issues
–
show
The method
Sensei_Utils::sensei_grade_question_auto() has been deprecated with message: since 1.7.4 use WooThemes_Sensei_Grading::grade_question_auto instead
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead. ![]() |
|||
766 | $all_question_grades[ $question_id ] = $question_grade; |
||
767 | $grade_total += $question_grade; |
||
768 | |||
769 | } else { |
||
770 | |||
771 | // There is a question that cannot be autograded |
||
772 | $quiz_autogradable = false; |
||
773 | |||
774 | } // end if in_array( $question_type... |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
40% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
775 | |||
776 | }// end for each question |
||
777 | |||
778 | // Only if the whole quiz was autogradable do we set a grade |
||
779 | if ( $quiz_autogradable ) { |
||
780 | |||
781 | $quiz_total = Sensei_Utils::sensei_get_quiz_total( $quiz_id ); |
||
782 | // Check for zero total from grades |
||
783 | if ( 0 < $quiz_total ) { |
||
784 | $grade = abs( round( ( doubleval( $grade_total ) * 100 ) / ( $quiz_total ), 2 ) ); |
||
785 | } |
||
786 | else { |
||
787 | $grade = 0; |
||
788 | } |
||
789 | Sensei_Utils::sensei_grade_quiz( $quiz_id, $grade, $user_id, $quiz_grade_type ); |
||
790 | |||
791 | } else { |
||
792 | |||
793 | $grade = new WP_Error( 'autograde', __( 'This quiz is not able to be automatically graded.', 'woothemes-sensei' ) ); |
||
794 | |||
795 | } |
||
796 | |||
797 | // store the auto gradable grades. If the quiz is not auto gradable the grades can be use as the default |
||
798 | // when doing manual grading. |
||
799 | Sensei()->quiz-> set_user_grades( $all_question_grades, $lesson_id, $user_id ); |
||
800 | |||
801 | return $grade; |
||
802 | |||
803 | } // End grade_quiz_auto() |
||
804 | |||
805 | /** |
||
806 | * Grade question automatically |
||
807 | * |
||
808 | * This function checks the question typ and then grades it accordingly. |
||
809 | * |
||
810 | * @since 1.7.4 |
||
811 | * |
||
812 | * @param integer $question_id |
||
813 | * @param string $question_type of the standard Sensei question types |
||
814 | * @param string $answer |
||
815 | * @param int $user_id |
||
816 | * |
||
817 | * @return int $question_grade |
||
818 | */ |
||
819 | public static function grade_question_auto( $question_id = 0, $question_type = '', $answer = '', $user_id = 0 ) { |
||
820 | |||
821 | if( intval( $user_id ) == 0 ) { |
||
822 | |||
823 | $user_id = get_current_user_id(); |
||
0 ignored issues
–
show
$user_id is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
824 | |||
825 | } |
||
826 | |||
827 | if( ! ( intval( $question_id ) > 0 ) ) { |
||
828 | |||
829 | return false; |
||
830 | |||
831 | } |
||
832 | |||
833 | |||
834 | Sensei()->question->get_question_type( $question_id ); |
||
835 | |||
836 | /** |
||
837 | * Applying a grade before the auto grading takes place. |
||
838 | * |
||
839 | * This filter is applied just before the question is auto graded. It fires in the context of a single question |
||
840 | * in the sensei_grade_question_auto function. It fires irrespective of the question type. If you return a value |
||
841 | * other than false the auto grade functionality will be ignored and your supplied grade will be user for this question. |
||
842 | * |
||
843 | * @param int $question_grade default false |
||
844 | * @param int $question_id |
||
845 | * @param string $question_type one of the Sensei question type. |
||
846 | * @param string $answer user supplied question answer |
||
847 | */ |
||
848 | $question_grade = apply_filters( 'sensei_pre_grade_question_auto', false, $question_id, $question_type, $answer ); |
||
849 | |||
850 | if ( false !== $question_grade ) { |
||
851 | |||
852 | return $question_grade; |
||
853 | |||
854 | } |
||
855 | |||
856 | // auto grading core |
||
857 | if( in_array( $question_type , array( 'multiple-choice' , 'boolean' ) ) ){ |
||
858 | |||
859 | $right_answer = (array) get_post_meta( $question_id, '_question_right_answer', true ); |
||
860 | |||
861 | if( 0 == get_magic_quotes_gpc() ) { |
||
862 | $answer = wp_unslash( $answer ); |
||
863 | } |
||
864 | $answer = (array) $answer; |
||
865 | if ( is_array( $right_answer ) && count( $right_answer ) == count( $answer ) ) { |
||
866 | // Loop through all answers ensure none are 'missing' |
||
867 | $all_correct = true; |
||
868 | foreach ( $answer as $check_answer ) { |
||
869 | if ( !in_array( $check_answer, $right_answer ) ) { |
||
870 | $all_correct = false; |
||
871 | } |
||
872 | } |
||
873 | // If all correct then grade |
||
874 | if ( $all_correct ) { |
||
875 | $question_grade = Sensei()->question->get_question_grade( $question_id ); |
||
876 | } |
||
877 | } |
||
878 | |||
879 | } elseif( 'gap-fill' == $question_type ){ |
||
880 | |||
881 | $question_grade = self::grade_gap_fill_question( $question_id ,$answer ); |
||
882 | |||
883 | } else{ |
||
884 | |||
885 | /** |
||
886 | * Grading questions that are not auto gradable. |
||
887 | * |
||
888 | * This filter is applied the context of ta single question within the sensei_grade_question_auto function. |
||
889 | * It fires for all other questions types. It does not apply to 'multiple-choice' , 'boolean' and gap-fill. |
||
890 | * |
||
891 | * @param int $question_grade default zero |
||
892 | * @param int $question_id |
||
893 | * @param string $question_type one of the Sensei question type. |
||
894 | * @param string $answer user supplied question answer |
||
895 | */ |
||
896 | $question_grade = ( int ) apply_filters( 'sensei_grade_question_auto', $question_grade, $question_id, $question_type, $answer ); |
||
897 | |||
898 | } // end if $question_type |
||
899 | |||
900 | return $question_grade; |
||
901 | } // end grade_question_auto |
||
902 | |||
903 | /** |
||
904 | * Grading logic specifically for the gap fill questions |
||
905 | * |
||
906 | * @since 1.9.0 |
||
907 | * @param $question_id |
||
908 | * @param $user_answer |
||
909 | * |
||
910 | * @return bool | int false or the grade given to the user answer |
||
911 | */ |
||
912 | public static function grade_gap_fill_question( $question_id, $user_answer ){ |
||
913 | |||
914 | $right_answer = get_post_meta( $question_id, '_question_right_answer', true ); |
||
915 | $gapfill_array = explode( '||', $right_answer ); |
||
916 | |||
917 | if( 0 == get_magic_quotes_gpc() ) { // deprecated from PHP 5.4 but we still support PHP 5.2 |
||
918 | $user_answer = wp_unslash( $user_answer ); |
||
919 | } |
||
920 | |||
921 | /** |
||
922 | * case sensitive grading filter |
||
923 | * |
||
924 | * alter the value simply use this code in your plugin or the themes functions.php |
||
925 | * add_filter( 'sensei_gap_fill_case_sensitive_grading','__return_true' ); |
||
926 | * |
||
927 | * @param bool $do_case_sensitive_comparison default false. |
||
928 | * |
||
929 | * @since 1.9.0 |
||
930 | */ |
||
931 | $do_case_sensitive_comparison = apply_filters('sensei_gap_fill_case_sensitive_grading', false ); |
||
932 | |||
933 | if( $do_case_sensitive_comparison ){ |
||
934 | |||
935 | // Case Sensitive Check that the 'gap' is "exactly" equal to the given answer |
||
936 | View Code Duplication | if ( trim(($gapfill_array[1])) == trim( $user_answer ) ) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
937 | |||
938 | return Sensei()->question->get_question_grade( $question_id ); |
||
939 | |||
940 | } else if (@preg_match('/' . $gapfill_array[1] . '/i', null) !== FALSE) { |
||
941 | |||
942 | if (preg_match('/' . $gapfill_array[1] . '/i', $user_answer)) { |
||
943 | |||
944 | return Sensei()->question->get_question_grade($question_id); |
||
945 | |||
946 | }else{ |
||
947 | |||
948 | return false; |
||
949 | |||
950 | } |
||
951 | |||
952 | }else{ |
||
953 | |||
954 | return false; |
||
955 | |||
956 | } |
||
957 | |||
958 | View Code Duplication | }else{ |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
959 | |||
960 | // Case Sensitive Check that the 'gap' is "exactly" equal to the given answer |
||
961 | if ( trim(strtolower($gapfill_array[1])) == trim(strtolower( $user_answer )) ) { |
||
962 | |||
963 | return Sensei()->question->get_question_grade( $question_id ); |
||
964 | |||
965 | } else if (@preg_match('/' . $gapfill_array[1] . '/i', null) !== FALSE) { |
||
966 | |||
967 | if (preg_match('/' . $gapfill_array[1] . '/i', $user_answer)) { |
||
968 | |||
969 | return Sensei()->question->get_question_grade( $question_id ); |
||
970 | |||
971 | }else{ |
||
972 | |||
973 | return false; |
||
974 | |||
975 | } |
||
976 | |||
977 | }else{ |
||
978 | |||
979 | return false; |
||
980 | |||
981 | } |
||
982 | |||
983 | } |
||
984 | |||
985 | } |
||
986 | |||
987 | /** |
||
988 | * Counts the lessons that have been graded manually and automatically |
||
989 | * |
||
990 | * @since 1.9.0 |
||
991 | * @return int $number_of_graded_lessons |
||
992 | */ |
||
993 | public static function get_graded_lessons_count(){ |
||
994 | |||
995 | global $wpdb; |
||
996 | |||
997 | $comment_query_piece[ 'select'] = "SELECT COUNT(*) AS total"; |
||
998 | $comment_query_piece[ 'from'] = " FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON ( {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id ) "; |
||
999 | $comment_query_piece[ 'where'] = " WHERE {$wpdb->comments}.comment_type IN ('sensei_lesson_status') AND ( {$wpdb->commentmeta}.meta_key = 'grade')"; |
||
1000 | $comment_query_piece[ 'orderby'] = " ORDER BY {$wpdb->comments}.comment_date_gmt DESC "; |
||
1001 | |||
1002 | $comment_query = $comment_query_piece['select'] . $comment_query_piece['from'] . $comment_query_piece['where'] . $comment_query_piece['orderby']; |
||
1003 | $number_of_graded_lessons = intval( $wpdb->get_var( $comment_query, 0, 0 ) ); |
||
1004 | |||
1005 | return $number_of_graded_lessons; |
||
1006 | } |
||
1007 | |||
1008 | /** |
||
1009 | * Add together all the graded lesson grades |
||
1010 | * |
||
1011 | * @since 1.9.0 |
||
1012 | * @return double $sum_of_all_grades |
||
1013 | */ |
||
1014 | public static function get_graded_lessons_sum(){ |
||
1015 | |||
1016 | global $wpdb; |
||
1017 | |||
1018 | $comment_query_piece[ 'select'] = "SELECT SUM({$wpdb->commentmeta}.meta_value) AS meta_sum"; |
||
1019 | $comment_query_piece[ 'from'] = " FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON ( {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id ) "; |
||
1020 | $comment_query_piece[ 'where'] = " WHERE {$wpdb->comments}.comment_type IN ('sensei_lesson_status') AND ( {$wpdb->commentmeta}.meta_key = 'grade')"; |
||
1021 | $comment_query_piece[ 'orderby'] = " ORDER BY {$wpdb->comments}.comment_date_gmt DESC "; |
||
1022 | |||
1023 | $comment_query = $comment_query_piece['select'] . $comment_query_piece['from'] . $comment_query_piece['where'] . $comment_query_piece['orderby']; |
||
1024 | $sum_of_all_grades = intval( $wpdb->get_var( $comment_query, 0, 0 ) ); |
||
1025 | |||
1026 | return $sum_of_all_grades; |
||
1027 | |||
1028 | } |
||
1029 | |||
1030 | /** |
||
1031 | * Get the sum of all grades for the given user. |
||
1032 | * |
||
1033 | * @since 1.9.0 |
||
1034 | * @param $user_id |
||
1035 | * @return double |
||
1036 | */ |
||
1037 | View Code Duplication | public static function get_user_graded_lessons_sum( $user_id ){ |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1038 | global $wpdb; |
||
1039 | |||
1040 | $clean_user_id = esc_sql( $user_id); |
||
1041 | $comment_query_piece[ 'select'] = "SELECT SUM({$wpdb->commentmeta}.meta_value) AS meta_sum"; |
||
1042 | $comment_query_piece[ 'from'] = " FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON ( {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id ) "; |
||
1043 | $comment_query_piece[ 'where'] = " WHERE {$wpdb->comments}.comment_type IN ('sensei_lesson_status') AND ( {$wpdb->commentmeta}.meta_key = 'grade') AND {$wpdb->comments}.user_id = {$clean_user_id} "; |
||
1044 | $comment_query_piece[ 'orderby'] = " ORDER BY {$wpdb->comments}.comment_date_gmt DESC "; |
||
1045 | |||
1046 | $comment_query = $comment_query_piece['select'] . $comment_query_piece['from'] . $comment_query_piece['where'] . $comment_query_piece['orderby']; |
||
1047 | $sum_of_all_grades = intval( $wpdb->get_var( $comment_query, 0, 0 ) ); |
||
1048 | |||
1049 | return $sum_of_all_grades; |
||
1050 | } |
||
1051 | |||
1052 | /** |
||
1053 | * Get the sum of all user grades for the given lesson. |
||
1054 | * |
||
1055 | * @since 1.9.0 |
||
1056 | * |
||
1057 | * @param int lesson_id |
||
1058 | * @return double |
||
1059 | */ |
||
1060 | View Code Duplication | public static function get_lessons_users_grades_sum( $lesson_id ){ |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1061 | |||
1062 | global $wpdb; |
||
1063 | |||
1064 | $clean_lesson_id = esc_sql( $lesson_id); |
||
1065 | $comment_query_piece[ 'select'] = "SELECT SUM({$wpdb->commentmeta}.meta_value) AS meta_sum"; |
||
1066 | $comment_query_piece[ 'from'] = " FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON ( {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id ) "; |
||
1067 | $comment_query_piece[ 'where'] = " WHERE {$wpdb->comments}.comment_type IN ('sensei_lesson_status') AND ( {$wpdb->commentmeta}.meta_key = 'grade') AND {$wpdb->comments}.comment_post_ID = {$clean_lesson_id} "; |
||
1068 | $comment_query_piece[ 'orderby'] = " ORDER BY {$wpdb->comments}.comment_date_gmt DESC "; |
||
1069 | |||
1070 | $comment_query = $comment_query_piece['select'] . $comment_query_piece['from'] . $comment_query_piece['where'] . $comment_query_piece['orderby']; |
||
1071 | $sum_of_all_grades = intval( $wpdb->get_var( $comment_query, 0, 0 ) ); |
||
1072 | |||
1073 | return $sum_of_all_grades; |
||
1074 | |||
1075 | }//get_lessons_user_grades_sum |
||
1076 | |||
1077 | /** |
||
1078 | * Get the sum of all user grades for the given course. |
||
1079 | * |
||
1080 | * @since 1.9.0 |
||
1081 | * |
||
1082 | * @param int $course_id |
||
1083 | * @return double |
||
1084 | */ |
||
1085 | View Code Duplication | public static function get_course_users_grades_sum( $course_id ){ |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1086 | |||
1087 | global $wpdb; |
||
1088 | |||
1089 | $clean_course_id = esc_sql( $course_id); |
||
1090 | $comment_query_piece[ 'select'] = "SELECT SUM({$wpdb->commentmeta}.meta_value) AS meta_sum"; |
||
1091 | $comment_query_piece[ 'from'] = " FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON ( {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id ) "; |
||
1092 | $comment_query_piece[ 'where'] = " WHERE {$wpdb->comments}.comment_type IN ('sensei_course_status') AND ( {$wpdb->commentmeta}.meta_key = 'percent') AND {$wpdb->comments}.comment_post_ID = {$clean_course_id} "; |
||
1093 | $comment_query_piece[ 'orderby'] = " ORDER BY {$wpdb->comments}.comment_date_gmt DESC "; |
||
1094 | |||
1095 | $comment_query = $comment_query_piece['select'] . $comment_query_piece['from'] . $comment_query_piece['where'] . $comment_query_piece['orderby']; |
||
1096 | $sum_of_all_grades = intval( $wpdb->get_var( $comment_query, 0, 0 ) ); |
||
1097 | |||
1098 | return $sum_of_all_grades; |
||
1099 | |||
1100 | }//get_lessons_user_grades_sum |
||
1101 | |||
1102 | } // End Class |
||
1103 | |||
1104 | /** |
||
1105 | * Class WooThemes_Sensei_Grading |
||
1106 | * @ignore only for backward compatibility |
||
1107 | * @since 1.9.0 |
||
1108 | */ |
||
1109 | class WooThemes_Sensei_Grading extends Sensei_Grading{} |
||
1110 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.