Completed
Branch FET-9784-autopopulate-forms (4bc800)
by
unknown
1438:07 queued 1423:17
created

EEH_Form_Fields   F

Complexity

Total Complexity 284

Size/Duplication

Total Lines 1473
Duplicated Lines 3.94 %

Coupling/Cohesion

Components 2
Dependencies 16

Importance

Changes 0
Metric Value
dl 58
loc 1473
rs 0.6314
c 0
b 0
f 0
wmc 284
lcom 2
cbo 16

32 Methods

Rating   Name   Duplication   Size   Complexity  
F get_form_fields() 0 131 28
D get_form_fields_array() 32 114 30
A generate_event_category_dropdown() 0 19 2
B submit_button() 0 17 6
C select_input() 0 47 15
C generate_question_groups_html() 0 39 8
D generate_question_groups_html2() 0 81 18
D generate_form_input() 9 63 16
D text() 0 27 9
D textarea() 0 31 10
F select() 3 43 18
A _generate_select_option_group() 0 8 2
A _generate_select_option() 0 7 4
F radio() 3 52 23
F checkbox() 3 61 21
D datepicker() 0 32 9
A remove_label_keep_required_msg() 0 3 1
A hidden_input() 0 4 2
A prep_question() 0 14 1
A prep_answer() 0 8 4
B prep_answer_options() 0 20 10
A prep_option_value() 0 3 1
A prep_required() 0 7 2
C get_label_size_class() 0 28 8
B _load_system_dropdowns() 0 18 5
A _load_specialized_dropdowns() 0 11 3
B generate_state_dropdown() 0 22 6
B generate_country_dropdown() 0 19 6
A two_digit_months_dropdown_options() 4 8 2
A next_decade_two_digit_year_dropdown_options() 4 10 2
B generate_registration_months_dropdown() 0 30 4
B generate_event_months_dropdown() 0 55 8

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EEH_Form_Fields often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EEH_Form_Fields, and based on these observations, apply Extract Interface, too.

1
<?php
2
if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('NO direct script access allowed'); }
3
4
/**
5
 * Event Espresso
6
 *
7
 * Event Registration and Management Plugin for Wordpress
8
 *
9
 * @package		Event Espresso
10
 * @author		Seth Shoultes
11
 * @copyright	(c)2009-2012 Event Espresso All Rights Reserved.
12
 * @license		http://eventespresso.com/support/terms-conditions/  ** see Plugin Licensing **
13
 * @link		http://www.eventespresso.com
14
 * @version		3.2.P
15
 * @deprecated usage of this helper is discouraged since 4.8.30.rc.009, instead
16
 * consider using the form system classes in core/libraries/form_sections. See
17
 * http://developer.eventespresso.com/docs/ee4-forms-system/.
18
 * The reason this is discouraged is because the forms system partially duplicates the
19
 * same behaviour (displaying HTML inputs), but also simplifies form validation
20
 * server-side and client-side and normalization (putting form data into the expected
21
 * datatypes in PHP). Also there have been a few bugs noticed (see https://events.codebasehq.com/projects/event-espresso/tickets/9165)
22
 * and maintaining this class AND the forms system is extra work.
23
 * Once we have removed all usage of this from EE core, it's expected that we will
24
 * start issuing deprecation notices
25
 * 
26
 *
27
 * ------------------------------------------------------------------------
28
 *
29
 * EEH_Form_Fields
30
 *
31
 * This is a helper utility class for taking in an array of form field arguments and spitting out the relevant html formatted form fields.
32
 *
33
 * @package		Event Espresso
34
 * @subpackage	/helper/EEH_Form_Fields.helper.php
35
 * @author		Darren Ethier, Brent Christensen
36
 *
37
 * ------------------------------------------------------------------------
38
 */
39
40
41
42
43
class EEH_Form_Fields {
44
45
46
	/**
47
	 *  Generates HTML for the forms used on admin pages
48
	 *
49
	 *
50
	 * 	@static
51
	 * 	@access public
52
	 * 	@param	array $input_vars - array of input field details
53
	 * 	format:
54
	 * 	$template_form_fields['field-id'] = array(
55
	 * 		'name' => 'name_attribute',
56
	 * 		'label' => __('Field Label', 'event_espresso'), //or false
57
	 * 		'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden', 'checkbox', 'wp_editor'
58
	 * 		'type' => 'int', //what "type" the value is (i.e. string, int etc)
59
	 * 		'required' => false, //boolean for whether the field is required
60
	 * 		'validation' => true, //boolean, whether to validate the field (todo)
61
	 * 		'value' => 'some_value_for_field', //what value is used for field
62
	 * 		'format' => '%d', //what format the value is (%d, %f, or %s)
63
	 * 		'db-col' => 'column_in_db' //used to indicate which column the field corresponds with in the db
64
	 * 		'options' => optiona, optionb || array('value' => 'label', '') //if the input type is "select", this allows you to set the args for the different <option> tags.
65
	 * 		'tabindex' => 1 //this allows you to set the tabindex for the field.
66
	 *      'append_content' => '' //this allows you to send in html content to append to the field.
67
	 * 	)
68
	 * 	@param	array $id - used for defining unique identifiers for the form.
69
	 * 	@return string
70
	 * 	@todo: at some point we can break this down into other static methods to abstract it a bit better.
71
	 */
72
	static public function get_form_fields( $input_vars = array(), $id = FALSE ) {
73
		
74
		if ( empty($input_vars) ) {
75
			EE_Error::add_error( __('missing required variables for the form field generator', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
76
			return FALSE;
77
		}
78
79
		// if you don't behave - this is what you're gonna get !!!
80
		$close = true;
81
		$output = '<ul>'; //this is for using built-in wp styles... watch carefully...
82
83
		// cycle thru inputs
84
		foreach ($input_vars as $input_key => $input_value) {
85
86
			$defaults = array(
87
				'name' => $input_key,
88
				'label' => __('No label', 'event_espresso'),
89
				'input' => 'hidden',
90
				'type' => 'int',
91
				'required' => FALSE,
92
				'validation' => TRUE,
93
				'value' => 'some_value_for_field',
94
				'format' => '%d',
95
				'db-col' => 'column_in_db',
96
				'options' => array(),
97
				'tabindex' => '',
98
				'append_content' => ''
99
				);
100
101
			$input_value = wp_parse_args( $input_value, $defaults );
102
103
			// required fields get a *
104
			$required = isset($input_value['required']) && $input_value['required'] ? ' <span>*</span>: ' : ': ';
105
			// and the css class "required"
106
			$css_class = isset( $input_value['css_class'] ) ? $input_value['css_class'] : '';
107
			$styles = $input_value['required'] ? 'required ' . $css_class : $css_class;
108
109
			$field_id = ($id) ? $id . '-' . $input_key : $input_key;
110
			$tabindex = !empty($input_value['tabindex']) ? ' tabindex="' . $input_value['tabindex'] . '"' : '';
111
112
			//rows or cols?
113
			$rows = isset($input_value['rows'] ) ? $input_value['rows'] : '10';
114
			$cols = isset($input_value['cols'] ) ? $input_value['cols'] : '80';
115
116
			//any content?
117
			$append_content = $input_value['append_content'];
118
119
			$output .= (!$close) ? '<ul>' : '';
120
			$output .= '<li>';
121
122
			// what type of input are we dealing with ?
123
			switch ($input_value['input']) {
124
125
				// text inputs
126
				case 'text' :
127
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
128
					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" class="' . $styles . '" type="text" value="' . $input_value['value'] . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
129
					break;
130
131
				// dropdowns
132
				case 'select' :
133
134
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
135
					$output .= "\n\t\t\t" . '<select id="' . $field_id . '" class="' . $styles . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
136
137
					if (is_array($input_value['options'])) {
138
						$options = $input_value['options'];
139
					} else {
140
						$options = explode(',', $input_value['options']);
141
					}
142
143
					foreach ($options as $key => $value) {
144
						$selected = isset( $input_value['value'] ) && $input_value['value'] == $key ? 'selected=selected' : '';
145
						//$key = str_replace( ' ', '_', sanitize_key( $value ));
146
						$output .= "\n\t\t\t\t" . '<option '. $selected . ' value="' . $key . '">' . $value . '</option>';
147
					}
148
					$output .= "\n\t\t\t" . '</select>';
149
150
					break;
151
152
				case 'textarea' :
153
154
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
155
					$output .= "\n\t\t\t" . '<textarea id="' . $field_id . '" class="' . $styles . '" rows="'.$rows.'" cols="'.$cols.'" name="' . $input_value['name'] . '"' . $tabindex . '>' . $input_value['value'] . '</textarea>';
156
					break;
157
158
				case 'hidden' :
159
					$close = false;
160
					$output .= "</li></ul>";
161
					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="hidden" name="' . $input_value['name'] . '" value="' . $input_value['value'] . '">';
162
					break;
163
164
				case 'checkbox' :
165
					$checked = ( $input_value['value'] == 1 ) ? 'checked="checked"' : '';
166
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
167
					$output .= "\n\t\t\t" . '<input id="' . $field_id. '" type="checkbox" name="' . $input_value['name'] . '" value="1"' . $checked . $tabindex . ' />';
168
					break;
169
170
				case 'wp_editor' :
171
					$close = false;
172
					$editor_settings = array(
173
						'textarea_name' => $input_value['name'],
174
						'textarea_rows' => $rows,
175
						'editor_class' => $styles,
176
						'tabindex' => $input_value['tabindex']
177
					);
178
					$output .= '</li>';
179
					$output .= '</ul>';
180
					$output .= '<h4>' . $input_value['label'] . '</h4>';
181
					if ( $append_content ) {
182
						$output .= $append_content;
183
					}
184
					ob_start();
185
					wp_editor( $input_value['value'], $field_id, $editor_settings);
186
					$editor = ob_get_contents();
187
					ob_end_clean();
188
					$output .= $editor;
189
					break;
190
191
				}
192
				if ( $append_content && $input_value['input'] !== 'wp_editor' ) {
193
					$output .= $append_content;
194
				}
195
				$output .= ($close) ? '</li>' : '';
196
197
198
		} // end foreach( $input_vars as $input_key => $input_value )
199
		$output .= ($close) ? '</ul>' : '';
200
201
		return $output;
202
	}
203
204
	/**
205
	 * form_fields_array
206
	 * This utility function assembles form fields from a given structured array with field information.
207
	 * //TODO: This is an alternate generator that we may want to use instead.
208
	 *
209
	 * @param  array $fields structured array of fields to assemble in the following format:
210
	 * [field_name] => array(
211
	 * 		['label'] => 'label for field',
212
	 * 		['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select type of field you can indicated the labels for each option via this index
213
	 * 		['extra_desc'] => 'extra description for the field', //optional
214
	 * 		['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults to text
215
	 * 		['value'] => 'value that goes in the field', //(if multi then this is an array of values and the 'default' paramater will be used for what is selected)
216
	 * 		['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
217
	 * 		['class'] => 'name-of-class(es)-for-input',
218
	 * 		['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi select type of field you can indicate the css class for each option via this index.
219
	 * 		['id'] => 'css-id-for-input') //defaults to 'field_name'
220
	 * 		['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields generated are going to be used in a loop and you want to make sure that the field identifiers are unique from each other.
221
	 * 		['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types such as textarea to indicate cols/rows.
222
	 * 		['tabindex'] => '' //this allows you to set the tabindex for the field.
223
	 * 		['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally contain an array of arguments for the editor setup.
224
	 *
225
	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
226
	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
227
	 */
228
	static public function get_form_fields_array($fields) {
229
230
		$form_fields = array();
231
		$fields = (array) $fields;
232
233
		foreach ( $fields as $field_name => $field_atts ) {
234
			//defaults:
235
			$defaults = array(
236
				'label' => '',
237
				'labels' => '',
238
				'extra_desc' => '',
239
				'type' => 'text',
240
				'value' => '',
241
				'default' => '',
242
				'class' => '',
243
				'classes' => '',
244
				'id' => $field_name,
245
				'unique_id' => '',
246
				'dimensions' => array('10', '5'),
247
				'tabindex' => '',
248
				'wpeditor_args' => array()
249
				);
250
			// merge defaults with passed arguments
251
			$_fields = wp_parse_args( $field_atts, $defaults);
252
			extract( $_fields );
253
			// generate label
254
			$label = empty($label) ? '' : '<label for="' . $id . '">' . $label . '</label>';
255
			// generate field name
256
			$f_name = !empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
257
258
			//tabindex
259
			$tabindex_str = !empty( $tabindex ) ? ' tabindex="' . $tabindex . '"' : '';
260
261
			//we determine what we're building based on the type
262
			switch ( $type ) {
263
264
				case 'textarea' :
265
						$fld = '<textarea id="' . $id . '" class="' . $class . '" rows="' . $dimensions[1] . '" cols="' . $dimensions[0] . '" name="' . $f_name . '"' . $tabindex_str . '>' . $value . '</textarea>';
266
						$fld .= $extra_desc;
267
					break;
268
269 View Code Duplication
				case 'checkbox' :
270
						$c_input = '';
271
						if ( is_array($value) ) {
272
							foreach ( $value as $key => $val ) {
273
								$c_id = $field_name . '_' . $value;
274
								$c_class = isset($classes[$key]) ? ' class="' . $classes[$key] . '" ' : '';
275
								$c_label = isset($labels[$key]) ? '<label for="' . $c_id . '">' . $labels[$key] . '</label>' : '';
276
								$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
277
								$c_input .= '<input name="' . $f_name . '[]" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
278
							}
279
							$fld = $c_input;
280
						} else {
281
							$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
282
							$fld = '<input name="'. $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
283
						}
284
					break;
285
286 View Code Duplication
				case 'radio' :
287
						$c_input = '';
288
						if ( is_array($value) ) {
289
							foreach ( $value as $key => $val ) {
290
								$c_id = $field_name . '_' . $value;
291
								$c_class = isset($classes[$key]) ? 'class="' . $classes[$key] . '" ' : '';
292
								$c_label = isset($labels[$key]) ? '<label for="' . $c_id . '">' . $labels[$key] . '</label>' : '';
293
								$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
294
								$c_input .= '<input name="' . $f_name . '" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
295
							}
296
							$fld = $c_input;
297
						} else {
298
							$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
299
							$fld = '<input name="'. $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
300
						}
301
					break;
302
303
				case 'hidden' :
304
						$fld = '<input name="' . $f_name . '" type="hidden" id="' . $id . '" class="' . $class . '" value="' . $value . '" />' . "\n";
305
					break;
306
307
				case 'select' :
308
						$fld = '<select name="' . $f_name . '" class="' . $class . '" id="' . $id . '"' . $tabindex_str . '>' . "\n";
309
						foreach ( $value as $key => $val ) {
310
							$checked = !empty($default) && $default == $val ? ' selected="selected"' : '';
311
							$fld .= "\t" . '<option value="' . $val . '"' . $checked . '>' . $labels[$key] . '</option>' . "\n";
312
						}
313
						$fld .= '</select>';
314
					break;
315
316
				case 'wp_editor' :
317
						$editor_settings = array(
318
							'textarea_name' => $f_name,
319
							'textarea_rows' => $dimensions[1],
320
							'editor_class' => $class,
321
							'tabindex' => $tabindex
322
							);
323
						$editor_settings = array_merge( $wpeditor_args, $editor_settings );
324
						ob_start();
325
						wp_editor( $value, $id, $editor_settings );
326
						$editor = ob_get_contents();
327
						ob_end_clean();
328
						$fld = $editor;
329
					break;
330
331
				default : //'text fields'
332
						$fld = '<input name="' . $f_name . '" type="text" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $tabindex_str . ' />' . "\n";
333
						$fld .= $extra_desc;
334
335
			}
336
337
			$form_fields[ $field_name ] = array( 'label' => $label, 'field' => $fld );
338
		}
339
340
		return $form_fields;
341
	}
342
343
344
345
346
347
348
	/**
349
	 * espresso admin page select_input
350
	 * Turns an array into a select fields
351
	 *
352
	 * @static
353
	 * @access public
354
	 * @param  string  $name       field name
355
	 * @param  array  $values     option values, numbered array starting at 0, where each value is an array with a key 'text' (meaning text to display' and 'id' (meaning the internal value)
356
	 * eg: array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or as an array of key-value pairs, where the key is to be used for the
357
	 * select input's name, and the value will be the text shown to the user.  Optionally you can also include an additional key of "class" which will add a specific class to the option for that value.
358
	 * @param  string  $default    default value
359
	 * @param  string  $parameters extra paramaters
360
	 * @param  string  $class      css class
361
	 * @param  boolean $autosize   whether to autosize the select or not
362
	 * @return string              html string for the select input
363
	 */
364
	static public function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true) {
365
		//if $values was submitted in the wrong format, convert it over
366
		if(!empty($values) && (!array_key_exists(0,$values) || !is_array($values[0]))){
367
			$converted_values=array();
368
			foreach($values as $id=>$text){
369
				$converted_values[]=array('id'=>$id,'text'=>$text);
370
			}
371
			$values=$converted_values;
372
		}
373
374
		$field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
375
		//Debug
376
		//EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
377
		if ( EEH_Formatter::ee_tep_not_null($parameters))
378
			$field .= ' ' . $parameters;
379
		if ($autosize) {
380
			$size = 'med';
381
			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
382
				if ($values[$ii]['text']) {
383
					if (strlen($values[$ii]['text']) > 5)
384
						$size = 'wide';
385
				}
386
			}
387
		} else {
388
			$size = '';
389
		}
390
391
		$field .= ' class="' . $class . ' ' . $size . '">';
392
393
		if (empty($default) && isset($GLOBALS[$name]))
394
			$default = stripslashes($GLOBALS[$name]);
395
396
397
		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
398
			$field .= '<option value="' . $values[$i]['id'] . '"';
399
			if ($default == $values[$i]['id']) {
400
				$field .= ' selected = "selected"';
401
			}
402
			if ( isset( $values[$i]['class'] ) ) {
403
				$field .= ' class="' . $values[$i]['class'] . '"';
404
			}
405
			$field .= '>' . $values[$i]['text'] . '</option>';
406
		}
407
		$field .= '</select>';
408
409
		return $field;
410
	}
411
412
413
414
415
416
417
	/**
418
	 * generate_question_groups_html
419
 	 *
420
	 * @param string $question_groups
421
	 * @return string HTML
422
	 */
423
	static function generate_question_groups_html( $question_groups = array(), $group_wrapper = 'fieldset' ) {
424
425
		$html = '';
426
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
427
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
428
429
		if ( ! empty( $question_groups )) {
430
			//EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
431
			// loop thru question groups
432
			foreach ( $question_groups as $QSG ) {
0 ignored issues
show
Bug introduced by
The expression $question_groups of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
433
				// check that questions exist
434
				if ( ! empty( $QSG['QSG_questions'] )) {
435
					// use fieldsets
436
					$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
437
					// group_name
438
					$html .= $QSG['QSG_show_group_name'] ? "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . self::prep_answer( $QSG['QSG_name'] ) . '</h5>' : '';
439
					// group_desc
440
					$html .= $QSG['QSG_show_group_desc'] && ! empty( $QSG['QSG_desc'] ) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer( $QSG['QSG_desc'] ) . '</div>' : '';
441
442
					$html .= $before_question_group_questions;
443
					// loop thru questions
444
					foreach ( $QSG['QSG_questions'] as $question ) {
445
//						EEH_Debug_Tools::printr( $question, '$question  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
446
						$QFI = new EE_Question_Form_Input(
447
							$question['qst_obj'],
448
							$question['ans_obj'],
449
							$question
450
						);
451
						$html .= self::generate_form_input( $QFI );
452
					}
453
					$html .= $after_question_group_questions;
454
					$html .= "\n\t" . '</' . $group_wrapper . '>';
455
				}
456
			}
457
		}
458
459
		return $html;
460
461
	}
462
463
464
465
	/**
466
	 * generate_question_groups_html
467
	 *
468
	 * @param array         $question_groups
469
	 * @param array        $q_meta
470
	 * @param bool         $from_admin
471
	 * @param string       $group_wrapper
472
	 * @return string HTML
473
	 */
474
	static function generate_question_groups_html2( $question_groups = array(), $q_meta = array(), 	$from_admin = FALSE, $group_wrapper = 'fieldset' ) {
475
476
		$html = '';
477
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
478
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
479
480
		$default_q_meta = array(
481
				'att_nmbr' => 1,
482
				'ticket_id' => '',
483
				'input_name' => '',
484
				'input_id' => '',
485
				'input_class' => ''
486
		);
487
		$q_meta = array_merge( $default_q_meta, $q_meta );
488
		//EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
489
490
		if ( ! empty( $question_groups )) {
491
//			EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
492
			// loop thru question groups
493
			foreach ( $question_groups as $QSG ) {
494
				if ( $QSG instanceof EE_Question_Group ) {
495
					// check that questions exist
496
497
					$where = array( 'QST_deleted' => 0 );
498
					if ( ! $from_admin ) {
499
						$where['QST_admin_only'] = 0;
500
					}
501
					$questions = $QSG->questions( array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
502
					if ( ! empty( $questions )) {
503
						// use fieldsets
504
						$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get( 'QSG_identifier' ) . '">';
505
						// group_name
506
						if ( $QSG->show_group_name() ) {
507
							$html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty( 'QSG_name' ) . '</h5>';
508
						}
509
						// group_desc
510
						if ( $QSG->show_group_desc() ) {
511
							$html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty( 'QSG_desc'  ) . '</div>';
512
						}
513
514
						$html .= $before_question_group_questions;
515
						// loop thru questions
516
						foreach ( $questions as $QST ) {
517
							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
518
519
							$answer = NULL;
520
521
							if (  isset( $_GET['qstn'] ) && isset( $q_meta['input_id'] ) && isset( $q_meta['att_nmbr'] )) {
522
								// check for answer in $_GET in case we are reprocessing a form after an error
523
								if ( isset( $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] )) {
524
									$answer = is_array( $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] ) ? $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] : sanitize_text_field( $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] );
525
								}
526
							} else if ( isset( $q_meta['attendee'] ) && $q_meta['attendee'] ) {
527
								//attendee data from the session
528
								$answer = isset( $q_meta['attendee'][ $qstn_id ] ) ? $q_meta['attendee'][ $qstn_id ] : NULL;
529
							}
530
531
532
533
							$QFI = new EE_Question_Form_Input(
534
									$QST,
535
									EE_Answer::new_instance ( array(
536
											'ANS_ID'=> 0,
537
											'QST_ID'=> 0,
538
											'REG_ID'=> 0,
539
											'ANS_value'=> $answer
540
									)),
541
									$q_meta
542
							);
543
							//EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
544
							$html .= self::generate_form_input( $QFI );
545
						}
546
						$html .= $after_question_group_questions;
547
						$html .= "\n\t" . '</' . $group_wrapper . '>';
548
					}
549
				}
550
			}
551
		}
552
		return $html;
553
554
	}
555
556
557
558
559
560
561
	/**
562
	 * generate_form_input
563
 	 *
564
	 * @param EE_Question_Form_Input $QFI
565
	 * @return string HTML
566
	 */
567
	static function generate_form_input( EE_Question_Form_Input $QFI ) {
568
		if ( isset( $QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin() ) {
0 ignored issues
show
Bug introduced by
The property QST_admin_only does not seem to exist in EE_Question_Form_Input.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
569
			return '';
570
		}
571
572
		$QFI = self::_load_system_dropdowns( $QFI );
0 ignored issues
show
Documentation introduced by
$QFI is of type object<EE_Question_Form_Input>, but the function expects a array.

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...
573
		$QFI = self::_load_specialized_dropdowns( $QFI );
0 ignored issues
show
Documentation introduced by
$QFI is of type array, but the function expects a object<EE_Question_Form_Input>.

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...
574
575
		//we also need to verify
576
577
		$display_text = $QFI->get('QST_display_text');
578
		$input_name = $QFI->get('QST_input_name');
579
		$answer = EE_Registry::instance()->REQ->is_set( $input_name ) ? EE_Registry::instance()->REQ->get( $input_name ) : $QFI->get('ANS_value');
580
		$input_id = $QFI->get('QST_input_id');
581
		$input_class = $QFI->get('QST_input_class');
582
//		$disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
583
		$disabled = $QFI->get('QST_disabled') ? TRUE : FALSE;
584
		$required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>' );
585
		$QST_required = $QFI->get('QST_required');
586
		$required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
587
		$use_html_entities = $QFI->get_meta( 'htmlentities' );
588
		$required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __( 'This field is required', 'event_espresso' );
589
		$required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer( $required_text, $use_html_entities ) . '</div>' : '';
590
		$label_class = 'espresso-form-input-lbl';
591
		$QST_options = $QFI->options(true,$answer);
592
		$options = is_array( $QST_options ) ? self::prep_answer_options( $QST_options ) : array();
593
		$system_ID = $QFI->get('QST_system');
594
		$label_b4 = $QFI->get_meta( 'label_b4' );
595
		$use_desc_4_label = $QFI->get_meta( 'use_desc_4_label' );
596
597
598
		switch ( $QFI->get('QST_type') ){
599
600
			case 'TEXTAREA' :
601
					return EEH_Form_Fields::textarea( $display_text, $answer, $input_name, $input_id, $input_class, array(), $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities );
0 ignored issues
show
Documentation introduced by
$disabled is of type boolean, but the function expects a false|string.

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...
602
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
603
604 View Code Duplication
			case 'DROPDOWN' :
605
					return EEH_Form_Fields::select( $display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, TRUE );
0 ignored issues
show
Documentation introduced by
$disabled is of type boolean, but the function expects a false|string.

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...
606
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
607
608
609 View Code Duplication
			case 'RADIO_BTN' :
610
					return EEH_Form_Fields::radio( $display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities, $label_b4, $use_desc_4_label );
611
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
612
613 View Code Duplication
			case 'CHECKBOX' :
614
					return EEH_Form_Fields::checkbox( $display_text, $answer, $options, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $label_b4, $system_ID, $use_html_entities );
0 ignored issues
show
Documentation introduced by
$disabled is of type boolean, but the function expects a false|string.

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...
615
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
616
617
			case 'DATE' :
618
					return EEH_Form_Fields::datepicker( $display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities );
0 ignored issues
show
Documentation introduced by
$disabled is of type boolean, but the function expects a false|string.

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...
619
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
620
621
			case 'TEXT' :
622
			default:
623
					return EEH_Form_Fields::text( $display_text, $answer, $input_name, $input_id, $input_class, $required, $required_text, $label_class, $disabled, $system_ID, $use_html_entities );
0 ignored issues
show
Documentation introduced by
$disabled is of type boolean, but the function expects a false|string.

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...
624
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
625
626
		}
627
628
629
	}
630
631
632
633
634
635
636
	/**
637
	 * generates HTML for a form text input
638
 	 *
639
	 * @param string $question 	label content
640
	 * @param string $answer 		form input value attribute
641
	 * @param string $name 			form input name attribute
642
	 * @param string $id 				form input css id attribute
643
	 * @param string $class 			form input css class attribute
644
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
645
	 * @param string $label_class 	css class attribute for the label
646
	 * @param string $disabled 		disabled="disabled" or null
647
	 * @return string HTML
648
	 */
649
	static function text( $question = FALSE, $answer = NULL, $name = FALSE, $id = '', $class = '', $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $system_ID = FALSE, $use_html_entities = TRUE ) {
650
		// need these
651
		if ( ! $question || ! $name ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
652
			return NULL;
653
		}
654
		// prep the answer
655
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
656
		// prep the required array
657
		$required = self::prep_required( $required );
0 ignored issues
show
Security Bug introduced by
It seems like $required can also be of type false; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, did you maybe forget to handle an error condition?
Loading history...
658
		// set disabled tag
659
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
0 ignored issues
show
Bug Best Practice introduced by
The expression $disabled of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
660
		// ya gots ta have style man!!!
661
		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
662
		$class = empty( $class ) ? $txt_class : $class;
663
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
664
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
665
666
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
667
		// filter label but ensure required text comes before it
668
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
669
670
		$input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr( $answer ) . '"  title="' . esc_attr( $required['msg'] ) . '" ' . $disabled .' ' . $extra . '/>';
671
672
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
673
		return  $label_html . $input_html;
674
675
	}
676
677
678
679
680
681
	/**
682
	 * generates HTML for a form textarea
683
 	 *
684
	 * @param string $question 		label content
685
	 * @param string $answer 		form input value attribute
686
	 * @param string $name 			form input name attribute
687
	 * @param string $id 				form input css id attribute
688
	 * @param string $class 			form input css class attribute
689
	 * @param array $dimensions	array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
690
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
691
	 * @param string $label_class 	css class attribute for the label
692
	 * @param string $disabled 		disabled="disabled" or null
693
	 * @return string HTML
694
	 */
695
	static function textarea( $question = FALSE, $answer = NULL, $name = FALSE, $id = '', $class = '', $dimensions = FALSE, $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $system_ID = FALSE, $use_html_entities = TRUE ) {
696
		// need these
697
		if ( ! $question || ! $name ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
698
			return NULL;
699
		}
700
		// prep the answer
701
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
702
		// prep the required array
703
		$required = self::prep_required( $required );
0 ignored issues
show
Security Bug introduced by
It seems like $required can also be of type false; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, did you maybe forget to handle an error condition?
Loading history...
704
		// make sure $dimensions is an array
705
		$dimensions = is_array( $dimensions ) ? $dimensions : array();
706
		// and set some defaults
707
		$dimensions = array_merge( array( 'rows' => 3, 'cols' => 40 ), $dimensions );
708
		// set disabled tag
709
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
0 ignored issues
show
Bug Best Practice introduced by
The expression $disabled of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
710
		// ya gots ta have style man!!!
711
		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
712
		$class = empty( $class ) ? $txt_class : $class;
713
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
714
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
715
716
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
717
		// filter label but ensure required text comes before it
718
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
719
720
		$input_html = "\n\t\t\t" . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>' . $answer . '</textarea>';
721
722
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
723
		return  $label_html . $input_html;
724
725
	}
726
727
728
729
730
731
732
	/**
733
	 * generates HTML for a form select input
734
 	 *
735
	 * @param string $question 		label content
736
	 * @param string $answer 		form input value attribute
737
	 * @param array $options			array of answer options where array key = option value and array value = option display text
738
	 * @param string $name 			form input name attribute
739
	 * @param string $id 				form input css id attribute
740
	 * @param string $class 			form input css class attribute
741
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
742
	 * @param string $label_class 	css class attribute for the label
743
	 * @param string $disabled 		disabled="disabled" or null
744
	 * @return string HTML
745
	 */
746
	static function select( $question = FALSE, $answer = NULL, $options = FALSE, $name = FALSE, $id = '', $class = '', $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $system_ID = FALSE, $use_html_entities = TRUE, $add_please_select_option = FALSE ) {
747
748
		// need these
749 View Code Duplication
		if ( ! $question || ! $name || ! $options || empty( $options ) || ! is_array( $options )) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
750
			return NULL;
751
		}
752
		// prep the answer
753
		$answer = is_array( $answer ) ? self::prep_answer( array_shift( $answer ), $use_html_entities) : self::prep_answer( $answer, $use_html_entities );
754
		// prep the required array
755
		$required = self::prep_required( $required );
0 ignored issues
show
Security Bug introduced by
It seems like $required can also be of type false; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, did you maybe forget to handle an error condition?
Loading history...
756
		// set disabled tag
757
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
0 ignored issues
show
Bug Best Practice introduced by
The expression $disabled of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
758
		// ya gots ta have style man!!!
759
		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
760
		$class = empty( $class ) ? $txt_class : $class;
761
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
762
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
763
764
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
765
		// filter label but ensure required text comes before it
766
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
767
768
		$input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr( $required['msg'] ) . '"' . $disabled . ' ' . $extra . '>';
769
		// recursively count array elements, to determine total number of options
770
		$only_option = count( $options, 1 ) == 1 ? TRUE : FALSE;
771
		if ( ! $only_option ) {
772
			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
773
			$selected = $answer === NULL ? ' selected="selected"' : '';
774
			$input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
775
		}
776
		foreach ( $options as $key => $value ) {
777
			// if value is an array, then create option groups, else create regular ol' options
778
			$input_html .= is_array( $value ) ? self::_generate_select_option_group( $key, $value, $answer, $use_html_entities ) : self::_generate_select_option( $value->value(), $value->desc(), $answer, $only_option, $use_html_entities );
0 ignored issues
show
Documentation introduced by
$only_option is of type boolean, but the function expects a false|integer.

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...
779
		}
780
781
		$input_html .= "\n\t\t\t" . '</select>';
782
783
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID );
784
785
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
786
		return  $label_html . $input_html;
787
788
	}
789
790
791
792
	/**
793
	 * 	_generate_select_option_group
794
	 *
795
	 * 	if  $value for a select box is an array, then the key will be used as the optgroup label
796
	 * 	and the value array will be looped thru and the elements sent to _generate_select_option
797
	 *
798
	 * @param mixed $opt_group
799
	 * @param mixed $QSOs
800
	 * @param mixed $answer
801
	 * @param boolean $use_html_entities
802
	 * @return string
803
	 */
804
	private static function _generate_select_option_group( $opt_group, $QSOs, $answer, $use_html_entities = true ){
805
		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value( $opt_group ) . '">';
806
		foreach ( $QSOs as $QSO ) {
807
			$html .= self::_generate_select_option( $QSO->value(), $QSO->desc(), $answer, false, $use_html_entities );
808
		}
809
		$html .= "\n\t\t\t\t" . '</optgroup>';
810
		return $html;
811
	}
812
813
814
815
	/**
816
	 * 	_generate_select_option
817
	 * @param mixed $key
818
	 * @param mixed $value
819
	 * @param mixed $answer
820
	 * @param int $only_option
821
	 * @param boolean $use_html_entities
822
	 * @return string
823
	 */
824
	private static function _generate_select_option( $key, $value, $answer, $only_option = FALSE, $use_html_entities = true ){
825
		$key = self::prep_answer( $key, $use_html_entities );
826
		$value = self::prep_answer( $value, $use_html_entities );
827
		$value = ! empty( $value ) ? $value : $key;
828
		$selected = ( $answer == $key || $only_option ) ? ' selected="selected"' : '';
0 ignored issues
show
Bug Best Practice introduced by
The expression $only_option of type false|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
829
		return "\n\t\t\t\t" . '<option value="' . self::prep_option_value( $key ) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
830
	}
831
832
833
834
	/**
835
	 * generates HTML for form radio button inputs
836
	 *
837
	 * @param bool|string $question    label content
838
	 * @param string      $answer      form input value attribute
839
	 * @param array|bool  $options     array of answer options where array key = option value and array value = option display text
840
	 * @param bool|string $name        form input name attribute
841
	 * @param string      $id          form input css id attribute
842
	 * @param string      $class       form input css class attribute
843
	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
844
	 * @param string      $required_text
845
	 * @param string      $label_class css class attribute for the label
846
	 * @param bool|string $disabled    disabled="disabled" or null
847
	 * @param bool        $system_ID
848
	 * @param bool        $use_html_entities
849
	 * @param bool        $label_b4
850
	 * @param bool        $use_desc_4_label
851
	 * @return string HTML
852
	 */
853
	static function radio( $question = FALSE, $answer = NULL, $options = FALSE, $name = FALSE, $id = '', $class = '', $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $system_ID = FALSE, $use_html_entities = TRUE, $label_b4 = FALSE, $use_desc_4_label = FALSE ) {
854
		// need these
855 View Code Duplication
		if ( ! $question || ! $name || ! $options || empty( $options ) || ! is_array( $options )) {
856
			return NULL;
857
		}
858
		// prep the answer
859
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
860
		// prep the required array
861
		$required = self::prep_required( $required );
0 ignored issues
show
Bug introduced by
It seems like $required can also be of type boolean; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
862
		// set disabled tag
863
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
864
		// ya gots ta have style man!!!
865
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
866
		$class = ! empty( $class ) ? $class : 'espresso-radio-btn-inp';
867
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
868
869
		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label> ';
0 ignored issues
show
Bug introduced by
It seems like $question defined by parameter $question on line 853 can also be of type boolean; however, EEH_Form_Fields::prep_question() does only seem to accept string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
870
		// filter label but ensure required text comes before it
871
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
872
873
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
874
875
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
876
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
877
878
		foreach ( $options as $OPT ) {
879
			if ( $OPT instanceof EE_Question_Option ) {
880
				$value = self::prep_option_value( $OPT->value() );
881
				$label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
882
				$size = $use_desc_4_label ? self::get_label_size_class( $OPT->value() . ' ' . $OPT->desc() ) : self::get_label_size_class( $OPT->value() );
883
				$desc = $OPT->desc();//no self::prep_answer
884
				$answer = is_numeric( $value ) && empty( $answer ) ? 0 : $answer;
885
				$checked = (string)$value == (string)$answer ? ' checked="checked"' : '';
886
				$opt = '-' . sanitize_key( $value );
887
888
				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
889
				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
890
				$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
891
				$input_html .= "\n\t\t\t\t\t\t" . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr( $required['msg'] ) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
892
				$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
893
				$input_html .= "\n\t\t\t\t\t" . '</label>';
894
				$input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
895
				$input_html .= "\n\t\t\t\t" . '</li>';
896
			}
897
		}
898
899
		$input_html .= "\n\t\t\t" . '</ul>';
900
901
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
902
		return  $label_html . $input_html;
903
904
	}
905
906
907
908
909
910
911
	/**
912
	 * generates HTML for form checkbox inputs
913
 	 *
914
	 * @param string $question 		label content
915
	 * @param string $answer 		form input value attribute
916
	 * @param array $options 			array of options where array key = option value and array value = option display text
917
	 * @param string $name 			form input name attribute
918
	 * @param string $id 				form input css id attribute
919
	 * @param string $class 			form input css class attribute
920
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
921
	 * @param string $label_class 	css class attribute for the label
922
	 * @param string $disabled 		disabled="disabled" or null
923
	 * @return string HTML
924
	 */
925
	static function checkbox( $question = FALSE, $answer = NULL, $options = FALSE, $name = FALSE, $id = '', $class = '', $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $label_b4 = FALSE, $system_ID = FALSE, $use_html_entities = TRUE ) {
926
		// need these
927 View Code Duplication
		if ( ! $question || ! $name || ! $options || empty( $options ) || ! is_array( $options )) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
928
			return NULL;
929
		}
930
		$answer = maybe_unserialize( $answer );
931
932
		// prep the answer(s)
933
		$answer = is_array( $answer ) ? $answer : array( sanitize_key( $answer ) => $answer );
934
935
		foreach ( $answer as $key => $value ) {
936
			$key = self::prep_option_value( $key );
937
			$answer[$key] = self::prep_answer( $value, $use_html_entities );
938
		}
939
940
		// prep the required array
941
		$required = self::prep_required( $required );
0 ignored issues
show
Security Bug introduced by
It seems like $required can also be of type false; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, did you maybe forget to handle an error condition?
Loading history...
942
		// set disabled tag
943
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
0 ignored issues
show
Bug Best Practice introduced by
The expression $disabled of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
944
		// ya gots ta have style man!!!
945
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
946
		$class = empty( $class ) ? 'espresso-radio-btn-inp' : $class;
947
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
948
949
		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label> ';
950
		// filter label but ensure required text comes before it
951
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
952
953
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
954
955
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
956
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
957
958
		foreach ( $options as $OPT ) {
959
			$value = $OPT->value();//self::prep_option_value( $OPT->value() );
960
			$size = self::get_label_size_class(  $OPT->value() . ' ' . $OPT->desc() );
961
			$text = self::prep_answer( $OPT->value() );
962
			$desc = $OPT->desc() ;
963
			$opt = '-' . sanitize_key( $value );
964
965
			$checked = is_array( $answer ) && in_array( $text, $answer ) ? ' checked="checked"' : '';
966
967
			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
968
			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
969
			$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
970
			$input_html .= "\n\t\t\t\t\t\t" . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" title="' . esc_attr( $required['msg'] ) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
971
			$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
972
 			$input_html .= "\n\t\t\t\t\t" . '</label>';
973
			if ( ! empty( $desc ) && $desc != $text ) {
974
	 			$input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
975
			}
976
			$input_html .= "\n\t\t\t\t" . '</li>';
977
978
		}
979
980
		$input_html .= "\n\t\t\t" . '</ul>';
981
982
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
983
		return  $label_html . $input_html;
984
985
	}
986
987
988
989
990
991
992
	/**
993
	 * generates HTML for a form datepicker input
994
 	 *
995
	 * @param string $question 	label content
996
	 * @param string $answer 		form input value attribute
997
	 * @param string $name 			form input name attribute
998
	 * @param string $id 				form input css id attribute
999
	 * @param string $class 			form input css class attribute
1000
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
1001
	 * @param string $label_class 	css class attribute for the label
1002
	 * @param string $disabled 		disabled="disabled" or null
1003
	 * @return string HTML
1004
	 */
1005
	static function datepicker( $question = FALSE, $answer = NULL, $name = FALSE, $id = '', $class = '', $required = FALSE, $required_text = '', $label_class = '', $disabled = FALSE, $system_ID = FALSE, $use_html_entities = TRUE ) {
1006
		// need these
1007
		if ( ! $question || ! $name ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $question of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $name of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1008
			return NULL;
1009
		}
1010
		// prep the answer
1011
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
1012
		// prep the required array
1013
		$required = self::prep_required( $required );
0 ignored issues
show
Security Bug introduced by
It seems like $required can also be of type false; however, EEH_Form_Fields::prep_required() does only seem to accept string|array, did you maybe forget to handle an error condition?
Loading history...
1014
		// set disabled tag
1015
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
0 ignored issues
show
Bug Best Practice introduced by
The expression $disabled of type false|string is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
1016
		// ya gots ta have style man!!!
1017
		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1018
		$class = empty( $class ) ? $txt_class : $class;
1019
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
1020
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
1021
1022
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
1023
		// filter label but ensure required text comes before it
1024
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
1025
1026
		$input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  title="' . esc_attr( $required['msg'] ) . '" ' . $disabled . ' ' . $extra . '/>';
1027
1028
		// enqueue scripts
1029
		wp_register_style( 'espresso-ui-theme', EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css', array(), EVENT_ESPRESSO_VERSION );
1030
		wp_enqueue_style( 'espresso-ui-theme');
1031
		wp_enqueue_script( 'jquery-ui-datepicker' );
1032
1033
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
1034
		return  $label_html . $input_html;
1035
1036
	}
1037
1038
1039
1040
	/**
1041
	 * 	remove_label_keep_required_msg
1042
	 * 	this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1043
	 * 	@access public
1044
	 * 	@return 	string
1045
	 */
1046
	public static function remove_label_keep_required_msg( $label_html, $required_text ) {
0 ignored issues
show
Unused Code introduced by
The parameter $label_html is not used and could be removed.

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

Loading history...
1047
		return $required_text;
1048
	}
1049
1050
1051
1052
1053
1054
	/**
1055
	 * Simply return sthe HTML for a hidden input of the given name and value.
1056
	 * @param string $name
1057
	 * @param string $value
1058
	 * @return string HTML
1059
	 */
1060
	static function hidden_input( $name, $value, $id = '' ){
1061
		$id = ! empty( $id ) ? $id : $name;
1062
		return '<input id="' . $id . '" type="hidden" name="'.$name.'" value="' .  $value . '"/>';
1063
	}
1064
1065
1066
1067
1068
1069
	/**
1070
	 * prep_question
1071
	 * @param string $question
1072
	 * @return string
1073
	 */
1074
	static function prep_question( $question ){
1075
		return $question;
1076
//		$link = '';
1077
//		// does this label have a help link attached ?
1078
//		if ( strpos( $question, '<a ' ) !== FALSE ) {
1079
//			$qbits = explode( '<a ', $question );
1080
//			foreach ( $qbits as $qbit ) {
1081
//				$link = strpos( $qbit, 'title="' ) !== FALSE ? $qbit : $link;
1082
//				$question = strpos( $qbit, 'title="' ) === FALSE ? $qbit : $question;
1083
//			}
1084
//			$link = '<a ' . $link;
1085
//		}
1086
//		return htmlspecialchars( trim( stripslashes( str_replace( '&#039;', "'", $question ))), ENT_QUOTES, 'UTF-8' ) . ' ' . $link;
1087
	}
1088
1089
1090
1091
1092
	/**
1093
	 * 	prep_answer
1094
	 * @param mixed $answer
1095
	 * @return string
1096
	 */
1097
	static function prep_answer( $answer, $use_html_entities = TRUE ){
1098
		//make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired, we want "0".
1099
		if ( is_bool( $answer ) ) {
1100
			$answer = $answer ? 1 : 0;
1101
		}
1102
		$answer = trim( stripslashes( str_replace( '&#039;', "'", $answer )));
1103
		return $use_html_entities ? htmlentities( $answer, ENT_QUOTES, 'UTF-8' ) : $answer;
1104
	}
1105
1106
1107
1108
	/**
1109
	 * 	prep_answer_options
1110
	 * 	@param array $QSOs  array of EE_Question_Option objects
1111
	 * 	@return array
1112
	 */
1113
	public static function prep_answer_options( $QSOs = array() ){
1114
		$prepped_answer_options = array();
1115
		if ( is_array( $QSOs ) && ! empty( $QSOs )) {
1116
			foreach( $QSOs as $key => $QSO ) {
1117
				if ( ! $QSO instanceof EE_Question_Option ) {
1118
					$QSO = EE_Question_Option::new_instance( array(
1119
						'QSO_value' => is_array( $QSO ) && isset( $QSO['id'] ) ? (string)$QSO['id'] : (string)$key,
1120
						'QSO_desc' => is_array( $QSO ) && isset( $QSO['text'] ) ? (string)$QSO['text'] : (string)$QSO
1121
					));
1122
				}
1123
				if ( $QSO->opt_group() ) {
1124
					$prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
0 ignored issues
show
Bug introduced by
The method opt_group does only exist in EE_Question_Option, but not in EE_Attendee.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
1125
				} else {
1126
					$prepped_answer_options[] = $QSO;
1127
				}
1128
			}
1129
		}
1130
//		d( $prepped_answer_options );
1131
		return $prepped_answer_options;
1132
	}
1133
1134
1135
	/**
1136
	 * 	prep_option_value
1137
	 * @param string $option_value
1138
	 * @return string
1139
	 */
1140
	static function prep_option_value( $option_value ){
1141
		return esc_attr( trim( stripslashes( $option_value ) ) );
1142
	}
1143
1144
1145
1146
1147
	/**
1148
	 * 	prep_required
1149
	 * @param string|array 	$required
1150
	 * @return array
1151
	 */
1152
	static function prep_required( $required = array() ){
1153
		// make sure required is an array
1154
		$required = is_array( $required ) ? $required : array();
1155
		// and set some defaults
1156
		$required = array_merge( array( 'label' => '', 'class' => '', 'msg' => '' ), $required );
1157
		return $required;
1158
	}
1159
1160
1161
1162
	/**
1163
	 * 	get_label_size_class
1164
	 * @param string 	$value
1165
	 * @return string
1166
	 */
1167
	static function get_label_size_class( $value = FALSE ){
1168
			if ( $value === FALSE || $value == '' ) {
1169
				return ' class="medium-lbl"';
1170
			}
1171
			// determine length of option value
1172
			$val_size = strlen( $value );
1173
			switch( $val_size ){
1174
				case $val_size < 3 :
1175
					$size =  ' class="nano-lbl"';
1176
					break;
1177
				case $val_size < 6 :
1178
					$size =  ' class="micro-lbl"';
1179
					break;
1180
				case $val_size < 12 :
1181
					$size =  ' class="tiny-lbl"';
1182
					break;
1183
				case $val_size < 25 :
1184
					$size =  ' class="small-lbl"';
1185
					break;
1186
				case $val_size > 100 :
1187
					$size =  ' class="big-lbl"';
1188
					break;
1189
				default:
1190
					$size =  ' class="medium-lbl"';
1191
					break;
1192
			}
1193
		return $size;
1194
	}
1195
1196
1197
1198
1199
	/**
1200
	 * 	_load_system_dropdowns
1201
	 * @param array 	$QFI
1202
	 * @return array
1203
	 */
1204
	private static function _load_system_dropdowns( $QFI ){
1205
		$QST_system = $QFI->get('QST_system');
0 ignored issues
show
Bug introduced by
The method get cannot be called on $QFI (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1206
		switch ( $QST_system ) {
1207
			case 'state' :
1208
				$QFI = self::generate_state_dropdown( $QFI );
1209
				break;
1210
			case 'country' :
1211
				$QFI = self::generate_country_dropdown( $QFI );
1212
				break;
1213
			case 'admin-state' :
1214
				$QFI = self::generate_state_dropdown( $QFI, TRUE );
1215
				break;
1216
			case 'admin-country' :
1217
				$QFI = self::generate_country_dropdown( $QFI, TRUE );
1218
				break;
1219
		}
1220
		return $QFI;
1221
	}
1222
1223
1224
1225
	/**
1226
	 * This preps dropdowns that are specialized.
1227
	 *
1228
	 * @since  4.6.0
1229
	 *
1230
	 * @param EE_Question_Form_Input $QFI
1231
	 *
1232
	 * @return EE_Question_Form_Input
1233
	 */
1234
	protected static function _load_specialized_dropdowns( $QFI ) {
1235
		switch( $QFI->get( 'QST_type' ) ) {
1236
			case 'STATE' :
1237
				$QFI = self::generate_state_dropdown( $QFI );
0 ignored issues
show
Documentation introduced by
$QFI is of type object<EE_Question_Form_Input>, but the function expects a array.

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...
Bug Compatibility introduced by
The expression self::generate_state_dropdown($QFI); of type array adds the type array to the return on line 1243 which is incompatible with the return type documented by EEH_Form_Fields::_load_specialized_dropdowns of type EE_Question_Form_Input.
Loading history...
1238
				break;
1239
			case 'COUNTRY' :
1240
				$QFI = self::generate_country_dropdown( $QFI );
0 ignored issues
show
Bug Compatibility introduced by
The expression self::generate_country_dropdown($QFI); of type array adds the type array to the return on line 1243 which is incompatible with the return type documented by EEH_Form_Fields::_load_specialized_dropdowns of type EE_Question_Form_Input.
Loading history...
1241
				break;
1242
		}
1243
		return $QFI;
1244
	}
1245
1246
1247
1248
	/**
1249
	 *    generate_state_dropdown
1250
	 * @param array $QST
1251
	 * @param bool  $get_all
1252
	 * @return array
1253
	 */
1254
	public static function generate_state_dropdown( $QST, $get_all = FALSE ){
1255
		$states = $get_all ? EEM_State::instance()->get_all_states() : EEM_State::instance()->get_all_states_of_active_countries();
1256
		if ( $states && count( $states ) != count( $QST->options() )) {
0 ignored issues
show
Bug introduced by
The method options cannot be called on $QST (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1257
			$QST->set( 'QST_type', 'DROPDOWN' );
0 ignored issues
show
Bug introduced by
The method set cannot be called on $QST (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1258
			// if multiple countries, we'll create option groups within the dropdown
1259
			foreach ( $states as $state ) {
0 ignored issues
show
Bug introduced by
The expression $states of type array<integer,object<EE_Base_Class>>|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1260
				if ( $state instanceof EE_State ) {
1261
					$QSO = EE_Question_Option::new_instance ( array (
1262
						'QSO_value' => $state->ID(),
1263
						'QSO_desc' => $state->name(),
1264
						'QST_ID' => $QST->get( 'QST_ID' ),
0 ignored issues
show
Bug introduced by
The method get cannot be called on $QST (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1265
						'QSO_deleted' => FALSE
1266
					));
1267
					// set option group
1268
					$QSO->set_opt_group( $state->country()->name() );
0 ignored issues
show
Documentation Bug introduced by
The method set_opt_group does not exist on object<EE_Attendee>? 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...
1269
					// add option to question
1270
					$QST->add_temp_option( $QSO );
0 ignored issues
show
Bug introduced by
The method add_temp_option cannot be called on $QST (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
1271
				}
1272
			}
1273
		}
1274
		return $QST;
1275
	}
1276
1277
1278
1279
	/**
1280
	 *    generate_country_dropdown
1281
	 * @param      $QST
1282
	 * @param bool $get_all
1283
	 * @internal param array $question
1284
	 * @return array
1285
	 */
1286
	public static function generate_country_dropdown( $QST, $get_all = FALSE ){
1287
		$countries = $get_all ? EEM_Country::instance()->get_all_countries() : EEM_Country::instance()->get_all_active_countries();
1288
		if ( $countries && count( $countries ) != count( $QST->options() ) ) {
1289
			$QST->set( 'QST_type', 'DROPDOWN' );
1290
			// now add countries
1291
			foreach ( $countries as $country ) {
0 ignored issues
show
Bug introduced by
The expression $countries of type array<integer,object<EE_Base_Class>>|boolean is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
1292
				if ( $country instanceof EE_Country ) {
1293
					$QSO = EE_Question_Option::new_instance ( array (
1294
						'QSO_value' => $country->ID(),
1295
						'QSO_desc' => $country->name(),
1296
						'QST_ID' => $QST->get( 'QST_ID' ),
1297
						'QSO_deleted' => FALSE
1298
					));
1299
					$QST->add_temp_option( $QSO );
1300
				}
1301
			}
1302
		}
1303
		return $QST;
1304
	}
1305
1306
1307
1308
1309
1310
	/**
1311
	 * 	generates options for a month dropdown selector with numbers from 01 to 12
1312
	 * 	@return array()
0 ignored issues
show
Documentation introduced by
The doc-type array() could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
1313
	 */
1314
	public static function two_digit_months_dropdown_options() {
1315
		$options = array();
1316 View Code Duplication
		for ( $x = 1; $x <= 12; $x++ ) {
1317
			$mm = str_pad( $x, 2, '0', STR_PAD_LEFT );
1318
			$options[ (string)$mm ] = (string)$mm;
1319
		}
1320
		return EEH_Form_Fields::prep_answer_options( $options );
1321
	}
1322
1323
1324
1325
1326
1327
	/**
1328
	 * 	generates a year dropdown selector with numbers for the next ten years
1329
	 * 	@return object
1330
	 */
1331
	public static function next_decade_two_digit_year_dropdown_options() {
1332
		$options = array();
1333
		$current_year = date('y');
1334
		$next_decade = $current_year + 10;
1335 View Code Duplication
		for ( $x = $current_year; $x <= $next_decade; $x++ ) {
1336
			$yy = str_pad( $x, 2, '0', STR_PAD_LEFT );
1337
			$options[ (string)$yy ] = (string)$yy;
1338
		}
1339
		return EEH_Form_Fields::prep_answer_options( $options );
1340
	}
1341
1342
1343
1344
1345
1346
	/**
1347
	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for list table filter.
1348
	 * @param  string  $cur_date     any currently selected date can be entered here.
1349
	 * @param  string  $status       Registration status
1350
	 * @param  integer $evt_category Event Category ID if the Event Category filter is selected
1351
	 * @return string                html
1352
	 */
1353
	public static function generate_registration_months_dropdown( $cur_date = '', $status = '', $evt_category = 0 ) {
1354
		$_where = array();
1355
		if ( !empty( $status ) ) {
1356
			$_where['STS_ID'] = $status;
1357
		}
1358
1359
		if ( $evt_category > 0 ) {
1360
			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1361
		}
1362
1363
		$regdtts = EEM_Registration::instance()->get_reg_months_and_years( $_where );
1364
1365
		//setup vals for select input helper
1366
		$options = array(
1367
			0 => array(
1368
				'text' => __('Select a Month/Year', 'event_espresso'),
1369
				'id' => ''
1370
				)
1371
			);
1372
1373
		foreach ( $regdtts as $regdtt ) {
1374
			$date = $regdtt->reg_month. ' ' . $regdtt->reg_year;
1375
			$options[] = array(
1376
				'text' => $date,
1377
				'id' => $date
1378
				);
1379
		}
1380
1381
		return self::select_input('month_range', $options, $cur_date, '', 'wide' );
1382
	}
1383
1384
1385
1386
	/**
1387
	 * generates a month/year dropdown selector for all events matching the given criteria
1388
	 * Typically used for list table filter
1389
	 * @param  string $cur_date          any currently selected date can be entered here.
1390
	 * @param  string $status            "view" (i.e. all, today, month, draft)
1391
	 * @param  int    $evt_category      category event belongs to
1392
	 * @param  string $evt_active_status "upcoming", "expired", "active", or "inactive"
1393
	 * @return string                    html
1394
	 */
1395
	public static function generate_event_months_dropdown( $cur_date = '', $status = NULL, $evt_category = NULL, $evt_active_status = NULL ) {
1396
		//determine what post_status our condition will have for the query.
1397
		switch ( $status ) {
1398
			case 'month' :
1399
			case 'today' :
1400
			case NULL :
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $status of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
1401
			case 'all' :
1402
				$where['Event.status'] = array( 'NOT IN', array('trash') );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1403
				break;
1404
1405
			case 'draft' :
1406
				$where['Event.status'] = array( 'IN', array('draft', 'auto-draft') );
0 ignored issues
show
Coding Style Comprehensibility introduced by
$where was never initialized. Although not strictly required by PHP, it is generally a good practice to add $where = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1407
1408
			default :
1409
				$where['Event.status'] = $status;
0 ignored issues
show
Bug introduced by
The variable $where does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1410
		}
1411
1412
		//categories?
1413
1414
1415
		if ( !empty ( $evt_category ) ) {
1416
			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1417
			$where['Event.Term_Taxonomy.term_id'] = $evt_category;
1418
		}
1419
1420
1421
//		$where['DTT_is_primary'] = 1;
1422
1423
		$DTTS = EE_Registry::instance()->load_model('Datetime')->get_dtt_months_and_years($where, $evt_active_status );
0 ignored issues
show
Documentation Bug introduced by
The method get_dtt_months_and_years does not exist on object<EEM_Base>? 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...
1424
1425
		//let's setup vals for select input helper
1426
		$options = array(
1427
			0 => array(
1428
				'text' => __('Select a Month/Year', 'event_espresso'),
1429
				'id' => ""
1430
				)
1431
			);
1432
1433
1434
1435
		//translate month and date
1436
		global $wp_locale;
1437
1438
		foreach ( $DTTS as $DTT ) {
1439
			$localized_date = $wp_locale->get_month( $DTT->dtt_month_num ) . ' ' . $DTT->dtt_year;
1440
			$id = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1441
			$options[] = array(
1442
				'text' => $localized_date,
1443
				'id' => $id
1444
				);
1445
		}
1446
1447
1448
		return self::select_input( 'month_range', $options, $cur_date, '', 'wide' );
1449
	}
1450
1451
1452
1453
	/**
1454
	 * generates the dropdown selector for event categories
1455
	 * typically used as a filter on list tables.
1456
	 * @param  integer $current_cat currently selected category
1457
	 * @return string               html for dropdown
1458
	 */
1459
	public static function generate_event_category_dropdown( $current_cat = -1 ) {
1460
		$categories = EEM_Term::instance()->get_all_ee_categories(TRUE);
1461
		$options = array(
1462
			'0' => array(
1463
				'text' => __('All Categories', 'event_espresso'),
1464
				'id' => -1
1465
				)
1466
			);
1467
1468
		//setup categories for dropdown
1469
		foreach ( $categories as $category ) {
1470
			$options[] = array(
1471
				'text' => $category->get('name'),
1472
				'id' => $category->ID()
1473
				);
1474
		}
1475
1476
		return self::select_input( 'EVT_CAT', $options, $current_cat );
1477
	}
1478
1479
1480
1481
	/**
1482
	 *    generate a submit button with or without it's own microform
1483
	 *    this is the only way to create buttons that are compatible across all themes
1484
	 *
1485
	 * @access    public
1486
	 * @param    string   $url              - the form action
1487
	 * @param    string   $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm" for the form
1488
	 * @param    string   $class            - css classes (separated by spaces if more than one)
1489
	 * @param    string   $text             - what appears on the button
1490
	 * @param    string   $nonce_action     - if using nonces
1491
	 * @param    bool|string $input_only       - whether to print form header and footer. TRUE returns the input without the form
1492
	 * @param    string   $extra_attributes - any extra attributes that need to be attached to the form input
1493
	 * @return    void
1494
	 */
1495
	public static function submit_button( $url = '', $ID = '', $class = '', $text = '', $nonce_action = '', $input_only = FALSE, $extra_attributes = '' ) {
1496
		$btn = '';
1497
		if ( empty( $url ) || empty( $ID )) {
1498
			return $btn;
1499
		}
1500
		$text = ! empty( $text ) ? $text : __('Submit', 'event_espresso' );
1501
		$btn .= '<input id="' . $ID . '-btn" class="' . $class . '" type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
1502
		if ( ! $input_only ) {
1503
			$btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
1504
			$btn_frm .= ! empty( $nonce_action ) ? wp_nonce_field( $nonce_action, $nonce_action . '_nonce', TRUE, FALSE ) : '';
1505
			$btn_frm .= $btn;
1506
			$btn_frm .= '</form>';
1507
			$btn = $btn_frm;
1508
			unset ( $btn_frm );
1509
		}
1510
		return $btn;
1511
	}
1512
1513
1514
1515
}//end class EEH_Form_Fields
1516