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 | * All functionality pertaining to the Admin Analysis in Sensei. |
||
6 | * |
||
7 | * @package Analytics |
||
8 | * @author Automattic |
||
9 | * @since 1.0.0 |
||
10 | */ |
||
11 | class Sensei_Analysis { |
||
12 | |||
13 | public $name; |
||
14 | public $file; |
||
15 | public $page_slug; |
||
16 | |||
17 | /** |
||
18 | * Constructor |
||
19 | * @since 1.0.0 |
||
20 | * @param string $file |
||
21 | */ |
||
22 | public function __construct ( $file ) { |
||
23 | $this->name = __('Analysis', 'woothemes-sensei'); |
||
24 | $this->file = $file; |
||
25 | $this->page_slug = 'sensei_analysis'; |
||
26 | |||
27 | // Admin functions |
||
28 | if ( is_admin() ) { |
||
29 | add_action( 'admin_menu', array( $this, 'analysis_admin_menu' ), 10); |
||
30 | add_action( 'analysis_wrapper_container', array( $this, 'wrapper_container' ) ); |
||
31 | if ( isset( $_GET['page'] ) && ( $_GET['page'] == $this->page_slug ) ) { |
||
32 | |||
33 | add_action( 'admin_print_styles', array( $this, 'enqueue_styles' ) ); |
||
34 | |||
35 | } |
||
36 | |||
37 | add_action( 'admin_init', array( $this, 'report_download_page' ) ); |
||
38 | |||
39 | add_filter( 'user_search_columns', array( $this, 'user_search_columns_filter' ), 10, 3 ); |
||
40 | } // End If Statement |
||
41 | } // End __construct() |
||
42 | |||
43 | |||
44 | /** |
||
45 | * analysis_admin_menu function. |
||
46 | * @since 1.0.0 |
||
47 | * @access public |
||
48 | * @return void |
||
49 | */ |
||
50 | View Code Duplication | public function analysis_admin_menu() { |
|
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. ![]() |
|||
51 | global $menu, $woocommerce; |
||
52 | |||
53 | if ( current_user_can( 'manage_sensei_grades' ) ) { |
||
54 | |||
55 | add_submenu_page( 'sensei', __('Analysis', 'woothemes-sensei'), __('Analysis', 'woothemes-sensei') , 'manage_sensei_grades', 'sensei_analysis', array( $this, 'analysis_page' ) ); |
||
56 | |||
57 | } |
||
58 | |||
59 | } // End analysis_admin_menu() |
||
60 | |||
61 | /** |
||
62 | * enqueue_styles function. |
||
63 | * |
||
64 | * @description Load in CSS styles where necessary. |
||
65 | * @access public |
||
66 | * @since 1.0.0 |
||
67 | * @return void |
||
68 | */ |
||
69 | public function enqueue_styles () { |
||
70 | |||
71 | wp_enqueue_style( 'woothemes-sensei-admin' ); |
||
72 | |||
73 | wp_enqueue_style( 'woothemes-sensei-settings-api', Sensei()->plugin_url . 'assets/css/settings.css', '', Sensei()->version ); |
||
74 | |||
75 | } // End enqueue_styles() |
||
76 | |||
77 | /** |
||
78 | * load_data_table_files loads required files for Analysis |
||
79 | * @since 1.2.0 |
||
80 | * @return void |
||
81 | */ |
||
82 | public function load_data_table_files() { |
||
83 | |||
84 | // Load Analysis Classes |
||
85 | $classes_to_load = array( 'list-table', |
||
86 | 'analysis-overview', |
||
87 | 'analysis-user-profile', |
||
88 | 'analysis-course', |
||
89 | 'analysis-lesson' |
||
90 | ); |
||
91 | foreach ( $classes_to_load as $class_file ) { |
||
92 | Sensei()->load_class( $class_file ); |
||
93 | } // End For Loop |
||
94 | } // End load_data_table_files() |
||
95 | |||
96 | /** |
||
97 | * load_data_object creates new instance of class |
||
98 | * @param string $name Name of class |
||
99 | * @param integer $data constructor arguments |
||
100 | * @param undefined $optional_data optional constructor arguments |
||
101 | * @return object class instance object |
||
102 | */ |
||
103 | public function load_data_object( $name = '', $data = 0, $optional_data = null ) { |
||
104 | // Load Analysis data |
||
105 | $object_name = 'Sensei_Analysis_' . $name . '_List_Table'; |
||
106 | if ( is_null($optional_data) ) { |
||
107 | $sensei_analysis_object = new $object_name( $data ); |
||
108 | } else { |
||
109 | $sensei_analysis_object = new $object_name( $data, $optional_data ); |
||
110 | } |
||
111 | $sensei_analysis_object->prepare_items(); |
||
112 | return $sensei_analysis_object; |
||
113 | } // End load_data_object() |
||
114 | |||
115 | /** |
||
116 | * analysis_page function. |
||
117 | * @since 1.0.0 |
||
118 | * @access public |
||
119 | * @return void |
||
120 | */ |
||
121 | public function analysis_page() { |
||
122 | |||
123 | $course_id = 0; |
||
124 | $lesson_id = 0; |
||
125 | $user_id = 0; |
||
126 | if( isset( $_GET['course_id'] ) ) { |
||
127 | $course_id = intval( $_GET['course_id'] ); |
||
128 | } |
||
129 | if( isset( $_GET['lesson_id'] ) ) { |
||
130 | $lesson_id = intval( $_GET['lesson_id'] ); |
||
131 | } |
||
132 | if( isset( $_GET['user_id'] ) ) { |
||
133 | $user_id = intval( $_GET['user_id'] ); |
||
134 | } |
||
135 | $type = isset( $_GET['view'] ) ? esc_html( $_GET['view'] ) : false; |
||
136 | |||
137 | if ( 0 < $lesson_id ) { |
||
138 | // Viewing a specific Lesson and all its Learners |
||
139 | $this->analysis_lesson_users_view( $lesson_id ); |
||
140 | } |
||
141 | elseif ( 0 < $course_id && !$user_id && 'user' == $type ) { |
||
142 | // Viewing a specific Course and all its Learners |
||
143 | $this->analysis_course_users_view( $course_id ); |
||
144 | } |
||
145 | elseif ( 0 < $course_id && 0 < $user_id ) { |
||
146 | // Viewing a specific Learner on a specific Course, showing their Lessons |
||
147 | $this->analysis_user_course_view( $course_id, $user_id ); |
||
148 | } |
||
149 | elseif( 0 < $course_id ) { |
||
150 | // Viewing a specific Course and all it's Lessons |
||
151 | $this->analysis_course_view( $course_id ); |
||
152 | } |
||
153 | elseif ( 0 < $user_id ) { |
||
154 | // Viewing a specific Learner, and their Courses |
||
155 | $this->analysis_user_profile_view( $user_id ); |
||
156 | } |
||
157 | else { |
||
158 | // Overview of all Learners, all Courses, or all Lessons |
||
159 | $this->analysis_default_view( $type ); |
||
160 | } // End If Statement |
||
161 | } // End analysis_page() |
||
162 | |||
163 | /** |
||
164 | * Default view for analysis, showing an overview of all Learners, Courses and Lessons |
||
165 | * @since 1.2.0 |
||
166 | * @return void |
||
167 | */ |
||
168 | public function analysis_default_view( $type ) { |
||
169 | |||
170 | // Load Analysis data |
||
171 | $sensei_analysis_overview = $this->load_data_object( 'Overview', $type ); |
||
172 | // Wrappers |
||
173 | do_action( 'analysis_before_container' ); |
||
174 | do_action( 'analysis_wrapper_container', 'top' ); |
||
175 | $this->analysis_headers(); |
||
176 | ?> |
||
177 | <div id="poststuff" class="sensei-analysis-wrap"> |
||
178 | <div class="sensei-analysis-sidebar"> |
||
179 | <?php |
||
180 | do_action( 'sensei_analysis_before_stats_boxes' ); |
||
181 | foreach ( $sensei_analysis_overview->stats_boxes() as $key => $value ) { |
||
182 | $this->render_stats_box( esc_html( $key ), esc_html( $value ) ); |
||
183 | } // End For Loop |
||
184 | do_action( 'sensei_analysis_after_stats_boxes' ); |
||
185 | ?> |
||
186 | </div> |
||
187 | <div class="sensei-analysis-main"> |
||
188 | <?php $sensei_analysis_overview->display(); ?> |
||
189 | </div> |
||
190 | <div class="sensei-analysis-extra"> |
||
191 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
192 | </div> |
||
193 | </div> |
||
194 | <?php |
||
195 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
196 | do_action( 'analysis_after_container' ); |
||
197 | } // End analysis_default_view() |
||
198 | |||
199 | /** |
||
200 | * An individual users' profile view for analysis, showing their Courses |
||
201 | * @since 1.2.0 |
||
202 | * @param integer $user_id |
||
203 | * @return void |
||
204 | */ |
||
205 | View Code Duplication | public function analysis_user_profile_view( $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. ![]() |
|||
206 | |||
207 | // Load Analysis data |
||
208 | $sensei_analysis_user_profile = $this->load_data_object( 'User_Profile', $user_id ); |
||
209 | // Wrappers |
||
210 | do_action( 'analysis_before_container' ); |
||
211 | do_action( 'analysis_wrapper_container', 'top' ); |
||
212 | $this->analysis_headers( array( 'nav' => 'user_profile' ) ); |
||
213 | ?> |
||
214 | <div id="poststuff" class="sensei-analysis-wrap user-profile"> |
||
215 | <div class="sensei-analysis-main"> |
||
216 | <?php $sensei_analysis_user_profile->display(); ?> |
||
217 | </div> |
||
218 | <div class="sensei-analysis-extra"> |
||
219 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
220 | </div> |
||
221 | </div> |
||
222 | <?php |
||
223 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
224 | do_action( 'analysis_after_container' ); |
||
225 | } // End analysis_user_profile_view() |
||
226 | |||
227 | /** |
||
228 | * An individual Course view for analysis, showing the Courses Lessons |
||
229 | * @since 1.2.0 |
||
230 | * @param integer $course_id |
||
231 | * @return void |
||
232 | */ |
||
233 | View Code Duplication | public function analysis_course_view( $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. ![]() |
|||
234 | |||
235 | // Load Analysis data |
||
236 | $sensei_analysis_course = $this->load_data_object( 'Course', $course_id ); |
||
237 | // Wrappers |
||
238 | do_action( 'analysis_before_container' ); |
||
239 | do_action( 'analysis_wrapper_container', 'top' ); |
||
240 | $this->analysis_headers( array( 'nav' => 'course' ) ); |
||
241 | ?> |
||
242 | <div id="poststuff" class="sensei-analysis-wrap course-profile"> |
||
243 | <div class="sensei-analysis-main"> |
||
244 | <?php $sensei_analysis_course->display(); ?> |
||
245 | </div> |
||
246 | <div class="sensei-analysis-extra"> |
||
247 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
248 | </div> |
||
249 | </div> |
||
250 | <?php |
||
251 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
252 | do_action( 'analysis_after_container' ); |
||
253 | } // End analysis_course_view() |
||
254 | |||
255 | /** |
||
256 | * An individual Course view for analysis, showing a specific Learners Lessons |
||
257 | * @since 1.2.0 |
||
258 | * @param integer $course_id |
||
259 | * @param integer $user_id |
||
260 | * @return void |
||
261 | */ |
||
262 | View Code Duplication | public function analysis_user_course_view( $course_id, $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. ![]() |
|||
263 | |||
264 | // Load Analysis data |
||
265 | $sensei_analysis_user_course = $this->load_data_object( 'Course', $course_id, $user_id ); |
||
0 ignored issues
–
show
$user_id is of type integer , but the function expects a object<undefined>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
266 | // Wrappers |
||
267 | do_action( 'analysis_before_container' ); |
||
268 | do_action( 'analysis_wrapper_container', 'top' ); |
||
269 | $this->analysis_headers( array( 'nav' => 'user_course' ) ); |
||
270 | ?> |
||
271 | <div id="poststuff" class="sensei-analysis-wrap course-profile"> |
||
272 | <div class="sensei-analysis-main"> |
||
273 | <?php $sensei_analysis_user_course->display(); ?> |
||
274 | </div> |
||
275 | <div class="sensei-analysis-extra"> |
||
276 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
277 | </div> |
||
278 | </div> |
||
279 | <?php |
||
280 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
281 | do_action( 'analysis_after_container' ); |
||
282 | } // End analysis_user_course_view() |
||
283 | |||
284 | /** |
||
285 | * An individual Course view for analysis, showing all the Learners |
||
286 | * @since 1.2.0 |
||
287 | * @param integer $course_id |
||
288 | * @return void |
||
289 | */ |
||
290 | View Code Duplication | public function analysis_course_users_view( $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. ![]() |
|||
291 | |||
292 | // Load Analysis data |
||
293 | $sensei_analysis_course_users = $this->load_data_object( 'Course', $course_id ); |
||
294 | // Wrappers |
||
295 | do_action( 'analysis_before_container' ); |
||
296 | do_action( 'analysis_wrapper_container', 'top' ); |
||
297 | $this->analysis_headers( array( 'nav' => 'course_users' ) ); |
||
298 | ?> |
||
299 | <div id="poststuff" class="sensei-analysis-wrap course-profile"> |
||
300 | <div class="sensei-analysis-main"> |
||
301 | <?php $sensei_analysis_course_users->display(); ?> |
||
302 | </div> |
||
303 | <div class="sensei-analysis-extra"> |
||
304 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
305 | </div> |
||
306 | </div> |
||
307 | <?php |
||
308 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
309 | do_action( 'analysis_after_container' ); |
||
310 | } // End analysis_course_users_view() |
||
311 | |||
312 | /** |
||
313 | * An individual Lesson view for analysis, showing all the Learners |
||
314 | * @since 1.2.0 |
||
315 | * @param integer $lesson_id |
||
316 | * @return void |
||
317 | */ |
||
318 | View Code Duplication | public function analysis_lesson_users_view( $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. ![]() |
|||
319 | |||
320 | // Load Analysis data |
||
321 | $sensei_analysis_lesson_users = $this->load_data_object( 'Lesson', $lesson_id ); |
||
322 | // Wrappers |
||
323 | do_action( 'analysis_before_container' ); |
||
324 | do_action( 'analysis_wrapper_container', 'top' ); |
||
325 | $this->analysis_headers( array( 'nav' => 'lesson_users' ) ); |
||
326 | ?> |
||
327 | <div id="poststuff" class="sensei-analysis-wrap course-profile"> |
||
328 | <div class="sensei-analysis-main"> |
||
329 | <?php $sensei_analysis_lesson_users->display(); ?> |
||
330 | </div> |
||
331 | <div class="sensei-analysis-extra"> |
||
332 | <?php do_action( 'sensei_analysis_extra' ); ?> |
||
333 | </div> |
||
334 | </div> |
||
335 | <?php |
||
336 | do_action( 'analysis_wrapper_container', 'bottom' ); |
||
337 | do_action( 'analysis_after_container' ); |
||
338 | } // End analysis_lesson_users_view() |
||
339 | |||
340 | /** |
||
341 | * render_stats_box outputs stats boxes |
||
342 | * @since 1.2.0 |
||
343 | * @param $title string title of stat |
||
344 | * @param $data string stats data |
||
345 | * @return void |
||
346 | */ |
||
347 | public function render_stats_box( $title, $data ) { |
||
348 | ?><div class="postbox"> |
||
349 | <h2><span><?php echo $title; ?></span></h2> |
||
350 | <div class="inside"> |
||
351 | <p class="stat"><?php echo $data; ?></p> |
||
352 | </div> |
||
353 | </div><?php |
||
354 | } // End render_stats_box() |
||
355 | |||
356 | /** |
||
357 | * analysis_headers outputs analysis general headers |
||
358 | * @since 1.2.0 |
||
359 | * @return void |
||
360 | */ |
||
361 | View Code Duplication | public function analysis_headers( $args = array( 'nav' => 'default' ) ) { |
|
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. ![]() |
|||
362 | |||
363 | $function = 'analysis_' . $args['nav'] . '_nav'; |
||
364 | $this->$function(); |
||
365 | ?> |
||
366 | <p class="powered-by-woo"> |
||
367 | |||
368 | <?php _e( 'Powered by', 'woothemes-sensei' ); ?> |
||
369 | |||
370 | <a href="http://www.woothemes.com/" title="WooThemes"> |
||
371 | |||
372 | <img src="<?php echo Sensei()->plugin_url; ?>assets/images/woothemes.png" alt="WooThemes" /> |
||
373 | |||
374 | </a> |
||
375 | |||
376 | </p> |
||
377 | |||
378 | <?php |
||
379 | do_action( 'sensei_analysis_after_headers' ); |
||
380 | } // End analysis_headers() |
||
381 | |||
382 | /** |
||
383 | * wrapper_container wrapper for analysis area |
||
384 | * @since 1.2.0 |
||
385 | * @param $which string |
||
386 | * @return void |
||
387 | */ |
||
388 | public function wrapper_container( $which ) { |
||
389 | if ( 'top' == $which ) { |
||
390 | ?><div id="woothemes-sensei" class="wrap woothemes-sensei"><?php |
||
391 | } elseif ( 'bottom' == $which ) { |
||
392 | ?></div><!--/#woothemes-sensei--><?php |
||
393 | } // End If Statement |
||
394 | } // End wrapper_container() |
||
395 | |||
396 | /** |
||
397 | * Default nav area for Analysis, overview of Learners, Courses and Lessons |
||
398 | * @since 1.2.0 |
||
399 | * @return void |
||
400 | */ |
||
401 | public function analysis_default_nav() { |
||
402 | |||
403 | $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 ) ); |
||
404 | $view = isset($_GET['view']) ? esc_html( $_GET['view'] ) : ''; |
||
405 | switch ( $view ) { |
||
406 | case 'courses' : |
||
407 | $title .= sprintf( ' <span class="course-title">> %s</span>', __( 'Courses', 'woothemes-sensei' ) ); |
||
408 | break; |
||
409 | |||
410 | case 'lessons' : |
||
411 | $title .= sprintf( ' <span class="lesson-title">> %s</span>', __( 'Lessons', 'woothemes-sensei' ) ); |
||
412 | break; |
||
413 | |||
414 | case 'users' : |
||
415 | default : |
||
416 | $title .= sprintf( ' <span class="user-title">> %s</span>', __( 'Learners', 'woothemes-sensei' ) ); |
||
417 | break; |
||
418 | } |
||
419 | ?> |
||
420 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
421 | <?php |
||
422 | } // End analysis_default_nav() |
||
423 | |||
424 | /** |
||
425 | * Nav area for Analysis of a specific User profile |
||
426 | * @since 1.2.0 |
||
427 | * @return void |
||
428 | */ |
||
429 | public function analysis_user_profile_nav() { |
||
430 | |||
431 | $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 ) ); |
||
432 | if ( isset( $_GET['user_id'] ) && 0 < intval( $_GET['user_id'] ) ) { |
||
433 | |||
434 | $user_id = intval( $_GET['user_id'] ); |
||
435 | $url = esc_url( add_query_arg( array( 'page' => $this->page_slug, 'user' => $user_id ), admin_url( 'admin.php' ) ) ); |
||
436 | $user_name = Sensei_Learner::get_full_name( $user_id ); |
||
437 | $title .= sprintf( ' <span class="user-title">> <a href="%s">%s</a></span>', $url, $user_name ); |
||
438 | |||
439 | } // End If Statement |
||
440 | ?> |
||
441 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
442 | <?php |
||
443 | } // End analysis_user_profile_nav() |
||
444 | |||
445 | /** |
||
446 | * Nav area for Analysis of a specific Course and its Lessons, specific to a User |
||
447 | * @since 1.2.0 |
||
448 | * @return void |
||
449 | */ |
||
450 | public function analysis_user_course_nav() { |
||
451 | |||
452 | $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 ) ); |
||
453 | if ( isset( $_GET['user_id'] ) && 0 < intval( $_GET['user_id'] ) ) { |
||
454 | $user_id = intval( $_GET['user_id'] ); |
||
455 | $user_data = get_userdata( $user_id ); |
||
456 | $url = add_query_arg( array( 'page' => $this->page_slug, 'user_id' => $user_id ), admin_url( 'admin.php' ) ); |
||
457 | $user_name = Sensei_Learner::get_full_name( $user_id ); |
||
458 | $title .= sprintf( ' <span class="user-title">> <a href="%s">%s</a></span>', $url, $user_name ); |
||
459 | $title .= sprintf( ' <span class="user-title">> <a href="%s">%s</a></span>', esc_url( $url ), $user_data->display_name ); |
||
460 | } // End If Statement |
||
461 | if ( isset( $_GET['course_id'] ) ) { |
||
462 | $course_id = intval( $_GET['course_id'] ); |
||
463 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
464 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) ); |
||
465 | } |
||
466 | ?> |
||
467 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
468 | <?php |
||
469 | } // End analysis_user_course_nav() |
||
470 | |||
471 | /** |
||
472 | * Nav area for Analysis of a specific Course and displaying its Lessons |
||
473 | * @since 1.2.0 |
||
474 | * @return void |
||
475 | */ |
||
476 | View Code Duplication | public function analysis_course_nav() { |
|
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. ![]() |
|||
477 | |||
478 | $title = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'page' => $this->page_slug ), admin_url( 'admin.php' ) ), esc_html( $this->name ) ); |
||
479 | if ( isset( $_GET['course_id'] ) ) { |
||
480 | $course_id = intval( $_GET['course_id'] ); |
||
481 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
482 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>',esc_url( $url ), get_the_title( $course_id ) ); |
||
483 | } |
||
484 | ?> |
||
485 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
486 | <?php |
||
487 | } // End analysis_course_nav() |
||
488 | |||
489 | /** |
||
490 | * Nav area for Analysis of a specific Course displaying its Users |
||
491 | * @since 1.2.0 |
||
492 | * @return void |
||
493 | */ |
||
494 | View Code Duplication | public function analysis_course_users_nav() { |
|
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. ![]() |
|||
495 | |||
496 | $title = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'page' => $this->page_slug ), admin_url( 'admin.php' ) ), esc_html( $this->name ) ); |
||
497 | if ( isset( $_GET['course_id'] ) ) { |
||
498 | $course_id = intval( $_GET['course_id'] ); |
||
499 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
500 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) ); |
||
501 | } |
||
502 | ?> |
||
503 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
504 | <?php |
||
505 | } // End analysis_course_users_nav() |
||
506 | |||
507 | /** |
||
508 | * Nav area for Analysis of a specific Lesson displaying its Users |
||
509 | * @since 1.2.0 |
||
510 | * @return void |
||
511 | */ |
||
512 | public function analysis_lesson_users_nav() { |
||
513 | |||
514 | $title = sprintf( '<a href="%s">%s</a>', add_query_arg( array( 'page' => $this->page_slug ), admin_url( 'admin.php' ) ), esc_html( $this->name ) ); |
||
515 | if ( isset( $_GET['lesson_id'] ) ) { |
||
516 | $lesson_id = intval( $_GET['lesson_id'] ); |
||
517 | $course_id = intval( get_post_meta( $lesson_id, '_lesson_course', true ) ); |
||
518 | $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id ), admin_url( 'admin.php' ) ); |
||
519 | $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) ); |
||
520 | $url = add_query_arg( array( 'page' => $this->page_slug, 'lesson_id' => $lesson_id ), admin_url( 'admin.php' ) ); |
||
521 | $title .= sprintf( ' <span class="lesson-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $lesson_id ) ); |
||
522 | } |
||
523 | ?> |
||
524 | <h1><?php echo apply_filters( 'sensei_analysis_nav_title', $title ); ?></h1> |
||
525 | <?php |
||
526 | } // End analysis_lesson_users_nav() |
||
527 | |||
528 | /** |
||
529 | * Handles CSV export requests |
||
530 | * @since 1.2.0 |
||
531 | * @return void |
||
532 | */ |
||
533 | public function report_download_page() { |
||
534 | // Check if is a report |
||
535 | if ( !empty( $_GET['sensei_report_download'] ) ) { |
||
536 | $report = sanitize_text_field( $_GET['sensei_report_download'] ); |
||
537 | |||
538 | // Simple verification to ensure intent, Note that a Nonce is per user, so the URL can't be shared |
||
539 | if ( !wp_verify_nonce( $_REQUEST['_sdl_nonce'], 'sensei_csv_download-' . $report ) ) { |
||
540 | wp_die( __('Invalid request', 'woothemes-sensei') ); |
||
541 | } |
||
542 | |||
543 | // Setup the variables we might need |
||
544 | $filename = apply_filters( 'sensei_csv_export_filename', $report ); |
||
545 | $course_id = 0; |
||
546 | $lesson_id = 0; |
||
547 | $user_id = 0; |
||
548 | if( isset( $_GET['course_id'] ) ) { |
||
549 | $course_id = intval( $_GET['course_id'] ); |
||
550 | } |
||
551 | if( isset( $_GET['lesson_id'] ) ) { |
||
552 | $lesson_id = intval( $_GET['lesson_id'] ); |
||
553 | } |
||
554 | if( isset( $_GET['user_id'] ) ) { |
||
555 | $user_id = intval( $_GET['user_id'] ); |
||
556 | } |
||
557 | $type = isset( $_GET['view'] ) ? esc_html( $_GET['view'] ) : false; |
||
558 | |||
559 | if ( 0 < $lesson_id ) { |
||
560 | // Viewing a specific Lesson and all its Learners |
||
561 | $sensei_analysis_report_object = $this->load_report_object( 'Lesson', $lesson_id ); |
||
562 | } |
||
563 | elseif ( 0 < $course_id && 0 < $user_id ) { |
||
564 | // Viewing a specific User on a specific Course |
||
565 | $sensei_analysis_report_object = $this->load_report_object( 'Course', $course_id, $user_id ); |
||
0 ignored issues
–
show
$user_id is of type integer , but the function expects a object<undefined>|null .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
566 | } |
||
567 | elseif( 0 < $course_id ) { |
||
568 | // Viewing a specific Course and all it's Lessons, or it's Learners |
||
569 | $sensei_analysis_report_object = $this->load_report_object( 'Course', $course_id ); |
||
570 | } |
||
571 | elseif ( 0 < $user_id ) { |
||
572 | // Viewing a specific Learner, and their Courses |
||
573 | $sensei_analysis_report_object = $this->load_report_object( 'User_Profile', $user_id ); |
||
574 | } |
||
575 | else { |
||
576 | // Overview of all Learners, all Courses, or all Lessons |
||
577 | $sensei_analysis_report_object = $this->load_report_object( 'Overview', $type ); |
||
578 | } // End If Statement |
||
579 | |||
580 | // Handle the headers |
||
581 | $this->report_set_headers( $filename ); |
||
582 | |||
583 | // Collate the data, there could be many different reports for a single object |
||
584 | $report_data_array = $sensei_analysis_report_object->generate_report( $report ); |
||
585 | |||
586 | // Output the data |
||
587 | $this->report_write_download( $report_data_array ); |
||
588 | |||
589 | // Cleanly exit |
||
590 | exit; |
||
591 | } // End wp_query check |
||
592 | } // End report_download_page() |
||
593 | |||
594 | /** |
||
595 | * Sets headers for CSV reporting export |
||
596 | * @since 1.2.0 |
||
597 | * @param string $filename name of report file |
||
598 | * @return void |
||
599 | */ |
||
600 | public function report_set_headers( $filename = '' ) { |
||
601 | header( 'Content-Type: text/csv' ); |
||
602 | header( 'Content-Disposition: attachment;filename=' . $filename . '.csv'); |
||
603 | } // End report_set_headers() |
||
604 | |||
605 | /** |
||
606 | * Loads the right object for CSV reporting |
||
607 | * @since 1.2.0 |
||
608 | * @param string $name Name of class |
||
609 | * @param integer $data constructor arguments |
||
610 | * @param undefined $optional_data optional constructor arguments |
||
611 | * @return object class instance object |
||
612 | */ |
||
613 | public function load_report_object( $name = '', $data = 0, $optional_data = null ) { |
||
614 | $object_name = 'WooThemes_Sensei_Analysis_' . $name . '_List_Table'; |
||
615 | if ( is_null($optional_data) ) { |
||
616 | $sensei_analysis_report_object = new $object_name( $data ); |
||
617 | } else { |
||
618 | $sensei_analysis_report_object = new $object_name( $data, $optional_data ); |
||
619 | } |
||
620 | return $sensei_analysis_report_object; |
||
621 | } // End load_report_object() |
||
622 | |||
623 | /** |
||
624 | * Write array data to CSV |
||
625 | * @since 1.2.0 |
||
626 | * @param array $report_data data array |
||
627 | * @return void |
||
628 | */ |
||
629 | public function report_write_download( $report_data = array() ) { |
||
630 | $fp = fopen('php://output', 'w'); |
||
631 | foreach ($report_data as $row) { |
||
632 | fputcsv($fp, $row); |
||
633 | } // End For Loop |
||
634 | fclose($fp); |
||
635 | } // End report_write_download() |
||
636 | |||
637 | /** |
||
638 | * Adds display_name to the default list of search columns for the WP User Object |
||
639 | * @since 1.4.5 |
||
640 | * @param array $search_columns array of default user columns to search |
||
641 | * @param string $search search string |
||
642 | * @param object $user_query_object WP_User_Query Object |
||
643 | * @return array $search_columns array of user columns to search |
||
644 | */ |
||
645 | public function user_search_columns_filter( $search_columns, $search, $user_query_object ) { |
||
0 ignored issues
–
show
|
|||
646 | // Alter $search_columns to include the fields you want to search on |
||
647 | array_push( $search_columns, 'display_name' ); |
||
648 | return $search_columns; |
||
649 | } |
||
650 | |||
651 | } // End Class |
||
652 | |||
653 | /** |
||
654 | * Class WooThemes_Sensei_Analysis |
||
655 | * @ignore only for backward compatibility |
||
656 | * @since 1.9.0 |
||
657 | */ |
||
658 | class WooThemes_Sensei_Analysis extends Sensei_Analysis {} |
||
659 |
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.