Sensei_Shortcode_Courses::__construct()   F
last analyzed

Complexity

Conditions 13
Paths 1536

Size

Total Lines 31
Code Lines 15

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 31
rs 2.7716
cc 13
eloc 15
nc 1536
nop 3

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 17 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
 * Renders the [sensei_courses] shortcode
6
 *
7
 * This class is loaded int WP by the shortcode loader class.
8
 *
9
 * @class Sensei_Shortcode_User_Courses
10
 *
11
 * @package Content
12
 * @subpackage Shortcode
13
 * @author Automattic
14
 *
15
 * @since 1.9.0
16
 */
17
class Sensei_Shortcode_Courses implements Sensei_Shortcode_Interface {
18
19
    /**
20
     * @var WP_Query to help setup the query needed by the render method.
21
     */
22
    protected $query;
23
24
    /**
25
     * @var string number of items to show on the current page
26
     * Default: -1.
27
     */
28
    protected $number;
29
30
    /**
31
     * @var string ordery by course field
32
     * Default: date
33
     */
34
    protected $orderby;
35
36
    /**
37
     * @var string ASC or DESC
38
     * Default: 'DESC'
39
     */
40
    protected  $order;
41
42
    /**
43
     * @var category can be completed or active or all
44
     */
45
    protected $category;
46
47
    /**
48
     * @var string teacher id to limit the courses to
49
     */
50
    protected $teacher;
51
52
    /**
53
     * @var string csv of course ids to limit the search to
54
     */
55
    protected $ids;
56
57
    /**
58
     * @var exclude courses by id
59
     */
60
    protected $exclude;
61
62
    /**
63
     * Setup the shortcode object
64
     *
65
     * @since 1.9.0
66
     * @param array $attributes
67
     * @param string $content
68
     * @param string $shortcode the shortcode that was called for this instance
69
     */
70
    public function __construct( $attributes, $content, $shortcode ){
71
72
        // set up all argument need for constructing the course query
73
        $this->number = isset( $attributes['number'] ) ? $attributes['number'] : '10';
74
        $this->teacher = isset( $attributes['teacher'] ) ? $attributes['teacher'] : '';
75
        $this->orderby = isset( $attributes['orderby'] ) ? $attributes['orderby'] : 'date';
76
77
        // set the default for menu_order to be ASC
78
        if( 'menu_order' == $this->orderby && !isset( $attributes['order']  ) ){
79
80
            $this->order =  'ASC';
81
82
        }else{
83
84
            // for everything else use the value passed or the default DESC
85
            $this->order = isset( $attributes['order']  ) ? $attributes['order'] : 'DESC';
86
87
        }
88
89
        $category = isset( $attributes['category'] ) ? $attributes['category'] : '';
90
        $this->category = is_numeric( $category ) ? intval( $category ) : $category;
91
92
        $ids =  isset( $attributes['ids'] ) ? $attributes['ids'] : '';
93
        $this->ids = empty( $ids ) ? '' : explode( ',', $ids );
0 ignored issues
show
Documentation Bug introduced by
It seems like empty($ids) ? '' : explode(',', $ids) can also be of type array. However, the property $ids is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
94
95
        $exclude =  isset( $attributes['exclude'] ) ? $attributes['exclude'] : '';
96
        $this->exclude = empty( $exclude ) ? '' : explode( ',', $exclude );
0 ignored issues
show
Documentation Bug introduced by
It seems like empty($exclude) ? '' : explode(',', $exclude) of type string or array is incompatible with the declared type object<exclude> of property $exclude.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
97
98
        // setup the course query that will be used when rendering
99
        $this->setup_course_query();
100
    }
101
102
    /**
103
     * Sets up the object course query
104
     * that will be used int he render method.
105
     *
106
     * @since 1.9.0
107
     */
108
    protected function setup_course_query(){
109
110
        // query defaults
111
        $query_args = array(
112
            'post_type'        => 'course',
113
            'post_status'      => 'publish',
114
            'orderby'          => $this->orderby,
115
            'order'            => $this->order,
116
            'posts_per_page'   => $this->number,
117
118
        );
119
120
        // setup the teacher query if any teacher was specified
121
        if( !empty( $this->teacher )){
122
123
            // when users passed in a csv
124
            if( strpos( $this->teacher, ',' ) ){
125
126
                $teachers = explode( ',', $this->teacher );
127
128
                // for all user names given convert them to user ID's
129
                foreach( $teachers as $index => $teacher  ){
130
131
                    //replace the teacher value with the teachers ID
132
                    if( ! is_numeric( $teacher ) ){
133
134
                        $user = get_user_by('login', $teacher);
135
                        $teachers[$index] = $user->ID;
136
137
                    }
138
139
                } // end for each
140
141
                $teacher_query_by = 'author__in';
142
                $this->teacher = $teachers;
0 ignored issues
show
Documentation Bug introduced by
It seems like $teachers of type array is incompatible with the declared type string of property $teacher.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
143
144
            }else{
145
                // when users passed in a single teacher value
146
                $teacher_query_by = is_numeric( $this->teacher )? 'author':'author_name';
147
148
            }
149
150
            // attach teacher query by and teacher query value to the course query
151
            $query_args[ $teacher_query_by ] = $this->teacher;
152
153
        }// end if empty teacher
154
155
156
        // add the course category taxonomy query
157
        if( ! empty( $this->category ) ) {
158
159
            $tax_query = array();
160
            $term_id = intval( term_exists($this->category) );
161
162
            if (! empty( $term_id) ) {
163
164
                $tax_query = array(
165
                    'taxonomy' => 'course-category',
166
                    'field' => 'id',
167
                    'terms' => $term_id,
168
                );
169
170
            }
171
172
            $query_args['tax_query'] = array($tax_query);
173
174
        }
175
176
        // limit the query if the user supplied ids
177
        if( ! empty( $this->ids ) && is_array( $this->ids ) ) {
178
179
            $query_args['post__in'] = $this->ids;
180
181
        }
182
183
        // exclude the course by id fromt he query
184
        if( ! empty( $this->exclude ) && is_array( $this->exclude ) ) {
185
186
            $query_args['post__not_in'] = $this->exclude;
187
188
        }
189
190
        $this->query = new WP_Query( $query_args );
191
192
    }// end setup _course_query
193
194
    /**
195
     * Rendering the shortcode this class is responsible for.
196
     *
197
     * @return string $content
198
     */
199 View Code Duplication
    public function render(){
0 ignored issues
show
Duplication introduced by
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...
200
201
        global $wp_query;
202
203
        // keep a reference to old query
204
        $current_global_query = $wp_query;
205
206
        // assign the query setup in $this-> setup_course_query
207
        $wp_query = $this->query;
208
209
        ob_start();
210
        Sensei_Templates::get_template('loop-course.php');
211
        $shortcode_output =  ob_get_clean();
212
213
        //restore old query
214
        $wp_query = $current_global_query;
215
216
        return $shortcode_output;
217
218
    }// end render
219
220
}