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-posttypes.php (9 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 14 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 Post Types Class
6
 *
7
 * All functionality pertaining to the post types and taxonomies in Sensei.
8
 *
9
 * @package Core
10
 * @author Automattic
11
 *
12
 * @since 1.0.0
13
 */
14
class Sensei_PostTypes {
15
	public $token;
16
	public $slider_labels;
17
	public $role_caps;
18
19
    /**
20
     * @var Sensei_Course
21
     */
22
    public $course;
23
24
    /**
25
     * @var Sensei_Lesson
26
     */
27
    public $lesson;
28
29
    /**
30
     * @var Sensei_Question
31
     */
32
    public $question;
33
34
    /**
35
     * @var Sensei_Quiz
36
     */
37
    public $quiz;
38
39
	/**
40
	 * Constructor
41
	 * @since  1.0.0
42
	 */
43
	public function __construct () {
44
45
		// Setup Post Types
46
		$this->labels = array();
47
        $this->token = 'woothemes-sensei-posttypes';
48
49
		$this->setup_post_type_labels_base();
50
		add_action( 'init', array( $this, 'setup_course_post_type' ), 100 );
51
		add_action( 'init', array( $this, 'setup_lesson_post_type' ), 100 );
52
		add_action( 'init', array( $this, 'setup_quiz_post_type' ), 100 );
53
		add_action( 'init', array( $this, 'setup_question_post_type' ), 100 );
54
		add_action( 'init', array( $this, 'setup_multiple_question_post_type' ), 100 );
55
		add_action( 'init', array( $this, 'setup_sensei_message_post_type' ), 100 );
56
57
		// Setup Taxonomies
58
		add_action( 'init', array( $this, 'setup_course_category_taxonomy' ), 100 );
59
		add_action( 'init', array( $this, 'setup_quiz_type_taxonomy' ), 100 );
60
		add_action( 'init', array( $this, 'setup_question_type_taxonomy' ), 100 );
61
		add_action( 'init', array( $this, 'setup_question_category_taxonomy' ), 100 );
62
		add_action( 'init', array( $this, 'setup_lesson_tag_taxonomy' ), 100 );
63
64
		// Load Post Type Objects
65
		$default_post_types = array( 'course' => 'Course', 'lesson' => 'Lesson', 'quiz' => 'Quiz', 'question' => 'Question', 'messages' => 'Messages' ) ;
66
		$this->load_posttype_objects( $default_post_types );
67
68
		// Admin functions
69
		if ( is_admin() ) {
70
			$this->set_role_cap_defaults( $default_post_types );
71
			global $pagenow;
72
			if ( ( $pagenow == 'post.php' || $pagenow == 'post-new.php' ) ) {
73
				add_filter( 'enter_title_here', array( $this, 'enter_title_here' ), 10 );
74
				add_filter( 'post_updated_messages', array( $this, 'setup_post_type_messages' ) );
75
			} // End If Statement
76
		} // End If Statement
77
78
		// Add 'Edit Quiz' link to admin bar
79
		add_action( 'admin_bar_menu', array( $this, 'quiz_admin_bar_menu' ), 81 );
80
81
	} // End __construct()
82
83
	/**
84
	 * load_posttype_objects function.
85
	 * Dynamically loads post type objects for meta boxes on backend
86
	 * @access public
87
	 * @param array $posttypes (default: array())
88
	 * @return void
89
	 */
90
	public function load_posttype_objects( $posttypes = array() ) {
91
92
		foreach ( $posttypes as $posttype_token => $posttype_name ) {
93
94
			// Load the files
95
			$class_name = 'WooThemes_Sensei_' . $posttype_name;
96
			$this->$posttype_token = new $class_name();
97
			$this->$posttype_token->token = $posttype_token;
98
99
		} // End For Loop
100
101
	} // End load_posttype_objects
102
103
	/**
104
	 * Setup the "course" post type, it's admin menu item and the appropriate labels and permissions.
105
	 * @since  1.0.0
106
     * @uses  Sensei()
107
	 * @return void
108
	 */
109
	public function setup_course_post_type () {
110
111
		$args = array(
112
		    'labels'              => $this->create_post_type_labels( $this->labels['course']['singular'], $this->labels['course']['plural'], $this->labels['course']['menu'] ),
113
		    'public'              => true,
114
		    'publicly_queryable'  => true,
115
		    'show_ui'             => true,
116
		    'show_in_menu'        => true,
117
		    'show_in_admin_bar'   => true,
118
		    'query_var'           => true,
119
		    'rewrite'             => array(
120
                'slug' => esc_attr( apply_filters( 'sensei_course_slug', _x( 'course', 'post type single url base', 'woothemes-sensei' ) ) ) ,
121
                'with_front' => true,
122
                'feeds' => true,
123
                'pages' => true
124
            ),
125
		    'map_meta_cap'        => true,
126
		    'capability_type'     => 'course',
127
            'has_archive'         => $this->get_course_post_type_archive_slug(),
128
		    'hierarchical'        => false,
129
		    'menu_position'       => 51,
130
		    'supports'            => array( 'title', 'editor', 'excerpt', 'thumbnail' )
131
		);
132
133
        /**
134
         * Filter the arguments passed in when registering the Sensei Course post type.
135
         *
136
         * @since 1.9.0
137
         * @param array $args
138
         */
139
		register_post_type( 'course', apply_filters( 'sensei_register_post_type_course', $args ) );
140
141
	} // End setup_course_post_type()
142
143
    /**
144
     * Figure out of the course post type has an archive and what it should be.
145
     *
146
     * This function should return 'courses' or the page_uri for the course page setting.
147
     *
148
     * For backward compatibility  sake ( pre 1.9 )If the course page set in settings
149
     * still has any of the old shortcodes: [newcourses][featuredcourses][freecourses][paidcourses] the
150
     * page slug will not be returned. For any other pages without it the page URI will be returned.
151
     *
152
     *
153
     * @sine 1.9.0
154
     *
155
     *
156
     * @return false|string
157
     */
158
    public function get_course_post_type_archive_slug(){
159
160
        $settings_course_page = get_post( Sensei()->settings->get( 'course_page' ) );
161
162
        // for a valid post that doesn't have any of the old short codes set the archive the same
163
        // as the page URI
164
        if( is_a( $settings_course_page, 'WP_Post') && ! $this->has_old_shortcodes( $settings_course_page->post_content ) ){
165
166
             return get_page_uri( $settings_course_page->ID );
167
168
        }else{
169
170
            return 'courses';
171
172
        }
173
174
    }// end course_post_type_determine_archive
175
176
    /**
177
     * Check if given content has any of these old shortcodes:
178
     * [newcourses][featuredcourses][freecourses][paidcourses]
179
     *
180
     * @since 1.9.0
181
     *
182
     * @param string $content
183
     *
184
     * @return bool
185
     */
186
    public function has_old_shortcodes( $content ){
187
188
        return  ( has_shortcode( $content, 'newcourses')
189
        || has_shortcode( $content, 'featuredcourses')
190
        || has_shortcode( $content, 'freecourses')
191
        || has_shortcode( $content, 'paidcourses') );
192
193
    }// end has old shortcodes
194
195
196
	/**
197
	 * Setup the "lesson" post type, it's admin menu item and the appropriate labels and permissions.
198
	 * @since  1.0.0
199
	 * @uses  Sensei()
200
	 * @return void
201
	 */
202
	public function setup_lesson_post_type () {
203
204
		$supports_array = array( 'title', 'editor', 'excerpt', 'thumbnail', 'page-attributes' );
205
		$allow_comments = false;
206
		if ( isset( Sensei()->settings->settings[ 'lesson_comments' ] ) ) {
207
			$allow_comments = Sensei()->settings->settings[ 'lesson_comments' ];
208
		} // End If Statement
209
		if ( $allow_comments ) {
210
			array_push( $supports_array, 'comments' );
211
		} // End If Statement
212
213
		$args = array(
214
		    'labels' => $this->create_post_type_labels(  $this->labels['lesson']['singular'], $this->labels['lesson']['plural'], $this->labels['lesson']['menu'] ),
215
		    'public' => true,
216
		    'publicly_queryable' => true,
217
		    'show_ui' => true,
218
		    'show_in_menu' => true,
219
		    'query_var' => true,
220
		    'rewrite' => array(
221
                'slug' => esc_attr( apply_filters( 'sensei_lesson_slug', _x( 'lesson', 'post type single slug', 'woothemes-sensei' ) ) ) ,
222
                'with_front' =>  true,
223
                'feeds' => true,
224
                'pages' => true
225
            ),
226
		    'map_meta_cap' => true,
227
		    'capability_type' => 'lesson',
228
		    'has_archive' => true,
229
		    'hierarchical' => false,
230
		    'menu_position' => 52,
231
		    'supports' => $supports_array
232
		);
233
234
        /**
235
         * Filter the arguments passed in when registering the Sensei Lesson post type.
236
         *
237
         * @since 1.9.0
238
         * @param array $args
239
         */
240
		register_post_type( 'lesson', apply_filters( 'sensei_register_post_type_lesson', $args ) );
241
242
	} // End setup_lesson_post_type()
243
244
	/**
245
	 * Setup the "quiz" post type, it's admin menu item and the appropriate labels and permissions.
246
	 * @since  1.0.0
247
     * @uses  Sensei()
248
	 * @return void
249
	 */
250 View Code Duplication
	public function setup_quiz_post_type () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
251
252
		$args = array(
253
		    'labels' => $this->create_post_type_labels(
254
                $this->labels['quiz']['singular'],
255
                $this->labels['quiz']['plural'],
256
                $this->labels['quiz']['menu']
257
            ),
258
		    'public' => true,
259
		    'publicly_queryable' => true,
260
		    'show_ui' => true,
261
		    'show_in_menu' => false,
262
		    'show_in_nav_menus' => false,
263
		    'query_var' => true,
264
		    'exclude_from_search' => true,
265
		    'rewrite' => array(
266
                'slug' => esc_attr( apply_filters( 'sensei_quiz_slug', _x( 'quiz', 'post type single slug', 'woothemes-sensei' ) ) ) ,
267
                'with_front' =>  true,
268
                'feeds' => true,
269
                'pages' => true
270
            ),
271
		    'map_meta_cap' => true,
272
		    'capability_type' => 'quiz',
273
		    'has_archive' => false,
274
		    'hierarchical' => false,
275
		    'menu_position' => 20, // Below "Pages"
276
		    'supports' => array( '' )
277
		);
278
279
        /**
280
         * Filter the arguments passed in when registering the Sensei Quiz post type.
281
         *
282
         * @since 1.9.0
283
         * @param array $args
284
         */
285
		register_post_type( 'quiz', apply_filters( 'sensei_register_post_type_quiz', $args ) );
286
287
	} // End setup_quiz_post_type()
288
289
290
	/**
291
	 * Setup the "question" post type, it's admin menu item and the appropriate labels and permissions.
292
	 * @since  1.0.0
293
	 * @return void
294
	 */
295 View Code Duplication
	public function setup_question_post_type () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
296
297
		$args = array(
298
		    'labels' => $this->create_post_type_labels( $this->labels['question']['singular'], $this->labels['question']['plural'], $this->labels['question']['menu'] ),
299
		    'public' => false,
300
		    'publicly_queryable' => true,
301
		    'show_ui' => true,
302
		    'show_in_menu' => true,
303
		    'show_in_nav_menus' => false,
304
		    'query_var' => true,
305
		    'exclude_from_search' => true,
306
		    'rewrite' => array(
307
                'slug' => esc_attr( apply_filters( 'sensei_question_slug', _x( 'question', 'post type single slug', 'woothemes-sensei' ) ) ) ,
308
                'with_front' =>  true,
309
                'feeds' => true,
310
                'pages' => true
311
            ),
312
		    'map_meta_cap' => true,
313
		    'capability_type' => 'question',
314
		    'has_archive' => true,
315
		    'hierarchical' => false,
316
		    'menu_position' => 51,
317
		    'supports' => array( 'title' )
318
		);
319
320
        /**
321
         * Filter the arguments passed in when registering the Sensei Question post type.
322
         *
323
         * @since 1.9.0
324
         * @param array $args
325
         */
326
		register_post_type( 'question', apply_filters('sensei_register_post_type_question', $args ) );
327
328
	} // End setup_question_post_type()
329
330
	/**
331
	 * Setup the "multiple_question" post type, it's admin menu item and the appropriate labels and permissions.
332
	 * @since  1.6.0
333
	 * @return void
334
	 */
335 View Code Duplication
	public function setup_multiple_question_post_type () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
336
337
		$args = array(
338
		    'labels' => $this->create_post_type_labels( $this->labels['multiple_question']['singular'], $this->labels['multiple_question']['plural'], $this->labels['multiple_question']['menu'] ),
339
		    'public' => false,
340
		    'publicly_queryable' => false,
341
		    'show_ui' => false,
342
		    'show_in_menu' => false,
343
		    'show_in_nav_menus' => false,
344
		    'query_var' => false,
345
		    'exclude_from_search' => true,
346
		    'rewrite' => array(
347
                'slug' => esc_attr( apply_filters( 'sensei_multiple_question_slug', _x( 'multiple_question', 'post type single slug', 'woothemes-sensei' ) ) ) ,
348
                'with_front' =>  false,
349
                'feeds' => false,
350
                'pages' => false
351
            ),
352
		    'map_meta_cap' => true,
353
		    'capability_type' => 'question',
354
		    'has_archive' => false,
355
		    'hierarchical' => false,
356
		    'menu_position' => 51,
357
		    'supports' => array( 'title', 'custom-fields' )
358
		);
359
360
		register_post_type( 'multiple_question', $args );
361
	} // End setup_multiple_question_post_type()
362
363
	/**
364
	 * Setup the "sensei_message" post type, it's admin menu item and the appropriate labels and permissions.
365
	 * @since  1.6.0
366
	 * @return void
367
	 */
368
	public function setup_sensei_message_post_type () {
369
370
		if( ! isset( Sensei()->settings->settings['messages_disable'] ) || ! Sensei()->settings->settings['messages_disable'] ) {
371
372
			$args = array(
373
			    'labels' => $this->create_post_type_labels( $this->labels['sensei_message']['singular'], $this->labels['sensei_message']['plural'], $this->labels['sensei_message']['menu'] ),
374
			    'public' => true,
375
			    'publicly_queryable' => true,
376
			    'show_ui' => true,
377
			    'show_in_menu' => 'admin.php?page=sensei',
378
			    'show_in_nav_menus' => true,
379
			    'query_var' => true,
380
			    'exclude_from_search' => true,
381
			    'rewrite' => array(
382
                    'slug' => esc_attr( apply_filters( 'sensei_messages_slug', _x( 'messages', 'post type single slug', 'woothemes-sensei' ) ) ) ,
383
                    'with_front' =>  false,
384
                    'feeds' => false,
385
                    'pages' => true
386
                ),
387
			    'map_meta_cap' => true,
388
			    'capability_type' => 'question',
389
			    'has_archive' => true,
390
			    'hierarchical' => false,
391
			    'menu_position' => 50,
392
			    'supports' => array( 'title', 'editor', 'comments' ),
393
			);
394
395
            /**
396
             * Filter the arguments passed in when registering the Sensei sensei_message post type.
397
             *
398
             * @since 1.9.0
399
             * @param array $args
400
             */
401
			register_post_type( 'sensei_message', apply_filters('sensei_register_post_type_sensei_message',  $args ) );
402
		}
403
	} // End setup_sensei_message_post_type()
404
405
	/**
406
	 * Setup the "course category" taxonomy, linked to the "course" post type.
407
	 * @since  1.1.0
408
	 * @return void
409
	 */
410 View Code Duplication
	public function setup_course_category_taxonomy () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
411
		// "Course Categories" Custom Taxonomy
412
		$labels = array(
413
			'name' => _x( 'Course Categories', 'taxonomy general name', 'woothemes-sensei' ),
414
			'singular_name' => _x( 'Course Category', 'taxonomy singular name', 'woothemes-sensei' ),
415
			'search_items' =>  __( 'Search Course Categories', 'woothemes-sensei' ),
416
			'all_items' => __( 'All Course Categories', 'woothemes-sensei' ),
417
			'parent_item' => __( 'Parent Course Category', 'woothemes-sensei' ),
418
			'parent_item_colon' => __( 'Parent Course Category:', 'woothemes-sensei' ),
419
			'edit_item' => __( 'Edit Course Category', 'woothemes-sensei' ),
420
			'update_item' => __( 'Update Course Category', 'woothemes-sensei' ),
421
			'add_new_item' => __( 'Add New Course Category', 'woothemes-sensei' ),
422
			'new_item_name' => __( 'New Course Category Name', 'woothemes-sensei' ),
423
			'menu_name' => __( 'Course Categories', 'woothemes-sensei' ),
424
			'popular_items' => null // Hides the "Popular" section above the "add" form in the admin.
425
		);
426
427
		$args = array(
428
			'hierarchical' => true,
429
			'labels' => $labels,
430
			'show_ui' => true,
431
			'query_var' => true,
432
			'show_in_nav_menus' => true,
433
            'capabilities' => array(
434
                'manage_terms' => 'manage_categories',
435
                'edit_terms'   => 'edit_courses',
436
                'delete_terms' => 'manage_categories',
437
                'assign_terms' => 'edit_courses',),
438
			'rewrite' => array( 'slug' => esc_attr( apply_filters( 'sensei_course_category_slug', _x( 'course-category', 'taxonomy archive slug', 'woothemes-sensei' ) ) ) )
439
		);
440
441
		register_taxonomy( 'course-category', array( 'course' ), $args );
442
443
	} // End setup_course_category_taxonomy()
444
445
	/**
446
	 * Setup the "quiz type" taxonomy, linked to the "quiz" post type.
447
	 * @since  1.0.0
448
	 * @return void
449
	 */
450 View Code Duplication
	public function setup_quiz_type_taxonomy () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
451
452
		// "Quiz Types" Custom Taxonomy
453
		$labels = array(
454
			'name' => _x( 'Quiz Types', 'taxonomy general name', 'woothemes-sensei' ),
455
			'singular_name' => _x( 'Quiz Type', 'taxonomy singular name', 'woothemes-sensei' ),
456
			'search_items' =>  __( 'Search Quiz Types', 'woothemes-sensei' ),
457
			'all_items' => __( 'All Quiz Types', 'woothemes-sensei' ),
458
			'parent_item' => __( 'Parent Quiz Type', 'woothemes-sensei' ),
459
			'parent_item_colon' => __( 'Parent Quiz Type:', 'woothemes-sensei' ),
460
			'edit_item' => __( 'Edit Quiz Type', 'woothemes-sensei' ),
461
			'update_item' => __( 'Update Quiz Type', 'woothemes-sensei' ),
462
			'add_new_item' => __( 'Add New Quiz Type', 'woothemes-sensei' ),
463
			'new_item_name' => __( 'New Quiz Type Name', 'woothemes-sensei' ),
464
			'menu_name' => __( 'Quiz Types', 'woothemes-sensei' ),
465
			'popular_items' => null // Hides the "Popular" section above the "add" form in the admin.
466
		);
467
468
		$args = array(
469
			'hierarchical' => false,
470
			'labels' => $labels,
471
			'show_ui' => true, /* TO DO - future releases */
472
			'query_var' => true,
473
			'show_in_nav_menus' => false,
474
            'public' => false,
475
			'rewrite' => array( 'slug' => esc_attr( apply_filters( 'sensei_quiz_type_slug', _x( 'quiz-type', 'taxonomy archive slug', 'woothemes-sensei' ) ) ) )
476
		);
477
478
		register_taxonomy( 'quiz-type', array( 'quiz' ), $args );
479
	} // End setup_quiz_type_taxonomy()
480
481
	/**
482
	 * Setup the "question type" taxonomy, linked to the "question" post type.
483
	 * @since  1.3.0
484
	 * @return void
485
	 */
486 View Code Duplication
	public function setup_question_type_taxonomy () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
487
488
		// "Question Types" Custom Taxonomy
489
		$labels = array(
490
			'name' => _x( 'Question Types', 'taxonomy general name', 'woothemes-sensei' ),
491
			'singular_name' => _x( 'Question Type', 'taxonomy singular name', 'woothemes-sensei' ),
492
			'search_items' =>  __( 'Search Question Types', 'woothemes-sensei' ),
493
			'all_items' => __( 'All Question Types', 'woothemes-sensei' ),
494
			'parent_item' => __( 'Parent Question Type', 'woothemes-sensei' ),
495
			'parent_item_colon' => __( 'Parent Question Type:', 'woothemes-sensei' ),
496
			'edit_item' => __( 'Edit Question Type', 'woothemes-sensei' ),
497
			'update_item' => __( 'Update Question Type', 'woothemes-sensei' ),
498
			'add_new_item' => __( 'Add New Question Type', 'woothemes-sensei' ),
499
			'new_item_name' => __( 'New Question Type Name', 'woothemes-sensei' ),
500
			'menu_name' => __( 'Question Types', 'woothemes-sensei' ),
501
			'popular_items' => null // Hides the "Popular" section above the "add" form in the admin.
502
		);
503
504
		$args = array(
505
			'hierarchical' => false,
506
			'labels' => $labels,
507
			'show_ui' => false,
508
			'public' => false,
509
			'query_var' => false,
510
			'show_in_nav_menus' => false,
511
			'show_admin_column' => true,
512
			'rewrite' => array( 'slug' => esc_attr( apply_filters( 'sensei_question_type_slug', _x( 'question-type', 'taxonomy archive slug', 'woothemes-sensei' ) ) ) )
513
		);
514
515
		register_taxonomy( 'question-type', array( 'question' ), $args );
516
	} // End setup_question_type_taxonomy()
517
518
	/**
519
	 * Setup the "question category" taxonomy, linked to the "question" post type.
520
	 * @since  1.3.0
521
	 * @return void
522
	 */
523 View Code Duplication
	public function setup_question_category_taxonomy () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
524
		// "Question Categories" Custom Taxonomy
525
		$labels = array(
526
			'name' => _x( 'Question Categories', 'taxonomy general name', 'woothemes-sensei' ),
527
			'singular_name' => _x( 'Question Category', 'taxonomy singular name', 'woothemes-sensei' ),
528
			'search_items' =>  __( 'Search Question Categories', 'woothemes-sensei' ),
529
			'all_items' => __( 'All Question Categories', 'woothemes-sensei' ),
530
			'parent_item' => __( 'Parent Question Category', 'woothemes-sensei' ),
531
			'parent_item_colon' => __( 'Parent Question Category:', 'woothemes-sensei' ),
532
			'edit_item' => __( 'Edit Question Category', 'woothemes-sensei' ),
533
			'update_item' => __( 'Update Question Category', 'woothemes-sensei' ),
534
			'add_new_item' => __( 'Add New Question Category', 'woothemes-sensei' ),
535
			'new_item_name' => __( 'New Question Category Name', 'woothemes-sensei' ),
536
			'menu_name' => __( 'Categories', 'woothemes-sensei' ),
537
		);
538
539
		$args = array(
540
			'hierarchical' => true,
541
			'labels' => $labels,
542
			'show_ui' => true,
543
			'public' => false,
544
			'query_var' => false,
545
			'show_in_nav_menus' => false,
546
			'show_admin_column' => true,
547
            'capabilities' => array(
548
                'manage_terms' => 'manage_categories',
549
                'edit_terms'   => 'edit_questions',
550
                'delete_terms' => 'manage_categories',
551
                'assign_terms' => 'edit_questions',),
552
			'rewrite' => array( 'slug' => esc_attr( apply_filters( 'sensei_question_category_slug', _x( 'question-category', 'taxonomy archive slug', 'woothemes-sensei' ) ) ) )
553
		);
554
555
		register_taxonomy( 'question-category', array( 'question' ), $args );
556
	} // End setup_question_type_taxonomy()
557
558
	/**
559
	 * Setup the "lesson tags" taxonomy, linked to the "lesson" post type.
560
	 * @since  1.5.0
561
	 * @return void
562
	 */
563 View Code Duplication
	public function setup_lesson_tag_taxonomy () {
0 ignored issues
show
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
564
		// "Lesson Tags" Custom Taxonomy
565
		$labels = array(
566
			'name' => _x( 'Lesson Tags', 'taxonomy general name', 'woothemes-sensei' ),
567
			'singular_name' => _x( 'Lesson Tag', 'taxonomy singular name', 'woothemes-sensei' ),
568
			'search_items' =>  __( 'Search Lesson Tags', 'woothemes-sensei' ),
569
			'all_items' => __( 'All Lesson Tags', 'woothemes-sensei' ),
570
			'parent_item' => __( 'Parent Tag', 'woothemes-sensei' ),
571
			'parent_item_colon' => __( 'Parent Tag:', 'woothemes-sensei' ),
572
			'edit_item' => __( 'Edit Lesson Tag', 'woothemes-sensei' ),
573
			'update_item' => __( 'Update Lesson Tag', 'woothemes-sensei' ),
574
			'add_new_item' => __( 'Add New Lesson Tag', 'woothemes-sensei' ),
575
			'new_item_name' => __( 'New Tag Name', 'woothemes-sensei' ),
576
			'menu_name' => __( 'Lesson Tags', 'woothemes-sensei' )
577
		);
578
579
		$args = array(
580
			'hierarchical' => false,
581
			'labels' => $labels,
582
			'show_ui' => true,
583
			'query_var' => true,
584
			'show_in_nav_menus' => true,
585
            'capabilities' => array(
586
                'manage_terms' => 'manage_categories',
587
                'edit_terms'   => 'edit_lessons',
588
                'delete_terms' => 'manage_categories',
589
                'assign_terms' => 'edit_lessons',),
590
			'rewrite' => array( 'slug' => esc_attr( apply_filters( 'sensei_lesson_tag_slug', _x( 'lesson-tag', 'taxonomy archive slug', 'woothemes-sensei' ) ) ) )
591
		);
592
593
		register_taxonomy( 'lesson-tag', array( 'lesson' ), $args );
594
	} // End setup_lesson_tag_taxonomy()
595
596
	/**
597
	 * Setup the singular, plural and menu label names for the post types.
598
	 * @since  1.0.0
599
	 * @return void
600
	 */
601
	private function setup_post_type_labels_base () {
602
		$this->labels = array( 'course' => array(), 'lesson' => array(), 'quiz' => array(), 'question' => array() );
603
604
		$this->labels['course'] = array( 'singular' => __( 'Course', 'woothemes-sensei' ), 'plural' => __( 'Courses', 'woothemes-sensei' ), 'menu' => __( 'Courses', 'woothemes-sensei' ) );
605
		$this->labels['lesson'] = array( 'singular' => __( 'Lesson', 'woothemes-sensei' ), 'plural' => __( 'Lessons', 'woothemes-sensei' ), 'menu' => __( 'Lessons', 'woothemes-sensei' ) );
606
		$this->labels['quiz'] = array( 'singular' => __( 'Quiz', 'woothemes-sensei' ), 'plural' => __( 'Quizzes', 'woothemes-sensei' ), 'menu' => __( 'Quizzes', 'woothemes-sensei' ) );
607
		$this->labels['question'] = array( 'singular' => __( 'Question', 'woothemes-sensei' ), 'plural' => __( 'Questions', 'woothemes-sensei' ), 'menu' => __( 'Questions', 'woothemes-sensei' ) );
608
		$this->labels['multiple_question'] = array( 'singular' => __( 'Multiple Question', 'woothemes-sensei' ), 'plural' => __( 'Multiple Questions', 'woothemes-sensei' ), 'menu' => __( 'Multiple Questions', 'woothemes-sensei' ) );
609
		$this->labels['sensei_message'] = array( 'singular' => __( 'Message', 'woothemes-sensei' ), 'plural' => __( 'Messages', 'woothemes-sensei' ), 'menu' => __( 'Messages', 'woothemes-sensei' ) );
610
611
	} // End setup_post_type_labels_base()
612
613
	/**
614
	 * Create the labels for a specified post type.
615
	 * @since  1.0.0
616
	 * @param  string $singular The label for a singular instance of the post type
617
	 * @param  string $plural   The label for a plural instance of the post type
618
	 * @param  string $menu     The menu item label
619
	 * @return array            An array of the labels to be used
620
	 */
621
	private function create_post_type_labels ( $singular, $plural, $menu ) {
622
623
		$lower_case_plural =  function_exists( 'mb_strtolower' ) ? mb_strtolower( $plural, 'UTF-8') :  strtolower( $plural );
624
625
		$labels = array(
626
		    'name' => sprintf( _x( '%s', 'post type general name', 'woothemes-sensei' ), $plural ),
627
		    'singular_name' => sprintf( _x( '%s', 'post type singular name', 'woothemes-sensei' ), $singular ),
628
		    'add_new' => __( 'Add New', 'woothemes-sensei' ),
629
		    'add_new_item' => sprintf( __( 'Add New %s', 'woothemes-sensei' ), $singular ),
630
		    'edit_item' => sprintf( __( 'Edit %s', 'woothemes-sensei' ), $singular ),
631
		    'new_item' => sprintf( __( 'New %s', 'woothemes-sensei' ), $singular ),
632
		    'all_items' => sprintf( __( 'All %s', 'woothemes-sensei' ), $plural ),
633
		    'view_item' => sprintf( __( 'View %s', 'woothemes-sensei' ), $singular ),
634
		    'search_items' => sprintf( __( 'Search %s', 'woothemes-sensei' ), $plural ),
635
		    'not_found' =>  sprintf( __( 'No %s found', 'woothemes-sensei' ), $lower_case_plural ) ,
636
		    'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'woothemes-sensei' ),  $lower_case_plural ),
637
		    'parent_item_colon' => '',
638
		    'menu_name' => sprintf( __( '%s', 'woothemes-sensei' ), $menu )
639
		  );
640
641
		return $labels;
642
	} // End create_post_type_labels()
643
644
	/**
645
	 * Setup update messages for the post types.
646
	 * @since  1.0.0
647
	 * @param  array $messages The existing array of messages for post types.
648
	 * @return array           The modified array of messages for post types.
649
	 */
650
	public function setup_post_type_messages ( $messages ) {
651
		global $post, $post_ID;
652
653
		$messages['course'] = $this->create_post_type_messages( 'course' );
654
		$messages['lesson'] = $this->create_post_type_messages( 'lesson' );
655
		$messages['quiz'] = $this->create_post_type_messages( 'quiz' );
656
		$messages['question'] = $this->create_post_type_messages( 'question' );
657
		$messages['multiple_question'] = $this->create_post_type_messages( 'multiple_question' );
658
659
		return $messages;
660
	} // End setup_post_type_messages()
661
662
	/**
663
	 * Create an array of messages for a specified post type.
664
	 * @since  1.0.0
665
	 * @param  string $post_type The post type for which to create messages.
666
	 * @return array            An array of messages (empty array if the post type isn't one we're looking to work with).
667
	 */
668
	private function create_post_type_messages ( $post_type ) {
669
		global $post, $post_ID;
670
671
		if ( ! isset( $this->labels[$post_type] ) ) { return array(); }
672
673
		$messages = array(
674
			0 => '',
675
			1 => sprintf( __( '%1$s updated. %2$sView %1$s%3$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], '<a href="' . esc_url( get_permalink( $post_ID ) ) . '">', '</a>' ),
676
			2 => __( 'Custom field updated.' , 'woothemes-sensei' ),
677
			3 => __( 'Custom field deleted.' , 'woothemes-sensei' ),
678
			4 => sprintf( __( '%1$s updated.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'] ),
679
			5 => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
680
			6 => sprintf( __( '%1$s published. %2$sView %1$s%3$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], '<a href="' . esc_url( get_permalink( $post_ID ) ) . '">', '</a>' ),
681
			7 => sprintf( __( '%1$s saved.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'] ),
682
			8 => sprintf( __( '%1$s submitted. %2$sPreview %1$s%3$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], '<a target="_blank" href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) . '">', '</a>' ),
683
			9 => sprintf( __( '%1$s scheduled for: %2$s. %3$sPreview %4$s%5$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], '<strong>' . date_i18n( __( 'M j, Y @ G:i' , 'woothemes-sensei' ), strtotime( $post->post_date ) ) . '</strong>', '<a target="_blank" href="' . esc_url( get_permalink( $post_ID ) ) . '">', $this->labels[$post_type]['singular'], '</a>' ),
684
			10 => sprintf( __( '%1$s draft updated. %2$sPreview %3$s%4$s.' , 'woothemes-sensei' ), $this->labels[$post_type]['singular'], '<a target="_blank" href="' . esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) . '">', $this->labels[$post_type]['singular'], '</a>' ),
685
		);
686
687
		return $messages;
688
	} // End create_post_type_messages()
689
690
	/**
691
	 * Change the "Enter Title Here" text for the "slide" post type.
692
	 * @access public
693
	 * @since  1.0.0
694
	 * @param  string $title
695
	 * @return string $title
696
	 */
697
	public function enter_title_here ( $title ) {
698
		if ( get_post_type() == 'course' ) {
699
			$title = __( 'Enter a title for this course here', 'woothemes-sensei' );
700
		} elseif ( get_post_type() == 'lesson' ) {
701
			$title = __( 'Enter a title for this lesson here', 'woothemes-sensei' );
702
		}
703
704
		return $title;
705
	} // End enter_title_here()
706
707
	/**
708
	 * Assigns the defaults for each user role capabilities.
709
	 *
710
	 * @since  1.1.0
711
     *
712
	 * @param array $post_types
713
	 * @return void
714
	 */
715
	public function set_role_cap_defaults( $post_types = array() ) {
716
717
		foreach ( $post_types as $post_type_item => $post_type_name ) {
718
			// Super Admin
719
			$this->role_caps[] =  array(	'administrator' 	=> array( 	'edit_' . $post_type_item,
720
																			'read_' . $post_type_item,
721
																			'delete_' . $post_type_item,
722
																			'create_' . $post_type_item . 's',
723
																			'edit_' . $post_type_item . 's',
724
																			'edit_others_' . $post_type_item . 's',
725
																			'publish_' . $post_type_item . 's',
726
																			'read_private_' . $post_type_item . 's',
727
																			'read',
728
																			'delete_' . $post_type_item . 's',
729
																			'delete_private_' . $post_type_item . 's',
730
																			'delete_published_' . $post_type_item . 's',
731
																			'delete_others_' . $post_type_item . 's',
732
																			'edit_private_' . $post_type_item . 's',
733
																			'edit_published_' . $post_type_item . 's',
734
																			'manage_sensei',
735
																			'manage_sensei_grades' ),
736
											'editor' 			=> array(	'edit_' . $post_type_item,
737
																			'read_' . $post_type_item,
738
																			'delete_' . $post_type_item,
739
																			'create_' . $post_type_item . 's',
740
																		 	'edit_' . $post_type_item . 's',
741
																			'edit_others_' . $post_type_item . 's',
742
																			'publish_' . $post_type_item . 's',
743
																			'read_private_' . $post_type_item . 's',
744
																			'read',
745
																			'delete_' . $post_type_item . 's',
746
																			'delete_private_' . $post_type_item . 's',
747
																			'delete_published_' . $post_type_item . 's',
748
																			'delete_others_' . $post_type_item . 's',
749
																			'edit_private_' . $post_type_item . 's',
750
																			'edit_published_' . $post_type_item . 's' ),
751
											'author' 			=> array( 	'edit_' . $post_type_item,
752
																			'read_' . $post_type_item,
753
																			'delete_' . $post_type_item,
754
																			'create_' . $post_type_item . 's',
755
																			'edit_' . $post_type_item . 's',
756
																			'publish_' . $post_type_item . 's',
757
																			'read',
758
																			'delete_' . $post_type_item . 's',
759
																			'delete_published_' . $post_type_item . 's',
760
																			'edit_published_' . $post_type_item . 's' ),
761
											'contributor' 		=> array( 	'edit_' . $post_type_item,
762
																			'read_' . $post_type_item,
763
																			'delete_' . $post_type_item,
764
																			'create_' . $post_type_item . 's',
765
																			'edit_' . $post_type_item . 's',
766
																			'read',
767
																			'delete_' . $post_type_item . 's' ),
768
											'subscriber' 		=> array( 	'read' )
769
770
										);
771
		} // End For Loop
772
773
	} // End set_role_cap_defaults()
774
775
	/**
776
	 * Adds a 'Edit Quiz' link to the admin bar when viewing a Quiz linked to a corresponding Lesson
777
	 * 
778
	 * @since  1.7.0
779
     * @param WP_Admin_Bar $bar
780
	 * @return void
781
	 */
782
	public function quiz_admin_bar_menu( $bar ) {
783
		if ( is_single() && 'quiz' == get_queried_object()->post_type ) {
784
			$lesson_id = get_post_meta( get_queried_object()->ID, '_quiz_lesson', true );
785
			if ( $lesson_id ) {
786
				$object_type = get_post_type_object('quiz');
787
				$bar->add_menu( array(
788
					'id' => 'edit',
789
					'title' => $object_type->labels->edit_item,
790
					'href' => get_edit_post_link( $lesson_id ),
791
				) );
792
			}
793
		}
794
	}
795
796
} // End Class
797
798
/**
799
 * Class WooThemes_Sensei_PostTypes
800
 * @ignore only for backward compatibility
801
 * @since 1.9.0
802
 */
803
class WooThemes_Sensei_PostTypes extends Sensei_PostTypes{}
804