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 | * Analysis User Profile Data Table in Sensei. |
||
6 | * |
||
7 | * @package Analytics |
||
8 | * @author Automattic |
||
9 | * |
||
10 | * @since 1.2.0 |
||
11 | */ |
||
12 | class Sensei_Analysis_User_Profile_List_Table extends Sensei_List_Table { |
||
13 | public $user_id; |
||
14 | public $page_slug = 'sensei_analysis'; |
||
15 | |||
16 | /** |
||
17 | * Constructor |
||
18 | * @since 1.2.0 |
||
19 | * @return void |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Adding a
@return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.
Adding a Please refer to the PHP core documentation on constructors. ![]() |
|||
20 | */ |
||
21 | public function __construct ( $user_id = 0 ) { |
||
22 | $this->user_id = intval( $user_id ); |
||
23 | |||
24 | // Load Parent token into constructor |
||
25 | parent::__construct( 'analysis_user_profile' ); |
||
26 | |||
27 | // Actions |
||
28 | add_action( 'sensei_before_list_table', array( $this, 'data_table_header' ) ); |
||
29 | add_action( 'sensei_after_list_table', array( $this, 'data_table_footer' ) ); |
||
30 | |||
31 | add_filter( 'sensei_list_table_search_button_text', array( $this, 'search_button' ) ); |
||
32 | } // End __construct() |
||
33 | |||
34 | /** |
||
35 | * Define the columns that are going to be used in the table |
||
36 | * @since 1.7.0 |
||
37 | * @return array $columns, the array of columns to use with the table |
||
38 | */ |
||
39 | View Code Duplication | function get_columns() { |
|
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. ![]() |
|||
40 | $columns = array( |
||
41 | 'title' => __( 'Course', 'woothemes-sensei' ), |
||
42 | 'started' => __( 'Date Started', 'woothemes-sensei' ), |
||
43 | 'completed' => __( 'Date Completed', 'woothemes-sensei' ), |
||
44 | 'status' => __( 'Status', 'woothemes-sensei' ), |
||
45 | // 'grade' => __( 'Grade', 'woothemes-sensei' ), |
||
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. ![]() |
|||
46 | 'percent' => __( 'Percent Complete', 'woothemes-sensei' ), |
||
47 | ); |
||
48 | $columns = apply_filters( 'sensei_analysis_user_profile_columns', $columns ); |
||
49 | return $columns; |
||
50 | } |
||
51 | |||
52 | /** |
||
53 | * Define the columns that are going to be used in the table |
||
54 | * @since 1.7.0 |
||
55 | * @return array $columns, the array of columns to use with the table |
||
56 | */ |
||
57 | View Code Duplication | function get_sortable_columns() { |
|
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. ![]() |
|||
58 | $columns = array( |
||
59 | 'title' => array( 'title', false ), |
||
60 | 'started' => array( 'started', false ), |
||
61 | 'completed' => array( 'completed', false ), |
||
62 | 'status' => array( 'status', false ), |
||
63 | // '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. ![]() |
|||
64 | 'percent' => array( 'percent', false ) |
||
65 | ); |
||
66 | $columns = apply_filters( 'sensei_analysis_user_profile_columns_sortable', $columns ); |
||
67 | return $columns; |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Prepare the table with different parameters, pagination, columns and table elements |
||
72 | * @since 1.7.0 |
||
73 | * @return void |
||
74 | */ |
||
75 | View Code Duplication | public function prepare_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. ![]() |
|||
76 | global $per_page; |
||
77 | |||
78 | // Handle orderby (needs work) |
||
79 | $orderby = ''; |
||
80 | if ( !empty( $_GET['orderby'] ) ) { |
||
81 | if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) { |
||
82 | $orderby = esc_html( $_GET['orderby'] ); |
||
83 | } // End If Statement |
||
84 | } |
||
85 | |||
86 | // Handle order |
||
87 | $order = 'ASC'; |
||
88 | if ( !empty( $_GET['order'] ) ) { |
||
89 | $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC'; |
||
90 | } |
||
91 | |||
92 | // Handle search, need 4.1 version of WP to be able to restrict statuses to known post_ids |
||
93 | $search = false; |
||
94 | if ( !empty( $_GET['s'] ) ) { |
||
95 | $search = esc_html( $_GET['s'] ); |
||
96 | } // End If Statement |
||
97 | $this->search = $search; |
||
98 | |||
99 | $per_page = $this->get_items_per_page( 'sensei_comments_per_page' ); |
||
100 | $per_page = apply_filters( 'sensei_comments_per_page', $per_page, 'sensei_comments' ); |
||
101 | |||
102 | $paged = $this->get_pagenum(); |
||
103 | $offset = 0; |
||
104 | if ( !empty($paged) ) { |
||
105 | $offset = $per_page * ( $paged - 1 ); |
||
106 | } // End If Statement |
||
107 | |||
108 | $args = array( |
||
109 | 'number' => $per_page, |
||
110 | 'offset' => $offset, |
||
111 | 'orderby' => $orderby, |
||
112 | 'order' => $order, |
||
113 | ); |
||
114 | if ( $this->search ) { |
||
115 | $args['search'] = $this->search; |
||
116 | } // End If Statement |
||
117 | |||
118 | $this->items = $this->get_course_statuses( $args ); |
||
119 | |||
120 | $total_items = $this->total_items; |
||
121 | $total_pages = ceil( $total_items / $per_page ); |
||
122 | $this->set_pagination_args( array( |
||
123 | 'total_items' => $total_items, |
||
124 | 'total_pages' => $total_pages, |
||
125 | 'per_page' => $per_page |
||
126 | ) ); |
||
127 | } |
||
128 | |||
129 | /** |
||
130 | * Generate a csv report with different parameters, pagination, columns and table elements |
||
131 | * @since 1.7.0 |
||
132 | * @return data |
||
133 | */ |
||
134 | View Code Duplication | public function generate_report( $report ) { |
|
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. ![]() |
|||
135 | |||
136 | $data = array(); |
||
137 | |||
138 | $this->csv_output = true; |
||
139 | |||
140 | // Handle orderby |
||
141 | $orderby = ''; |
||
142 | if ( !empty( $_GET['orderby'] ) ) { |
||
143 | if ( array_key_exists( esc_html( $_GET['orderby'] ), $this->get_sortable_columns() ) ) { |
||
144 | $orderby = esc_html( $_GET['orderby'] ); |
||
145 | } // End If Statement |
||
146 | } |
||
147 | |||
148 | // Handle order |
||
149 | $order = 'ASC'; |
||
150 | if ( !empty( $_GET['order'] ) ) { |
||
151 | $order = ( 'ASC' == strtoupper($_GET['order']) ) ? 'ASC' : 'DESC'; |
||
152 | } |
||
153 | |||
154 | // Handle search |
||
155 | $search = false; |
||
156 | if ( !empty( $_GET['s'] ) ) { |
||
157 | $search = esc_html( $_GET['s'] ); |
||
158 | } // End If Statement |
||
159 | $this->search = $search; |
||
160 | |||
161 | $args = array( |
||
162 | 'orderby' => $orderby, |
||
163 | 'order' => $order, |
||
164 | ); |
||
165 | if ( $this->search ) { |
||
166 | $args['search'] = $this->search; |
||
167 | } // End If Statement |
||
168 | |||
169 | // Start the csv with the column headings |
||
170 | $column_headers = array(); |
||
171 | $columns = $this->get_columns(); |
||
172 | foreach( $columns AS $key => $title ) { |
||
173 | $column_headers[] = $title; |
||
174 | } |
||
175 | $data[] = $column_headers; |
||
176 | |||
177 | $this->items = $this->get_course_statuses( $args ); |
||
178 | |||
179 | // Process each row |
||
180 | foreach( $this->items AS $item) { |
||
181 | $data[] = $this->get_row_data( $item ); |
||
182 | } |
||
183 | |||
184 | return $data; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * Generates the overall array for a single item in the display |
||
189 | * @since 1.7.0 |
||
190 | * @param object $item The current item |
||
191 | */ |
||
192 | protected function get_row_data( $item ) { |
||
193 | |||
194 | $course_title = get_the_title( $item->comment_post_ID ); |
||
195 | $course_percent = get_comment_meta( $item->comment_ID, 'percent', true ); |
||
196 | $course_start_date = get_comment_meta( $item->comment_ID, 'start', true ); |
||
197 | $course_end_date = ''; |
||
198 | |||
199 | 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. ![]() |
|||
200 | |||
201 | $status = __( 'Completed', 'woothemes-sensei' ); |
||
202 | $status_class = 'graded'; |
||
203 | |||
204 | $course_end_date = $item->comment_date; |
||
205 | |||
206 | } else { |
||
207 | |||
208 | $status = __( 'In Progress', 'woothemes-sensei' ); |
||
209 | $status_class = 'in-progress'; |
||
210 | |||
211 | } |
||
212 | |||
213 | // Output users data |
||
214 | 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. ![]() |
|||
215 | $url = add_query_arg( array( 'page' => $this->page_slug, 'user_id' => $this->user_id, 'course_id' => $item->comment_post_ID ), admin_url( 'admin.php' ) ); |
||
216 | |||
217 | $course_title = '<strong><a class="row-title" href="' . esc_url( $url ) . '">' . $course_title . '</a></strong>'; |
||
218 | $status = sprintf( '<span class="%s">%s</span>', $status_class, $status ); |
||
219 | if ( is_numeric($course_percent) ) { |
||
220 | $course_percent .= '%'; |
||
221 | } |
||
222 | } // End If Statement |
||
223 | $column_data = apply_filters( 'sensei_analysis_user_profile_column_data', array( 'title' => $course_title, |
||
224 | 'started' => $course_start_date, |
||
225 | 'completed' => $course_end_date, |
||
226 | 'status' => $status, |
||
227 | 'percent' => $course_percent, |
||
228 | ), $item ); |
||
229 | |||
230 | return $column_data; |
||
231 | } |
||
232 | |||
233 | /** |
||
234 | * Return array of Course statuses |
||
235 | * @since 1.7.0 |
||
236 | * @return array statuses |
||
237 | */ |
||
238 | private function get_course_statuses( $args ) { |
||
239 | |||
240 | $activity_args = array( |
||
241 | 'user_id' => $this->user_id, |
||
242 | 'type' => 'sensei_course_status', |
||
243 | 'number' => $args['number'], |
||
244 | 'offset' => $args['offset'], |
||
245 | 'orderby' => $args['orderby'], |
||
246 | 'order' => $args['order'], |
||
247 | 'status' => 'any', |
||
248 | ); |
||
249 | |||
250 | $activity_args = apply_filters( 'sensei_analysis_user_profile_filter_statuses', $activity_args ); |
||
251 | |||
252 | // WP_Comment_Query doesn't support SQL_CALC_FOUND_ROWS, so instead do this twice |
||
253 | $this->total_items = Sensei_Utils::sensei_check_for_activity( array_merge( $activity_args, array('count' => true, 'offset' => 0, 'number' => 0) ) ); |
||
254 | |||
255 | // Ensure we change our range to fit (in case a search threw off the pagination) - Should this be added to all views? |
||
256 | if ( $this->total_items < $activity_args['offset'] ) { |
||
257 | |||
258 | $new_paged = floor( $this->total_items / $activity_args['number'] ); |
||
259 | $activity_args['offset'] = $new_paged * $activity_args['number']; |
||
260 | |||
261 | } |
||
262 | $statuses = Sensei_Utils::sensei_check_for_activity( $activity_args, true ); |
||
263 | |||
264 | // Need to always return an array, even with only 1 item |
||
265 | if ( !is_array($statuses) ) { |
||
266 | $statuses = array( $statuses ); |
||
267 | } |
||
268 | |||
269 | return $statuses; |
||
270 | } // End get_course_statuses() |
||
271 | |||
272 | /** |
||
273 | * Sets output when no items are found |
||
274 | * Overloads the parent method |
||
275 | * @since 1.2.0 |
||
276 | * @return void |
||
277 | */ |
||
278 | public function no_items() { |
||
279 | echo __( 'No courses found.', 'woothemes-sensei' ); |
||
280 | } // End no_items() |
||
281 | |||
282 | /** |
||
283 | * Output for table heading |
||
284 | * @since 1.2.0 |
||
285 | * @return void |
||
286 | */ |
||
287 | public function data_table_header() { |
||
288 | echo '<strong>' . __( 'Courses', 'woothemes-sensei' ) . '</strong>'; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Output for table footer |
||
293 | * @since 1.7.0 |
||
294 | * @return void |
||
295 | */ |
||
296 | View Code Duplication | public function data_table_footer() { |
|
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. ![]() |
|||
297 | $user = get_user_by( 'id', $this->user_id ); |
||
298 | $report = sanitize_title( $user->display_name ) . '-course-overview'; |
||
299 | $url = add_query_arg( array( 'page' => $this->page_slug, 'user_id' => $this->user_id, 'sensei_report_download' => $report ), admin_url( 'admin.php' ) ); |
||
300 | 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>'; |
||
301 | } |
||
302 | |||
303 | /** |
||
304 | * The text for the search button |
||
305 | * @since 1.7.0 |
||
306 | * @return string |
||
307 | */ |
||
308 | public function search_button( $text = '' ) { |
||
309 | return __( 'Search Courses', 'woothemes-sensei' ); |
||
310 | } |
||
311 | |||
312 | } // End Class |
||
313 | |||
314 | /** |
||
315 | * Class WooThemes_Sensei_Analysis_User_Profile_List_Table |
||
316 | * @ignore only for backward compatibility |
||
317 | * @since 1.9.0 |
||
318 | */ |
||
319 | class WooThemes_Sensei_Analysis_User_Profile_List_Table extends WooThemes_Sensei_List_Table {} |
||
320 |
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.