Issues (896)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

includes/class-sensei-teacher.php (5 issues)

Upgrade to new PHP Analysis Engine

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
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 13 and the first side effect is on line 2.

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.

Loading history...
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 ) {
0 ignored issues
show
The parameter $post is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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 ) {
0 ignored issues
show
The parameter $perm is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
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
0 ignored issues
show
There is no parameter named $course_id. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
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
The doc-type $query could not be parsed: Unknown type name "$query" at position 0. (view supported doc-types)

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.

Loading history...
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