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 |
||
0 ignored issues
–
show
|
|||
2 | if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
||
3 | |||
4 | /** |
||
5 | * Admin Analysis Course Data Table in Sensei. |
||
6 | * |
||
7 | * @package Analytics |
||
8 | * @author Automattic |
||
9 | * @since 1.2.0 |
||
10 | */ |
||
11 | class Sensei_Analysis_Course_List_Table extends WooThemes_Sensei_List_Table { |
||
12 | public $user_id; |
||
13 | public $course_id; |
||
14 | public $total_lessons; |
||
15 | public $user_ids; |
||
16 | public $view = 'lesson'; |
||
17 | public $page_slug = 'sensei_analysis'; |
||
18 | |||
19 | /** |
||
20 | * Constructor |
||
21 | * @since 1.2.0 |
||
22 | */ |
||
23 | public function __construct ( $course_id = 0, $user_id = 0 ) { |
||
24 | $this->course_id = intval( $course_id ); |
||
25 | $this->user_id = intval( $user_id ); |
||
26 | |||
27 | if( isset( $_GET['view'] ) && in_array( $_GET['view'], array( 'user', 'lesson' ) ) ) { |
||
28 | $this->view = $_GET['view']; |
||
29 | } |
||
30 | |||
31 | // Viewing a single Learner always sets the view to Lessons |
||
32 | if( $this->user_id ) { |
||
33 | $this->view = 'lesson'; |
||
34 | } |
||
35 | |||
36 | // Load Parent token into constructor |
||
37 | parent::__construct( 'analysis_course' ); |
||
38 | |||
39 | // Actions |
||
40 | add_action( 'sensei_before_list_table', array( $this, 'data_table_header' ) ); |
||
41 | add_action( 'sensei_after_list_table', array( $this, 'data_table_footer' ) ); |
||
42 | |||
43 | add_filter( 'sensei_list_table_search_button_text', array( $this, 'search_button' ) ); |
||
44 | |||
45 | } // End __construct() |
||
46 | |||
47 | /** |
||
48 | * Define the columns that are going to be used in the table |
||
49 | * @since 1.7.0 |
||
50 | * @return array $columns, the array of columns to use with the table |
||
51 | */ |
||
52 | function get_columns() { |
||
0 ignored issues
–
show
|
|||
53 | |||
54 | switch( $this->view ) { |
||
55 | View Code Duplication | case 'user' : |
|
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. ![]() |
|||
56 | $columns = array( |
||
57 | 'title' => __( 'Learner', 'woothemes-sensei' ), |
||
58 | 'started' => __( 'Date Started', 'woothemes-sensei' ), |
||
59 | 'completed' => __( 'Date Completed', 'woothemes-sensei' ), |
||
60 | 'user_status' => __( 'Status', 'woothemes-sensei' ), |
||
61 | 'percent' => __( 'Percent Complete', 'woothemes-sensei' ), |
||
62 | ); |
||
63 | break; |
||
64 | |||
65 | case 'lesson' : |
||
66 | default: |
||
67 | if ( $this->user_id ) { |
||
68 | |||
69 | $columns = array( |
||
70 | 'title' => __( 'Lesson', 'woothemes-sensei' ), |
||
71 | 'started' => __( 'Date Started', 'woothemes-sensei' ), |
||
72 | 'completed' => __( 'Date Completed', 'woothemes-sensei' ), |
||
73 | 'user_status' => __( 'Status', 'woothemes-sensei' ), |
||
74 | 'grade' => __( 'Grade', 'woothemes-sensei' ), |
||
75 | ); |
||
76 | |||
77 | } else { |
||
78 | |||
79 | $columns = array( |
||
80 | 'title' => __( 'Lesson', 'woothemes-sensei' ), |
||
81 | 'num_learners' => __( 'Learners', 'woothemes-sensei' ), |
||
82 | 'completions' => __( 'Completed', 'woothemes-sensei' ), |
||
83 | 'average_grade' => __( 'Average Grade', 'woothemes-sensei' ), |
||
84 | ); |
||
85 | |||
86 | } |
||
87 | break; |
||
88 | } |
||
89 | // Backwards compatible |
||
90 | $columns = apply_filters( 'sensei_analysis_course_' . $this->view . '_columns', $columns, $this ); |
||
91 | // Moving forward, single filter with args |
||
92 | $columns = apply_filters( 'sensei_analysis_course_columns', $columns, $this ); |
||
93 | return $columns; |
||
94 | } |
||
95 | |||
96 | /** |
||
97 | * Define the columns that are going to be used in the table |
||
98 | * @since 1.7.0 |
||
99 | * @return array $columns, the array of columns to use with the table |
||
100 | */ |
||
101 | function get_sortable_columns() { |
||
0 ignored issues
–
show
|
|||
102 | |||
103 | switch( $this->view ) { |
||
104 | case 'user' : |
||
105 | $columns = array( |
||
106 | 'title' => array( 'title', false ), |
||
107 | 'started' => array( 'started', false ), |
||
108 | 'completed' => array( 'completed', false ), |
||
109 | 'user_status' => array( 'user_status', false ), |
||
110 | // 'grade' => array( 'grade', false ), |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
54% 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. ![]() |
|||
111 | 'percent' => array( 'percent', false ) |
||
112 | ); |
||
113 | break; |
||
114 | |||
115 | case 'lesson' : |
||
116 | default: |
||
117 | if ( $this->user_id ) { |
||
118 | |||
119 | $columns = array( |
||
120 | 'title' => array( 'title', false ), |
||
121 | 'started' => array( 'started', false ), |
||
122 | 'completed' => array( 'completed', false ), |
||
123 | 'user_status' => array( 'user_status', false ), |
||
124 | 'grade' => array( 'grade', false ), |
||
125 | ); |
||
126 | |||
127 | } else { |
||
128 | |||
129 | $columns = array( |
||
130 | 'title' => array( 'title', false ), |
||
131 | 'num_learners' => array( 'num_learners', false ), |
||
132 | 'completions' => array( 'completions', false ), |
||
133 | 'average_grade' => array( 'average_grade', false ) |
||
134 | ); |
||
135 | |||
136 | } |
||
137 | break; |
||
138 | } |
||
139 | // Backwards compatible |
||
140 | $columns = apply_filters( 'sensei_analysis_course_' . $this->view . '_columns_sortable', $columns, $this ); |
||
141 | // Moving forward, single filter with args |
||
142 | $columns = apply_filters( 'sensei_analysis_course_columns_sortable', $columns, $this ); |
||
143 | return $columns; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Prepare the table with different parameters, pagination, columns and table elements |
||
148 | * @since 1.7.0 |
||
149 | * @return void |
||
150 | */ |
||
151 | public function prepare_items() { |
||
152 | global $per_page; |
||
153 | |||
154 | // Handle orderby (needs work) |
||
155 | $orderby = ''; |
||
156 | if ( !empty( $_GET['orderby'] ) ) { |
||
157 | if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) { |
||
158 | $orderby = esc_html( $_GET['orderby'] ); |
||
159 | } // End If Statement |
||
160 | } |
||
161 | |||
162 | // Handle order |
||
163 | $order = 'ASC'; |
||
164 | if ( !empty( $_GET['order'] ) ) { |
||
165 | $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC'; |
||
166 | } |
||
167 | |||
168 | // Handle search, need 4.1 version of WP to be able to restrict statuses to known post_ids |
||
169 | $search = false; |
||
170 | if ( !empty( $_GET['s'] ) ) { |
||
171 | $search = esc_html( $_GET['s'] ); |
||
172 | } // End If Statement |
||
173 | $this->search = $search; |
||
174 | |||
175 | $per_page = $this->get_items_per_page( 'sensei_comments_per_page' ); |
||
176 | $per_page = apply_filters( 'sensei_comments_per_page', $per_page, 'sensei_comments' ); |
||
177 | |||
178 | $paged = $this->get_pagenum(); |
||
179 | $offset = 0; |
||
180 | if ( !empty($paged) ) { |
||
181 | $offset = $per_page * ( $paged - 1 ); |
||
182 | } // End If Statement |
||
183 | |||
184 | $args = array( |
||
185 | 'number' => $per_page, |
||
186 | 'offset' => $offset, |
||
187 | 'orderby' => $orderby, |
||
188 | 'order' => $order, |
||
189 | ); |
||
190 | if ( $this->search ) { |
||
191 | $args['search'] = $this->search; |
||
192 | } // End If Statement |
||
193 | |||
194 | View Code Duplication | switch( $this->view ) { |
|
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. ![]() |
|||
195 | case 'user' : |
||
196 | $this->items = $this->get_course_statuses( $args ); |
||
197 | break; |
||
198 | |||
199 | case 'lesson': |
||
200 | default: |
||
201 | $this->items = $this->get_lessons( $args ); |
||
202 | break; |
||
203 | } |
||
204 | |||
205 | $total_items = $this->total_items; |
||
206 | $total_pages = ceil( $total_items / $per_page ); |
||
207 | $this->set_pagination_args( array( |
||
208 | 'total_items' => $total_items, |
||
209 | 'total_pages' => $total_pages, |
||
210 | 'per_page' => $per_page |
||
211 | ) ); |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Generate a csv report with different parameters, pagination, columns and table elements |
||
216 | * @since 1.7.0 |
||
217 | * @return data |
||
218 | */ |
||
219 | public function generate_report( $report ) { |
||
220 | |||
221 | $data = array(); |
||
222 | |||
223 | $this->csv_output = true; |
||
224 | |||
225 | // Handle orderby |
||
226 | $orderby = ''; |
||
227 | if ( !empty( $_GET['orderby'] ) ) { |
||
228 | if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) { |
||
229 | $orderby = esc_html( $_GET['orderby'] ); |
||
230 | } // End If Statement |
||
231 | } |
||
232 | |||
233 | // Handle order |
||
234 | $order = 'ASC'; |
||
235 | if ( !empty( $_GET['order'] ) ) { |
||
236 | $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC'; |
||
237 | } |
||
238 | |||
239 | // Handle search |
||
240 | $search = false; |
||
241 | if ( !empty( $_GET['s'] ) ) { |
||
242 | $search = esc_html( $_GET['s'] ); |
||
243 | } // End If Statement |
||
244 | $this->search = $search; |
||
245 | |||
246 | $args = array( |
||
247 | 'orderby' => $orderby, |
||
248 | 'order' => $order, |
||
249 | ); |
||
250 | if ( $this->search ) { |
||
251 | $args['search'] = $this->search; |
||
252 | } // End If Statement |
||
253 | |||
254 | // Start the csv with the column headings |
||
255 | $column_headers = array(); |
||
256 | $columns = $this->get_columns(); |
||
257 | foreach( $columns AS $key => $title ) { |
||
258 | $column_headers[] = $title; |
||
259 | } |
||
260 | $data[] = $column_headers; |
||
261 | |||
262 | View Code Duplication | switch( $this->view ) { |
|
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. ![]() |
|||
263 | case 'user' : |
||
264 | $this->items = $this->get_course_statuses( $args ); |
||
265 | break; |
||
266 | |||
267 | case 'lesson': |
||
268 | default: |
||
269 | $this->items = $this->get_lessons( $args ); |
||
270 | break; |
||
271 | } |
||
272 | |||
273 | // Process each row |
||
274 | foreach( $this->items AS $item) { |
||
275 | $data[] = $this->get_row_data( $item ); |
||
276 | } |
||
277 | |||
278 | return $data; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Generates the overall array for a single item in the display |
||
283 | * |
||
284 | * @since 1.7.0 |
||
285 | * @param object $item The current item |
||
286 | */ |
||
287 | protected function get_row_data( $item ) { |
||
288 | |||
289 | switch( $this->view ) { |
||
290 | case 'user' : |
||
291 | $user_start_date = get_comment_meta( $item->comment_ID, 'start', true ); |
||
292 | $user_end_date = $item->comment_date; |
||
293 | |||
294 | View Code Duplication | if( 'complete' == $item->comment_approved ) { |
|
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. ![]() |
|||
295 | |||
296 | $status = __( 'Completed', 'woothemes-sensei' ); |
||
297 | $status_class = 'graded'; |
||
298 | |||
299 | } else { |
||
300 | |||
301 | $status = __( 'In Progress', 'woothemes-sensei' ); |
||
302 | $status_class = 'in-progress'; |
||
303 | $user_end_date = ''; |
||
304 | |||
305 | } |
||
306 | $course_percent = get_comment_meta( $item->comment_ID, 'percent', true ); |
||
307 | |||
308 | // Output users data |
||
309 | $user_name = Sensei_Learner::get_full_name( $item->user_id ); |
||
310 | |||
311 | View Code Duplication | if ( !$this->csv_output ) { |
|
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. ![]() |
|||
312 | |||
313 | $url = add_query_arg( array( 'page' => $this->page_slug, 'user_id' => $item->user_id, 'course_id' => $this->course_id ), admin_url( 'admin.php' ) ); |
||
314 | |||
315 | $user_name = '<strong><a class="row-title" href="' . esc_url( $url ) . '">' . $user_name . '</a></strong>'; |
||
316 | $status = sprintf( '<span class="%s">%s</span>', $status_class, $status ); |
||
317 | if ( is_numeric($course_percent) ) { |
||
318 | |||
319 | $course_percent .= '%'; |
||
320 | |||
321 | } |
||
322 | |||
323 | } // End If Statement |
||
324 | |||
325 | $column_data = apply_filters( 'sensei_analysis_course_column_data', array( 'title' => $user_name, |
||
326 | 'started' => $user_start_date, |
||
327 | 'completed' => $user_end_date, |
||
328 | 'user_status' => $status, |
||
329 | 'percent' => $course_percent, |
||
330 | ), $item, $this ); |
||
331 | break; |
||
332 | |||
333 | case 'lesson': |
||
334 | default: |
||
335 | // Displaying lessons for this Course for a specific User |
||
336 | if ( $this->user_id ) { |
||
337 | $status = __( 'Not started', 'woothemes-sensei' ); |
||
338 | $user_start_date = $user_end_date = $status_class = $grade = ''; |
||
339 | |||
340 | $lesson_args = array( |
||
341 | 'post_id' => $item->ID, |
||
342 | 'user_id' => $this->user_id, |
||
343 | 'type' => 'sensei_lesson_status', |
||
344 | 'status' => 'any', |
||
345 | ); |
||
346 | $lesson_status = Sensei_Utils::sensei_check_for_activity( apply_filters( 'sensei_analysis_course_user_lesson', $lesson_args, $item, $this->user_id ), true ); |
||
347 | |||
348 | if ( !empty($lesson_status) ) { |
||
349 | $user_start_date = get_comment_meta( $lesson_status->comment_ID, 'start', true ); |
||
350 | $user_end_date = $lesson_status->comment_date; |
||
351 | |||
352 | View Code Duplication | if( 'complete' == $lesson_status->comment_approved ) { |
|
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. ![]() |
|||
353 | $status = __( 'Completed', 'woothemes-sensei' ); |
||
354 | $status_class = 'graded'; |
||
355 | |||
356 | $grade = __( 'No Grade', 'woothemes-sensei' ); |
||
357 | } |
||
358 | elseif( 'graded' == $lesson_status->comment_approved ) { |
||
359 | $status = __( 'Graded', 'woothemes-sensei' ); |
||
360 | $status_class = 'graded'; |
||
361 | |||
362 | $grade = get_comment_meta( $lesson_status->comment_ID, 'grade', true); |
||
363 | } |
||
364 | elseif( 'passed' == $lesson_status->comment_approved ) { |
||
365 | $status = __( 'Passed', 'woothemes-sensei' ); |
||
366 | $status_class = 'graded'; |
||
367 | |||
368 | $grade = get_comment_meta( $lesson_status->comment_ID, 'grade', true); |
||
369 | } |
||
370 | elseif( 'failed' == $lesson_status->comment_approved ) { |
||
371 | $status = __( 'Failed', 'woothemes-sensei' ); |
||
372 | $status_class = 'failed'; |
||
373 | |||
374 | $grade = get_comment_meta( $lesson_status->comment_ID, 'grade', true); |
||
375 | } |
||
376 | elseif( 'ungraded' == $lesson_status->comment_approved ) { |
||
377 | $status = __( 'Ungraded', 'woothemes-sensei' ); |
||
378 | $status_class = 'ungraded'; |
||
379 | |||
380 | } |
||
381 | elseif( 'in-progress' == $lesson_status->comment_approved ) { |
||
382 | $status = __( 'In Progress', 'woothemes-sensei' ); |
||
383 | $user_end_date = ''; |
||
384 | } |
||
385 | } // END lesson_status |
||
386 | |||
387 | // Output users data |
||
388 | if ( $this->csv_output ) { |
||
389 | $lesson_title = apply_filters( 'the_title', $item->post_title, $item->ID ); |
||
390 | } |
||
391 | else { |
||
392 | $url = add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $item->ID ), admin_url( 'admin.php' ) ); |
||
393 | $lesson_title = '<strong><a class="row-title" href="' . esc_url( $url ) . '">' . apply_filters( 'the_title', $item->post_title, $item->ID ) . '</a></strong>'; |
||
394 | |||
395 | $status = sprintf( '<span class="%s">%s</span>', $status_class, $status ); |
||
396 | if ( is_numeric($grade) ) { |
||
397 | $grade .= '%'; |
||
398 | } |
||
399 | } // End If Statement |
||
400 | $column_data = apply_filters( 'sensei_analysis_course_column_data', array( 'title' => $lesson_title, |
||
401 | 'started' => $user_start_date, |
||
402 | 'completed' => $user_end_date, |
||
403 | 'user_status' => $status, |
||
404 | 'grade' => $grade, |
||
405 | ), $item, $this ); |
||
406 | } |
||
407 | // Display lessons for this Course regardless of users |
||
408 | else { |
||
409 | // Get Learners (i.e. those who have started) |
||
410 | $lesson_args = array( |
||
411 | 'post_id' => $item->ID, |
||
412 | 'type' => 'sensei_lesson_status', |
||
413 | 'status' => 'any', |
||
414 | ); |
||
415 | $lesson_students = Sensei_Utils::sensei_check_for_activity( apply_filters( 'sensei_analysis_lesson_learners', $lesson_args, $item ) ); |
||
416 | |||
417 | // Get Course Completions |
||
418 | $lesson_args = array( |
||
419 | 'post_id' => $item->ID, |
||
420 | 'type' => 'sensei_lesson_status', |
||
421 | 'status' => array( 'complete', 'graded', 'passed', 'failed' ), |
||
422 | 'count' => true, |
||
423 | ); |
||
424 | $lesson_completions = Sensei_Utils::sensei_check_for_activity( apply_filters( 'sensei_analysis_lesson_completions', $lesson_args, $item ) ); |
||
425 | |||
426 | $lesson_average_grade = __('n/a', 'woothemes-sensei'); |
||
427 | if ( false != get_post_meta($item->ID, '_quiz_has_questions', true) ) { |
||
428 | // Get Percent Complete |
||
429 | $grade_args = array( |
||
430 | 'post_id' => $item->ID, |
||
431 | 'type' => 'sensei_lesson_status', |
||
432 | 'status' => array( 'graded', 'passed', 'failed' ), |
||
433 | 'meta_key' => 'grade', |
||
434 | ); |
||
435 | add_filter( 'comments_clauses', array( 'WooThemes_Sensei_Utils', 'comment_total_sum_meta_value_filter' ) ); |
||
436 | $lesson_grades = Sensei_Utils::sensei_check_for_activity( apply_filters( 'sensei_analysis_lesson_grades', $grade_args, $item ), true ); |
||
437 | remove_filter( 'comments_clauses', array( 'WooThemes_Sensei_Utils', 'comment_total_sum_meta_value_filter' ) ); |
||
438 | |||
439 | $grade_count = !empty( $lesson_grades->total ) ? $lesson_grades->total : 1; |
||
440 | $grade_total = !empty( $lesson_grades->meta_sum ) ? doubleval( $lesson_grades->meta_sum ) : 0; |
||
441 | $lesson_average_grade = abs( round( doubleval( $grade_total / $grade_count ), 2 ) ); |
||
442 | } |
||
443 | // Output lesson data |
||
444 | View Code Duplication | if ( $this->csv_output ) { |
|
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. ![]() |
|||
445 | $lesson_title = apply_filters( 'the_title', $item->post_title, $item->ID ); |
||
446 | } |
||
447 | else { |
||
448 | $url = add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $item->ID ), admin_url( 'admin.php' ) ); |
||
449 | $lesson_title = '<strong><a class="row-title" href="' . esc_url( $url ) . '">' . apply_filters( 'the_title', $item->post_title, $item->ID ) . '</a></strong>'; |
||
450 | |||
451 | if ( is_numeric( $lesson_average_grade ) ) { |
||
452 | $lesson_average_grade .= '%'; |
||
453 | } |
||
454 | } // End If Statement |
||
455 | $column_data = apply_filters( 'sensei_analysis_course_column_data', array( 'title' => $lesson_title, |
||
456 | 'num_learners' => $lesson_students, |
||
457 | 'completions' => $lesson_completions, |
||
458 | 'average_grade' => $lesson_average_grade, |
||
459 | ), $item, $this ); |
||
460 | } // END if |
||
461 | break; |
||
462 | } // END switch |
||
463 | |||
464 | return $column_data; |
||
465 | } |
||
466 | |||
467 | /** |
||
468 | * Return array of course statuses |
||
469 | * @since 1.7.0 |
||
470 | * @return array statuses |
||
471 | */ |
||
472 | View Code Duplication | private function get_course_statuses( $args ) { |
|
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. ![]() |
|||
473 | |||
474 | $activity_args = array( |
||
475 | 'post_id' => $this->course_id, |
||
476 | 'type' => 'sensei_course_status', |
||
477 | 'number' => $args['number'], |
||
478 | 'offset' => $args['offset'], |
||
479 | 'orderby' => $args['orderby'], |
||
480 | 'order' => $args['order'], |
||
481 | 'status' => 'any', |
||
482 | ); |
||
483 | |||
484 | // Searching users on statuses requires sub-selecting the statuses by user_ids |
||
485 | if ( $this->search ) { |
||
486 | $user_args = array( |
||
487 | 'search' => '*' . $this->search . '*', |
||
488 | 'fields' => 'ID', |
||
489 | ); |
||
490 | // Filter for extending |
||
491 | $user_args = apply_filters( 'sensei_analysis_course_search_users', $user_args ); |
||
492 | if ( !empty( $user_args ) ) { |
||
493 | $learners_search = new WP_User_Query( $user_args ); |
||
494 | // Store for reuse on counts |
||
495 | $activity_args['user_id'] = (array) $learners_search->get_results(); |
||
496 | } |
||
497 | } // End If Statement |
||
498 | |||
499 | $activity_args = apply_filters( 'sensei_analysis_course_filter_statuses', $activity_args ); |
||
500 | |||
501 | // WP_Comment_Query doesn't support SQL_CALC_FOUND_ROWS, so instead do this twice |
||
502 | $this->total_items = Sensei_Utils::sensei_check_for_activity( array_merge( $activity_args, array('count' => true, 'offset' => 0, 'number' => 0) ) ); |
||
503 | |||
504 | // Ensure we change our range to fit (in case a search threw off the pagination) - Should this be added to all views? |
||
505 | if ( $this->total_items < $activity_args['offset'] ) { |
||
506 | $new_paged = floor( $this->total_items / $activity_args['number'] ); |
||
507 | $activity_args['offset'] = $new_paged * $activity_args['number']; |
||
508 | } |
||
509 | $statuses = Sensei_Utils::sensei_check_for_activity( $activity_args, true ); |
||
510 | // Need to always return an array, even with only 1 item |
||
511 | if ( !is_array($statuses) ) { |
||
512 | $statuses = array( $statuses ); |
||
513 | } |
||
514 | return $statuses; |
||
515 | } // End get_course_statuses() |
||
516 | |||
517 | /** |
||
518 | * Return array of Courses' lessons |
||
519 | * @since 1.7.0 |
||
520 | * @return array statuses |
||
521 | */ |
||
522 | private function get_lessons( $args ) { |
||
523 | |||
524 | $lessons_args = array( 'post_type' => 'lesson', |
||
525 | 'posts_per_page' => $args['number'], |
||
526 | 'offset' => $args['offset'], |
||
527 | 'meta_key' => '_order_' . $this->course_id, |
||
528 | // 'orderby' => $args['orderby'], |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
70% 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. ![]() |
|||
529 | 'order' => $args['order'], |
||
530 | 'meta_query' => array( |
||
531 | array( |
||
532 | 'key' => '_lesson_course', |
||
533 | 'value' => intval( $this->course_id ), |
||
534 | ), |
||
535 | ), |
||
536 | 'post_status' => array('publish', 'private'), |
||
537 | 'suppress_filters' => 0 |
||
538 | ); |
||
539 | if ( $this->search ) { |
||
540 | $lessons_args['s'] = $this->search; |
||
541 | } |
||
542 | if ( $this->csv_output ) { |
||
543 | $lessons_args['posts_per_page'] = '-1'; |
||
544 | } |
||
545 | |||
546 | // Using WP_Query as get_posts() doesn't support 'found_posts' |
||
547 | $lessons_query = new WP_Query( apply_filters( 'sensei_analysis_course_filter_lessons', $lessons_args ) ); |
||
548 | $this->total_items = $lessons_query->found_posts; |
||
549 | return $lessons_query->posts; |
||
550 | } // End get_lessons() |
||
551 | |||
552 | /** |
||
553 | * Sets output when no items are found |
||
554 | * Overloads the parent method |
||
555 | * @since 1.2.0 |
||
556 | * @return void |
||
557 | */ |
||
558 | View Code Duplication | public function no_items() { |
|
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. ![]() |
|||
559 | switch( $this->view ) { |
||
560 | case 'user' : |
||
561 | $text = __( 'No learners found.', 'woothemes-sensei' ); |
||
562 | break; |
||
563 | |||
564 | case 'lesson': |
||
565 | default: |
||
566 | $text = __( 'No lessons found.', 'woothemes-sensei' ); |
||
567 | break; |
||
568 | } |
||
569 | echo apply_filters( 'sensei_analysis_course_no_items_text', $text ); |
||
570 | } // End no_items() |
||
571 | |||
572 | /** |
||
573 | * Output for table heading |
||
574 | * @since 1.2.0 |
||
575 | * @return void |
||
576 | */ |
||
577 | public function data_table_header() { |
||
578 | if ( $this->user_id ) { |
||
579 | $learners_text = __( 'Other Learners taking this Course', 'woothemes-sensei' ); |
||
580 | } |
||
581 | else { |
||
582 | $learners_text = __( 'Learners taking this Course', 'woothemes-sensei' ); |
||
583 | } |
||
584 | $lessons_text = __( 'Lessons in this Course', 'woothemes-sensei' ); |
||
585 | |||
586 | $url_args = array( |
||
587 | 'page' => $this->page_slug, |
||
588 | 'course_id' => $this->course_id, |
||
589 | ); |
||
590 | $learners_url = esc_url( add_query_arg( array_merge( $url_args, array( 'view' => 'user' ) ), admin_url( 'admin.php' ) ) ); |
||
591 | $lessons_url = esc_url( add_query_arg( array_merge( $url_args, array( 'view' => 'lesson' ) ), admin_url( 'admin.php' ) ) ); |
||
592 | |||
593 | $learners_class = $lessons_class = ''; |
||
594 | |||
595 | $menu = array(); |
||
596 | switch( $this->view ) { |
||
597 | case 'user' : |
||
598 | $learners_class = 'current'; |
||
599 | break; |
||
600 | |||
601 | case 'lesson': |
||
602 | default: |
||
603 | $lessons_class = 'current'; |
||
604 | break; |
||
605 | } |
||
606 | $menu['lesson'] = sprintf( '<a href="%s" class="%s">%s</a>', $lessons_url, $lessons_class, $lessons_text ); |
||
607 | $menu['user'] = sprintf( '<a href="%s" class="%s">%s</a>', $learners_url, $learners_class, $learners_text ); |
||
608 | |||
609 | $menu = apply_filters( 'sensei_analysis_course_sub_menu', $menu ); |
||
610 | View Code Duplication | if ( !empty($menu) ) { |
|
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. ![]() |
|||
611 | echo '<ul class="subsubsub">' . "\n"; |
||
612 | foreach ( $menu as $class => $item ) { |
||
613 | $menu[ $class ] = "\t<li class='$class'>$item"; |
||
614 | } |
||
615 | echo implode( " |</li>\n", $menu ) . "</li>\n"; |
||
616 | echo '</ul>' . "\n"; |
||
617 | } |
||
618 | } // End data_table_header() |
||
619 | |||
620 | /** |
||
621 | * Output for table footer |
||
622 | * @since 1.2.0 |
||
623 | * @return void |
||
624 | */ |
||
625 | public function data_table_footer() { |
||
626 | |||
627 | $course = get_post( $this->course_id ); |
||
628 | $report = sanitize_title( $course->post_title ) . '-' . $this->view . 's-overview'; |
||
629 | if ( $this->user_id ) { |
||
630 | $user_name = Sensei_Learner::get_full_name( $this->user_id ); |
||
631 | $report = sanitize_title( $user_name ) . '-' . $report; |
||
632 | } |
||
633 | |||
634 | $url_args = array( 'page' => $this->page_slug, 'course_id' => $this->course_id, 'view' => $this->view, 'sensei_report_download' => $report ); |
||
635 | if ( $this->user_id ) { |
||
636 | $url_args['user_id'] = $this->user_id; |
||
637 | } |
||
638 | $url = add_query_arg( $url_args, admin_url( 'admin.php' ) ); |
||
639 | echo '<a class="button button-primary" href="' . esc_url( wp_nonce_url( $url, 'sensei_csv_download-' . $report, '_sdl_nonce' ) ) . '">' . __( 'Export all rows (CSV)', 'woothemes-sensei' ) . '</a>'; |
||
640 | } // End data_table_footer() |
||
641 | |||
642 | /** |
||
643 | * The text for the search button |
||
644 | * @since 1.7.0 |
||
645 | * @return string $text |
||
646 | */ |
||
647 | View Code Duplication | public function search_button( $text = '' ) { |
|
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. ![]() |
|||
648 | switch( $this->view ) { |
||
649 | case 'user': |
||
650 | $text = __( 'Search Learners', 'woothemes-sensei' ); |
||
651 | break; |
||
652 | |||
653 | case 'lesson': |
||
654 | default: |
||
655 | $text = __( 'Search Lessons', 'woothemes-sensei' ); |
||
656 | break; |
||
657 | } // End Switch Statement |
||
658 | |||
659 | return $text; |
||
660 | } |
||
661 | |||
662 | } // End Class |
||
663 | |||
664 | /** |
||
665 | * Class WooThemes_Sensei_Analysis_Course_List_Table |
||
666 | * @ignore only for backward compatibility |
||
667 | * @since 1.9.0 |
||
668 | * @ignore |
||
669 | */ |
||
670 | class WooThemes_Sensei_Analysis_Course_List_Table extends Sensei_Analysis_Course_List_Table {} |
||
671 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.