Completed
Branch BUG-9623-config-log (1352ef)
by
unknown
59:02 queued 45:33
created

EEH_Form_Fields   F

Complexity

Total Complexity 284

Size/Duplication

Total Lines 1476
Duplicated Lines 3.93 %

Coupling/Cohesion

Components 2
Dependencies 16
Metric Value
wmc 284
lcom 2
cbo 16
dl 58
loc 1476
rs 0.6314

32 Methods

Rating   Name   Duplication   Size   Complexity  
F get_form_fields() 0 131 28
A _generate_select_option() 0 7 4
A remove_label_keep_required_msg() 0 3 1
A hidden_input() 0 4 2
A prep_answer() 0 8 4
A prep_option_value() 0 3 1
D get_form_fields_array() 32 114 30
C select_input() 0 50 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
F radio() 3 52 23
F checkbox() 3 61 21
D datepicker() 0 32 9
A prep_question() 0 14 1
B prep_answer_options() 0 20 10
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
A generate_event_category_dropdown() 0 19 2
B submit_button() 0 17 6
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
		//load formatter helper
374
		EE_Registry::instance()->load_helper( 'Formatter' );
375
		//EE_Registry::instance()->load_helper( 'Formatter' );
376
377
		$field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
378
		//Debug
379
		//EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
380
		if ( EEH_Formatter::ee_tep_not_null($parameters))
381
			$field .= ' ' . $parameters;
382
		if ($autosize) {
383
			$size = 'med';
384
			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
385
				if ($values[$ii]['text']) {
386
					if (strlen($values[$ii]['text']) > 5)
387
						$size = 'wide';
388
				}
389
			}
390
		} else {
391
			$size = '';
392
		}
393
394
		$field .= ' class="' . $class . ' ' . $size . '">';
395
396
		if (empty($default) && isset($GLOBALS[$name]))
397
			$default = stripslashes($GLOBALS[$name]);
398
399
400
		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
401
			$field .= '<option value="' . $values[$i]['id'] . '"';
402
			if ($default == $values[$i]['id']) {
403
				$field .= ' selected = "selected"';
404
			}
405
			if ( isset( $values[$i]['class'] ) ) {
406
				$field .= ' class="' . $values[$i]['class'] . '"';
407
			}
408
			$field .= '>' . $values[$i]['text'] . '</option>';
409
		}
410
		$field .= '</select>';
411
412
		return $field;
413
	}
414
415
416
417
418
419
420
	/**
421
	 * generate_question_groups_html
422
 	 *
423
	 * @param string $question_groups
424
	 * @return string HTML
425
	 */
426
	static function generate_question_groups_html( $question_groups = array(), $group_wrapper = 'fieldset' ) {
427
428
		$html = '';
429
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
430
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
431
432
		if ( ! empty( $question_groups )) {
433
			//EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
434
			// loop thru question groups
435
			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...
436
				// check that questions exist
437
				if ( ! empty( $QSG['QSG_questions'] )) {
438
					// use fieldsets
439
					$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
440
					// group_name
441
					$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>' : '';
442
					// group_desc
443
					$html .= $QSG['QSG_show_group_desc'] && ! empty( $QSG['QSG_desc'] ) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer( $QSG['QSG_desc'] ) . '</div>' : '';
444
445
					$html .= $before_question_group_questions;
446
					// loop thru questions
447
					foreach ( $QSG['QSG_questions'] as $question ) {
448
//						EEH_Debug_Tools::printr( $question, '$question  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
449
						$QFI = new EE_Question_Form_Input(
450
							$question['qst_obj'],
451
							$question['ans_obj'],
452
							$question
453
						);
454
						$html .= self::generate_form_input( $QFI );
455
					}
456
					$html .= $after_question_group_questions;
457
					$html .= "\n\t" . '</' . $group_wrapper . '>';
458
				}
459
			}
460
		}
461
462
		return $html;
463
464
	}
465
466
467
468
	/**
469
	 * generate_question_groups_html
470
	 *
471
	 * @param array         $question_groups
472
	 * @param array        $q_meta
473
	 * @param bool         $from_admin
474
	 * @param string       $group_wrapper
475
	 * @return string HTML
476
	 */
477
	static function generate_question_groups_html2( $question_groups = array(), $q_meta = array(), 	$from_admin = FALSE, $group_wrapper = 'fieldset' ) {
478
479
		$html = '';
480
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
481
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
482
483
		$default_q_meta = array(
484
				'att_nmbr' => 1,
485
				'ticket_id' => '',
486
				'input_name' => '',
487
				'input_id' => '',
488
				'input_class' => ''
489
		);
490
		$q_meta = array_merge( $default_q_meta, $q_meta );
491
		//EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
492
493
		if ( ! empty( $question_groups )) {
494
//			EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
495
			// loop thru question groups
496
			foreach ( $question_groups as $QSG ) {
497
				if ( $QSG instanceof EE_Question_Group ) {
498
					// check that questions exist
499
500
					$where = array( 'QST_deleted' => 0 );
501
					if ( ! $from_admin ) {
502
						$where['QST_admin_only'] = 0;
503
					}
504
					$questions = $QSG->questions( array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
505
					if ( ! empty( $questions )) {
506
						// use fieldsets
507
						$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get( 'QSG_identifier' ) . '">';
508
						// group_name
509
						if ( $QSG->show_group_name() ) {
510
							$html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty( 'QSG_name' ) . '</h5>';
511
						}
512
						// group_desc
513
						if ( $QSG->show_group_desc() ) {
514
							$html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty( 'QSG_desc'  ) . '</div>';
515
						}
516
517
						$html .= $before_question_group_questions;
518
						// loop thru questions
519
						foreach ( $questions as $QST ) {
520
							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
521
522
							$answer = NULL;
523
524
							if (  isset( $_GET['qstn'] ) && isset( $q_meta['input_id'] ) && isset( $q_meta['att_nmbr'] )) {
525
								// check for answer in $_GET in case we are reprocessing a form after an error
526
								if ( isset( $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] )) {
527
									$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 ] );
528
								}
529
							} else if ( isset( $q_meta['attendee'] ) && $q_meta['attendee'] ) {
530
								//attendee data from the session
531
								$answer = isset( $q_meta['attendee'][ $qstn_id ] ) ? $q_meta['attendee'][ $qstn_id ] : NULL;
532
							}
533
534
535
536
							$QFI = new EE_Question_Form_Input(
537
									$QST,
538
									EE_Answer::new_instance ( array(
539
											'ANS_ID'=> 0,
540
											'QST_ID'=> 0,
541
											'REG_ID'=> 0,
542
											'ANS_value'=> $answer
543
									)),
544
									$q_meta
545
							);
546
							//EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
547
							$html .= self::generate_form_input( $QFI );
548
						}
549
						$html .= $after_question_group_questions;
550
						$html .= "\n\t" . '</' . $group_wrapper . '>';
551
					}
552
				}
553
			}
554
		}
555
		return $html;
556
557
	}
558
559
560
561
562
563
564
	/**
565
	 * generate_form_input
566
 	 *
567
	 * @param EE_Question_Form_Input $QFI
568
	 * @return string HTML
569
	 */
570
	static function generate_form_input( EE_Question_Form_Input $QFI ) {
571
		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...
572
			return '';
573
		}
574
575
		$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...
576
		$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...
577
578
		//we also need to verify
579
580
		$display_text = $QFI->get('QST_display_text');
581
		$input_name = $QFI->get('QST_input_name');
582
		$answer = EE_Registry::instance()->REQ->is_set( $input_name ) ? EE_Registry::instance()->REQ->get( $input_name ) : $QFI->get('ANS_value');
583
		$input_id = $QFI->get('QST_input_id');
584
		$input_class = $QFI->get('QST_input_class');
585
//		$disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
586
		$disabled = $QFI->get('QST_disabled') ? TRUE : FALSE;
587
		$required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>' );
588
		$QST_required = $QFI->get('QST_required');
589
		$required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
590
		$use_html_entities = $QFI->get_meta( 'htmlentities' );
591
		$required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __( 'This field is required', 'event_espresso' );
592
		$required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer( $required_text, $use_html_entities ) . '</div>' : '';
593
		$label_class = 'espresso-form-input-lbl';
594
		$QST_options = $QFI->options(true,$answer);
595
		$options = is_array( $QST_options ) ? self::prep_answer_options( $QST_options ) : array();
596
		$system_ID = $QFI->get('QST_system');
597
		$label_b4 = $QFI->get_meta( 'label_b4' );
598
		$use_desc_4_label = $QFI->get_meta( 'use_desc_4_label' );
599
600
601
		switch ( $QFI->get('QST_type') ){
602
603
			case 'TEXTAREA' :
604
					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...
605
				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...
606
607 View Code Duplication
			case 'DROPDOWN' :
608
					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...
609
				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...
610
611
612 View Code Duplication
			case 'RADIO_BTN' :
613
					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 );
614
				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...
615
616 View Code Duplication
			case 'CHECKBOX' :
617
					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...
618
				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...
619
620
			case 'DATE' :
621
					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...
622
				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...
623
624
			case 'TEXT' :
625
			default:
626
					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...
627
				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...
628
629
		}
630
631
632
	}
633
634
635
636
637
638
639
	/**
640
	 * generates HTML for a form text input
641
 	 *
642
	 * @param string $question 	label content
643
	 * @param string $answer 		form input value attribute
644
	 * @param string $name 			form input name attribute
645
	 * @param string $id 				form input css id attribute
646
	 * @param string $class 			form input css class attribute
647
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
648
	 * @param string $label_class 	css class attribute for the label
649
	 * @param string $disabled 		disabled="disabled" or null
650
	 * @return string HTML
651
	 */
652
	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 ) {
653
		// need these
654
		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...
655
			return NULL;
656
		}
657
		// prep the answer
658
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
659
		// prep the required array
660
		$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...
661
		// set disabled tag
662
		$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...
663
		// ya gots ta have style man!!!
664
		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
665
		$class = empty( $class ) ? $txt_class : $class;
666
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
667
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
668
669
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
670
		// filter label but ensure required text comes before it
671
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
672
673
		$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 . '/>';
674
675
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
676
		return  $label_html . $input_html;
677
678
	}
679
680
681
682
683
684
	/**
685
	 * generates HTML for a form textarea
686
 	 *
687
	 * @param string $question 		label content
688
	 * @param string $answer 		form input value attribute
689
	 * @param string $name 			form input name attribute
690
	 * @param string $id 				form input css id attribute
691
	 * @param string $class 			form input css class attribute
692
	 * @param array $dimensions	array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
693
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
694
	 * @param string $label_class 	css class attribute for the label
695
	 * @param string $disabled 		disabled="disabled" or null
696
	 * @return string HTML
697
	 */
698
	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 ) {
699
		// need these
700
		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...
701
			return NULL;
702
		}
703
		// prep the answer
704
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
705
		// prep the required array
706
		$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...
707
		// make sure $dimensions is an array
708
		$dimensions = is_array( $dimensions ) ? $dimensions : array();
709
		// and set some defaults
710
		$dimensions = array_merge( array( 'rows' => 3, 'cols' => 40 ), $dimensions );
711
		// set disabled tag
712
		$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...
713
		// ya gots ta have style man!!!
714
		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
715
		$class = empty( $class ) ? $txt_class : $class;
716
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
717
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
718
719
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
720
		// filter label but ensure required text comes before it
721
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
722
723
		$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>';
724
725
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
726
		return  $label_html . $input_html;
727
728
	}
729
730
731
732
733
734
735
	/**
736
	 * generates HTML for a form select input
737
 	 *
738
	 * @param string $question 		label content
739
	 * @param string $answer 		form input value attribute
740
	 * @param array $options			array of answer options where array key = option value and array value = option display text
741
	 * @param string $name 			form input name attribute
742
	 * @param string $id 				form input css id attribute
743
	 * @param string $class 			form input css class attribute
744
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
745
	 * @param string $label_class 	css class attribute for the label
746
	 * @param string $disabled 		disabled="disabled" or null
747
	 * @return string HTML
748
	 */
749
	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 ) {
750
751
		// need these
752 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...
753
			return NULL;
754
		}
755
		// prep the answer
756
		$answer = is_array( $answer ) ? self::prep_answer( array_shift( $answer ), $use_html_entities) : self::prep_answer( $answer, $use_html_entities );
757
		// prep the required array
758
		$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...
759
		// set disabled tag
760
		$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...
761
		// ya gots ta have style man!!!
762
		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
763
		$class = empty( $class ) ? $txt_class : $class;
764
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
765
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
766
767
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
768
		// filter label but ensure required text comes before it
769
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
770
771
		$input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr( $required['msg'] ) . '"' . $disabled . ' ' . $extra . '>';
772
		// recursively count array elements, to determine total number of options
773
		$only_option = count( $options, 1 ) == 1 ? TRUE : FALSE;
774
		if ( ! $only_option ) {
775
			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
776
			$selected = $answer === NULL ? ' selected="selected"' : '';
777
			$input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
778
		}
779
		foreach ( $options as $key => $value ) {
780
			// if value is an array, then create option groups, else create regular ol' options
781
			$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...
782
		}
783
784
		$input_html .= "\n\t\t\t" . '</select>';
785
786
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID );
787
788
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
789
		return  $label_html . $input_html;
790
791
	}
792
793
794
795
	/**
796
	 * 	_generate_select_option_group
797
	 *
798
	 * 	if  $value for a select box is an array, then the key will be used as the optgroup label
799
	 * 	and the value array will be looped thru and the elements sent to _generate_select_option
800
	 *
801
	 * @param mixed $opt_group
802
	 * @param mixed $QSOs
803
	 * @param mixed $answer
804
	 * @param boolean $use_html_entities
805
	 * @return string
806
	 */
807
	private static function _generate_select_option_group( $opt_group, $QSOs, $answer, $use_html_entities = true ){
808
		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value( $opt_group ) . '">';
809
		foreach ( $QSOs as $QSO ) {
810
			$html .= self::_generate_select_option( $QSO->value(), $QSO->desc(), $answer, false, $use_html_entities );
811
		}
812
		$html .= "\n\t\t\t\t" . '</optgroup>';
813
		return $html;
814
	}
815
816
817
818
	/**
819
	 * 	_generate_select_option
820
	 * @param mixed $key
821
	 * @param mixed $value
822
	 * @param mixed $answer
823
	 * @param int $only_option
824
	 * @param boolean $use_html_entities
825
	 * @return string
826
	 */
827
	private static function _generate_select_option( $key, $value, $answer, $only_option = FALSE, $use_html_entities = true ){
828
		$key = self::prep_answer( $key, $use_html_entities );
829
		$value = self::prep_answer( $value, $use_html_entities );
830
		$value = ! empty( $value ) ? $value : $key;
831
		$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...
832
		return "\n\t\t\t\t" . '<option value="' . self::prep_option_value( $key ) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
833
	}
834
835
836
837
	/**
838
	 * generates HTML for form radio button inputs
839
	 *
840
	 * @param bool|string $question    label content
841
	 * @param string      $answer      form input value attribute
842
	 * @param array|bool  $options     array of answer options where array key = option value and array value = option display text
843
	 * @param bool|string $name        form input name attribute
844
	 * @param string      $id          form input css id attribute
845
	 * @param string      $class       form input css class attribute
846
	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
847
	 * @param string      $required_text
848
	 * @param string      $label_class css class attribute for the label
849
	 * @param bool|string $disabled    disabled="disabled" or null
850
	 * @param bool        $system_ID
851
	 * @param bool        $use_html_entities
852
	 * @param bool        $label_b4
853
	 * @param bool        $use_desc_4_label
854
	 * @return string HTML
855
	 */
856
	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 ) {
857
		// need these
858 View Code Duplication
		if ( ! $question || ! $name || ! $options || empty( $options ) || ! is_array( $options )) {
859
			return NULL;
860
		}
861
		// prep the answer
862
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
863
		// prep the required array
864
		$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...
865
		// set disabled tag
866
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
867
		// ya gots ta have style man!!!
868
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
869
		$class = ! empty( $class ) ? $class : 'espresso-radio-btn-inp';
870
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
871
872
		$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 856 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...
873
		// filter label but ensure required text comes before it
874
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
875
876
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
877
878
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
879
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
880
881
		foreach ( $options as $OPT ) {
882
			if ( $OPT instanceof EE_Question_Option ) {
883
				$value = self::prep_option_value( $OPT->value() );
0 ignored issues
show
Documentation introduced by
$OPT->value() is of type boolean, but the function expects a 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...
884
				$label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
885
				$size = $use_desc_4_label ? self::get_label_size_class( $OPT->value() . ' ' . $OPT->desc() ) : self::get_label_size_class( $OPT->value() );
0 ignored issues
show
Documentation introduced by
$OPT->value() 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...
886
				$desc = $OPT->desc();//no self::prep_answer
887
				$answer = is_numeric( $value ) && empty( $answer ) ? 0 : $answer;
888
				$checked = (string)$value == (string)$answer ? ' checked="checked"' : '';
889
				$opt = '-' . sanitize_key( $value );
890
891
				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
892
				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
893
				$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
894
				$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 . '/>';
895
				$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
896
				$input_html .= "\n\t\t\t\t\t" . '</label>';
897
				$input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
898
				$input_html .= "\n\t\t\t\t" . '</li>';
899
			}
900
		}
901
902
		$input_html .= "\n\t\t\t" . '</ul>';
903
904
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
905
		return  $label_html . $input_html;
906
907
	}
908
909
910
911
912
913
914
	/**
915
	 * generates HTML for form checkbox inputs
916
 	 *
917
	 * @param string $question 		label content
918
	 * @param string $answer 		form input value attribute
919
	 * @param array $options 			array of options where array key = option value and array value = option display text
920
	 * @param string $name 			form input name attribute
921
	 * @param string $id 				form input css id attribute
922
	 * @param string $class 			form input css class attribute
923
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
924
	 * @param string $label_class 	css class attribute for the label
925
	 * @param string $disabled 		disabled="disabled" or null
926
	 * @return string HTML
927
	 */
928
	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 ) {
929
		// need these
930 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...
931
			return NULL;
932
		}
933
		$answer = maybe_unserialize( $answer );
934
935
		// prep the answer(s)
936
		$answer = is_array( $answer ) ? $answer : array( sanitize_key( $answer ) => $answer );
937
938
		foreach ( $answer as $key => $value ) {
939
			$key = self::prep_option_value( $key );
940
			$answer[$key] = self::prep_answer( $value, $use_html_entities );
941
		}
942
943
		// prep the required array
944
		$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...
945
		// set disabled tag
946
		$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...
947
		// ya gots ta have style man!!!
948
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
949
		$class = empty( $class ) ? 'espresso-radio-btn-inp' : $class;
950
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
951
952
		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label> ';
953
		// filter label but ensure required text comes before it
954
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
955
956
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
957
958
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
959
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
960
961
		foreach ( $options as $OPT ) {
962
			$value = $OPT->value();//self::prep_option_value( $OPT->value() );
963
			$size = self::get_label_size_class(  $OPT->value() . ' ' . $OPT->desc() );
964
			$text = self::prep_answer( $OPT->value() );
965
			$desc = $OPT->desc() ;
966
			$opt = '-' . sanitize_key( $value );
967
968
			$checked = is_array( $answer ) && in_array( $text, $answer ) ? ' checked="checked"' : '';
969
970
			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
971
			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
972
			$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
973
			$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 . '/>';
974
			$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
975
 			$input_html .= "\n\t\t\t\t\t" . '</label>';
976
			if ( ! empty( $desc ) && $desc != $text ) {
977
	 			$input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
978
			}
979
			$input_html .= "\n\t\t\t\t" . '</li>';
980
981
		}
982
983
		$input_html .= "\n\t\t\t" . '</ul>';
984
985
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
986
		return  $label_html . $input_html;
987
988
	}
989
990
991
992
993
994
995
	/**
996
	 * generates HTML for a form datepicker input
997
 	 *
998
	 * @param string $question 	label content
999
	 * @param string $answer 		form input value attribute
1000
	 * @param string $name 			form input name attribute
1001
	 * @param string $id 				form input css id attribute
1002
	 * @param string $class 			form input css class attribute
1003
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
1004
	 * @param string $label_class 	css class attribute for the label
1005
	 * @param string $disabled 		disabled="disabled" or null
1006
	 * @return string HTML
1007
	 */
1008
	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 ) {
1009
		// need these
1010
		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...
1011
			return NULL;
1012
		}
1013
		// prep the answer
1014
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
1015
		// prep the required array
1016
		$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...
1017
		// set disabled tag
1018
		$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...
1019
		// ya gots ta have style man!!!
1020
		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1021
		$class = empty( $class ) ? $txt_class : $class;
1022
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
1023
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
1024
1025
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
1026
		// filter label but ensure required text comes before it
1027
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
1028
1029
		$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 . '/>';
1030
1031
		// enqueue scripts
1032
		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 );
1033
		wp_enqueue_style( 'espresso-ui-theme');
1034
		wp_enqueue_script( 'jquery-ui-datepicker' );
1035
1036
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
1037
		return  $label_html . $input_html;
1038
1039
	}
1040
1041
1042
1043
	/**
1044
	 * 	remove_label_keep_required_msg
1045
	 * 	this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1046
	 * 	@access public
1047
	 * 	@return 	string
1048
	 */
1049
	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...
1050
		return $required_text;
1051
	}
1052
1053
1054
1055
1056
1057
	/**
1058
	 * Simply return sthe HTML for a hidden input of the given name and value.
1059
	 * @param string $name
1060
	 * @param string $value
1061
	 * @return string HTML
1062
	 */
1063
	static function hidden_input( $name, $value, $id = '' ){
1064
		$id = ! empty( $id ) ? $id : $name;
1065
		return '<input id="' . $id . '" type="hidden" name="'.$name.'" value="' .  $value . '"/>';
1066
	}
1067
1068
1069
1070
1071
1072
	/**
1073
	 * prep_question
1074
	 * @param string $question
1075
	 * @return string
1076
	 */
1077
	static function prep_question( $question ){
1078
		return $question;
1079
//		$link = '';
1080
//		// does this label have a help link attached ?
1081
//		if ( strpos( $question, '<a ' ) !== FALSE ) {
1082
//			$qbits = explode( '<a ', $question );
1083
//			foreach ( $qbits as $qbit ) {
1084
//				$link = strpos( $qbit, 'title="' ) !== FALSE ? $qbit : $link;
1085
//				$question = strpos( $qbit, 'title="' ) === FALSE ? $qbit : $question;
1086
//			}
1087
//			$link = '<a ' . $link;
1088
//		}
1089
//		return htmlspecialchars( trim( stripslashes( str_replace( '&#039;', "'", $question ))), ENT_QUOTES, 'UTF-8' ) . ' ' . $link;
1090
	}
1091
1092
1093
1094
1095
	/**
1096
	 * 	prep_answer
1097
	 * @param mixed $answer
1098
	 * @return string
1099
	 */
1100
	static function prep_answer( $answer, $use_html_entities = TRUE ){
1101
		//make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired, we want "0".
1102
		if ( is_bool( $answer ) ) {
1103
			$answer = $answer ? 1 : 0;
1104
		}
1105
		$answer = trim( stripslashes( str_replace( '&#039;', "'", $answer )));
1106
		return $use_html_entities ? htmlentities( $answer, ENT_QUOTES, 'UTF-8' ) : $answer;
1107
	}
1108
1109
1110
1111
	/**
1112
	 * 	prep_answer_options
1113
	 * 	@param array $QSOs  array of EE_Question_Option objects
1114
	 * 	@return array
1115
	 */
1116
	public static function prep_answer_options( $QSOs = array() ){
1117
		$prepped_answer_options = array();
1118
		if ( is_array( $QSOs ) && ! empty( $QSOs )) {
1119
			foreach( $QSOs as $key => $QSO ) {
1120
				if ( ! $QSO instanceof EE_Question_Option ) {
1121
					$QSO = EE_Question_Option::new_instance( array(
1122
						'QSO_value' => is_array( $QSO ) && isset( $QSO['id'] ) ? (string)$QSO['id'] : (string)$key,
1123
						'QSO_desc' => is_array( $QSO ) && isset( $QSO['text'] ) ? (string)$QSO['text'] : (string)$QSO
1124
					));
1125
				}
1126
				if ( $QSO->opt_group() ) {
1127
					$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...
1128
				} else {
1129
					$prepped_answer_options[] = $QSO;
1130
				}
1131
			}
1132
		}
1133
//		d( $prepped_answer_options );
1134
		return $prepped_answer_options;
1135
	}
1136
1137
1138
	/**
1139
	 * 	prep_option_value
1140
	 * @param string $option_value
1141
	 * @return string
1142
	 */
1143
	static function prep_option_value( $option_value ){
1144
		return esc_attr( trim( stripslashes( $option_value ) ) );
1145
	}
1146
1147
1148
1149
1150
	/**
1151
	 * 	prep_required
1152
	 * @param string|array 	$required
1153
	 * @return array
1154
	 */
1155
	static function prep_required( $required = array() ){
1156
		// make sure required is an array
1157
		$required = is_array( $required ) ? $required : array();
1158
		// and set some defaults
1159
		$required = array_merge( array( 'label' => '', 'class' => '', 'msg' => '' ), $required );
1160
		return $required;
1161
	}
1162
1163
1164
1165
	/**
1166
	 * 	get_label_size_class
1167
	 * @param string 	$value
1168
	 * @return string
1169
	 */
1170
	static function get_label_size_class( $value = FALSE ){
1171
			if ( $value === FALSE || $value == '' ) {
1172
				return ' class="medium-lbl"';
1173
			}
1174
			// determine length of option value
1175
			$val_size = strlen( $value );
1176
			switch( $val_size ){
1177
				case $val_size < 3 :
1178
					$size =  ' class="nano-lbl"';
1179
					break;
1180
				case $val_size < 6 :
1181
					$size =  ' class="micro-lbl"';
1182
					break;
1183
				case $val_size < 12 :
1184
					$size =  ' class="tiny-lbl"';
1185
					break;
1186
				case $val_size < 25 :
1187
					$size =  ' class="small-lbl"';
1188
					break;
1189
				case $val_size > 100 :
1190
					$size =  ' class="big-lbl"';
1191
					break;
1192
				default:
1193
					$size =  ' class="medium-lbl"';
1194
					break;
1195
			}
1196
		return $size;
1197
	}
1198
1199
1200
1201
1202
	/**
1203
	 * 	_load_system_dropdowns
1204
	 * @param array 	$QFI
1205
	 * @return array
1206
	 */
1207
	private static function _load_system_dropdowns( $QFI ){
1208
		$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...
1209
		switch ( $QST_system ) {
1210
			case 'state' :
1211
				$QFI = self::generate_state_dropdown( $QFI );
1212
				break;
1213
			case 'country' :
1214
				$QFI = self::generate_country_dropdown( $QFI );
1215
				break;
1216
			case 'admin-state' :
1217
				$QFI = self::generate_state_dropdown( $QFI, TRUE );
1218
				break;
1219
			case 'admin-country' :
1220
				$QFI = self::generate_country_dropdown( $QFI, TRUE );
1221
				break;
1222
		}
1223
		return $QFI;
1224
	}
1225
1226
1227
1228
	/**
1229
	 * This preps dropdowns that are specialized.
1230
	 *
1231
	 * @since  4.6.0
1232
	 *
1233
	 * @param EE_Question_Form_Input $QFI
1234
	 *
1235
	 * @return EE_Question_Form_Input
1236
	 */
1237
	protected static function _load_specialized_dropdowns( $QFI ) {
1238
		switch( $QFI->get( 'QST_type' ) ) {
1239
			case 'STATE' :
1240
				$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 1246 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
			case 'COUNTRY' :
1243
				$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 1246 which is incompatible with the return type documented by EEH_Form_Fields::_load_specialized_dropdowns of type EE_Question_Form_Input.
Loading history...
1244
				break;
1245
		}
1246
		return $QFI;
1247
	}
1248
1249
1250
1251
	/**
1252
	 *    generate_state_dropdown
1253
	 * @param array $QST
1254
	 * @param bool  $get_all
1255
	 * @return array
1256
	 */
1257
	public static function generate_state_dropdown( $QST, $get_all = FALSE ){
1258
		$states = $get_all ? EEM_State::instance()->get_all_states() : EEM_State::instance()->get_all_states_of_active_countries();
1259
		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...
1260
			$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...
1261
			// if multiple countries, we'll create option groups within the dropdown
1262
			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...
1263
				if ( $state instanceof EE_State ) {
1264
					$QSO = EE_Question_Option::new_instance ( array (
1265
						'QSO_value' => $state->ID(),
1266
						'QSO_desc' => $state->name(),
1267
						'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...
1268
						'QSO_deleted' => FALSE
1269
					));
1270
					// set option group
1271
					$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...
1272
					// add option to question
1273
					$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...
1274
				}
1275
			}
1276
		}
1277
		return $QST;
1278
	}
1279
1280
1281
1282
	/**
1283
	 *    generate_country_dropdown
1284
	 * @param      $QST
1285
	 * @param bool $get_all
1286
	 * @internal param array $question
1287
	 * @return array
1288
	 */
1289
	public static function generate_country_dropdown( $QST, $get_all = FALSE ){
1290
		$countries = $get_all ? EEM_Country::instance()->get_all_countries() : EEM_Country::instance()->get_all_active_countries();
1291
		if ( $countries && count( $countries ) != count( $QST->options() ) ) {
1292
			$QST->set( 'QST_type', 'DROPDOWN' );
1293
			// now add countries
1294
			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...
1295
				if ( $country instanceof EE_Country ) {
1296
					$QSO = EE_Question_Option::new_instance ( array (
1297
						'QSO_value' => $country->ID(),
1298
						'QSO_desc' => $country->name(),
1299
						'QST_ID' => $QST->get( 'QST_ID' ),
1300
						'QSO_deleted' => FALSE
1301
					));
1302
					$QST->add_temp_option( $QSO );
1303
				}
1304
			}
1305
		}
1306
		return $QST;
1307
	}
1308
1309
1310
1311
1312
1313
	/**
1314
	 * 	generates options for a month dropdown selector with numbers from 01 to 12
1315
	 * 	@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...
1316
	 */
1317
	public static function two_digit_months_dropdown_options() {
1318
		$options = array();
1319 View Code Duplication
		for ( $x = 1; $x <= 12; $x++ ) {
1320
			$mm = str_pad( $x, 2, '0', STR_PAD_LEFT );
1321
			$options[ (string)$mm ] = (string)$mm;
1322
		}
1323
		return EEH_Form_Fields::prep_answer_options( $options );
1324
	}
1325
1326
1327
1328
1329
1330
	/**
1331
	 * 	generates a year dropdown selector with numbers for the next ten years
1332
	 * 	@return object
1333
	 */
1334
	public static function next_decade_two_digit_year_dropdown_options() {
1335
		$options = array();
1336
		$current_year = date('y');
1337
		$next_decade = $current_year + 10;
1338 View Code Duplication
		for ( $x = $current_year; $x <= $next_decade; $x++ ) {
1339
			$yy = str_pad( $x, 2, '0', STR_PAD_LEFT );
1340
			$options[ (string)$yy ] = (string)$yy;
1341
		}
1342
		return EEH_Form_Fields::prep_answer_options( $options );
1343
	}
1344
1345
1346
1347
1348
1349
	/**
1350
	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for list table filter.
1351
	 * @param  string  $cur_date     any currently selected date can be entered here.
1352
	 * @param  string  $status       Registration status
1353
	 * @param  integer $evt_category Event Category ID if the Event Category filter is selected
1354
	 * @return string                html
1355
	 */
1356
	public static function generate_registration_months_dropdown( $cur_date = '', $status = '', $evt_category = 0 ) {
1357
		$_where = array();
1358
		if ( !empty( $status ) ) {
1359
			$_where['STS_ID'] = $status;
1360
		}
1361
1362
		if ( $evt_category > 0 ) {
1363
			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1364
		}
1365
1366
		$regdtts = EEM_Registration::instance()->get_reg_months_and_years( $_where );
1367
1368
		//setup vals for select input helper
1369
		$options = array(
1370
			0 => array(
1371
				'text' => __('Select a Month/Year', 'event_espresso'),
1372
				'id' => ''
1373
				)
1374
			);
1375
1376
		foreach ( $regdtts as $regdtt ) {
1377
			$date = $regdtt->reg_month. ' ' . $regdtt->reg_year;
1378
			$options[] = array(
1379
				'text' => $date,
1380
				'id' => $date
1381
				);
1382
		}
1383
1384
		return self::select_input('month_range', $options, $cur_date, '', 'wide' );
1385
	}
1386
1387
1388
1389
	/**
1390
	 * generates a month/year dropdown selector for all events matching the given criteria
1391
	 * Typically used for list table filter
1392
	 * @param  string $cur_date          any currently selected date can be entered here.
1393
	 * @param  string $status            "view" (i.e. all, today, month, draft)
1394
	 * @param  int    $evt_category      category event belongs to
1395
	 * @param  string $evt_active_status "upcoming", "expired", "active", or "inactive"
1396
	 * @return string                    html
1397
	 */
1398
	public static function generate_event_months_dropdown( $cur_date = '', $status = NULL, $evt_category = NULL, $evt_active_status = NULL ) {
1399
		//determine what post_status our condition will have for the query.
1400
		switch ( $status ) {
1401
			case 'month' :
1402
			case 'today' :
1403
			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...
1404
			case 'all' :
1405
				$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...
1406
				break;
1407
1408
			case 'draft' :
1409
				$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...
1410
1411
			default :
1412
				$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...
1413
		}
1414
1415
		//categories?
1416
1417
1418
		if ( !empty ( $evt_category ) ) {
1419
			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1420
			$where['Event.Term_Taxonomy.term_id'] = $evt_category;
1421
		}
1422
1423
1424
//		$where['DTT_is_primary'] = 1;
1425
1426
		$DTTS = EE_Registry::instance()->load_model('Datetime')->get_dtt_months_and_years($where, $evt_active_status );
0 ignored issues
show
Bug introduced by
The method get_dtt_months_and_years cannot be called on \EE_Registry::instance()->load_model('Datetime') (of type boolean).

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