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 Teacher class |
||
6 | * |
||
7 | * All functionality pertaining to the teacher role. |
||
8 | * |
||
9 | * @package Users |
||
10 | * @author Automattic |
||
11 | * @since 1.0.0 |
||
12 | */ |
||
13 | class Sensei_Teacher { |
||
14 | |||
15 | /** |
||
16 | * $teacher_role |
||
17 | * |
||
18 | * Keeps a reference to the teacher role object |
||
19 | * |
||
20 | * @access protected |
||
21 | * @since 1.8.0 |
||
22 | */ |
||
23 | protected $teacher_role; |
||
24 | |||
25 | /** |
||
26 | * $token |
||
27 | * |
||
28 | * Keeps a reference to the global sensei token |
||
29 | * |
||
30 | * @access protected |
||
31 | * @since 1.8.0 |
||
32 | */ |
||
33 | public $token; |
||
34 | |||
35 | /** |
||
36 | * Sensei_Teacher::__constructor |
||
37 | * |
||
38 | * Constructor Function |
||
39 | * |
||
40 | * @since 1.8.0 |
||
41 | * @access public |
||
42 | */ |
||
43 | public function __construct ( ) { |
||
44 | |||
45 | add_action( 'add_meta_boxes', array( $this , 'add_teacher_meta_boxes' ) , 10, 2 ); |
||
46 | add_action( 'save_post', array( $this, 'save_teacher_meta_box' ) ); |
||
47 | add_filter( 'parse_query', array( $this, 'limit_teacher_edit_screen_post_types' )); |
||
48 | add_filter( 'pre_get_posts', array( $this, 'course_analysis_teacher_access_limit' ) ); |
||
49 | add_filter( 'wp_count_posts', array( $this, 'list_table_counts' ), 10, 3 ); |
||
50 | |||
51 | add_action( 'pre_get_posts', array( $this, 'filter_queries' ) ); |
||
52 | |||
53 | //filter the quiz submissions |
||
54 | add_filter( 'sensei_check_for_activity' , array( $this, 'filter_grading_activity_queries') ); |
||
55 | |||
56 | //grading totals count only those belonging to the teacher |
||
57 | add_filter('sensei_count_statuses_args', array( $this, 'limit_grading_totals' ) ); |
||
58 | |||
59 | // show the courses owned by a user on his author archive page |
||
60 | add_filter( 'pre_get_posts', array( $this, 'add_courses_to_author_archive' ) ); |
||
61 | |||
62 | // notify admin when a teacher creates a course |
||
63 | add_action( 'transition_post_status',array( $this, 'notify_admin_teacher_course_creation' ), 10, 3 ); |
||
64 | |||
65 | // limit the analysis view to only the users taking courses belong to this teacher |
||
66 | add_filter( 'sensei_analysis_overview_filter_users',array( $this, 'limit_analysis_learners' ) , 5, 1 ); |
||
67 | |||
68 | // give teacher access to question post type |
||
69 | add_filter( 'sensei_lesson_quiz_questions', array( $this, 'allow_teacher_access_to_questions' ), 20, 2 ); |
||
70 | |||
71 | // Teacher column on the courses list on the admin edit screen |
||
72 | add_filter('manage_edit-course_columns' , array( $this, 'course_column_heading'), 10,1 ); |
||
73 | add_filter('manage_course_posts_custom_column' , array( $this, 'course_column_data'), 10,2 ); |
||
74 | |||
75 | //admin edit messages query limit teacher |
||
76 | add_filter( 'pre_get_posts', array( $this, 'limit_edit_messages_query' ) ); |
||
77 | |||
78 | //add filter by teacher on courses list |
||
79 | add_action( 'restrict_manage_posts', array( $this, 'course_teacher_filter_options' ) ); |
||
80 | add_filter( 'request', array( $this, 'teacher_filter_query_modify' ) ); |
||
81 | |||
82 | // Handle media library restrictions |
||
83 | add_filter( 'request', array( $this, 'restrict_media_library' ), 10, 1 ); |
||
84 | add_filter( 'ajax_query_attachments_args', array( $this, 'restrict_media_library_modal' ), 10, 1 ); |
||
85 | |||
86 | // update lesson owner to course teacher when saved |
||
87 | add_action( 'save_post', array( $this, 'update_lesson_teacher' ) ); |
||
88 | |||
89 | // If a Teacher logs in, redirect to /wp-admin/ |
||
90 | add_filter( 'wp_login', array( $this, 'teacher_login_redirect') , 10, 2 ); |
||
91 | |||
92 | |||
93 | add_action( 'admin_menu', array( $this, 'restrict_posts_menu_page'), 10); |
||
94 | add_filter('pre_get_comments', array ($this, 'restrict_comment_moderation'), 10, 1); |
||
95 | |||
96 | |||
97 | } // end __constructor() |
||
98 | |||
99 | /** |
||
100 | * Sensei_Teacher::create_teacher_role |
||
101 | * |
||
102 | * This function checks if the role exist, if not it creates it. |
||
103 | * for the teacher role |
||
104 | * |
||
105 | * @since 1.8.0 |
||
106 | * @access public |
||
107 | * @return void |
||
108 | */ |
||
109 | public function create_role ( ) { |
||
110 | |||
111 | // check if the role exists |
||
112 | $this->teacher_role = get_role( 'teacher' ); |
||
113 | |||
114 | // if the the teacher is not a valid WordPress role create it |
||
115 | if ( ! is_a( $this->teacher_role, 'WP_Role' ) ) { |
||
116 | // create the role |
||
117 | $this->teacher_role = add_role( 'teacher', __( 'Teacher', 'woothemes-sensei' ) ); |
||
118 | } |
||
119 | |||
120 | // add the capabilities before returning |
||
121 | $this->add_capabilities(); |
||
122 | |||
123 | }// end create_teacher_role |
||
124 | |||
125 | /** |
||
126 | * Sensei_Teacher::add_capabilities |
||
127 | * |
||
128 | * @since 1.8.0 |
||
129 | * @access protected |
||
130 | */ |
||
131 | protected function add_capabilities ( ) { |
||
132 | |||
133 | // if this is not a valid WP_Role object exit without adding anything |
||
134 | if( ! is_a( $this->teacher_role, 'WP_Role' ) || empty( $this->teacher_role ) ) { |
||
135 | return; |
||
136 | } |
||
137 | |||
138 | /** |
||
139 | * Sensei teachers capabilities array filter |
||
140 | * |
||
141 | * These capabilities will be applied to the teacher role |
||
142 | * @param array $capabilities |
||
143 | * keys: (string) $cap_name => (bool) $grant |
||
144 | */ |
||
145 | $caps = apply_filters( 'sensei_teacher_role_capabilities', array( |
||
146 | // General access rules |
||
147 | 'read' => true, |
||
148 | 'manage_sensei_grades' => true, |
||
149 | 'moderate_comments'=> true, |
||
150 | 'upload_files' => true, |
||
151 | 'edit_files' => true, |
||
152 | |||
153 | //Lessons |
||
154 | 'publish_lessons' => true, |
||
155 | 'manage_lesson_categories' => true, |
||
156 | 'edit_lessons' => true, |
||
157 | 'edit_published_lessons' => true, |
||
158 | 'edit_private_lessons' => true, |
||
159 | 'read_private_lessons' => true, |
||
160 | 'delete_published_lessons' => true, |
||
161 | |||
162 | // Courses |
||
163 | 'create_courses' => true, |
||
164 | 'publish_courses' => false, |
||
165 | 'manage_course_categories' => true, |
||
166 | 'edit_courses' => true, |
||
167 | 'edit_published_courses' => true, |
||
168 | 'edit_private_courses' => true, |
||
169 | 'read_private_courses' => true, |
||
170 | 'delete_published_courses' => true, |
||
171 | |||
172 | // Quiz |
||
173 | 'publish_quizzes' => true, |
||
174 | 'edit_quizzes' => true, |
||
175 | 'edit_published_quizzes' => true, |
||
176 | 'edit_private_quizzes' => true, |
||
177 | 'read_private_quizzes' => true, |
||
178 | |||
179 | // Questions |
||
180 | 'publish_questions' => true, |
||
181 | 'edit_questions' => true, |
||
182 | 'edit_published_questions' => true, |
||
183 | 'edit_private_questions' => true, |
||
184 | 'read_private_questions' => true, |
||
185 | |||
186 | //messages |
||
187 | 'publish_sensei_messages' => true, |
||
188 | 'edit_sensei_messages' => true, |
||
189 | 'edit_published_sensei_messages' => true, |
||
190 | 'edit_private_sensei_messages' => true, |
||
191 | 'read_private_sensei_messages' => true, |
||
192 | |||
193 | // Comments - |
||
194 | // Necessary cap so Teachers can moderate comments |
||
195 | // on their own lessons. We restrict access to other |
||
196 | // post types in $this->restrict_posts_menu_page() |
||
197 | |||
198 | 'edit_posts' => true, |
||
199 | |||
200 | )); |
||
201 | |||
202 | foreach ( $caps as $cap => $grant ) { |
||
203 | |||
204 | // load the capability on to the teacher role |
||
205 | $this->teacher_role->add_cap($cap, $grant); |
||
206 | |||
207 | } // end for each |
||
208 | |||
209 | }// end add_cap |
||
210 | |||
211 | /** |
||
212 | * Sensei_Teacher::teacher_meta_box |
||
213 | * |
||
214 | * Add the teacher metabox to the course post type edit screen |
||
215 | * |
||
216 | * @since 1.8.0 |
||
217 | * @access public |
||
218 | * @parameter string $post_type |
||
219 | * @parameter WP_Post $post |
||
220 | * @return void |
||
221 | */ |
||
222 | public function add_teacher_meta_boxes ( $post ) { |
||
223 | |||
224 | if( !current_user_can('manage_options') ){ |
||
225 | return; |
||
226 | } |
||
227 | add_meta_box( 'sensei-teacher', __( 'Teacher' , 'woothemes-sensei'), array( $this , 'teacher_meta_box_content' ), |
||
228 | 'course', |
||
229 | 'side', |
||
230 | 'core' |
||
231 | ); |
||
232 | |||
233 | } // end teacher_meta_box() |
||
234 | |||
235 | /** |
||
236 | * Sensei_Teacher::teacher_meta_box_content |
||
237 | * |
||
238 | * Render the teacher meta box markup |
||
239 | * |
||
240 | * @since 1.8.0 |
||
241 | * @access public |
||
242 | * @parameters |
||
243 | */ |
||
244 | public function teacher_meta_box_content ( $post ) { |
||
245 | |||
246 | // get the current author |
||
247 | $current_author = $post->post_author; |
||
248 | |||
249 | //get the users authorised to author courses |
||
250 | $users = $this->get_teachers_and_authors(); |
||
251 | |||
252 | ?> |
||
253 | <select name="sensei-course-teacher-author" class="sensei course teacher"> |
||
254 | |||
255 | <?php foreach ( $users as $user_id ) { ?> |
||
256 | |||
257 | <?php |
||
258 | $user = get_user_by('id', $user_id); |
||
259 | ?> |
||
260 | <option <?php selected( $current_author , $user_id , true ); ?> value="<?php echo $user_id; ?>" > |
||
261 | <?php echo $user->display_name; ?> |
||
262 | </option> |
||
263 | |||
264 | <?php }// end for each ?> |
||
265 | |||
266 | </select> |
||
267 | |||
268 | <?php |
||
269 | |||
270 | } // end render_teacher_meta_box() |
||
271 | |||
272 | /** |
||
273 | * Sensei_Teacher::get_teachers_and_authors |
||
274 | * |
||
275 | * Get a list of users who can author courses, lessons and quizes. |
||
276 | * |
||
277 | * @since 1.8.0 |
||
278 | * @access public |
||
279 | * @parameters |
||
280 | * @return array $users user id array |
||
281 | */ |
||
282 | public function get_teachers_and_authors ( ){ |
||
283 | |||
284 | $author_query_args = array( |
||
285 | 'blog_id' => $GLOBALS['blog_id'], |
||
286 | 'fields' => 'any', |
||
287 | 'who' => 'authors' |
||
288 | ); |
||
289 | |||
290 | $authors = get_users( $author_query_args ); |
||
291 | |||
292 | $teacher_query_args = array( |
||
293 | 'blog_id' => $GLOBALS['blog_id'], |
||
294 | 'fields' => 'any', |
||
295 | 'role' => 'teacher', |
||
296 | ); |
||
297 | |||
298 | $teachers = get_users( $teacher_query_args ); |
||
299 | |||
300 | return array_unique( array_merge( $teachers, $authors ) ); |
||
301 | |||
302 | }// end get_teachers_and_authors |
||
303 | |||
304 | /** |
||
305 | * Sensei_Teacher::save_teacher_meta_box |
||
306 | * |
||
307 | * Save the new teacher / author to course and all lessons |
||
308 | * |
||
309 | * Hooked into admin_init |
||
310 | * |
||
311 | * @since 1.8.0 |
||
312 | * @access public |
||
313 | * @parameters |
||
314 | * @return array $users user id array |
||
315 | */ |
||
316 | public function save_teacher_meta_box ( $course_id ){ |
||
317 | |||
318 | // check if this is a post from saving the teacher, if not exit early |
||
319 | if(! isset( $_POST[ 'sensei-course-teacher-author' ] ) || ! isset( $_POST['post_ID'] ) ){ |
||
320 | return; |
||
321 | } |
||
322 | |||
323 | //don't fire this hook again |
||
324 | remove_action('save_post', array( $this, 'save_teacher_meta_box' ) ); |
||
325 | |||
326 | // get the current post object |
||
327 | $post = get_post( $course_id ); |
||
328 | |||
329 | // get the current teacher/author |
||
330 | $current_author = absint( $post->post_author ); |
||
331 | $new_author = absint( $_POST[ 'sensei-course-teacher-author' ] ); |
||
332 | |||
333 | // loop through all post lessons to update their authors as well |
||
334 | $this->update_course_lessons_author( $course_id , $new_author ); |
||
335 | |||
336 | // do not do any processing if the selected author is the same as the current author |
||
337 | if( $current_author == $new_author ){ |
||
338 | return; |
||
339 | } |
||
340 | |||
341 | // save the course author |
||
342 | $post_updates = array( |
||
343 | 'ID' => $post->ID , |
||
344 | 'post_author' => $new_author |
||
345 | ); |
||
346 | wp_update_post( $post_updates ); |
||
347 | |||
348 | // ensure the the modules are update so that then new teacher has access to them |
||
349 | Sensei_Teacher::update_course_modules_author( $course_id, $new_author ); |
||
350 | |||
351 | // notify the new teacher |
||
352 | $this->teacher_course_assigned_notification( $new_author, $course_id ); |
||
353 | |||
354 | } // end save_teacher_meta_box |
||
355 | |||
356 | /** |
||
357 | * Update all the course terms set(selected) on the given course. Moving course term ownership to |
||
358 | * the new author. Making sure the course terms are maintained. |
||
359 | * |
||
360 | * This function also checks if terms are shared, with other courses |
||
361 | * |
||
362 | * @param $course_id |
||
363 | * @param $new_teacher_id |
||
364 | * @return void |
||
365 | */ |
||
366 | public static function update_course_modules_author( $course_id ,$new_teacher_id ){ |
||
367 | |||
368 | if( empty( $course_id ) || empty( $new_teacher_id ) ){ |
||
369 | return; |
||
370 | } |
||
371 | |||
372 | $terms_selected_on_course = wp_get_object_terms( $course_id, 'module' ); |
||
373 | |||
374 | if( empty( $terms_selected_on_course ) ){ |
||
375 | return; |
||
376 | } |
||
377 | |||
378 | foreach( $terms_selected_on_course as $term ){ |
||
379 | |||
380 | $term_author = Sensei_Core_Modules::get_term_author( $term->slug ); |
||
381 | if( $new_teacher_id != $term_author->ID ){ |
||
382 | |||
383 | $new_term = ''; |
||
384 | |||
385 | //if the new teacher is admin first check to see if the term with this name already exists |
||
386 | if( user_can( $new_teacher_id, 'manage_options' ) ){ |
||
387 | |||
388 | $slug_without_teacher_id = str_ireplace(' ', '-', trim( $term->name ) ); |
||
389 | $term_args = array( 'slug'=> $slug_without_teacher_id, 'hide_empty' => false, ); |
||
390 | $existing_admin_terms = get_terms( 'module', $term_args ); |
||
391 | if( !empty( $existing_admin_terms ) ){ |
||
392 | // insert it even if it exists |
||
393 | $new_term = get_term( $existing_admin_terms[0]->term_id, 'module', ARRAY_A ); |
||
394 | } |
||
395 | } |
||
396 | |||
397 | if( empty ( $new_term ) ){ |
||
398 | |||
399 | //setup the new slug |
||
400 | $new_author_term_slug = $new_teacher_id . '-' . str_ireplace(' ', '-', trim( $term->name ) ); |
||
401 | |||
402 | // create new term and set it |
||
403 | $new_term = wp_insert_term( $term->name,'module', array('slug'=> $new_author_term_slug ) ); |
||
404 | |||
405 | } |
||
406 | |||
407 | |||
408 | |||
409 | // if term exists |
||
410 | if( is_wp_error( $new_term ) && isset( $new_term->errors['term_exists'] ) ){ |
||
411 | |||
412 | $existing_term = get_term_by( 'slug', $new_author_term_slug, 'module'); |
||
413 | $term_id = $existing_term->term_id; |
||
414 | |||
415 | }else{ |
||
416 | |||
417 | // for a new term simply get the term from the returned value |
||
418 | $term_id = $new_term['term_id']; |
||
419 | |||
420 | } // end if term exist |
||
421 | |||
422 | // set the terms selected on the course |
||
423 | wp_set_object_terms( $course_id, $term_id , 'module', true ); |
||
424 | |||
425 | // remove old term |
||
426 | wp_remove_object_terms( $course_id, $term->term_id, 'module' ); |
||
427 | |||
428 | // update the lessons within the current module term |
||
429 | $lessons = Sensei()->course->course_lessons( $course_id ); |
||
430 | foreach( $lessons as $lesson ){ |
||
431 | |||
432 | if( has_term( $term->slug, 'module', $lesson ) ){ |
||
433 | |||
434 | // add the new term, the false at the end says to replace all terms on this module |
||
435 | // with the new term. |
||
436 | wp_set_object_terms( $lesson->ID, $term_id , 'module', false ); |
||
437 | update_post_meta( $lesson->ID, '_order_module_' . intval( $term_id ), 0 ); |
||
438 | } |
||
439 | |||
440 | }// end for each |
||
441 | |||
442 | } |
||
443 | } |
||
444 | |||
445 | }// end update_course_module_terms_author |
||
446 | |||
447 | /** |
||
448 | * Sensei_Teacher::update_course_lessons_author |
||
449 | * |
||
450 | * Update all course lessons and their quiz with a new author |
||
451 | * |
||
452 | * @since 1.8.0 |
||
453 | * @access public |
||
454 | * @parameters |
||
455 | * @return array $users user id array |
||
456 | */ |
||
457 | public function update_course_lessons_author ( $course_id, $new_author ){ |
||
458 | |||
459 | |||
460 | if( empty( $course_id ) || empty( $new_author ) ){ |
||
461 | return false; |
||
462 | } |
||
463 | |||
464 | //get a list of course lessons |
||
465 | $lessons = Sensei()->course->course_lessons( $course_id ); |
||
466 | |||
467 | if( empty( $lessons ) || ! is_array( $lessons ) ){ |
||
468 | return false; |
||
469 | } |
||
470 | |||
471 | // update each lesson and quiz author |
||
472 | foreach( $lessons as $lesson ){ |
||
473 | |||
474 | // don't update if the author is tha same as the new author |
||
475 | if( $new_author == $lesson->post_author ){ |
||
476 | continue; |
||
477 | } |
||
478 | |||
479 | // update lesson author |
||
480 | wp_update_post( array( |
||
481 | 'ID'=> $lesson->ID, |
||
482 | 'post_author' => $new_author |
||
483 | ) ); |
||
484 | |||
485 | // update quiz author |
||
486 | //get the lessons quiz |
||
487 | $lesson_quizzes = Sensei()->lesson->lesson_quizzes( $lesson->ID ); |
||
488 | if( is_array( $lesson_quizzes ) ){ |
||
489 | foreach ( $lesson_quizzes as $quiz_id ) { |
||
490 | // update quiz with new author |
||
491 | wp_update_post( array( |
||
492 | 'ID' => $quiz_id, |
||
493 | 'post_author' => $new_author |
||
494 | ) ); |
||
495 | } |
||
496 | }else{ |
||
497 | wp_update_post( array( |
||
498 | 'ID' => $lesson_quizzes, |
||
499 | 'post_author' => $new_author |
||
500 | ) ); |
||
501 | } |
||
502 | |||
503 | } // end for each lessons |
||
504 | |||
505 | return true; |
||
506 | |||
507 | }// end update_course_lessons_author |
||
508 | |||
509 | |||
510 | |||
511 | /** |
||
512 | * Sensei_Teacher::course_analysis_teacher_access_limit |
||
513 | * |
||
514 | * Alter the query so that users can only see their courses on the analysis page |
||
515 | * |
||
516 | * @since 1.8.0 |
||
517 | * @access public |
||
518 | * @parameters $query |
||
519 | * @return array $users user id array |
||
520 | */ |
||
521 | public function course_analysis_teacher_access_limit ( $query ) { |
||
522 | |||
523 | if( ! is_admin() || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ) { |
||
524 | return $query; |
||
525 | } |
||
526 | |||
527 | if ( ! function_exists( 'get_current_screen' ) ) { |
||
528 | return $query; |
||
529 | } |
||
530 | |||
531 | $screen = get_current_screen(); |
||
532 | $sensei_post_types = array('course', 'lesson', 'question' ); |
||
533 | |||
534 | // exit early for the following conditions |
||
535 | $limit_screen_ids = array( 'sensei_page_sensei_analysis', 'course_page_module-order' ); |
||
536 | |||
537 | if( ! $this->is_admin_teacher() || empty( $screen ) || ! in_array( $screen->id ,$limit_screen_ids ) |
||
538 | || ! in_array( $query->query['post_type'], $sensei_post_types ) ){ |
||
539 | return $query; |
||
540 | } |
||
541 | |||
542 | global $current_user; |
||
543 | // set the query author to the current user to only show those those posts |
||
544 | $query->set( 'author', $current_user->ID ); |
||
545 | return $query; |
||
546 | |||
547 | }// end course_analysis_teacher_access_limit |
||
548 | |||
549 | |||
550 | /** |
||
551 | * Sensei_Teacher::limit_teacher_edit_screen_post_types |
||
552 | * |
||
553 | * Determine if we're in admin and the current logged in use is a teacher |
||
554 | * |
||
555 | * @since 1.8.0 |
||
556 | * @access public |
||
557 | * @parameters array $wp_query |
||
558 | * @return bool $is_admin_teacher |
||
559 | */ |
||
560 | public function is_admin_teacher ( ){ |
||
561 | |||
562 | if( ! is_user_logged_in()){ |
||
563 | return false; |
||
564 | } |
||
565 | $is_admin_teacher = false; |
||
566 | |||
567 | if( is_admin() && Sensei_Teacher::is_a_teacher( get_current_user_id() ) ){ |
||
568 | |||
569 | $is_admin_teacher = true; |
||
570 | |||
571 | } |
||
572 | |||
573 | return $is_admin_teacher; |
||
574 | |||
575 | } // end is_admin_teacher |
||
576 | |||
577 | /** |
||
578 | * Show correct post counts on list table for Sensei post types |
||
579 | * |
||
580 | * @since 1.8.0 |
||
581 | * |
||
582 | * @param object $counts Default status counts |
||
583 | * @param string $type Current post type |
||
584 | * @param string $perm User permission level |
||
585 | * @return object Modified status counts |
||
586 | */ |
||
587 | public function list_table_counts( $counts, $type, $perm ) { |
||
588 | global $current_user; |
||
589 | |||
590 | if( ! in_array( $type, array( 'course', 'lesson', 'question' ) ) ) { |
||
591 | return $counts; |
||
592 | } |
||
593 | |||
594 | if( ! $this->is_admin_teacher() ) { |
||
595 | return $counts; |
||
596 | } |
||
597 | |||
598 | $args = array( |
||
599 | 'post_type' => $type, |
||
600 | 'author' => $current_user->ID, |
||
601 | 'posts_per_page' => -1 |
||
602 | ); |
||
603 | |||
604 | // Get all available statuses |
||
605 | $stati = get_post_stati(); |
||
606 | |||
607 | // Update count object |
||
608 | foreach( $stati as $status ) { |
||
609 | $args['post_status'] = $status; |
||
610 | $posts = get_posts( $args ); |
||
611 | $counts->$status = count( $posts ); |
||
612 | } |
||
613 | |||
614 | return $counts; |
||
615 | } |
||
616 | |||
617 | /** |
||
618 | * Filter the post queries to show |
||
619 | * only lesson /course and users that belong |
||
620 | * to the current logged teacher. |
||
621 | * |
||
622 | * @since 1.8.0 |
||
623 | * |
||
624 | */ |
||
625 | public function filter_queries ( $query ) { |
||
626 | global $current_user; |
||
627 | |||
628 | if( ! $this->is_admin_teacher() ) { |
||
629 | return; |
||
630 | } |
||
631 | |||
632 | if ( ! function_exists( 'get_current_screen' ) ) { |
||
633 | return; |
||
634 | } |
||
635 | |||
636 | $screen = get_current_screen(); |
||
637 | if( empty( $screen ) ) { |
||
638 | return $query; |
||
639 | } |
||
640 | switch( $screen->id ) { |
||
641 | case 'sensei_page_sensei_grading': |
||
642 | case 'sensei_page_sensei_analysis': |
||
643 | case 'sensei_page_sensei_learners': |
||
644 | case 'lesson': |
||
645 | case 'course': |
||
646 | case 'question': |
||
647 | case 'lesson_page_module-order': |
||
648 | |||
649 | /** |
||
650 | * sensei_filter_queries_set_author |
||
651 | * Filter the author Sensei set for queries |
||
652 | * |
||
653 | * @since 1.8.0 |
||
654 | * |
||
655 | * @param int $user_id |
||
656 | * @param string $screen_id |
||
657 | * |
||
658 | */ |
||
659 | $query->set( 'author', apply_filters( 'sensei_filter_queries_set_author', $current_user->ID, $screen->id ) ); |
||
660 | break; |
||
661 | } |
||
662 | } |
||
663 | |||
664 | /** |
||
665 | * Limit grading quizzes to only those within courses belonging to the current teacher |
||
666 | * . This excludes the admin user. |
||
667 | * |
||
668 | * @since 1.8.0 |
||
669 | * @hooked into the_comments |
||
670 | * @param array $comments |
||
671 | * |
||
672 | * @return array $comments |
||
673 | */ |
||
674 | public function filter_grading_activity_queries( $comments ){ |
||
675 | |||
676 | if( !is_admin() || ! $this->is_admin_teacher() || is_numeric( $comments ) || ! is_array( $comments ) ){ |
||
677 | return $comments ; |
||
678 | } |
||
679 | |||
680 | //check if we're on the grading screen |
||
681 | $screen = get_current_screen(); |
||
682 | |||
683 | if( empty( $screen ) || 'sensei_page_sensei_grading' != $screen->id ){ |
||
684 | return $comments; |
||
685 | } |
||
686 | |||
687 | // get the course and determine if the current teacher is the owner |
||
688 | // if not remove it from the list of comments to be returned |
||
689 | foreach( $comments as $key => $comment){ |
||
690 | $lesson = get_post( $comment->comment_post_ID ); |
||
691 | $course_id = Sensei()->lesson->get_course_id( $lesson->ID ); |
||
692 | $course = get_post( $course_id ); |
||
693 | if( ! isset( $course->post_author ) || intval( $course->post_author) != intval( get_current_user_id() ) ){ |
||
694 | //remove this as the teacher should see this. |
||
695 | unset( $comments[ $key ] ); |
||
696 | } |
||
697 | } |
||
698 | return $comments ; |
||
699 | |||
700 | }// end function filter grading |
||
701 | |||
702 | /** |
||
703 | * Limit the grading screen totals to only show lessons in the course |
||
704 | * belonging to the currently logged in teacher. This only applies to |
||
705 | * the teacher role. |
||
706 | * |
||
707 | * @since 1.8.0 |
||
708 | * |
||
709 | * @hooked into sensei_count_statuses_args |
||
710 | * @param array $args |
||
711 | * |
||
712 | * @return array $args |
||
713 | */ |
||
714 | public function limit_grading_totals( $args ){ |
||
715 | |||
716 | if( !is_admin() || ! $this->is_admin_teacher() || ! is_array( $args ) ){ |
||
717 | return $args ; |
||
718 | } |
||
719 | |||
720 | //get the teachers courses |
||
721 | // the query is already filtered to only the teacher |
||
722 | $courses = Sensei()->course->get_all_courses(); |
||
723 | |||
724 | if( empty( $courses ) || ! is_array( $courses ) ){ |
||
725 | return $args; |
||
726 | } |
||
727 | |||
728 | //setup the lessons quizzes to limit the grading totals to |
||
729 | $quiz_scope = array(); |
||
730 | foreach( $courses as $course ){ |
||
731 | |||
732 | $course_lessons = Sensei()->course->course_lessons( $course->ID ); |
||
733 | |||
734 | if( ! empty( $course_lessons ) && is_array( $course_lessons ) ){ |
||
735 | |||
736 | foreach( $course_lessons as $lesson ){ |
||
737 | |||
738 | $quiz_id = Sensei()->lesson->lesson_quizzes( $lesson->ID ); |
||
739 | if( !empty( $quiz_id ) ) { |
||
740 | |||
741 | array_push( $quiz_scope, $quiz_id ); |
||
742 | |||
743 | } |
||
744 | |||
745 | } |
||
746 | |||
747 | } |
||
748 | |||
749 | } |
||
750 | |||
751 | $args['post__in'] = $quiz_scope; |
||
752 | |||
753 | return $args; |
||
754 | } |
||
755 | |||
756 | /** |
||
757 | * It ensures that the author archive shows course by the current user. |
||
758 | * |
||
759 | * This function is hooked into the pre_get_posts filter |
||
760 | * |
||
761 | * @param WP_Query $query |
||
762 | * @return WP_Query $query |
||
763 | */ |
||
764 | public function add_courses_to_author_archive( $query ) { |
||
765 | |||
766 | if ( is_admin() || ! $query->is_author() ){ |
||
767 | return $query; |
||
768 | } |
||
769 | |||
770 | // this should only apply to users with the teacher role |
||
771 | $current_page_user = get_user_by('login', $query->get('author_name') ); |
||
772 | if( ! $current_page_user || ! in_array('teacher', $current_page_user->roles ) ) { |
||
773 | |||
774 | return $query; |
||
775 | |||
776 | } |
||
777 | |||
778 | // Change post types depending on what is set already |
||
779 | $current_post_types = $query->get( 'post_type' ); |
||
780 | if( empty( $current_post_types ) ){ |
||
781 | |||
782 | // if empty it means post by default, so add post so that it also includes that for now |
||
783 | $new_post_types = array( 'post', 'course' ); |
||
784 | |||
785 | } elseif( is_array( $current_post_types ) ) { |
||
786 | |||
787 | // merge the post types instead of overwriting it |
||
788 | $new_post_types = array_merge( $current_post_types, array( 'course' ) ); |
||
789 | |||
790 | }else{ |
||
791 | |||
792 | // in this instance it is probably just one post type in string format |
||
793 | $new_post_types = array( $current_post_types , 'course'); |
||
794 | |||
795 | } |
||
796 | |||
797 | // change the query before returning it |
||
798 | $query->set('post_type', $new_post_types ); |
||
799 | |||
800 | /** |
||
801 | * Change the query on the teacher author archive template |
||
802 | * |
||
803 | * @since 1.8.4 |
||
804 | * @param WP_Query $query |
||
805 | */ |
||
806 | return apply_filters( 'sensei_teacher_archive_query', $query ); |
||
807 | |||
808 | } |
||
809 | |||
810 | /** |
||
811 | * Notify teacher when someone assigns a course to their account. |
||
812 | * |
||
813 | * @since 1.8.0 |
||
814 | * |
||
815 | * @param $teacher_id |
||
816 | * @param $course_id |
||
817 | * @return bool |
||
818 | */ |
||
819 | public function teacher_course_assigned_notification( $teacher_id, $course_id ){ |
||
820 | |||
821 | if( 'course' != get_post_type( $course_id ) || ! get_userdata( $teacher_id ) ){ |
||
822 | return false; |
||
823 | } |
||
824 | |||
825 | // if new user is the same as the current logged user, they don't need an email |
||
826 | if( $teacher_id == get_current_user_id() ){ |
||
827 | return true; |
||
828 | } |
||
829 | |||
830 | // load the email class |
||
831 | include('emails/class-sensei-email-teacher-new-course-assignment.php'); |
||
832 | $email = new Sensei_Email_Teacher_New_Course_Assignment(); |
||
833 | $email->trigger( $teacher_id, $course_id ); |
||
834 | |||
835 | return true; |
||
836 | } // end teacher_course_assigned_notification |
||
837 | |||
838 | /** |
||
839 | * Email the admin when a teacher creates a new course |
||
840 | * |
||
841 | * This function hooks into wp_insert_post |
||
842 | * |
||
843 | * @since 1.8.0 |
||
844 | * @param int $course_id |
||
845 | * @return bool |
||
846 | */ |
||
847 | public function notify_admin_teacher_course_creation( $new_status, $old_status, $post ){ |
||
848 | |||
849 | $course_id = $post->ID; |
||
850 | |||
851 | if( 'publish'== $old_status || 'course' != get_post_type( $course_id ) || 'auto-draft' == get_post_status( $course_id ) |
||
852 | || 'trash' == get_post_status( $course_id ) || 'draft' == get_post_status( $course_id ) ) { |
||
853 | |||
854 | return false; |
||
855 | |||
856 | } |
||
857 | |||
858 | /** |
||
859 | * Filter the option to send admin notification emails when teachers creation |
||
860 | * course. |
||
861 | * |
||
862 | * @since 1.8.0 |
||
863 | * |
||
864 | * @param bool $on default true |
||
865 | */ |
||
866 | if( ! apply_filters('sensei_notify_admin_new_course_creation', true ) ){ |
||
867 | return false; |
||
868 | } |
||
869 | |||
870 | // setting up the data needed by the email template |
||
871 | global $sensei_email_data; |
||
872 | $template = 'admin-teacher-new-course-created'; |
||
873 | $course = get_post( $course_id ); |
||
874 | $teacher = new WP_User( $course->post_author ); |
||
875 | $recipient = get_option('admin_email', true); |
||
876 | |||
877 | // don't send if the course is created by admin |
||
878 | if( $recipient == $teacher->user_email || current_user_can( 'manage_options' )){ |
||
879 | return false; |
||
880 | } |
||
881 | |||
882 | /** |
||
883 | * Filter the email Header for the admin-teacher-new-course-created template |
||
884 | * |
||
885 | * @since 1.8.0 |
||
886 | * @param string $template |
||
887 | */ |
||
888 | $heading = apply_filters( 'sensei_email_heading', __( 'New course created.', 'woothemes-sensei' ), $template ); |
||
889 | |||
890 | /** |
||
891 | * Filter the email subject for the the |
||
892 | * admin-teacher-new-course-created template |
||
893 | * |
||
894 | * @since 1.8.0 |
||
895 | * @param string $subject default New course assigned to you |
||
896 | * @param string $template |
||
897 | */ |
||
898 | $subject = apply_filters('sensei_email_subject', |
||
899 | '['. get_bloginfo( 'name', 'display' ) .'] '. __( 'New course created by', 'woothemes-sensei' ) . ' ' . $teacher->display_name , |
||
900 | $template ); |
||
901 | |||
902 | //course edit link |
||
903 | $course_edit_link = admin_url('post.php?post=' . $course_id . '&action=edit' ); |
||
904 | |||
905 | // Construct data array |
||
906 | $email_data = array( |
||
907 | 'template' => $template, |
||
908 | 'heading' => $heading, |
||
909 | 'teacher' => $teacher, |
||
910 | 'course_id' => $course_id, |
||
911 | 'course_name' => $course->post_title, |
||
912 | 'course_edit_link' => $course_edit_link, |
||
913 | ); |
||
914 | |||
915 | /** |
||
916 | * Filter the sensei email data for the admin-teacher-new-course-created template |
||
917 | * |
||
918 | * @since 1.8.0 |
||
919 | * @param array $email_data |
||
920 | * @param string $template |
||
921 | */ |
||
922 | $sensei_email_data = apply_filters( 'sensei_email_data', $email_data , $template ); |
||
923 | |||
924 | // Send mail |
||
925 | Sensei()->emails->send( $recipient, $subject , Sensei()->emails->get_content( $template ) ); |
||
926 | |||
927 | }// end notify admin of course creation |
||
928 | |||
929 | /** |
||
930 | * Limit the analysis view to only the users taking courses belong to this teacher |
||
931 | * |
||
932 | * Hooked into sensei_analysis_get_learners |
||
933 | * @param array $args WP_User_Query arguments |
||
934 | * @return array $learners_query_results |
||
935 | */ |
||
936 | public function limit_analysis_learners( $args ){ |
||
937 | |||
938 | // show default for none teachers |
||
939 | if( ! Sensei()->teacher->is_admin_teacher() ) { |
||
940 | return $args; |
||
941 | } |
||
942 | |||
943 | // for teachers all courses only return those which belong to the teacher |
||
944 | // as they don't have access to course belonging to other users |
||
945 | $teacher_courses = Sensei()->course->get_all_courses(); |
||
946 | |||
947 | // if the user has no courses they should see no users |
||
948 | if( empty( $teacher_courses ) || ! is_array( $teacher_courses ) ){ |
||
949 | // tell the query to return 0 students |
||
950 | $args[ 'include'] = array( 0 ); |
||
951 | return $args; |
||
952 | |||
953 | } |
||
954 | |||
955 | $learner_ids_for_teacher_courses = array(); |
||
956 | foreach( $teacher_courses as $course ){ |
||
957 | |||
958 | $course_learner_ids = array(); |
||
959 | $activity_comments = Sensei_Utils::sensei_check_for_activity( array( 'post_id' => $course->ID, 'type' => 'sensei_course_status', 'field' => 'user_id' ), true ); |
||
960 | |||
961 | if( empty( $activity_comments ) || ( is_array( $activity_comments ) && ! ( count( $activity_comments ) > 0 ) ) ){ |
||
962 | continue; // skip to the next course as there are no users on this course |
||
963 | } |
||
964 | |||
965 | // it could be an array of comments or a single comment |
||
966 | if( is_array( $activity_comments ) ){ |
||
967 | |||
968 | foreach( $activity_comments as $comment ){ |
||
969 | |||
970 | $user = get_userdata( $comment->user_id ); |
||
971 | |||
972 | if( empty( $user ) ){ |
||
973 | // next comment in this array |
||
974 | continue; |
||
975 | } |
||
976 | |||
977 | $course_learner_ids[] = $user->ID; |
||
978 | } |
||
979 | |||
980 | }else{ |
||
981 | |||
982 | $user = get_userdata( $activity_comments->user_id ); |
||
983 | $course_learner_ids[] = $user->ID; |
||
984 | |||
985 | } |
||
986 | |||
987 | // add learners on this course to the all courses learner list |
||
988 | $learner_ids_for_teacher_courses = array_merge( $learner_ids_for_teacher_courses, $course_learner_ids ); |
||
989 | |||
990 | } |
||
991 | |||
992 | // if there are no students taking the courses by this teacher don't show them any of the other users |
||
993 | if( empty( $learner_ids_for_teacher_courses ) ){ |
||
994 | |||
995 | $args[ 'include'] = array( 0 ); |
||
996 | |||
997 | }else{ |
||
998 | |||
999 | $args[ 'include'] = $learner_ids_for_teacher_courses; |
||
1000 | |||
1001 | } |
||
1002 | |||
1003 | // return the WP_Use_Query arguments |
||
1004 | return $args; |
||
1005 | |||
1006 | }// end limit_analysis_learners |
||
1007 | |||
1008 | /** |
||
1009 | * Give teacher full admin access to the question post type |
||
1010 | * in certain cases. |
||
1011 | * |
||
1012 | * @since 1.8.0 |
||
1013 | * @param $questions |
||
1014 | * @return mixed |
||
1015 | */ |
||
1016 | public function allow_teacher_access_to_questions( $questions, $quiz_id ){ |
||
1017 | |||
1018 | if( ! $this->is_admin_teacher() ){ |
||
1019 | return $questions; |
||
1020 | } |
||
1021 | |||
1022 | $screen = get_current_screen(); |
||
1023 | |||
1024 | // don't run this filter within this functions call to Sensei()->lesson->lesson_quiz_questions |
||
1025 | remove_filter( 'sensei_lesson_quiz_questions', array( $this, 'allow_teacher_access_to_questions' ), 20 ); |
||
1026 | |||
1027 | if( ! empty( $screen ) && 'lesson'== $screen->post_type ){ |
||
1028 | |||
1029 | $admin_user = get_user_by('email', get_bloginfo('admin_email')); |
||
1030 | if( ! empty($admin_user) ){ |
||
1031 | |||
1032 | $current_teacher_id = get_current_user_id(); |
||
1033 | |||
1034 | // set current user to admin so teacher can view all questions |
||
1035 | wp_set_current_user( $admin_user->ID ); |
||
1036 | $questions = Sensei()->lesson->lesson_quiz_questions( $quiz_id ); |
||
1037 | |||
1038 | // set the teacher as the current use again |
||
1039 | wp_set_current_user( $current_teacher_id ); |
||
1040 | } |
||
1041 | |||
1042 | } |
||
1043 | // attach the filter again for other funtion calls to Sensei()->lesson->lesson_quiz_questions |
||
1044 | add_filter( 'sensei_lesson_quiz_questions', array( $this, 'allow_teacher_access_to_questions' ), 20,2 ); |
||
1045 | |||
1046 | return $questions; |
||
1047 | } |
||
1048 | |||
1049 | /** |
||
1050 | * Give the teacher role access to questions from the question bank |
||
1051 | * |
||
1052 | * @since 1.8.0 |
||
1053 | * @param $wp_query |
||
1054 | * @return mixed |
||
1055 | */ |
||
1056 | public function give_access_to_all_questions( $wp_query ){ |
||
1057 | |||
1058 | if( ! $this->is_admin_teacher() || !function_exists( 'get_current_screen') || 'question' != $wp_query->get('post_type') ){ |
||
1059 | |||
1060 | return $wp_query; |
||
1061 | } |
||
1062 | |||
1063 | $screen = get_current_screen(); |
||
1064 | if( ( isset($screen->id) && 'lesson' == $screen->id ) |
||
1065 | || ( defined( 'DOING_AJAX' ) && DOING_AJAX ) ){ |
||
1066 | |||
1067 | $admin_user = get_user_by('email', get_bloginfo('admin_email')); |
||
1068 | if( ! empty($admin_user) ){ |
||
1069 | |||
1070 | $current_teacher_id = get_current_user_id(); |
||
1071 | |||
1072 | // set current user to admin so teacher can view all questions |
||
1073 | wp_set_current_user( $admin_user->ID ); |
||
1074 | |||
1075 | //run new query as admin |
||
1076 | $wp_query = new WP_Query( $wp_query->query ); |
||
1077 | |||
1078 | //set the teache as current use again |
||
1079 | wp_set_current_user( $current_teacher_id ); |
||
1080 | |||
1081 | } |
||
1082 | } |
||
1083 | |||
1084 | return $wp_query; |
||
1085 | }// end give_access_to_all_questions |
||
1086 | |||
1087 | /** |
||
1088 | * Add new column heading to the course admin edit list |
||
1089 | * |
||
1090 | * @since 1.8.0 |
||
1091 | * @param $columns |
||
1092 | * @return array |
||
1093 | */ |
||
1094 | public function course_column_heading($columns) { |
||
1095 | |||
1096 | if( $this->is_admin_teacher() ){ |
||
1097 | return $columns; |
||
1098 | } |
||
1099 | $new_columns = array( |
||
1100 | 'teacher' => __('Teacher', 'woothemes-sensei'), |
||
1101 | ); |
||
1102 | return array_merge($columns, $new_columns); |
||
1103 | |||
1104 | }// end teacher column add |
||
1105 | |||
1106 | /** |
||
1107 | * Print out teacher column data |
||
1108 | * |
||
1109 | * @since 1.8.0 |
||
1110 | * @param $column |
||
1111 | * @param $course_id |
||
1112 | */ |
||
1113 | public function course_column_data( $column, $course_id ){ |
||
1114 | |||
1115 | if( $this->is_admin_teacher() || 'teacher' != $column ){ |
||
1116 | return; |
||
1117 | } |
||
1118 | |||
1119 | $course = get_post( $course_id ); |
||
1120 | $teacher = get_userdata( $course->post_author ); |
||
1121 | |||
1122 | if( !$teacher ){ |
||
1123 | return; |
||
1124 | } |
||
1125 | |||
1126 | echo '<a href="'. get_edit_user_link( $teacher->ID ) .'" >'. $teacher->display_name.'</a>'; |
||
1127 | |||
1128 | }// end course_column_ data |
||
1129 | |||
1130 | /** |
||
1131 | * Return only courses belonging to the given teacher. |
||
1132 | * |
||
1133 | * |
||
1134 | * @since 1.8.0 |
||
1135 | * |
||
1136 | * @param int $teacher_id |
||
1137 | * @param bool $return_ids_only |
||
1138 | * |
||
1139 | * @return array $teachers_courses |
||
1140 | */ |
||
1141 | public function get_teacher_courses( $teacher_id, $return_ids_only= false){ |
||
1142 | |||
1143 | $teachers_courses = array(); |
||
1144 | |||
1145 | if( empty( $teacher_id ) ){ |
||
1146 | $teacher_id = get_current_user_id(); |
||
1147 | } |
||
1148 | |||
1149 | $all_courses = Sensei()->course->get_all_courses(); |
||
1150 | |||
1151 | if( empty( $all_courses ) ){ |
||
1152 | return $all_courses; |
||
1153 | } |
||
1154 | |||
1155 | foreach( $all_courses as $course ){ |
||
1156 | |||
1157 | if( $course->post_author != $teacher_id ){ |
||
1158 | continue; |
||
1159 | } |
||
1160 | |||
1161 | if( $return_ids_only ){ |
||
1162 | |||
1163 | $teachers_courses[] = $course->ID; |
||
1164 | |||
1165 | }else{ |
||
1166 | |||
1167 | $teachers_courses[] = $course; |
||
1168 | |||
1169 | } |
||
1170 | |||
1171 | } |
||
1172 | |||
1173 | return $teachers_courses; |
||
1174 | |||
1175 | } |
||
1176 | |||
1177 | /** |
||
1178 | * Limit the message display to only those sent to the current teacher |
||
1179 | * |
||
1180 | * @since 1.8.0 |
||
1181 | * |
||
1182 | * @param $query |
||
1183 | * @return mixed |
||
1184 | */ |
||
1185 | public function limit_edit_messages_query( $query ){ |
||
1186 | if( ! $this->is_admin_teacher() || 'sensei_message' != $query->get('post_type') ){ |
||
1187 | return $query; |
||
1188 | } |
||
1189 | |||
1190 | $teacher = wp_get_current_user(); |
||
1191 | |||
1192 | $query->set( 'meta_key', '_receiver' ); |
||
1193 | $meta_query_args = array( |
||
1194 | 'key' => '_receiver', |
||
1195 | 'value' => $teacher->get('user_login') , |
||
1196 | 'compare' => '=' |
||
1197 | ); |
||
1198 | |||
1199 | $query->set('meta_query', $meta_query_args ); |
||
1200 | |||
1201 | return $query; |
||
1202 | } |
||
1203 | |||
1204 | |||
1205 | /** |
||
1206 | * Add options to filter courses by teacher |
||
1207 | * |
||
1208 | * @since 1.8.0 |
||
1209 | * |
||
1210 | * @return void |
||
1211 | */ |
||
1212 | public function course_teacher_filter_options() { |
||
1213 | global $typenow; |
||
1214 | |||
1215 | if( ! is_admin() || 'course' != $typenow || ! current_user_can('manage_sensei') ) { |
||
1216 | return; |
||
1217 | } |
||
1218 | |||
1219 | // get all roles |
||
1220 | $roles = get_editable_roles(); |
||
1221 | |||
1222 | // get roles with the course edit capability |
||
1223 | // and then get the users with those roles |
||
1224 | $users_who_can_edit_courses = array(); |
||
1225 | foreach( $roles as $role_item ){ |
||
1226 | |||
1227 | $role = get_role( strtolower( $role_item['name'] ) ); |
||
1228 | |||
1229 | if( is_a( $role, 'WP_Role' ) && $role->has_cap('edit_courses') ){ |
||
1230 | |||
1231 | $user_query_args = array( 'role' => $role->name, 'fields' => array( 'ID', 'display_name' ) ); |
||
1232 | $role_users_who_can_edit_courses = get_users( $user_query_args ); |
||
1233 | |||
1234 | // add user from the current $user_role to all users |
||
1235 | $users_who_can_edit_courses = array_merge( $users_who_can_edit_courses, $role_users_who_can_edit_courses ); |
||
1236 | |||
1237 | } |
||
1238 | |||
1239 | } |
||
1240 | |||
1241 | // Create the select element with the given users who can edit course |
||
1242 | $selected = isset( $_GET['course_teacher'] ) ? $_GET['course_teacher'] : ''; |
||
1243 | $course_options = ''; |
||
1244 | foreach( $users_who_can_edit_courses as $user ) { |
||
1245 | $course_options .= '<option value="' . esc_attr( $user->ID ) . '" ' . selected( $selected, $user->ID, false ) . '>' . $user->display_name . '</option>'; |
||
1246 | } |
||
1247 | |||
1248 | $output = '<select name="course_teacher" id="dropdown_course_teachers">'; |
||
1249 | $output .= '<option value="">'.__( 'Show all teachers', 'woothemes-sensei' ).'</option>'; |
||
1250 | $output .= $course_options; |
||
1251 | $output .= '</select>'; |
||
1252 | |||
1253 | echo $output; |
||
1254 | } |
||
1255 | |||
1256 | /** |
||
1257 | * Modify the main query on the admin course list screen |
||
1258 | * |
||
1259 | * @since 1.8.0 |
||
1260 | * |
||
1261 | * @param $query |
||
1262 | * @return $query |
||
0 ignored issues
–
show
|
|||
1263 | */ |
||
1264 | public function teacher_filter_query_modify( $query ){ |
||
1265 | global $typenow; |
||
1266 | |||
1267 | if( ! is_admin() && 'course' != $typenow || ! current_user_can('manage_sensei') ) { |
||
1268 | return $query; |
||
1269 | } |
||
1270 | $course_teacher = isset( $_GET['course_teacher'] ) ? $_GET['course_teacher'] : ''; |
||
1271 | |||
1272 | if( empty( $course_teacher ) ) { |
||
1273 | return $query; |
||
1274 | } |
||
1275 | |||
1276 | $query['author'] = $course_teacher; |
||
1277 | return $query; |
||
1278 | } |
||
1279 | |||
1280 | /** |
||
1281 | * Only show current teacher's media in the media library |
||
1282 | * @param array $request Default request arguments |
||
1283 | * @return array Modified request arguments |
||
1284 | */ |
||
1285 | public function restrict_media_library( $request = array() ) { |
||
1286 | |||
1287 | if( ! is_admin() ) { |
||
1288 | return $request; |
||
1289 | } |
||
1290 | |||
1291 | if( ! $this->is_admin_teacher() ) { |
||
1292 | return $request; |
||
1293 | } |
||
1294 | |||
1295 | $screen = get_current_screen(); |
||
1296 | |||
1297 | if( in_array( $screen->id, array( 'upload', 'course', 'lesson', 'question' ) ) ) { |
||
1298 | $teacher = intval( get_current_user_id() ); |
||
1299 | |||
1300 | if( $teacher ) { |
||
1301 | $request['author__in'] = array( $teacher ); |
||
1302 | } |
||
1303 | } |
||
1304 | |||
1305 | return $request; |
||
1306 | } // End restrict_media_library() |
||
1307 | |||
1308 | /** |
||
1309 | * Only show current teacher's media in the media library modal on the course/lesson/quesion edit screen |
||
1310 | * @param array $query Default query arguments |
||
1311 | * @return array Modified query arguments |
||
1312 | */ |
||
1313 | public function restrict_media_library_modal( $query = array() ) { |
||
1314 | |||
1315 | if( ! is_admin() ) { |
||
1316 | return $query; |
||
1317 | } |
||
1318 | |||
1319 | if( ! $this->is_admin_teacher() ) { |
||
1320 | return $query; |
||
1321 | } |
||
1322 | |||
1323 | $teacher = intval( get_current_user_id() ); |
||
1324 | |||
1325 | if( $teacher ) { |
||
1326 | $query['author__in'] = array( $teacher ); |
||
1327 | } |
||
1328 | |||
1329 | return $query; |
||
1330 | } // End restrict_media_library_modal() |
||
1331 | |||
1332 | /** |
||
1333 | * When saving the lesson, update the teacher if the lesson belongs to a course |
||
1334 | * |
||
1335 | * @since 1.8.0 |
||
1336 | * |
||
1337 | * @param int $lesson_id |
||
1338 | */ |
||
1339 | public function update_lesson_teacher( $lesson_id ){ |
||
1340 | |||
1341 | if( 'lesson'!= get_post_type() ){ |
||
1342 | return; |
||
1343 | } |
||
1344 | |||
1345 | // this should only run once per request cycle |
||
1346 | remove_action( 'save_post', array( $this, 'update_lesson_teacher' ) ); |
||
1347 | |||
1348 | $course_id = Sensei()->lesson->get_course_id( $lesson_id ); |
||
1349 | |||
1350 | if( empty( $course_id ) || ! $course_id ){ |
||
1351 | return; |
||
1352 | } |
||
1353 | |||
1354 | $course = get_post( $course_id ); |
||
1355 | |||
1356 | $lesson_update_args= array( |
||
1357 | 'ID' => $lesson_id , |
||
1358 | 'post_author' => $course->post_author |
||
1359 | ); |
||
1360 | wp_update_post( $lesson_update_args ); |
||
1361 | |||
1362 | } // end update_lesson_teacher |
||
1363 | |||
1364 | /** |
||
1365 | * Sensei_Teacher::limit_teacher_edit_screen_post_types |
||
1366 | * |
||
1367 | * Limit teachers to only see their courses, lessons and questions |
||
1368 | * |
||
1369 | * @since 1.8.0 |
||
1370 | * @access public |
||
1371 | * @parameters array $wp_query |
||
1372 | * @return WP_Query $wp_query |
||
1373 | */ |
||
1374 | public function limit_teacher_edit_screen_post_types( $wp_query ) { |
||
1375 | global $current_user; |
||
1376 | |||
1377 | //exit early |
||
1378 | if( ! $this->is_admin_teacher() ){ |
||
1379 | return $wp_query; |
||
1380 | } |
||
1381 | |||
1382 | if ( ! function_exists( 'get_current_screen' ) ) { |
||
1383 | return $wp_query; |
||
1384 | } |
||
1385 | |||
1386 | $screen = get_current_screen(); |
||
1387 | |||
1388 | if( empty( $screen ) ){ |
||
1389 | return $wp_query; |
||
1390 | } |
||
1391 | |||
1392 | // for any of these conditions limit what the teacher will see |
||
1393 | $limit_screens = array( |
||
1394 | 'edit-lesson', |
||
1395 | 'edit-course', |
||
1396 | 'edit-question', |
||
1397 | 'course_page_course-order', |
||
1398 | 'lesson_page_lesson-order', |
||
1399 | ); |
||
1400 | |||
1401 | if( in_array($screen->id , $limit_screens ) ) { |
||
1402 | |||
1403 | // set the query author to the current user to only show those those posts |
||
1404 | $wp_query->set( 'author', $current_user->ID ); |
||
1405 | } |
||
1406 | |||
1407 | return $wp_query; |
||
1408 | |||
1409 | } // end limit_teacher_edit_screen_post_types() |
||
1410 | |||
1411 | |||
1412 | /** |
||
1413 | * Sensei_Teacher::teacher_login_redirect |
||
1414 | * |
||
1415 | * Redirect teachers to /wp-admin/ after login |
||
1416 | * |
||
1417 | * @since 1.8.7 |
||
1418 | * @access public |
||
1419 | * @param string $user_login |
||
1420 | * @param object $user |
||
1421 | * @return void |
||
1422 | */ |
||
1423 | |||
1424 | public function teacher_login_redirect( $user_login, $user ) { |
||
1425 | |||
1426 | if (user_can($user, 'edit_courses')) { |
||
1427 | |||
1428 | if (isset($_POST['redirect_to'])) { |
||
1429 | |||
1430 | wp_redirect($_POST['redirect_to'], 303); |
||
1431 | |||
1432 | exit; |
||
1433 | |||
1434 | } else { |
||
1435 | |||
1436 | wp_redirect(admin_url(), 303); |
||
1437 | |||
1438 | exit; |
||
1439 | |||
1440 | } |
||
1441 | } |
||
1442 | |||
1443 | } // end teacher_login_redirect() |
||
1444 | |||
1445 | |||
1446 | |||
1447 | /** |
||
1448 | * Sensei_Teacher::restrict_posts_menu_page() |
||
1449 | * |
||
1450 | * Remove the Posts menu page for teachers and restrict access to it. |
||
1451 | * We have to do this because we give teachers the 'edit_posts' cap |
||
1452 | * so they can 'moderate_comments' as well. |
||
1453 | * |
||
1454 | * @since 1.8.7 |
||
1455 | * @access public |
||
1456 | * @parameters void |
||
1457 | * @return void |
||
1458 | */ |
||
1459 | |||
1460 | public function restrict_posts_menu_page() { |
||
1461 | |||
1462 | global $pagenow, $typenow; |
||
1463 | |||
1464 | $user = wp_get_current_user(); |
||
1465 | |||
1466 | /** |
||
1467 | * Filter the option to hide the Posts menu page. |
||
1468 | * |
||
1469 | * @since 1.8.7 |
||
1470 | * |
||
1471 | * @param bool $restrict default true |
||
1472 | */ |
||
1473 | |||
1474 | $restrict = apply_filters('sensei_restrict_posts_menu_page', true ); |
||
1475 | |||
1476 | if ( in_array( 'teacher', (array) $user->roles ) && !current_user_can('delete_posts') && $restrict) { |
||
1477 | |||
1478 | remove_menu_page('edit.php'); |
||
1479 | |||
1480 | if ($pagenow == "edit.php" || $pagenow == "post-new.php") { |
||
1481 | |||
1482 | if ($typenow == '' || $typenow == 'post' || $typenow == 'page') { |
||
1483 | |||
1484 | wp_die('You do not have sufficient permissions to access this page.'); |
||
1485 | |||
1486 | } |
||
1487 | |||
1488 | } |
||
1489 | |||
1490 | } |
||
1491 | |||
1492 | } // end restrict_posts_menu_page() |
||
1493 | |||
1494 | /** |
||
1495 | * Sensei_Teacher::restrict_comment_moderation() |
||
1496 | * |
||
1497 | * Restrict commendation moderation for teachers |
||
1498 | * so they can only moderate comments made to posts they own. |
||
1499 | * |
||
1500 | * @since 1.8.7 |
||
1501 | * @access public |
||
1502 | * @parameters obj $clauses |
||
1503 | * @return WP_Comment_Query $clauses |
||
1504 | */ |
||
1505 | |||
1506 | public function restrict_comment_moderation ( $clauses ) { |
||
1507 | |||
1508 | global $pagenow; |
||
1509 | |||
1510 | if( self::is_a_teacher( get_current_user_id() ) && $pagenow == "edit-comments.php") { |
||
1511 | |||
1512 | $clauses->query_vars['post_author'] = get_current_user_id(); |
||
1513 | |||
1514 | } |
||
1515 | |||
1516 | return $clauses; |
||
1517 | |||
1518 | } // end restrict_comment_moderation() |
||
1519 | |||
1520 | /** |
||
1521 | * Determine if a user is a teacher by ID |
||
1522 | * |
||
1523 | * @param int $user_id |
||
1524 | * |
||
1525 | * @return bool |
||
1526 | */ |
||
1527 | public static function is_a_teacher( $user_id ){ |
||
1528 | |||
1529 | $user = get_user_by('id', $user_id); |
||
1530 | |||
1531 | if( isset( $user->roles ) && in_array( 'teacher', $user->roles ) ){ |
||
1532 | |||
1533 | return true; |
||
1534 | |||
1535 | }else{ |
||
1536 | |||
1537 | return false; |
||
1538 | |||
1539 | } |
||
1540 | |||
1541 | }// end is_a_teacher |
||
1542 | |||
1543 | /** |
||
1544 | * The archive title on the teacher archive filter |
||
1545 | * |
||
1546 | * @since 1.9.0 |
||
1547 | */ |
||
1548 | public static function archive_title(){ |
||
1549 | |||
1550 | $author = get_user_by( 'id', get_query_var( 'author' ) ); |
||
1551 | $author_name = $author->display_name; |
||
1552 | ?> |
||
1553 | <h2 class="teacher-archive-title"> |
||
1554 | |||
1555 | <?php echo sprintf( __( 'All courses by %s', 'woothemes-sensei') , $author_name ); ?> |
||
1556 | |||
1557 | </h2> |
||
1558 | <?php |
||
1559 | |||
1560 | }// archive title |
||
1561 | |||
1562 | /** |
||
1563 | * Removing course meta on the teacher archive page |
||
1564 | * |
||
1565 | * @since 1.9.0 |
||
1566 | */ |
||
1567 | public static function remove_course_meta_on_teacher_archive(){ |
||
1568 | |||
1569 | remove_action('sensei_course_content_inside_before', array( Sensei()->course, 'the_course_meta' ) ); |
||
1570 | |||
1571 | } |
||
1572 | |||
1573 | } // End Class |
||
1574 |
This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.