Completed
Branch BUG-10209-session-encoding (d07fe7)
by
unknown
25:42 queued 14:15
created

EEM_Event::get_expired_events()   C

Complexity

Conditions 10
Paths 256

Size

Total Lines 56
Code Lines 30

Duplication

Lines 12
Ratio 21.43 %

Importance

Changes 0
Metric Value
cc 10
eloc 30
nc 256
nop 2
dl 12
loc 56
rs 5.0704
c 0
b 0
f 0

How to fix   Long Method    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 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
    exit('No direct script access allowed');
3
}
4
require_once(EE_MODELS . 'EEM_CPT_Base.model.php');
5
6
/**
7
 *
8
 * EEM_Event Model
9
 *
10
 * extends EEM_CPT_Base which extends EEM_Base
11
 *
12
 * @package               Event Espresso
13
 * @subpackage            includes/models/
14
 * @author                Michael Nelson, Brent Christensen
15
 *
16
 */
17
class EEM_Event extends EEM_CPT_Base
18
{
19
    
20
    /**
21
     * constant used by status(), indicating that no more tickets can be purchased for any of the datetimes for the
22
     * event
23
     */
24
    const sold_out = 'sold_out';
25
    
26
    /**
27
     * constant used by status(), indicating that upcoming event dates have been postponed (may be pushed to a later
28
     * date)
29
     */
30
    const postponed = 'postponed';
31
    
32
    /**
33
     * constant used by status(), indicating that the event will no longer occur
34
     */
35
    const cancelled = 'cancelled';
36
    
37
    
38
    /**
39
     * @var string
40
     */
41
    protected static $_default_reg_status = null;
42
    
43
    
44
    /**
45
     * private instance of the Event object
46
     * @var EEM_Event
47
     */
48
    protected static $_instance = null;
49
    
50
    
51
    /**
52
     *        This function is a singleton method used to instantiate the EEM_Event object
53
     *
54
     * @access public
55
     *
56
     * @param string $timezone
57
     *
58
     * @return EEM_Event
59
     */
60 View Code Duplication
    public static function instance($timezone = null)
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...
61
    {
62
        
63
        // check if instance of EEM_Event already exists
64
        if ( ! self::$_instance instanceof EEM_Event) {
65
            // instantiate Espresso_model
66
            self::$_instance = new self($timezone);
67
        }
68
        //we might have a timezone set, let set_timezone decide what to do with it
69
        self::$_instance->set_timezone($timezone);
70
        
71
        // EEM_Event object
72
        return self::$_instance;
73
    }
74
    
75
    
76
    /**
77
     * Adds a relationship to Term_Taxonomy for each CPT_Base
78
     *
79
     * @param string $timezone
80
     *
81
     * @return EEM_Event
0 ignored issues
show
Comprehensibility Best Practice introduced by
Adding a @return annotation to constructors is generally not recommended as a constructor does not have a meaningful return value.

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
82
     */
83
    protected function __construct($timezone = null)
84
    {
85
        
86
        EE_Registry::instance()->load_model('Registration');
87
        
88
        $this->singular_item = __('Event', 'event_espresso');
89
        $this->plural_item   = __('Events', 'event_espresso');
90
        
91
        // to remove Cancelled events from the frontend, copy the following filter to your functions.php file
92
        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__cancelled__Public', '__return_false' );
93
        // to remove Postponed events from the frontend, copy the following filter to your functions.php file
94
        // add_filter( 'AFEE__EEM_Event__construct___custom_stati__postponed__Public', '__return_false' );
95
        // to remove Sold Out events from the frontend, copy the following filter to your functions.php file
96
        //	add_filter( 'AFEE__EEM_Event__construct___custom_stati__sold_out__Public', '__return_false' );
97
        
98
        $this->_custom_stati = apply_filters(
99
            'AFEE__EEM_Event__construct___custom_stati',
100
            array(
101
                EEM_Event::cancelled => array(
102
                    'label'  => __('Cancelled', 'event_espresso'),
103
                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__cancelled__Public', true)
104
                ),
105
                EEM_Event::postponed => array(
106
                    'label'  => __('Postponed', 'event_espresso'),
107
                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__postponed__Public', true)
108
                ),
109
                EEM_Event::sold_out  => array(
110
                    'label'  => __('Sold Out', 'event_espresso'),
111
                    'public' => apply_filters('AFEE__EEM_Event__construct___custom_stati__sold_out__Public', true)
112
                )
113
            )
114
        );
115
        
116
        self::$_default_reg_status = empty(self::$_default_reg_status) ? EEM_Registration::status_id_pending_payment : self::$_default_reg_status;
117
        
118
        $this->_tables = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('Event_CPT' => new..., 'EVTM_ID', 'EVT_ID')) of type array<string,object<EE_P...<EE_Secondary_Table>"}> is incompatible with the declared type array<integer,object<EE_Table_Base>> of property $_tables.

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...
119
            'Event_CPT'  => new EE_Primary_Table('posts', 'ID'),
120
            'Event_Meta' => new EE_Secondary_Table('esp_event_meta', 'EVTM_ID', 'EVT_ID')
121
        );
122
        
123
        $this->_fields = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('Event_CPT' => arr...esso'), false, false))) of type array<string,array<strin...E_Boolean_Field>\"}>"}> is incompatible with the declared type array<integer,object<EE_Model_Field_Base>> of property $_fields.

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...
124
            'Event_CPT'  => array(
125
                'EVT_ID'         => new EE_Primary_Key_Int_Field('ID', __('Post ID for Event', 'event_espresso')),
126
                'EVT_name'       => new EE_Plain_Text_Field('post_title', __('Event Name', 'event_espresso'), false,
127
                    ''),
128
                'EVT_desc'       => new EE_Post_Content_Field('post_content', __('Event Description', 'event_espresso'),
129
                    false, ''),
130
                'EVT_slug'       => new EE_Slug_Field('post_name', __('Event Slug', 'event_espresso'), false, ''),
131
                'EVT_created'    => new EE_Datetime_Field('post_date', __('Date/Time Event Created', 'event_espresso'),
132
                    false, EE_Datetime_Field::now),
133
                'EVT_short_desc' => new EE_Simple_HTML_Field('post_excerpt',
134
                    __('Event Short Description', 'event_espresso'), false, ''),
135
                'EVT_modified'   => new EE_Datetime_Field('post_modified',
136
                    __('Date/Time Event Modified', 'event_espresso'), false, EE_Datetime_Field::now),
137
                'EVT_wp_user'    => new EE_WP_User_Field('post_author', __('Event Creator ID', 'event_espresso'),
138
                    false),
139
                'parent'         => new EE_Integer_Field('post_parent', __('Event Parent ID', 'event_espresso'), false,
140
                    0),
141
                'EVT_order'      => new EE_Integer_Field('menu_order', __('Event Menu Order', 'event_espresso'), false,
142
                    1),
143
                'post_type'      => new EE_WP_Post_Type_Field('espresso_events'),
144
                // EE_Plain_Text_Field( 'post_type', __( 'Event Post Type', 'event_espresso' ), FALSE, 'espresso_events' ),
145
                'status'         => new EE_WP_Post_Status_Field('post_status', __('Event Status', 'event_espresso'),
146
                    false, 'draft', $this->_custom_stati)
147
            ),
148
            'Event_Meta' => array(
149
                'EVTM_ID'                         => new EE_DB_Only_Float_Field('EVTM_ID',
150
                    __('Event Meta Row ID', 'event_espresso'), false),
151
                'EVT_ID_fk'                       => new EE_DB_Only_Int_Field('EVT_ID',
152
                    __('Foreign key to Event ID from Event Meta table', 'event_espresso'), false),
153
                'EVT_display_desc'                => new EE_Boolean_Field('EVT_display_desc',
154
                    __('Display Description Flag', 'event_espresso'), false, 1),
155
                'EVT_display_ticket_selector'     => new EE_Boolean_Field('EVT_display_ticket_selector',
156
                    __('Display Ticket Selector Flag', 'event_espresso'), false, 1),
157
                'EVT_visible_on'                  => new EE_Datetime_Field('EVT_visible_on',
158
                    __('Event Visible Date', 'event_espresso'), true, EE_Datetime_Field::now),
159
                'EVT_additional_limit'            => new EE_Integer_Field('EVT_additional_limit',
160
                    __('Limit of Additional Registrations on Same Transaction', 'event_espresso'), true, 10),
161
                'EVT_default_registration_status' => new EE_Enum_Text_Field(
162
                    'EVT_default_registration_status',
163
                    __('Default Registration Status on this Event', 'event_espresso'), false,
164
                    EEM_Event::$_default_reg_status, EEM_Registration::reg_status_array()
165
                ),
166
                'EVT_member_only'                 => new EE_Boolean_Field('EVT_member_only',
167
                    __('Member-Only Event Flag', 'event_espresso'), false, false),
168
                'EVT_phone'                       => new EE_Plain_Text_Field('EVT_phone',
169
                    __('Event Phone Number', 'event_espresso'), false),
170
                'EVT_allow_overflow'              => new EE_Boolean_Field('EVT_allow_overflow',
171
                    __('Allow Overflow on Event', 'event_espresso'), false, false),
172
                'EVT_timezone_string'             => new EE_Plain_Text_Field('EVT_timezone_string',
173
                    __('Timezone (name) for Event times', 'event_espresso'), false),
174
                'EVT_external_URL'                => new EE_Plain_Text_Field('EVT_external_URL',
175
                    __('URL of Event Page if hosted elsewhere', 'event_espresso'), true),
176
                'EVT_donations'                   => new EE_Boolean_Field('EVT_donations',
177
                    __('Accept Donations?', 'event_espresso'), false, false)
178
            
179
            )
180
        );
181
        
182
        $this->_model_relations = array(
0 ignored issues
show
Documentation Bug introduced by
It seems like array('Registration' => ..._Belongs_To_Relation()) of type array<string,object<EE_H...Belongs_To_Relation>"}> is incompatible with the declared type array<integer,object<EE_Model_Relation_Base>> of property $_model_relations.

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...
183
            'Registration'           => new EE_Has_Many_Relation(),
184
            'Datetime'               => new EE_Has_Many_Relation(),
185
            'Question_Group'         => new EE_HABTM_Relation('Event_Question_Group'),
0 ignored issues
show
Documentation introduced by
'Event_Question_Group' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
186
            'Venue'                  => new EE_HABTM_Relation('Event_Venue'),
0 ignored issues
show
Documentation introduced by
'Event_Venue' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
187
            'Term_Relationship'      => new EE_Has_Many_Relation(),
188
            'Term_Taxonomy'          => new EE_HABTM_Relation('Term_Relationship'),
0 ignored issues
show
Documentation introduced by
'Term_Relationship' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
189
            'Message_Template_Group' => new EE_HABTM_Relation('Event_Message_Template'),
0 ignored issues
show
Documentation introduced by
'Event_Message_Template' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
190
            'Attendee'               => new EE_HABTM_Relation('Registration'),
0 ignored issues
show
Documentation introduced by
'Registration' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
191
            'WP_User'                => new EE_Belongs_To_Relation(),
192
        );
193
        //this model is generally available for reading
194
        $this->_cap_restriction_generators[EEM_Base::caps_read] = new EE_Restriction_Generator_Public();
195
        parent::__construct($timezone);
196
    }
197
    
198
    
199
    /**
200
     * @param string $default_reg_status
201
     */
202
    public static function set_default_reg_status($default_reg_status)
203
    {
204
        self::$_default_reg_status = $default_reg_status;
205
        //if EEM_Event has already been instantiated, then we need to reset the `EVT_default_reg_status` field to use the new default.
206
        if (self::$_instance instanceof EEM_Event) {
207
            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status'] = new EE_Enum_Text_Field(
208
                'EVT_default_registration_status', __('Default Registration Status on this Event', 'event_espresso'),
209
                false, $default_reg_status, EEM_Registration::reg_status_array()
210
            );
211
            self::$_instance->_fields['Event_Meta']['EVT_default_registration_status']->_construct_finalize('Event_Meta',
212
                'EVT_default_registration_status', 'EEM_Event');
213
        }
214
    }
215
    
216
    
217
    /**
218
     *        get_question_groups
219
     *
220
     * @access        public
221
     * @return        array
222
     */
223
    public function get_all_question_groups()
224
    {
225
        return EE_Registry::instance()->load_model('Question_Group')->get_all(array(
226
            array('QSG_deleted' => false),
227
            'order_by' => array('QSG_order' => 'ASC')
228
        ));
229
    }
230
    
231
    
232
    /**
233
     *        get_question_groups
234
     *
235
     * @access        public
236
     *
237
     * @param        int $EVT_ID
238
     *
239
     * @return        array
240
     */
241 View Code Duplication
    public function get_all_event_question_groups($EVT_ID = 0)
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...
242
    {
243
        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
244
            EE_Error::add_error(__('An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
245
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
246
            
247
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EEM_Event::get_all_event_question_groups of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
248
        }
249
        
250
        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(array(
251
            array('EVT_ID' => $EVT_ID)
252
        ));
253
    }
254
    
255
    
256
    /**
257
     *        get_question_groups
258
     *
259
     * @access        public
260
     *
261
     * @param        int     $EVT_ID
262
     * @param        boolean $for_primary_attendee
263
     *
264
     * @return        array
265
     */
266 View Code Duplication
    public function get_event_question_groups($EVT_ID = 0, $for_primary_attendee = true)
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...
267
    {
268
        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
269
            EE_Error::add_error(__('An error occurred. No Event Question Groups could be retrieved because an Event ID was not received.',
270
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
271
            
272
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EEM_Event::get_event_question_groups of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
273
        }
274
        
275
        return EE_Registry::instance()->load_model('Event_Question_Group')->get_all(array(
276
            array('EVT_ID' => $EVT_ID, 'EQG_primary' => $for_primary_attendee)
277
        ));
278
    }
279
    
280
    
281
    /**
282
     *        get_question_groups
283
     *
284
     * @access        public
285
     *
286
     * @param        int             $EVT_ID
287
     * @param        EE_Registration $registration
288
     *
289
     * @return        array
290
     */
291
    public function get_question_groups_for_event($EVT_ID = 0, EE_Registration $registration)
292
    {
293
        
294
        if ( ! isset($EVT_ID) || ! absint($EVT_ID)) {
295
            EE_Error::add_error(__('An error occurred. No Question Groups could be retrieved because an Event ID was not received.',
296
                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
297
            
298
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EEM_Event::get_question_groups_for_event of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
299
        }
300
        
301
        $where_params = array(
302
            'Event_Question_Group.EVT_ID'      => $EVT_ID,
303
            'Event_Question_Group.EQG_primary' => $registration->count() == 1 ? true : false,
304
            'QSG_deleted'                      => false
305
        );
306
        
307
        return EE_Registry::instance()->load_model('Question_Group')->get_all(array(
308
            $where_params,
309
            'order_by' => array('QSG_order' => 'ASC')
310
        ));
311
        
312
    }
313
    
314
    
315
    /**
316
     *        get_question_target_db_column
317
     *
318
     * @access        public
319
     *
320
     * @param        string $QSG_IDs csv list of $QSG IDs
321
     *
322
     * @return        array
323
     */
324 View Code Duplication
    public function get_questions_in_groups($QSG_IDs = '')
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...
325
    {
326
        
327
        if (empty($QSG_IDs)) {
328
            EE_Error::add_error(__('An error occurred. No Question Group IDs were received.', 'event_espresso'),
329
                __FILE__, __FUNCTION__, __LINE__);
330
            
331
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EEM_Event::get_questions_in_groups of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
332
        }
333
        
334
        return EE_Registry::instance()->load_model('Question')->get_all(array(
335
            array(
336
                'Question_Group.QSG_ID' => array('IN', $QSG_IDs),
337
                'QST_deleted'           => false,
338
                'QST_admin_only'        => is_admin()
339
            ),
340
            'order_by' => 'QST_order'
341
        ));
342
        
343
    }
344
    
345
    
346
    /**
347
     *        get_options_for_question
348
     *
349
     * @access        public
350
     *
351
     * @param        string $QST_IDs csv list of $QST IDs
352
     *
353
     * @return        array
354
     */
355 View Code Duplication
    public function get_options_for_question($QST_IDs)
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...
356
    {
357
        
358
        if (empty($QST_IDs)) {
359
            EE_Error::add_error(__('An error occurred. No Question IDs were received.', 'event_espresso'), __FILE__,
360
                __FUNCTION__, __LINE__);
361
            
362
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type documented by EEM_Event::get_options_for_question of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

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

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
363
        }
364
        
365
        return EE_Registry::instance()->load_model('Question_Option')->get_all(array(
366
            array(
367
                'Question.QST_ID' => array('IN', $QST_IDs),
368
                'QSO_deleted'     => false
369
            ),
370
            'order_by' => 'QSO_ID'
371
        ));
372
        
373
    }
374
    
375
    
376
    /**
377
     *        _get_question_target_db_column
378
     * @deprecated as of 4.8.32.rc.001. Instead consider using
379
     * EE_Registration_Custom_Questions_Form located in
380
     * admin_pages/registrations/form_sections/EE_Registration_Custom_Questions_Form.form.php
381
     * @access     public
382
     *
383
     * @param    EE_Registration $registration (so existing answers for registration are included)
384
     * @param    int             $EVT_ID       so all question groups are included for event (not just answers from
385
     *                                         registration).
386
     *
387
     * @throws EE_Error
388
     * @return    array
389
     */
390
    public function assemble_array_of_groups_questions_and_options(EE_Registration $registration, $EVT_ID = 0)
391
    {
392
        
393
        if (empty($EVT_ID)) {
394
            throw new EE_Error(__('An error occurred. No EVT_ID is included.  Needed to know which question groups to retrieve.',
395
                'event_espresso'));
396
        }
397
        
398
        $questions = array();
399
        
400
        // get all question groups for event
401
        $qgs = $this->get_question_groups_for_event($EVT_ID, $registration);
402
        if ( ! empty($qgs)) {
403
            foreach ($qgs as $qg) {
404
                $qsts                                  = $qg->questions();
405
                $questions[$qg->ID()]                  = $qg->model_field_array();
406
                $questions[$qg->ID()]['QSG_questions'] = array();
407
                foreach ($qsts as $qst) {
408
                    if ($qst->is_system_question()) {
409
                        continue;
410
                    }
411
                    $answer                                                               = EEM_Answer::instance()->get_one(array(
412
                        array(
413
                            'QST_ID' => $qst->ID(),
414
                            'REG_ID' => $registration->ID()
415
                        )
416
                    ));
417
                    $answer                                                               = $answer instanceof EE_Answer ? $answer : EEM_Answer::instance()->create_default_object();
418
                    $qst_name                                                             = $qstn_id = $qst->ID();
419
                    $ans_id                                                               = $answer->ID();
420
                    $qst_name                                                             = ! empty($ans_id) ? '[' . $qst_name . '][' . $ans_id . ']' : '[' . $qst_name . ']';
421
                    $input_name                                                           = '';
422
                    $input_id                                                             = sanitize_key($qst->display_text());
423
                    $input_class                                                          = '';
424
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]                    = $qst->model_field_array();
425
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_name']  = 'qstn' . $input_name . $qst_name;
426
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_id']    = $input_id . '-' . $qstn_id;
427
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_input_class'] = $input_class;
428
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options']     = array();
429
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['qst_obj']         = $qst;
430
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['ans_obj']         = $answer;
431
                    //leave responses as-is, don't convert stuff into html entities please!
432
                    $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['htmlentities'] = false;
433
                    if ($qst->type() == 'RADIO_BTN' || $qst->type() == 'CHECKBOX' || $qst->type() == 'DROPDOWN') {
434
                        $QSOs = $qst->options(true, $answer->value());
0 ignored issues
show
Documentation Bug introduced by
The method value does not exist on object<EE_Base_Class>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
435
                        if (is_array($QSOs)) {
436
                            foreach ($QSOs as $QSO_ID => $QSO) {
437
                                $questions[$qg->ID()]['QSG_questions'][$qst->ID()]['QST_options'][$QSO_ID] = $QSO->model_field_array();
438
                            }
439
                        }
440
                    }
441
                    
442
                }
443
            }
444
        }
445
        
446
        return $questions;
447
    }
448
    
449
    
450
    /**
451
     *        _get_question_target_db_column
452
     *
453
     * @access        private
454
     *
455
     * @param        $QST
456
     *
457
     * @return        string        string
458
     */
459
    private function _generate_question_input_name($QST)
460
    {
461
        
462
        if ($QST->QST_system) {
463
            $qst_name = $QST->QST_system;
464
            /*			switch( $QST->QST_system ) {
465
            
466
                            case 1 :
467
                                    $qst_name = $QST->QST_ID . '-fname';
468
                                break;
469
            
470
                            case 2 :
471
                                    $qst_name = $QST->QST_ID . '-lname';
472
                                break;
473
            
474
                            case 3 :
475
                                    $qst_name = $QST->QST_ID . '-email';
476
                                break;
477
            
478
                            case 4 :
479
                                    $qst_name = $QST->QST_ID . '-address';
480
                                break;
481
            
482
                            case 5 :
483
                                    $qst_name = $QST->QST_ID . '-address2';
484
                                break;
485
            
486
                            case  6  :
487
                                    $qst_name = $QST->QST_ID . '-city';
488
                                break;
489
            
490
                            case 7 :
491
                                    $qst_name = $QST->QST_ID . '-state';
492
                                break;
493
            
494
                            case 8 :
495
                                    $qst_name = $QST->QST_ID . '-zip';
496
                                break;
497
            
498
                            case 9 :
499
                                    $qst_name = $QST->QST_ID . '-country';
500
                                break;
501
            
502
                            case 10 :
503
                                    $qst_name = $QST->QST_ID . '-phone-' . $QST->QST_ID;
504
                                break;
505
            
506
                        }*/
507
            
508
        } else {
509
            //$qst_name = $QST->QST_ID . '-' . str_replace( array( ' ', '-', '.' ), '_', strtolower( $QST->QST_display_text ));
510
            $qst_name = $QST->QST_ID;
511
        }
512
        
513
        return $qst_name;
514
    }
515
    
516
    
517
    /**
518
     * Gets all events that are published and have event start time earlier than now and an event end time later than
519
     * now
520
     *
521
     * @access public
522
     *
523
     * @param  array $query_params An array of query params to further filter on (note that status and DTT_EVT_start
524
     *                             and DTT_EVT_end will be overridden)
525
     * @param bool   $count        whether to return the count or not (default FALSE)
526
     *
527
     * @return array    EE_Event objects
528
     */
529
    public function get_active_events($query_params, $count = false)
530
    {
531 View Code Duplication
        if (array_key_exists(0, $query_params)) {
532
            $where_params = $query_params[0];
533
            unset($query_params[0]);
534
        } else {
535
            $where_params = array();
536
        }
537
        
538
        //if we have count make sure we don't include group by
539
        if ($count && isset($query_params['group_by'])) {
540
            unset($query_params['group_by']);
541
        }
542
        
543
        //let's add specific query_params for active_events - keep in mind this will override any sent status in the query AND any date queries.
544
        $where_params['status'] = array( 'IN', array( 'publish', EEM_Event::sold_out ) );
545
        //if already have where params for DTT_EVT_start or DTT_EVT_end then append these conditions
546 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_start'])) {
547
            $where_params['Datetime.DTT_EVT_start******'] = array(
548
                '<',
549
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
550
            );
551
        } else {
552
            $where_params['Datetime.DTT_EVT_start'] = array(
553
                '<',
554
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
555
            );
556
        }
557
        
558 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_end'])) {
559
            $where_params['Datetime.DTT_EVT_end*****'] = array(
560
                '>',
561
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')
562
            );
563
        } else {
564
            $where_params['Datetime.DTT_EVT_end'] = array(
565
                '>',
566
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')
567
            );
568
        }
569
        $query_params[0] = $where_params;
570
        
571
        // don't use $query_params with count() because we don't want to include additional query clauses like "GROUP BY"
572
        return $count ? $this->count(array($where_params), 'EVT_ID', true) : $this->get_all($query_params);
573
    }
574
    
575
    
576
    /**
577
     * get all events that are published and have an event start time later than now
578
     *
579
     * @access public
580
     *
581
     * @param  array $query_params An array of query params to further filter on (Note that status and DTT_EVT_start
582
     *                             will be overridden)
583
     * @param bool   $count        whether to return the count or not (default FALSE)
584
     *
585
     * @return array               EE_Event objects
586
     */
587
    public function get_upcoming_events($query_params, $count = false)
588
    {
589 View Code Duplication
        if (array_key_exists(0, $query_params)) {
590
            $where_params = $query_params[0];
591
            unset($query_params[0]);
592
        } else {
593
            $where_params = array();
594
        }
595
        
596
        //if we have count make sure we don't include group by
597
        if ($count && isset($query_params['group_by'])) {
598
            unset($query_params['group_by']);
599
        }
600
        
601
        //let's add specific query_params for active_events - keep in mind this will override any sent status in the query AND any date queries.
602
        $where_params['status'] = array( 'IN', array( 'publish', EEM_Event::sold_out ) );
603
        //if there are already query_params matching DTT_EVT_start then we need to modify that to add them.
604 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_start'])) {
605
            $where_params['Datetime.DTT_EVT_start*****'] = array(
606
                '>',
607
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
608
            );
609
        } else {
610
            $where_params['Datetime.DTT_EVT_start'] = array(
611
                '>',
612
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_start')
613
            );
614
        }
615
        $query_params[0] = $where_params;
616
        
617
        // don't use $query_params with count() because we don't want to include additional query clauses like "GROUP BY"
618
        return $count ? $this->count(array($where_params), 'EVT_ID', true) : $this->get_all($query_params);
619
    }
620
    
621
    
622
    /**
623
     * This only returns events that are expired.  They may still be published but all their datetimes have expired.
624
     *
625
     * @access public
626
     *
627
     * @param  array $query_params An array of query params to further filter on (note that status and DTT_EVT_end will
628
     *                             be overridden)
629
     * @param bool   $count        whether to return the count or not (default FALSE)
630
     *
631
     * @return array    EE_Event objects
632
     */
633
    public function get_expired_events($query_params, $count = false)
634
    {
635
        
636
        $where_params = isset($query_params[0]) ? $query_params[0] : array();
637
        
638
        //if we have count make sure we don't include group by
639
        if ($count && isset($query_params['group_by'])) {
640
            unset($query_params['group_by']);
641
        }
642
        
643
        //let's add specific query_params for active_events - keep in mind this will override any sent status in the query AND any date queries.
644
        if (isset($where_params['status'])) {
645
            unset($where_params['status']);
646
        }
647
        $exclude_query = $query_params;
648
        if (isset($exclude_query[0])) {
649
            unset($exclude_query[0]);
650
        }
651
        $exclude_query[0] = array(
652
            'Datetime.DTT_EVT_end' => array(
653
                '>',
654
                EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')
655
            )
656
        );
657
        //first get all events that have datetimes where its not expired.
658
        $event_ids = $this->_get_all_wpdb_results($exclude_query, OBJECT_K, 'Event_CPT.ID');
659
        $event_ids = array_keys($event_ids);
660
        
661
        //if we have any additional query_params, let's add them to the 'AND' condition
662
        $and_condition = array(
663
            'Datetime.DTT_EVT_end' => array('<', EEM_Datetime::instance()->current_time_for_query('DTT_EVT_end')),
664
            'EVT_ID'               => array('NOT IN', $event_ids)
665
        );
666
        
667 View Code Duplication
        if (isset($where_params['OR'])) {
668
            $and_condition['OR'] = $where_params['OR'];
669
            unset($where_params['OR']);
670
        }
671
        
672 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_end'])) {
673
            $and_condition['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
674
            unset($where_params['Datetime.DTT_EVT_end']);
675
        }
676
        
677 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_start'])) {
678
            $and_condition['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
679
            unset($where_params['Datetime.DTT_EVT_start']);
680
        }
681
        
682
        //merge remaining $where params with the and conditions.
683
        $where_params['AND'] = array_merge($and_condition, $where_params);
684
        $query_params[0]     = $where_params;
685
        
686
        // don't use $query_params with count() because we don't want to include additional query clauses like "GROUP BY"
687
        return $count ? $this->count(array($where_params), 'EVT_ID', true) : $this->get_all($query_params);
688
    }
689
    
690
    
691
    /**
692
     * This basically just returns the events that do not have the publish status.
693
     *
694
     * @param  array   $query_params An array of query params to further filter on (note that status will be
695
     *                               overwritten)
696
     * @param  boolean $count        whether to return the count or not (default FALSE)
697
     *
698
     * @return EE_Event[]            array of EE_Event objects
699
     */
700
    public function get_inactive_events($query_params, $count = false)
701
    {
702
        $where_params = isset($query_params[0]) ? $query_params[0] : array();
703
        
704
        //let's add in specific query_params for inactive events.
705
        if (isset($where_params['status'])) {
706
            unset($where_params['status']);
707
        }
708
        
709
        //if we have count make sure we don't include group by
710
        if ($count && isset($query_params['group_by'])) {
711
            unset($query_params['group_by']);
712
        }
713
        
714
        //if we have any additional query_params, let's add them to the 'AND' condition
715
        $where_params['AND']['status'] = array('!=', 'publish');
716
        
717 View Code Duplication
        if (isset($where_params['OR'])) {
718
            $where_params['AND']['OR'] = $where_params['OR'];
719
            unset($where_params['OR']);
720
        }
721
        
722 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_end'])) {
723
            $where_params['AND']['Datetime.DTT_EVT_end****'] = $where_params['Datetime.DTT_EVT_end'];
724
            unset($where_params['Datetime.DTT_EVT_end']);
725
        }
726
        
727 View Code Duplication
        if (isset($where_params['Datetime.DTT_EVT_start'])) {
728
            $where_params['AND']['Datetime.DTT_EVT_start'] = $where_params['Datetime.DTT_EVT_start'];
729
            unset($where_params['Datetime.DTT_EVT_start']);
730
        }
731
        
732
        $query_params[0] = $where_params;
733
        
734
        // don't use $query_params with count() because we don't want to include additional query clauses like "GROUP BY"
735
        return $count ? $this->count(array($where_params), 'EVT_ID', true) : $this->get_all($query_params);
736
    }
737
    
738
    
739
    /**
740
     * This is just injecting into the parent add_relationship_to so we do special handling on price relationships
741
     * because we don't want to override any existing global default prices but instead insert NEW prices that get
742
     * attached to the event. See parent for param descriptions
743
     */
744
    public function add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query = array())
745
    {
746
        
747
        if ($relationName == 'Price') {
748
            //let's get the PRC object for the given ID to make sure that we aren't dealing with a default
749
            $prc_chk = $this->get_related_model_obj($relationName)->ensure_is_obj($other_model_id_or_obj);
750
            //if EVT_ID = 0, then this is a default
751
            if ($prc_chk->get('EVT_ID') == 0) {
752
                //let's set the prc_id as 0 so we force an insert on the add_relation_to carried out by relation
753
                $prc_chk->set('PRC_ID', 0);
754
            }
755
            
756
            //run parent
757
            return parent::add_relationship_to($id_or_obj, $prc_chk, $relationName, $where_query);
758
        }
759
        
760
        //otherwise carry on as normal
761
        return parent::add_relationship_to($id_or_obj, $other_model_id_or_obj, $relationName, $where_query);
762
    }
763
    
764
    
765
}
766
// End of file EEM_Event.model.php
767
// Location: /includes/models/EEM_Event.model.php
768