1
|
|
|
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) exit('No direct script access allowed'); |
2
|
|
|
/** |
3
|
|
|
* Event Espresso |
4
|
|
|
* |
5
|
|
|
* Event Registration and Management Plugin for WordPress |
6
|
|
|
* |
7
|
|
|
* @ package Event Espresso |
8
|
|
|
* @ author Seth Shoultes |
9
|
|
|
* @ copyright (c) 2008-2011 Event Espresso All Rights Reserved. |
10
|
|
|
* @ license http://eventespresso.com/support/terms-conditions/ * see Plugin Licensing * |
11
|
|
|
* @ link http://www.eventespresso.com |
12
|
|
|
* @ version 4.0 |
13
|
|
|
* |
14
|
|
|
* ------------------------------------------------------------------------ |
15
|
|
|
* |
16
|
|
|
* Question Model |
17
|
|
|
* |
18
|
|
|
* @package Event Espresso |
19
|
|
|
* @subpackage includes/models/ |
20
|
|
|
* @author Michael Nelson |
21
|
|
|
* |
22
|
|
|
* ------------------------------------------------------------------------ |
23
|
|
|
*/ |
24
|
|
|
require_once ( EE_MODELS . 'EEM_Soft_Delete_Base.model.php' ); |
25
|
|
|
require_once( EE_CLASSES . 'EE_Question.class.php'); |
26
|
|
|
|
27
|
|
|
class EEM_Question extends EEM_Soft_Delete_Base { |
28
|
|
|
|
29
|
|
|
// constant used to indicate that the question type is COUNTRY |
30
|
|
|
const QST_type_country = 'COUNTRY'; |
31
|
|
|
|
32
|
|
|
// constant used to indicate that the question type is DATE |
33
|
|
|
const QST_type_date = 'DATE'; |
34
|
|
|
|
35
|
|
|
// constant used to indicate that the question type is DROPDOWN |
36
|
|
|
const QST_type_dropdown = 'DROPDOWN'; |
37
|
|
|
|
38
|
|
|
// constant used to indicate that the question type is CHECKBOX |
39
|
|
|
const QST_type_checkbox = 'CHECKBOX'; |
40
|
|
|
|
41
|
|
|
// constant used to indicate that the question type is RADIO_BTN |
42
|
|
|
const QST_type_radio = 'RADIO_BTN'; |
43
|
|
|
|
44
|
|
|
// constant used to indicate that the question type is STATE |
45
|
|
|
const QST_type_state = 'STATE'; |
46
|
|
|
|
47
|
|
|
// constant used to indicate that the question type is TEXT |
48
|
|
|
const QST_type_text = 'TEXT'; |
49
|
|
|
|
50
|
|
|
// constant used to indicate that the question type is TEXTAREA |
51
|
|
|
const QST_type_textarea = 'TEXTAREA'; |
52
|
|
|
|
53
|
|
|
// constant used to indicate that the question type is a TEXTAREA that allows simple html |
54
|
|
|
const QST_type_html_textarea = 'HTML_TEXTAREA'; |
55
|
|
|
|
56
|
|
|
// constant used to indicate that the question type is an email input |
57
|
|
|
const QST_type_email = 'EMAIL'; |
58
|
|
|
|
59
|
|
|
// constant used to indicate that the question type is a US-formatted phone number |
60
|
|
|
const QST_type_us_phone = 'US_PHONE'; |
61
|
|
|
|
62
|
|
|
// constant used to indicate that the question type is an integer (whole number) |
63
|
|
|
const QST_type_int = 'INTEGER'; |
64
|
|
|
|
65
|
|
|
// constant used to indicate that the question type is a decimal (float) |
66
|
|
|
const QST_type_decimal = 'DECIMAL'; |
67
|
|
|
|
68
|
|
|
// constant used to indicate that the question type is a valid URL |
69
|
|
|
const QST_type_url = 'URL'; |
70
|
|
|
|
71
|
|
|
// constant used to indicate that the question type is a YEAR |
72
|
|
|
const QST_type_year = 'YEAR'; |
73
|
|
|
|
74
|
|
|
// constant used to indicate that the question type is a multi-select |
75
|
|
|
const QST_type_multi_select = 'MULTI_SELECT'; |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Question types that are interchangeable, even after answers have been provided for them. |
79
|
|
|
* Top-level keys are category slugs, next level is an array of question types. If question types |
80
|
|
|
* aren't in this array, it is assumed they AREN'T interchangeable with any other question types. |
81
|
|
|
* @var array |
82
|
|
|
*/ |
83
|
|
|
protected $_question_type_categories = null; |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* lists all the question types which should be allowed. Ideally, this will be extensible. |
87
|
|
|
* @access private |
88
|
|
|
* @var array of strings |
89
|
|
|
*/ |
90
|
|
|
protected $_allowed_question_types; |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* brief descriptions for all the question types |
94
|
|
|
* @access private |
95
|
|
|
* @var array of strings |
96
|
|
|
*/ |
97
|
|
|
protected $_question_descriptions; |
98
|
|
|
|
99
|
|
|
|
100
|
|
|
// private instance of the Attendee object |
101
|
|
|
protected static $_instance = NULL; |
102
|
|
|
|
103
|
|
|
|
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* EEM_Question constructor. |
107
|
|
|
* |
108
|
|
|
* @param null $timezone |
109
|
|
|
*/ |
110
|
|
|
protected function __construct( $timezone = NULL ) { |
111
|
|
|
$this->singular_item = __('Question','event_espresso'); |
112
|
|
|
$this->plural_item = __('Questions','event_espresso'); |
113
|
|
|
$this->_allowed_question_types=apply_filters( |
114
|
|
|
'FHEE__EEM_Question__construct__allowed_question_types', |
115
|
|
|
array( |
116
|
|
|
EEM_Question::QST_type_text =>__('Text','event_espresso'), |
117
|
|
|
EEM_Question::QST_type_textarea =>__('Textarea','event_espresso'), |
118
|
|
|
EEM_Question::QST_type_checkbox =>__('Checkboxes','event_espresso'), |
119
|
|
|
EEM_Question::QST_type_radio =>__('Radio Buttons','event_espresso'), |
120
|
|
|
EEM_Question::QST_type_dropdown =>__('Dropdown','event_espresso'), |
121
|
|
|
EEM_Question::QST_type_state =>__('State/Province Dropdown','event_espresso'), |
122
|
|
|
EEM_Question::QST_type_country =>__('Country Dropdown','event_espresso'), |
123
|
|
|
EEM_Question::QST_type_date =>__('Date Picker','event_espresso'), |
124
|
|
|
EEM_Question::QST_type_html_textarea => __( 'HTML Textarea', 'event_espresso' ), |
125
|
|
|
EEM_Question::QST_type_email => __( 'Email', 'event_espresso' ), |
126
|
|
|
EEM_Question::QST_type_us_phone => __( 'USA - Format Phone', 'event_espresso' ), |
127
|
|
|
EEM_Question::QST_type_decimal => __( 'Number', 'event_espresso' ), |
128
|
|
|
EEM_Question::QST_type_int => __( 'Whole Number', 'event_espresso' ), |
129
|
|
|
EEM_Question::QST_type_url => __( 'URL', 'event_espresso' ), |
130
|
|
|
EEM_Question::QST_type_year => __( 'Year', 'event_espresso' ), |
131
|
|
|
EEM_Question::QST_type_multi_select => __( 'Multi Select', 'event_espresso' ) |
132
|
|
|
) |
133
|
|
|
); |
134
|
|
|
$this->_question_descriptions = apply_filters( |
135
|
|
|
'FHEE__EEM_Question__construct__allowed_question_types', |
136
|
|
|
array( |
137
|
|
|
EEM_Question::QST_type_text => __( 'A single line text input field', 'event_espresso' ), |
138
|
|
|
EEM_Question::QST_type_textarea => __( 'A multi line text input field', 'event_espresso' ), |
139
|
|
|
EEM_Question::QST_type_checkbox => __( 'Allows multiple preset options to be selected', 'event_espresso' ), |
140
|
|
|
EEM_Question::QST_type_radio => __( 'Allows a single preset option to be selected', 'event_espresso' ), |
141
|
|
|
EEM_Question::QST_type_dropdown => __( 'A dropdown that allows a single selection', 'event_espresso' ), |
142
|
|
|
EEM_Question::QST_type_state => __( 'A dropdown that lists states/provinces', 'event_espresso' ), |
143
|
|
|
EEM_Question::QST_type_country => __( 'A dropdown that lists countries', 'event_espresso' ), |
144
|
|
|
EEM_Question::QST_type_date => __( 'A popup calendar that allows date selections', 'event_espresso' ), |
145
|
|
|
EEM_Question::QST_type_html_textarea => __( 'A multi line text input field that allows HTML', 'event_espresso' ), |
146
|
|
|
EEM_Question::QST_type_email => __( 'A text field that must contain a valid Email address', 'event_espresso' ), |
147
|
|
|
EEM_Question::QST_type_us_phone => __( 'A text field that must contain a valid US phone number', 'event_espresso' ), |
148
|
|
|
EEM_Question::QST_type_decimal => __( 'A text field that allows number values with decimals', 'event_espresso' ), |
149
|
|
|
EEM_Question::QST_type_int => __( 'A text field that only allows whole numbers (no decimals)', 'event_espresso' ), |
150
|
|
|
EEM_Question::QST_type_url => __( 'A text field that must contain a valid URL', 'event_espresso' ), |
151
|
|
|
EEM_Question::QST_type_year => __( 'A dropdown that lists the last 100 years', 'event_espresso' ), |
152
|
|
|
EEM_Question::QST_type_multi_select => __( 'A dropdown that allows multiple selections', 'event_espresso' ) |
153
|
|
|
) |
154
|
|
|
); |
155
|
|
|
$this->_question_type_categories = apply_filters( |
156
|
|
|
'FHEE__EEM_Question__construct__question_type_categories', |
157
|
|
|
array( |
158
|
|
|
'text' => array( |
159
|
|
|
EEM_Question::QST_type_text, |
160
|
|
|
EEM_Question::QST_type_textarea, |
161
|
|
|
EEM_Question::QST_type_html_textarea, |
162
|
|
|
EEM_Question::QST_type_email, |
163
|
|
|
EEM_Question::QST_type_us_phone, |
164
|
|
|
EEM_Question::QST_type_int, |
165
|
|
|
EEM_Question::QST_type_decimal, |
166
|
|
|
EEM_Question::QST_type_url, |
167
|
|
|
), |
168
|
|
|
'single-answer-enum' => array( |
169
|
|
|
EEM_Question::QST_type_radio, |
170
|
|
|
EEM_Question::QST_type_dropdown |
171
|
|
|
), |
172
|
|
|
'multi-answer-enum' => array( |
173
|
|
|
EEM_Question::QST_type_checkbox, |
174
|
|
|
EEM_Question::QST_type_multi_select |
175
|
|
|
) |
176
|
|
|
) |
177
|
|
|
); |
178
|
|
|
|
179
|
|
|
$this->_tables = array( |
|
|
|
|
180
|
|
|
'Question'=>new EE_Primary_Table('esp_question','QST_ID') |
181
|
|
|
); |
182
|
|
|
$this->_fields = array( |
|
|
|
|
183
|
|
|
'Question'=>array( |
184
|
|
|
'QST_ID'=>new EE_Primary_Key_Int_Field('QST_ID', __('Question ID','event_espresso')), |
185
|
|
|
'QST_display_text'=>new EE_Full_HTML_Field('QST_display_text', __('Question Text','event_espresso'), true, ''), |
186
|
|
|
'QST_admin_label'=>new EE_Plain_Text_Field('QST_admin_label', __('Question Label (admin-only)','event_espresso'), true, ''), |
187
|
|
|
'QST_system'=>new EE_Plain_Text_Field('QST_system', __('Internal string ID for question','event_espresso'), TRUE, NULL ), |
188
|
|
|
'QST_type'=>new EE_Enum_Text_Field('QST_type', __('Question Type','event_espresso'),false, 'TEXT',$this->_allowed_question_types), |
189
|
|
|
'QST_required'=>new EE_Boolean_Field('QST_required', __('Required Question?','event_espresso'), false, false), |
190
|
|
|
'QST_required_text'=>new EE_Simple_HTML_Field('QST_required_text', __('Text to Display if Not Provided','event_espresso'), true, ''), |
191
|
|
|
'QST_order'=>new EE_Integer_Field('QST_order', __('Question Order','event_espresso'), false, 0), |
192
|
|
|
'QST_admin_only'=>new EE_Boolean_Field('QST_admin_only', __('Admin-Only Question?','event_espresso'), false, false), |
193
|
|
|
'QST_max' => new EE_Infinite_Integer_Field( 'QST_max', __( 'Max Size', 'event_espresso' ), false, EE_INF ), |
194
|
|
|
'QST_wp_user'=>new EE_WP_User_Field('QST_wp_user', __('Question Creator ID','event_espresso'), false ), |
195
|
|
|
'QST_deleted'=>new EE_Trashed_Flag_Field('QST_deleted', __('Flag Indicating question was deleted','event_espresso'), false, false) |
196
|
|
|
) |
197
|
|
|
); |
198
|
|
|
$this->_model_relations = array( |
|
|
|
|
199
|
|
|
'Question_Group'=>new EE_HABTM_Relation('Question_Group_Question'), |
200
|
|
|
'Question_Option'=>new EE_Has_Many_Relation(), |
201
|
|
|
'Answer'=>new EE_Has_Many_Relation(), |
202
|
|
|
'WP_User' => new EE_Belongs_To_Relation(), |
203
|
|
|
//for QST_order column |
204
|
|
|
'Question_Group_Question'=>new EE_Has_Many_Relation() |
205
|
|
|
); |
206
|
|
|
//this model is generally available for reading |
207
|
|
|
$this->_cap_restriction_generators[ EEM_Base::caps_read ] = new EE_Restriction_Generator_Public(); |
208
|
|
|
$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] = new EE_Restriction_Generator_Reg_Form('QST_system'); |
209
|
|
|
$this->_cap_restriction_generators[ EEM_Base::caps_edit ] = new EE_Restriction_Generator_Reg_Form('QST_system'); |
210
|
|
|
$this->_cap_restriction_generators[ EEM_Base::caps_delete ] = new EE_Restriction_Generator_Reg_Form('QST_system'); |
211
|
|
|
parent::__construct( $timezone ); |
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
/** |
215
|
|
|
* Returns the list of allowed question types, which are normally: 'TEXT','TEXTAREA','RADIO_BTN','DROPDOWN','CHECKBOX','DATE' |
216
|
|
|
* but they can be extended |
217
|
|
|
* @return string[] |
218
|
|
|
*/ |
219
|
|
|
public function allowed_question_types(){ |
220
|
|
|
return $this->_allowed_question_types; |
221
|
|
|
} |
222
|
|
|
/** |
223
|
|
|
* Gets all the question types in the same category |
224
|
|
|
* @param string $question_type one of EEM_Question::allowed_question_types( |
225
|
|
|
* @return string[] like EEM_Question::allowed_question_types() |
226
|
|
|
*/ |
227
|
|
|
public function question_types_in_same_category( $question_type ) { |
228
|
|
|
$question_types = array( $question_type ); |
229
|
|
|
foreach( $this->_question_type_categories as $category => $question_types_in_category ) { |
230
|
|
|
if( in_array( $question_type, $question_types_in_category ) ) { |
231
|
|
|
$question_types = $question_types_in_category; |
232
|
|
|
break; |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
return array_intersect_key( $this->allowed_question_types(), array_flip( $question_types ) ); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* Determines if the given question type is in the given question type category |
241
|
|
|
* @param string $question_type one of EEM_Question::allowed_question_types() |
242
|
|
|
* @param string $category one of the top-level keys of EEM_Question::question_type_categories() |
243
|
|
|
* @return boolean |
244
|
|
|
*/ |
245
|
|
|
public function question_type_is_in_category( $question_type, $category ) { |
246
|
|
|
if( ! isset( $this->_question_type_categories[ $category ] ) ) { |
247
|
|
|
return false; |
248
|
|
|
} |
249
|
|
|
return in_array( $question_type, $this->_question_type_categories[ $category ] ); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Returns the question type categories 2d array |
254
|
|
|
* @return array see EEM_Question::_question_type_categories |
255
|
|
|
*/ |
256
|
|
|
public function question_type_categories() { |
257
|
|
|
return $this->_question_type_categories; |
258
|
|
|
} |
259
|
|
|
|
260
|
|
|
/** |
261
|
|
|
* Returns an array of all the QST_system values that can be allowed in the system question group |
262
|
|
|
* identified by $system_question_group_id |
263
|
|
|
* @param string $system_question_group_id QSG_system |
264
|
|
|
* @return array of system question names (QST_system) |
265
|
|
|
*/ |
266
|
|
|
public function allowed_system_questions_in_system_question_group( $system_question_group_id ) { |
267
|
|
|
$question_system_ids = array(); |
268
|
|
|
switch( $system_question_group_id ) { |
269
|
|
|
case EEM_Question_Group::system_personal: |
270
|
|
|
$question_system_ids = array( |
271
|
|
|
EEM_Attendee::system_question_fname, |
272
|
|
|
EEM_Attendee::system_question_lname, |
273
|
|
|
EEM_Attendee::system_question_email, |
274
|
|
|
EEM_Attendee::system_question_phone |
275
|
|
|
); |
276
|
|
|
break; |
277
|
|
|
case EEM_Question_Group::system_address: |
278
|
|
|
$question_system_ids = array( |
279
|
|
|
EEM_Attendee::system_question_address, |
280
|
|
|
EEM_Attendee::system_question_address2, |
281
|
|
|
EEM_Attendee::system_question_city, |
282
|
|
|
EEM_Attendee::system_question_state, |
283
|
|
|
EEM_Attendee::system_question_country, |
284
|
|
|
EEM_Attendee::system_question_zip, |
285
|
|
|
EEM_Attendee::system_question_phone |
286
|
|
|
); |
287
|
|
|
break; |
288
|
|
|
} |
289
|
|
|
return apply_filters( 'FHEE__EEM_Question__system_questions_allowed_in_system_question_group__return', $question_system_ids, $system_question_group_id ); |
290
|
|
|
} |
291
|
|
|
|
292
|
|
|
/** |
293
|
|
|
* Returns an array of all the QST_system values that are required in the system question group |
294
|
|
|
* identified by $system_question_group_id |
295
|
|
|
* @param string $system_question_group_id QSG_system |
296
|
|
|
* @return array of system question names (QST_system) |
297
|
|
|
*/ |
298
|
|
|
public function required_system_questions_in_system_question_group( $system_question_group_id ) { |
299
|
|
|
$question_system_ids = null; |
|
|
|
|
300
|
|
|
switch( $system_question_group_id ) { |
301
|
|
|
case EEM_Question_Group::system_personal: |
302
|
|
|
$question_system_ids = array( |
303
|
|
|
EEM_Attendee::system_question_fname, |
304
|
|
|
EEM_Attendee::system_question_email, |
305
|
|
|
); |
306
|
|
|
break; |
307
|
|
|
default: |
308
|
|
|
$question_system_ids = array(); |
309
|
|
|
} |
310
|
|
|
return apply_filters( 'FHEE__EEM_Question__system_questions_required_in_system_question_group', $question_system_ids, $system_question_group_id ); |
311
|
|
|
} |
312
|
|
|
|
313
|
|
|
|
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Gets an array for converting between QST_system and QST_IDs for system questions. Eg, if you want to know |
317
|
|
|
* which system question QST_ID corresponds to the QST_system 'city', use EEM_Question::instance()->get_Question_ID_from_system_string('city'); |
318
|
|
|
* @param $QST_system |
319
|
|
|
* @return int of QST_ID for the question that corresponds to that QST_system |
320
|
|
|
*/ |
321
|
|
|
public function get_Question_ID_from_system_string( $QST_system ){ |
322
|
|
|
return $this->get_var( array( array( 'QST_system' => $QST_system ) ) ); |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
|
326
|
|
|
|
327
|
|
|
/** |
328
|
|
|
* searches the db for the question with the latest question order and returns that value. |
329
|
|
|
* @access public |
330
|
|
|
* @return int |
331
|
|
|
*/ |
332
|
|
View Code Duplication |
public function get_latest_question_order() { |
|
|
|
|
333
|
|
|
$columns_to_select = array( |
334
|
|
|
'max_order' => array("MAX(QST_order)","%d") |
335
|
|
|
); |
336
|
|
|
$max = $this->_get_all_wpdb_results( array(), ARRAY_A, $columns_to_select ); |
337
|
|
|
return $max[0]['max_order']; |
338
|
|
|
} |
339
|
|
|
|
340
|
|
|
/** |
341
|
|
|
* Returns an array where keys are system question QST_system values, |
342
|
|
|
* and values are the highest question max the admin can set on the question |
343
|
|
|
* (aka the "max max"; eg, a site admin can change the zip question to have a max |
344
|
|
|
* of 5, but no larger than 12) |
345
|
|
|
* @return array |
346
|
|
|
*/ |
347
|
|
|
public function system_question_maxes() { |
348
|
|
|
return array( |
349
|
|
|
'fname' => 45, |
350
|
|
|
'lname' => 45, |
351
|
|
|
'address' => 255, |
352
|
|
|
'address2' => 255, |
353
|
|
|
'city' => 45, |
354
|
|
|
'zip' => 12, |
355
|
|
|
'email' => 255, |
356
|
|
|
'phone' => 45, |
357
|
|
|
); |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* Given a QST_system value, gets the question's largest allowable max input. |
362
|
|
|
* @see Registration_Form_Admin_Page::system_question_maxes() |
363
|
|
|
* @param string $system_question_value |
364
|
|
|
* @return int|float |
365
|
|
|
*/ |
366
|
|
|
public function absolute_max_for_system_question( $system_question_value ) { |
367
|
|
|
$maxes = $this->system_question_maxes(); |
368
|
|
|
if( isset( $maxes[ $system_question_value ] ) ) { |
369
|
|
|
return $maxes[ $system_question_value ]; |
370
|
|
|
} else { |
371
|
|
|
return EE_INF; |
372
|
|
|
} |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
|
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* @return array |
379
|
|
|
*/ |
380
|
|
|
public function question_descriptions() { |
381
|
|
|
return $this->_question_descriptions; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
|
385
|
|
|
|
386
|
|
|
|
387
|
|
|
|
388
|
|
|
} |
389
|
|
|
// End of file EEM_Question.model.php |
390
|
|
|
// Location: /includes/models/EEM_Question.model.php |
391
|
|
|
|
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..