Completed
Branch FET-8284-automagic-dependency-... (a299cf)
by
unknown
1189:26 queued 1175:37
created

EEH_Form_Fields   F

Complexity

Total Complexity 284

Size/Duplication

Total Lines 1472
Duplicated Lines 3.94 %

Coupling/Cohesion

Components 2
Dependencies 16

Importance

Changes 3
Bugs 0 Features 0
Metric Value
c 3
b 0
f 0
dl 58
loc 1472
rs 0.6314
wmc 284
lcom 2
cbo 16

32 Methods

Rating   Name   Duplication   Size   Complexity  
F get_form_fields() 0 131 28
D text() 0 27 9
F select() 3 43 18
A _generate_select_option_group() 0 8 2
A _generate_select_option() 0 7 4
A prep_option_value() 0 3 1
A prep_required() 0 7 2
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 textarea() 0 31 10
F radio() 3 52 23
F checkbox() 3 61 21
D datepicker() 0 32 9
A remove_label_keep_required_msg() 0 3 1
A hidden_input() 0 4 2
A prep_question() 0 14 1
A prep_answer() 0 8 4
B prep_answer_options() 0 20 10
C get_label_size_class() 0 28 8
B _load_system_dropdowns() 0 18 5
A _load_specialized_dropdowns() 0 11 3
B generate_state_dropdown() 0 22 6
B generate_country_dropdown() 0 19 6
A two_digit_months_dropdown_options() 4 8 2
A next_decade_two_digit_year_dropdown_options() 4 10 2
B generate_registration_months_dropdown() 0 30 4
B generate_event_months_dropdown() 0 53 8
A generate_event_category_dropdown() 0 19 2
B submit_button() 0 17 6

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
 *
16
 * ------------------------------------------------------------------------
17
 *
18
 * EEH_Form_Fields
19
 *
20
 * This is a helper utility class for taking in an array of form field arguments and spitting out the relevant html formatted form fields.
21
 *
22
 * @package		Event Espresso
23
 * @subpackage	/helper/EEH_Form_Fields.helper.php
24
 * @author		Darren Ethier, Brent Christensen
25
 *
26
 * ------------------------------------------------------------------------
27
 */
28
29
30
31
32
class EEH_Form_Fields {
33
34
35
	/**
36
	 *  Generates HTML for the forms used on admin pages
37
	 *
38
	 *
39
	 * 	@static
40
	 * 	@access public
41
	 * 	@param	array $input_vars - array of input field details
42
	 * 	format:
43
	 * 	$template_form_fields['field-id'] = array(
44
	 * 		'name' => 'name_attribute',
45
	 * 		'label' => __('Field Label', 'event_espresso'), //or false
46
	 * 		'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden', 'checkbox', 'wp_editor'
47
	 * 		'type' => 'int', //what "type" the value is (i.e. string, int etc)
48
	 * 		'required' => false, //boolean for whether the field is required
49
	 * 		'validation' => true, //boolean, whether to validate the field (todo)
50
	 * 		'value' => 'some_value_for_field', //what value is used for field
51
	 * 		'format' => '%d', //what format the value is (%d, %f, or %s)
52
	 * 		'db-col' => 'column_in_db' //used to indicate which column the field corresponds with in the db
53
	 * 		'options' => optiona, optionb || array('value' => 'label', '') //if the input type is "select", this allows you to set the args for the different <option> tags.
54
	 * 		'tabindex' => 1 //this allows you to set the tabindex for the field.
55
	 *      'append_content' => '' //this allows you to send in html content to append to the field.
56
	 * 	)
57
	 * 	@param	array $id - used for defining unique identifiers for the form.
58
	 * 	@return string
59
	 * 	@todo: at some point we can break this down into other static methods to abstract it a bit better.
60
	 */
61
	static public function get_form_fields( $input_vars = array(), $id = FALSE ) {
62
63
		if ( empty($input_vars) ) {
64
			EE_Error::add_error( __('missing required variables for the form field generator', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
65
			return FALSE;
66
		}
67
68
		// if you don't behave - this is what you're gonna get !!!
69
		$close = true;
70
		$output = '<ul>'; //this is for using built-in wp styles... watch carefully...
71
72
		// cycle thru inputs
73
		foreach ($input_vars as $input_key => $input_value) {
74
75
			$defaults = array(
76
				'name' => $input_key,
77
				'label' => __('No label', 'event_espresso'),
78
				'input' => 'hidden',
79
				'type' => 'int',
80
				'required' => FALSE,
81
				'validation' => TRUE,
82
				'value' => 'some_value_for_field',
83
				'format' => '%d',
84
				'db-col' => 'column_in_db',
85
				'options' => array(),
86
				'tabindex' => '',
87
				'append_content' => ''
88
				);
89
90
			$input_value = wp_parse_args( $input_value, $defaults );
91
92
			// required fields get a *
93
			$required = isset($input_value['required']) && $input_value['required'] ? ' <span>*</span>: ' : ': ';
94
			// and the css class "required"
95
			$css_class = isset( $input_value['css_class'] ) ? $input_value['css_class'] : '';
96
			$styles = $input_value['required'] ? 'required ' . $css_class : $css_class;
97
98
			$field_id = ($id) ? $id . '-' . $input_key : $input_key;
99
			$tabindex = !empty($input_value['tabindex']) ? ' tabindex="' . $input_value['tabindex'] . '"' : '';
100
101
			//rows or cols?
102
			$rows = isset($input_value['rows'] ) ? $input_value['rows'] : '10';
103
			$cols = isset($input_value['cols'] ) ? $input_value['cols'] : '80';
104
105
			//any content?
106
			$append_content = $input_value['append_content'];
107
108
			$output .= (!$close) ? '<ul>' : '';
109
			$output .= '<li>';
110
111
			// what type of input are we dealing with ?
112
			switch ($input_value['input']) {
113
114
				// text inputs
115
				case 'text' :
116
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
117
					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" class="' . $styles . '" type="text" value="' . $input_value['value'] . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
118
					break;
119
120
				// dropdowns
121
				case 'select' :
122
123
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
124
					$output .= "\n\t\t\t" . '<select id="' . $field_id . '" class="' . $styles . '" name="' . $input_value['name'] . '"' . $tabindex . '>';
125
126
					if (is_array($input_value['options'])) {
127
						$options = $input_value['options'];
128
					} else {
129
						$options = explode(',', $input_value['options']);
130
					}
131
132
					foreach ($options as $key => $value) {
133
						$selected = isset( $input_value['value'] ) && $input_value['value'] == $key ? 'selected=selected' : '';
134
						//$key = str_replace( ' ', '_', sanitize_key( $value ));
135
						$output .= "\n\t\t\t\t" . '<option '. $selected . ' value="' . $key . '">' . $value . '</option>';
136
					}
137
					$output .= "\n\t\t\t" . '</select>';
138
139
					break;
140
141
				case 'textarea' :
142
143
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
144
					$output .= "\n\t\t\t" . '<textarea id="' . $field_id . '" class="' . $styles . '" rows="'.$rows.'" cols="'.$cols.'" name="' . $input_value['name'] . '"' . $tabindex . '>' . $input_value['value'] . '</textarea>';
145
					break;
146
147
				case 'hidden' :
148
					$close = false;
149
					$output .= "</li></ul>";
150
					$output .= "\n\t\t\t" . '<input id="' . $field_id . '" type="hidden" name="' . $input_value['name'] . '" value="' . $input_value['value'] . '">';
151
					break;
152
153
				case 'checkbox' :
154
					$checked = ( $input_value['value'] == 1 ) ? 'checked="checked"' : '';
155
					$output .= "\n\t\t\t" . '<label for="' . $field_id . '">' . $input_value['label'] . $required . '</label>';
156
					$output .= "\n\t\t\t" . '<input id="' . $field_id. '" type="checkbox" name="' . $input_value['name'] . '" value="1"' . $checked . $tabindex . ' />';
157
					break;
158
159
				case 'wp_editor' :
160
					$close = false;
161
					$editor_settings = array(
162
						'textarea_name' => $input_value['name'],
163
						'textarea_rows' => $rows,
164
						'editor_class' => $styles,
165
						'tabindex' => $input_value['tabindex']
166
					);
167
					$output .= '</li>';
168
					$output .= '</ul>';
169
					$output .= '<h4>' . $input_value['label'] . '</h4>';
170
					if ( $append_content ) {
171
						$output .= $append_content;
172
					}
173
					ob_start();
174
					wp_editor( $input_value['value'], $field_id, $editor_settings);
175
					$editor = ob_get_contents();
176
					ob_end_clean();
177
					$output .= $editor;
178
					break;
179
180
				}
181
				if ( $append_content && $input_value['input'] !== 'wp_editor' ) {
182
					$output .= $append_content;
183
				}
184
				$output .= ($close) ? '</li>' : '';
185
186
187
		} // end foreach( $input_vars as $input_key => $input_value )
188
		$output .= ($close) ? '</ul>' : '';
189
190
		return $output;
191
	}
192
193
	/**
194
	 * form_fields_array
195
	 * This utility function assembles form fields from a given structured array with field information.
196
	 * //TODO: This is an alternate generator that we may want to use instead.
197
	 *
198
	 * @param  array $fields structured array of fields to assemble in the following format:
199
	 * [field_name] => array(
200
	 * 		['label'] => 'label for field',
201
	 * 		['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
202
	 * 		['extra_desc'] => 'extra description for the field', //optional
203
	 * 		['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults to text
204
	 * 		['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)
205
	 * 		['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
206
	 * 		['class'] => 'name-of-class(es)-for-input',
207
	 * 		['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.
208
	 * 		['id'] => 'css-id-for-input') //defaults to 'field_name'
209
	 * 		['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.
210
	 * 		['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types such as textarea to indicate cols/rows.
211
	 * 		['tabindex'] => '' //this allows you to set the tabindex for the field.
212
	 * 		['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally contain an array of arguments for the editor setup.
213
	 *
214
	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
215
	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
216
	 */
217
	static public function get_form_fields_array($fields) {
218
219
		$form_fields = array();
220
		$fields = (array) $fields;
221
222
		foreach ( $fields as $field_name => $field_atts ) {
223
			//defaults:
224
			$defaults = array(
225
				'label' => '',
226
				'labels' => '',
227
				'extra_desc' => '',
228
				'type' => 'text',
229
				'value' => '',
230
				'default' => '',
231
				'class' => '',
232
				'classes' => '',
233
				'id' => $field_name,
234
				'unique_id' => '',
235
				'dimensions' => array('10', '5'),
236
				'tabindex' => '',
237
				'wpeditor_args' => array()
238
				);
239
			// merge defaults with passed arguments
240
			$_fields = wp_parse_args( $field_atts, $defaults);
241
			extract( $_fields );
242
			// generate label
243
			$label = empty($label) ? '' : '<label for="' . $id . '">' . $label . '</label>';
244
			// generate field name
245
			$f_name = !empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
246
247
			//tabindex
248
			$tabindex_str = !empty( $tabindex ) ? ' tabindex="' . $tabindex . '"' : '';
249
250
			//we determine what we're building based on the type
251
			switch ( $type ) {
252
253
				case 'textarea' :
254
						$fld = '<textarea id="' . $id . '" class="' . $class . '" rows="' . $dimensions[1] . '" cols="' . $dimensions[0] . '" name="' . $f_name . '"' . $tabindex_str . '>' . $value . '</textarea>';
255
						$fld .= $extra_desc;
256
					break;
257
258 View Code Duplication
				case 'checkbox' :
259
						$c_input = '';
260
						if ( is_array($value) ) {
261
							foreach ( $value as $key => $val ) {
262
								$c_id = $field_name . '_' . $value;
263
								$c_class = isset($classes[$key]) ? ' class="' . $classes[$key] . '" ' : '';
264
								$c_label = isset($labels[$key]) ? '<label for="' . $c_id . '">' . $labels[$key] . '</label>' : '';
265
								$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
266
								$c_input .= '<input name="' . $f_name . '[]" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
267
							}
268
							$fld = $c_input;
269
						} else {
270
							$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
271
							$fld = '<input name="'. $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
272
						}
273
					break;
274
275 View Code Duplication
				case 'radio' :
276
						$c_input = '';
277
						if ( is_array($value) ) {
278
							foreach ( $value as $key => $val ) {
279
								$c_id = $field_name . '_' . $value;
280
								$c_class = isset($classes[$key]) ? 'class="' . $classes[$key] . '" ' : '';
281
								$c_label = isset($labels[$key]) ? '<label for="' . $c_id . '">' . $labels[$key] . '</label>' : '';
282
								$checked = !empty($default) && $default == $val ? ' checked="checked" ' : '';
283
								$c_input .= '<input name="' . $f_name . '" type="checkbox" id="' . $c_id . '"' . $c_class . 'value="' . $val . '"' . $checked . $tabindex_str . ' />' . "\n" . $c_label;
284
							}
285
							$fld = $c_input;
286
						} else {
287
							$checked = !empty($default) && $default == $val ? 'checked="checked" ' : '';
288
							$fld = '<input name="'. $f_name . '" type="checkbox" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $checked . $tabindex_str . ' />' . "\n";
289
						}
290
					break;
291
292
				case 'hidden' :
293
						$fld = '<input name="' . $f_name . '" type="hidden" id="' . $id . '" class="' . $class . '" value="' . $value . '" />' . "\n";
294
					break;
295
296
				case 'select' :
297
						$fld = '<select name="' . $f_name . '" class="' . $class . '" id="' . $id . '"' . $tabindex_str . '>' . "\n";
298
						foreach ( $value as $key => $val ) {
299
							$checked = !empty($default) && $default == $val ? ' selected="selected"' : '';
300
							$fld .= "\t" . '<option value="' . $val . '"' . $checked . '>' . $labels[$key] . '</option>' . "\n";
301
						}
302
						$fld .= '</select>';
303
					break;
304
305
				case 'wp_editor' :
306
						$editor_settings = array(
307
							'textarea_name' => $f_name,
308
							'textarea_rows' => $dimensions[1],
309
							'editor_class' => $class,
310
							'tabindex' => $tabindex
311
							);
312
						$editor_settings = array_merge( $wpeditor_args, $editor_settings );
313
						ob_start();
314
						wp_editor( $value, $id, $editor_settings );
315
						$editor = ob_get_contents();
316
						ob_end_clean();
317
						$fld = $editor;
318
					break;
319
320
				default : //'text fields'
321
						$fld = '<input name="' . $f_name . '" type="text" id="' . $id . '" class="' . $class . '" value="' . $value . '"' . $tabindex_str . ' />' . "\n";
322
						$fld .= $extra_desc;
323
324
			}
325
326
			$form_fields[ $field_name ] = array( 'label' => $label, 'field' => $fld );
327
		}
328
329
		return $form_fields;
330
	}
331
332
333
334
335
336
337
	/**
338
	 * espresso admin page select_input
339
	 * Turns an array into a select fields
340
	 *
341
	 * @static
342
	 * @access public
343
	 * @param  string  $name       field name
344
	 * @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)
345
	 * 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
346
	 * 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.
347
	 * @param  string  $default    default value
348
	 * @param  string  $parameters extra paramaters
349
	 * @param  string  $class      css class
350
	 * @param  boolean $autosize   whether to autosize the select or not
351
	 * @return string              html string for the select input
352
	 */
353
	static public function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true) {
354
		//if $values was submitted in the wrong format, convert it over
355
		if(!empty($values) && (!array_key_exists(0,$values) || !is_array($values[0]))){
356
			$converted_values=array();
357
			foreach($values as $id=>$text){
358
				$converted_values[]=array('id'=>$id,'text'=>$text);
359
			}
360
			$values=$converted_values;
361
		}
362
		//load formatter helper
363
		EE_Registry::instance()->load_helper( 'Formatter' );
364
		//EE_Registry::instance()->load_helper( 'Formatter' );
365
366
		$field = '<select id="' . EEH_Formatter::ee_tep_output_string($name) . '" name="' . EEH_Formatter::ee_tep_output_string($name) . '"';
367
		//Debug
368
		//EEH_Debug_Tools::printr( $values, '$values  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
369
		if ( EEH_Formatter::ee_tep_not_null($parameters))
370
			$field .= ' ' . $parameters;
371
		if ($autosize) {
372
			$size = 'med';
373
			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
374
				if ($values[$ii]['text']) {
375
					if (strlen($values[$ii]['text']) > 5)
376
						$size = 'wide';
377
				}
378
			}
379
		} else {
380
			$size = '';
381
		}
382
383
		$field .= ' class="' . $class . ' ' . $size . '">';
384
385
		if (empty($default) && isset($GLOBALS[$name]))
386
			$default = stripslashes($GLOBALS[$name]);
387
388
389
		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
390
			$field .= '<option value="' . $values[$i]['id'] . '"';
391
			if ($default == $values[$i]['id']) {
392
				$field .= ' selected = "selected"';
393
			}
394
			if ( isset( $values[$i]['class'] ) ) {
395
				$field .= ' class="' . $values[$i]['class'] . '"';
396
			}
397
			$field .= '>' . $values[$i]['text'] . '</option>';
398
		}
399
		$field .= '</select>';
400
401
		return $field;
402
	}
403
404
405
406
407
408
409
	/**
410
	 * generate_question_groups_html
411
 	 *
412
	 * @param string $question_groups
413
	 * @return string HTML
414
	 */
415
	static function generate_question_groups_html( $question_groups = array(), $group_wrapper = 'fieldset' ) {
416
417
		$html = '';
418
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
419
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
420
421
		if ( ! empty( $question_groups )) {
422
			//EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
423
			// loop thru question groups
424
			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...
425
				// check that questions exist
426
				if ( ! empty( $QSG['QSG_questions'] )) {
427
					// use fieldsets
428
					$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG['QSG_identifier'] . '">';
429
					// group_name
430
					$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>' : '';
431
					// group_desc
432
					$html .= $QSG['QSG_show_group_desc'] && ! empty( $QSG['QSG_desc'] ) ? '<div class="espresso-question-group-desc-pg">' . self::prep_answer( $QSG['QSG_desc'] ) . '</div>' : '';
433
434
					$html .= $before_question_group_questions;
435
					// loop thru questions
436
					foreach ( $QSG['QSG_questions'] as $question ) {
437
//						EEH_Debug_Tools::printr( $question, '$question  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
438
						$QFI = new EE_Question_Form_Input(
439
							$question['qst_obj'],
440
							$question['ans_obj'],
441
							$question
442
						);
443
						$html .= self::generate_form_input( $QFI );
444
					}
445
					$html .= $after_question_group_questions;
446
					$html .= "\n\t" . '</' . $group_wrapper . '>';
447
				}
448
			}
449
		}
450
451
		return $html;
452
453
	}
454
455
456
457
	/**
458
	 * generate_question_groups_html
459
	 *
460
	 * @param array         $question_groups
461
	 * @param array        $q_meta
462
	 * @param bool         $from_admin
463
	 * @param string       $group_wrapper
464
	 * @return string HTML
465
	 */
466
	static function generate_question_groups_html2( $question_groups = array(), $q_meta = array(), 	$from_admin = FALSE, $group_wrapper = 'fieldset' ) {
467
468
		$html = '';
469
		$before_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '' );
470
		$after_question_group_questions = apply_filters( 'FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '' );
471
472
		$default_q_meta = array(
473
				'att_nmbr' => 1,
474
				'ticket_id' => '',
475
				'input_name' => '',
476
				'input_id' => '',
477
				'input_class' => ''
478
		);
479
		$q_meta = array_merge( $default_q_meta, $q_meta );
480
		//EEH_Debug_Tools::printr( $q_meta, '$q_meta  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
481
482
		if ( ! empty( $question_groups )) {
483
//			EEH_Debug_Tools::printr( $question_groups, '$question_groups  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
484
			// loop thru question groups
485
			foreach ( $question_groups as $QSG ) {
486
				if ( $QSG instanceof EE_Question_Group ) {
487
					// check that questions exist
488
489
					$where = array( 'QST_deleted' => 0 );
490
					if ( ! $from_admin ) {
491
						$where['QST_admin_only'] = 0;
492
					}
493
					$questions = $QSG->questions( array( $where, 'order_by' => array( 'Question_Group_Question.QGQ_order' => 'ASC' )));
494
					if ( ! empty( $questions )) {
495
						// use fieldsets
496
						$html .= "\n\t" . '<' . $group_wrapper . ' class="espresso-question-group-wrap" id="' . $QSG->get( 'QSG_identifier' ) . '">';
497
						// group_name
498
						if ( $QSG->show_group_name() ) {
499
							$html .=  "\n\t\t" . '<h5 class="espresso-question-group-title-h5 section-title">' . $QSG->get_pretty( 'QSG_name' ) . '</h5>';
500
						}
501
						// group_desc
502
						if ( $QSG->show_group_desc() ) {
503
							$html .=  '<div class="espresso-question-group-desc-pg">' . $QSG->get_pretty( 'QSG_desc'  ) . '</div>';
504
						}
505
506
						$html .= $before_question_group_questions;
507
						// loop thru questions
508
						foreach ( $questions as $QST ) {
509
							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
510
511
							$answer = NULL;
512
513
							if (  isset( $_GET['qstn'] ) && isset( $q_meta['input_id'] ) && isset( $q_meta['att_nmbr'] )) {
514
								// check for answer in $_GET in case we are reprocessing a form after an error
515
								if ( isset( $_GET['qstn'][ $q_meta['input_id'] ][ $qstn_id ] )) {
516
									$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 ] );
517
								}
518
							} else if ( isset( $q_meta['attendee'] ) && $q_meta['attendee'] ) {
519
								//attendee data from the session
520
								$answer = isset( $q_meta['attendee'][ $qstn_id ] ) ? $q_meta['attendee'][ $qstn_id ] : NULL;
521
							}
522
523
524
525
							$QFI = new EE_Question_Form_Input(
526
									$QST,
527
									EE_Answer::new_instance ( array(
528
											'ANS_ID'=> 0,
529
											'QST_ID'=> 0,
530
											'REG_ID'=> 0,
531
											'ANS_value'=> $answer
532
									)),
533
									$q_meta
534
							);
535
							//EEH_Debug_Tools::printr( $QFI, '$QFI  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span>', 'auto' );
536
							$html .= self::generate_form_input( $QFI );
537
						}
538
						$html .= $after_question_group_questions;
539
						$html .= "\n\t" . '</' . $group_wrapper . '>';
540
					}
541
				}
542
			}
543
		}
544
		return $html;
545
546
	}
547
548
549
550
551
552
553
	/**
554
	 * generate_form_input
555
 	 *
556
	 * @param EE_Question_Form_Input $QFI
557
	 * @return string HTML
558
	 */
559
	static function generate_form_input( EE_Question_Form_Input $QFI ) {
560
		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...
561
			return '';
562
		}
563
564
		$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...
565
		$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...
566
567
		//we also need to verify
568
569
		$display_text = $QFI->get('QST_display_text');
570
		$input_name = $QFI->get('QST_input_name');
571
		$answer = EE_Registry::instance()->REQ->is_set( $input_name ) ? EE_Registry::instance()->REQ->get( $input_name ) : $QFI->get('ANS_value');
572
		$input_id = $QFI->get('QST_input_id');
573
		$input_class = $QFI->get('QST_input_class');
574
//		$disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
575
		$disabled = $QFI->get('QST_disabled') ? TRUE : FALSE;
576
		$required_label = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>' );
577
		$QST_required = $QFI->get('QST_required');
578
		$required = $QST_required ? array( 'label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required ) : array();
579
		$use_html_entities = $QFI->get_meta( 'htmlentities' );
580
		$required_text = $QFI->get('QST_required_text') != '' ? $QFI->get('QST_required_text') : __( 'This field is required', 'event_espresso' );
581
		$required_text = $QST_required ? "\n\t\t\t" . '<div class="required-text hidden">' . self::prep_answer( $required_text, $use_html_entities ) . '</div>' : '';
582
		$label_class = 'espresso-form-input-lbl';
583
		$QST_options = $QFI->options(true,$answer);
584
		$options = is_array( $QST_options ) ? self::prep_answer_options( $QST_options ) : array();
585
		$system_ID = $QFI->get('QST_system');
586
		$label_b4 = $QFI->get_meta( 'label_b4' );
587
		$use_desc_4_label = $QFI->get_meta( 'use_desc_4_label' );
588
589
590
		switch ( $QFI->get('QST_type') ){
591
592
			case 'TEXTAREA' :
593
					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...
594
				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...
595
596 View Code Duplication
			case 'DROPDOWN' :
597
					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...
598
				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...
599
600
601 View Code Duplication
			case 'RADIO_BTN' :
602
					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 );
603
				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...
604
605 View Code Duplication
			case 'CHECKBOX' :
606
					return EEH_Form_Fields::checkbox( $display_text, $answer, $options, $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...
607
				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...
608
609
			case 'DATE' :
610
					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...
611
				break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

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

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

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

Loading history...
612
613
			case 'TEXT' :
614
			default:
615
					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...
616
				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...
617
618
		}
619
620
621
	}
622
623
624
625
626
627
628
	/**
629
	 * generates HTML for a form text input
630
 	 *
631
	 * @param string $question 	label content
632
	 * @param string $answer 		form input value attribute
633
	 * @param string $name 			form input name attribute
634
	 * @param string $id 				form input css id attribute
635
	 * @param string $class 			form input css class attribute
636
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
637
	 * @param string $label_class 	css class attribute for the label
638
	 * @param string $disabled 		disabled="disabled" or null
639
	 * @return string HTML
640
	 */
641
	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 ) {
642
		// need these
643
		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...
644
			return NULL;
645
		}
646
		// prep the answer
647
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
648
		// prep the required array
649
		$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...
650
		// set disabled tag
651
		$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...
652
		// ya gots ta have style man!!!
653
		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
654
		$class = empty( $class ) ? $txt_class : $class;
655
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
656
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
657
658
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
659
		// filter label but ensure required text comes before it
660
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
661
662
		$input_html = "\n\t\t\t" . '<input type="text" name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" value="' . $answer . '"  title="' . esc_attr( $required['msg'] ) . '" ' . $disabled .' ' . $extra . '/>';
663
664
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
665
		return  $label_html . $input_html;
666
667
	}
668
669
670
671
672
673
	/**
674
	 * generates HTML for a form textarea
675
 	 *
676
	 * @param string $question 		label content
677
	 * @param string $answer 		form input value attribute
678
	 * @param string $name 			form input name attribute
679
	 * @param string $id 				form input css id attribute
680
	 * @param string $class 			form input css class attribute
681
	 * @param array $dimensions	array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
682
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
683
	 * @param string $label_class 	css class attribute for the label
684
	 * @param string $disabled 		disabled="disabled" or null
685
	 * @return string HTML
686
	 */
687
	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 ) {
688
		// need these
689
		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...
690
			return NULL;
691
		}
692
		// prep the answer
693
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
694
		// prep the required array
695
		$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...
696
		// make sure $dimensions is an array
697
		$dimensions = is_array( $dimensions ) ? $dimensions : array();
698
		// and set some defaults
699
		$dimensions = array_merge( array( 'rows' => 3, 'cols' => 40 ), $dimensions );
700
		// set disabled tag
701
		$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...
702
		// ya gots ta have style man!!!
703
		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
704
		$class = empty( $class ) ? $txt_class : $class;
705
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
706
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
707
708
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
709
		// filter label but ensure required text comes before it
710
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
711
712
		$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>';
713
714
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
715
		return  $label_html . $input_html;
716
717
	}
718
719
720
721
722
723
724
	/**
725
	 * generates HTML for a form select input
726
 	 *
727
	 * @param string $question 		label content
728
	 * @param string $answer 		form input value attribute
729
	 * @param array $options			array of answer options where array key = option value and array value = option display text
730
	 * @param string $name 			form input name attribute
731
	 * @param string $id 				form input css id attribute
732
	 * @param string $class 			form input css class attribute
733
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
734
	 * @param string $label_class 	css class attribute for the label
735
	 * @param string $disabled 		disabled="disabled" or null
736
	 * @return string HTML
737
	 */
738
	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 ) {
739
740
		// need these
741 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...
742
			return NULL;
743
		}
744
		// prep the answer
745
		$answer = is_array( $answer ) ? self::prep_answer( array_shift( $answer )) : self::prep_answer( $answer, $use_html_entities );
746
		// prep the required array
747
		$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...
748
		// set disabled tag
749
		$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...
750
		// ya gots ta have style man!!!
751
		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
752
		$class = empty( $class ) ? $txt_class : $class;
753
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
754
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
755
756
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
757
		// filter label but ensure required text comes before it
758
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
759
760
		$input_html = "\n\t\t\t" . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" title="' . esc_attr( $required['msg'] ) . '"' . $disabled . ' ' . $extra . '>';
761
		// recursively count array elements, to determine total number of options
762
		$only_option = count( $options, 1 ) == 1 ? TRUE : FALSE;
763
		if ( ! $only_option ) {
764
			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
765
			$selected = $answer === NULL ? ' selected="selected"' : '';
766
			$input_html .= $add_please_select_option ? "\n\t\t\t\t" . '<option value=""' . $selected . '>' . __(' - please select - ', 'event_espresso') . '</option>' : '';
767
		}
768
		foreach ( $options as $key => $value ) {
769
			// if value is an array, then create option groups, else create regular ol' options
770
			$input_html .= is_array( $value ) ? self::_generate_select_option_group( $key, $value, $answer ) : self::_generate_select_option( $value->value(), $value->desc(), $answer, $only_option );
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...
771
		}
772
773
		$input_html .= "\n\t\t\t" . '</select>';
774
775
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__select__before_end_wrapper', $input_html, $question, $answer, $name, $id, $class, $system_ID );
776
777
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
778
		return  $label_html . $input_html;
779
780
	}
781
782
783
784
	/**
785
	 * 	_generate_select_option_group
786
	 *
787
	 * 	if  $value for a select box is an array, then the key will be used as the optgroup label
788
	 * 	and the value array will be looped thru and the elements sent to _generate_select_option
789
	 *
790
	 * @param mixed $opt_group
791
	 * @param mixed $QSOs
792
	 * @param mixed $answer
793
	 * @return string
794
	 */
795
	private static function _generate_select_option_group( $opt_group, $QSOs, $answer ){
796
		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value( $opt_group ) . '">';
797
		foreach ( $QSOs as $QSO ) {
798
			$html .= self::_generate_select_option( $QSO->value(), $QSO->desc(), $answer );
799
		}
800
		$html .= "\n\t\t\t\t" . '</optgroup>';
801
		return $html;
802
	}
803
804
805
806
	/**
807
	 * 	_generate_select_option
808
	 * @param mixed $key
809
	 * @param mixed $value
810
	 * @param mixed $answer
811
	 * @param int $only_option
812
	 * @return string
813
	 */
814
	private static function _generate_select_option( $key, $value, $answer, $only_option = FALSE ){
815
		$key = self::prep_answer( $key );
816
		$value = self::prep_answer( $value );
817
		$value = ! empty( $value ) ? $value : $key;
818
		$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...
819
		return "\n\t\t\t\t" . '<option value="' . self::prep_option_value( $key ) . '"' . $selected . '> ' . $value . '&nbsp;&nbsp;&nbsp;</option>';
820
	}
821
822
823
824
	/**
825
	 * generates HTML for form radio button inputs
826
	 *
827
	 * @param bool|string $question    label content
828
	 * @param string      $answer      form input value attribute
829
	 * @param array|bool  $options     array of answer options where array key = option value and array value = option display text
830
	 * @param bool|string $name        form input name attribute
831
	 * @param string      $id          form input css id attribute
832
	 * @param string      $class       form input css class attribute
833
	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
834
	 * @param string      $required_text
835
	 * @param string      $label_class css class attribute for the label
836
	 * @param bool|string $disabled    disabled="disabled" or null
837
	 * @param bool        $system_ID
838
	 * @param bool        $use_html_entities
839
	 * @param bool        $label_b4
840
	 * @param bool        $use_desc_4_label
841
	 * @return string HTML
842
	 */
843
	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 ) {
844
		// need these
845 View Code Duplication
		if ( ! $question || ! $name || ! $options || empty( $options ) || ! is_array( $options )) {
846
			return NULL;
847
		}
848
		// prep the answer
849
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
850
		// prep the required array
851
		$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...
852
		// set disabled tag
853
		$disabled = $answer === NULL || ! $disabled  ? '' : ' disabled="disabled"';
854
		// ya gots ta have style man!!!
855
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
856
		$class = ! empty( $class ) ? $class : 'espresso-radio-btn-inp';
857
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
858
859
		$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 843 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...
860
		// filter label but ensure required text comes before it
861
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
862
863
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
864
865
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
866
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
867
868
		foreach ( $options as $OPT ) {
869
			if ( $OPT instanceof EE_Question_Option ) {
870
				$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...
871
				$label = $use_desc_4_label ? $OPT->desc() : $OPT->value();
872
				$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...
873
				$desc = $OPT->desc();//no self::prep_answer
874
				$answer = is_numeric( $value ) && empty( $answer ) ? 0 : $answer;
875
				$checked = (string)$value == (string)$answer ? ' checked="checked"' : '';
876
				$opt = '-' . sanitize_key( $value );
877
878
				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
879
				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
880
				$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
881
				$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 . '/>';
882
				$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span class="espresso-radio-btn-desc">' . $label . '</span>' : '';
883
				$input_html .= "\n\t\t\t\t\t" . '</label>';
884
				$input_html .= $use_desc_4_label ? '' : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
885
				$input_html .= "\n\t\t\t\t" . '</li>';
886
			}
887
		}
888
889
		$input_html .= "\n\t\t\t" . '</ul>';
890
891
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
892
		return  $label_html . $input_html;
893
894
	}
895
896
897
898
899
900
901
	/**
902
	 * generates HTML for form checkbox inputs
903
 	 *
904
	 * @param string $question 		label content
905
	 * @param string $answer 		form input value attribute
906
	 * @param array $options 			array of options where array key = option value and array value = option display text
907
	 * @param string $name 			form input name attribute
908
	 * @param string $id 				form input css id attribute
909
	 * @param string $class 			form input css class attribute
910
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
911
	 * @param string $label_class 	css class attribute for the label
912
	 * @param string $disabled 		disabled="disabled" or null
913
	 * @return string HTML
914
	 */
915
	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 ) {
0 ignored issues
show
Unused Code introduced by
The parameter $use_html_entities 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...
916
		// need these
917 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...
918
			return NULL;
919
		}
920
		$answer = maybe_unserialize( $answer );
921
922
		// prep the answer(s)
923
		$answer = is_array( $answer ) ? $answer : array( sanitize_key( $answer ) => $answer );
924
925
		foreach ( $answer as $key => $value ) {
926
			$key = self::prep_option_value( $key );
927
			$answer[$key] = self::prep_answer( $value );
928
		}
929
930
		// prep the required array
931
		$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...
932
		// set disabled tag
933
		$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...
934
		// ya gots ta have style man!!!
935
		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
936
		$class = empty( $class ) ? 'espresso-radio-btn-inp' : $class;
937
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
938
939
		$label_html = $required_text . "\n\t\t\t" . '<label class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label> ';
940
		// filter label but ensure required text comes before it
941
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
942
943
		$input_html = "\n\t\t\t" . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
944
945
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
946
		$class .= ! empty( $required['class'] ) ? ' ' . $required['class'] : '';
947
948
		foreach ( $options as $OPT ) {
949
			$value = $OPT->value();//self::prep_option_value( $OPT->value() );
950
			$size = self::get_label_size_class(  $OPT->value() . ' ' . $OPT->desc() );
951
			$text = self::prep_answer( $OPT->value() );
952
			$desc = $OPT->desc() ;
953
			$opt = '-' . sanitize_key( $value );
954
955
			$checked = is_array( $answer ) && in_array( $text, $answer ) ? ' checked="checked"' : '';
956
957
			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
958
			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
959
			$input_html .= $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
960
			$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 . '/>';
961
			$input_html .= ! $label_b4  ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
962
 			$input_html .= "\n\t\t\t\t\t" . '</label>';
963
			if ( ! empty( $desc ) && $desc != $text ) {
964
	 			$input_html .= "\n\t\t\t\t\t" . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">' . $desc . '</div>';
965
			}
966
			$input_html .= "\n\t\t\t\t" . '</li>';
967
968
		}
969
970
		$input_html .= "\n\t\t\t" . '</ul>';
971
972
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
973
		return  $label_html . $input_html;
974
975
	}
976
977
978
979
980
981
982
	/**
983
	 * generates HTML for a form datepicker input
984
 	 *
985
	 * @param string $question 	label content
986
	 * @param string $answer 		form input value attribute
987
	 * @param string $name 			form input name attribute
988
	 * @param string $id 				form input css id attribute
989
	 * @param string $class 			form input css class attribute
990
	 * @param array $required 		'label', 'class', and 'msg' - array of values for required "label" content, css required 'class', and required 'msg' attribute
991
	 * @param string $label_class 	css class attribute for the label
992
	 * @param string $disabled 		disabled="disabled" or null
993
	 * @return string HTML
994
	 */
995
	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 ) {
996
		// need these
997
		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...
998
			return NULL;
999
		}
1000
		// prep the answer
1001
		$answer = is_array( $answer ) ? '' : self::prep_answer( $answer, $use_html_entities );
1002
		// prep the required array
1003
		$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...
1004
		// set disabled tag
1005
		$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...
1006
		// ya gots ta have style man!!!
1007
		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1008
		$class = empty( $class ) ? $txt_class : $class;
1009
		$class .= ! empty( $system_ID ) ? ' ' . $system_ID : '';
1010
		$extra = apply_filters( 'FHEE__EEH_Form_Fields__additional_form_field_attributes', '' );
1011
1012
		$label_html = $required_text . "\n\t\t\t" . '<label for="' . $name . '" class="' . $label_class . '">' . self::prep_question( $question ) . $required['label'] . '</label><br/>';
1013
		// filter label but ensure required text comes before it
1014
		$label_html = apply_filters( 'FHEE__EEH_Form_Fields__label_html', $label_html, $required_text );
1015
1016
		$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 . '/>';
1017
1018
		// enqueue scripts
1019
		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 );
1020
		wp_enqueue_style( 'espresso-ui-theme');
1021
		wp_enqueue_script( 'jquery-ui-datepicker' );
1022
1023
		$input_html =  apply_filters( 'FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id );
1024
		return  $label_html . $input_html;
1025
1026
	}
1027
1028
1029
1030
	/**
1031
	 * 	remove_label_keep_required_msg
1032
	 * 	this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1033
	 * 	@access public
1034
	 * 	@return 	string
1035
	 */
1036
	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...
1037
		return $required_text;
1038
	}
1039
1040
1041
1042
1043
1044
	/**
1045
	 * Simply return sthe HTML for a hidden input of the given name and value.
1046
	 * @param string $name
1047
	 * @param string $value
1048
	 * @return string HTML
1049
	 */
1050
	static function hidden_input( $name, $value, $id = '' ){
1051
		$id = ! empty( $id ) ? $id : $name;
1052
		return '<input id="' . $id . '" type="hidden" name="'.$name.'" value="' .  $value . '"/>';
1053
	}
1054
1055
1056
1057
1058
1059
	/**
1060
	 * prep_question
1061
	 * @param string $question
1062
	 * @return string
1063
	 */
1064
	static function prep_question( $question ){
1065
		return $question;
1066
//		$link = '';
1067
//		// does this label have a help link attached ?
1068
//		if ( strpos( $question, '<a ' ) !== FALSE ) {
1069
//			$qbits = explode( '<a ', $question );
1070
//			foreach ( $qbits as $qbit ) {
1071
//				$link = strpos( $qbit, 'title="' ) !== FALSE ? $qbit : $link;
1072
//				$question = strpos( $qbit, 'title="' ) === FALSE ? $qbit : $question;
1073
//			}
1074
//			$link = '<a ' . $link;
1075
//		}
1076
//		return htmlspecialchars( trim( stripslashes( str_replace( '&#039;', "'", $question ))), ENT_QUOTES, 'UTF-8' ) . ' ' . $link;
1077
	}
1078
1079
1080
1081
1082
	/**
1083
	 * 	prep_answer
1084
	 * @param mixed $answer
1085
	 * @return string
1086
	 */
1087
	static function prep_answer( $answer, $use_html_entities = TRUE ){
1088
		//make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired, we want "0".
1089
		if ( is_bool( $answer ) ) {
1090
			$answer = $answer ? 1 : 0;
1091
		}
1092
		$answer = trim( stripslashes( str_replace( '&#039;', "'", $answer )));
1093
		return $use_html_entities ? htmlentities( $answer, ENT_QUOTES, 'UTF-8' ) : $answer;
1094
	}
1095
1096
1097
1098
	/**
1099
	 * 	prep_answer_options
1100
	 * 	@param array $QSOs  array of EE_Question_Option objects
1101
	 * 	@return array
1102
	 */
1103
	public static function prep_answer_options( $QSOs = array() ){
1104
		$prepped_answer_options = array();
1105
		if ( is_array( $QSOs ) && ! empty( $QSOs )) {
1106
			foreach( $QSOs as $key => $QSO ) {
1107
				if ( ! $QSO instanceof EE_Question_Option ) {
1108
					$QSO = EE_Question_Option::new_instance( array(
1109
						'QSO_value' => is_array( $QSO ) && isset( $QSO['id'] ) ? (string)$QSO['id'] : (string)$key,
1110
						'QSO_desc' => is_array( $QSO ) && isset( $QSO['text'] ) ? (string)$QSO['text'] : (string)$QSO
1111
					));
1112
				}
1113
				if ( $QSO->opt_group() ) {
1114
					$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...
1115
				} else {
1116
					$prepped_answer_options[] = $QSO;
1117
				}
1118
			}
1119
		}
1120
//		d( $prepped_answer_options );
1121
		return $prepped_answer_options;
1122
	}
1123
1124
1125
	/**
1126
	 * 	prep_option_value
1127
	 * @param string $option_value
1128
	 * @return string
1129
	 */
1130
	static function prep_option_value( $option_value ){
1131
		return trim( stripslashes( $option_value ));
1132
	}
1133
1134
1135
1136
1137
	/**
1138
	 * 	prep_required
1139
	 * @param string|array 	$required
1140
	 * @return array
1141
	 */
1142
	static function prep_required( $required = array() ){
1143
		// make sure required is an array
1144
		$required = is_array( $required ) ? $required : array();
1145
		// and set some defaults
1146
		$required = array_merge( array( 'label' => '', 'class' => '', 'msg' => '' ), $required );
1147
		return $required;
1148
	}
1149
1150
1151
1152
	/**
1153
	 * 	get_label_size_class
1154
	 * @param string 	$value
1155
	 * @return string
1156
	 */
1157
	static function get_label_size_class( $value = FALSE ){
1158
			if ( $value === FALSE || $value == '' ) {
1159
				return ' class="medium-lbl"';
1160
			}
1161
			// determine length of option value
1162
			$val_size = strlen( $value );
1163
			switch( $val_size ){
1164
				case $val_size < 3 :
1165
					$size =  ' class="nano-lbl"';
1166
					break;
1167
				case $val_size < 6 :
1168
					$size =  ' class="micro-lbl"';
1169
					break;
1170
				case $val_size < 12 :
1171
					$size =  ' class="tiny-lbl"';
1172
					break;
1173
				case $val_size < 25 :
1174
					$size =  ' class="small-lbl"';
1175
					break;
1176
				case $val_size > 100 :
1177
					$size =  ' class="big-lbl"';
1178
					break;
1179
				default:
1180
					$size =  ' class="medium-lbl"';
1181
					break;
1182
			}
1183
		return $size;
1184
	}
1185
1186
1187
1188
1189
	/**
1190
	 * 	_load_system_dropdowns
1191
	 * @param array 	$QFI
1192
	 * @return array
1193
	 */
1194
	private static function _load_system_dropdowns( $QFI ){
1195
		$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...
1196
		switch ( $QST_system ) {
1197
			case 'state' :
1198
				$QFI = self::generate_state_dropdown( $QFI );
1199
				break;
1200
			case 'country' :
1201
				$QFI = self::generate_country_dropdown( $QFI );
1202
				break;
1203
			case 'admin-state' :
1204
				$QFI = self::generate_state_dropdown( $QFI, TRUE );
1205
				break;
1206
			case 'admin-country' :
1207
				$QFI = self::generate_country_dropdown( $QFI, TRUE );
1208
				break;
1209
		}
1210
		return $QFI;
1211
	}
1212
1213
1214
1215
	/**
1216
	 * This preps dropdowns that are specialized.
1217
	 *
1218
	 * @since  4.6.0
1219
	 *
1220
	 * @param EE_Question_Form_Input $QFI
1221
	 *
1222
	 * @return EE_Question_Form_Input
1223
	 */
1224
	protected static function _load_specialized_dropdowns( $QFI ) {
1225
		switch( $QFI->get( 'QST_type' ) ) {
1226
			case 'STATE' :
1227
				$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 1233 which is incompatible with the return type documented by EEH_Form_Fields::_load_specialized_dropdowns of type EE_Question_Form_Input.
Loading history...
1228
				break;
1229
			case 'COUNTRY' :
1230
				$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 1233 which is incompatible with the return type documented by EEH_Form_Fields::_load_specialized_dropdowns of type EE_Question_Form_Input.
Loading history...
1231
				break;
1232
		}
1233
		return $QFI;
1234
	}
1235
1236
1237
1238
	/**
1239
	 *    generate_state_dropdown
1240
	 * @param array $QST
1241
	 * @param bool  $get_all
1242
	 * @return array
1243
	 */
1244
	public static function generate_state_dropdown( $QST, $get_all = FALSE ){
1245
		$states = $get_all ? EEM_State::instance()->get_all_states() : EEM_State::instance()->get_all_states_of_active_countries();
1246
		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...
1247
			$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...
1248
			// if multiple countries, we'll create option groups within the dropdown
1249
			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...
1250
				if ( $state instanceof EE_State ) {
1251
					$QSO = EE_Question_Option::new_instance ( array (
1252
						'QSO_value' => $state->ID(),
1253
						'QSO_desc' => $state->name(),
1254
						'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...
1255
						'QSO_deleted' => FALSE
1256
					));
1257
					// set option group
1258
					$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...
1259
					// add option to question
1260
					$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...
1261
				}
1262
			}
1263
		}
1264
		return $QST;
1265
	}
1266
1267
1268
1269
	/**
1270
	 *    generate_country_dropdown
1271
	 * @param      $QST
1272
	 * @param bool $get_all
1273
	 * @internal param array $question
1274
	 * @return array
1275
	 */
1276
	public static function generate_country_dropdown( $QST, $get_all = FALSE ){
1277
		$countries = $get_all ? EEM_Country::instance()->get_all_countries() : EEM_Country::instance()->get_all_active_countries();
1278
		if ( $countries && count( $countries ) != count( $QST->options() ) ) {
1279
			$QST->set( 'QST_type', 'DROPDOWN' );
1280
			// now add countries
1281
			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...
1282
				if ( $country instanceof EE_Country ) {
1283
					$QSO = EE_Question_Option::new_instance ( array (
1284
						'QSO_value' => $country->ID(),
1285
						'QSO_desc' => $country->name(),
1286
						'QST_ID' => $QST->get( 'QST_ID' ),
1287
						'QSO_deleted' => FALSE
1288
					));
1289
					$QST->add_temp_option( $QSO );
1290
				}
1291
			}
1292
		}
1293
		return $QST;
1294
	}
1295
1296
1297
1298
1299
1300
	/**
1301
	 * 	generates options for a month dropdown selector with numbers from 01 to 12
1302
	 * 	@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...
1303
	 */
1304
	public static function two_digit_months_dropdown_options() {
1305
		$options = array();
1306 View Code Duplication
		for ( $x = 1; $x <= 12; $x++ ) {
1307
			$mm = str_pad( $x, 2, '0', STR_PAD_LEFT );
1308
			$options[ (string)$mm ] = (string)$mm;
1309
		}
1310
		return EEH_Form_Fields::prep_answer_options( $options );
1311
	}
1312
1313
1314
1315
1316
1317
	/**
1318
	 * 	generates a year dropdown selector with numbers for the next ten years
1319
	 * 	@return object
1320
	 */
1321
	public static function next_decade_two_digit_year_dropdown_options() {
1322
		$options = array();
1323
		$current_year = date('y');
1324
		$next_decade = $current_year + 10;
1325 View Code Duplication
		for ( $x = $current_year; $x <= $next_decade; $x++ ) {
1326
			$yy = str_pad( $x, 2, '0', STR_PAD_LEFT );
1327
			$options[ (string)$yy ] = (string)$yy;
1328
		}
1329
		return EEH_Form_Fields::prep_answer_options( $options );
1330
	}
1331
1332
1333
1334
1335
1336
	/**
1337
	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for list table filter.
1338
	 * @param  string  $cur_date     any currently selected date can be entered here.
1339
	 * @param  string  $status       Registration status
1340
	 * @param  integer $evt_category Event Category ID if the Event Category filter is selected
1341
	 * @return string                html
1342
	 */
1343
	public static function generate_registration_months_dropdown( $cur_date = '', $status = '', $evt_category = 0 ) {
1344
		$_where = array();
1345
		if ( !empty( $status ) ) {
1346
			$_where['STS_ID'] = $status;
1347
		}
1348
1349
		if ( $evt_category > 0 ) {
1350
			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1351
		}
1352
1353
		$regdtts = EEM_Registration::instance()->get_reg_months_and_years( $_where );
1354
1355
		//setup vals for select input helper
1356
		$options = array(
1357
			0 => array(
1358
				'text' => __('Select a Month/Year', 'event_espresso'),
1359
				'id' => ''
1360
				)
1361
			);
1362
1363
		foreach ( $regdtts as $regdtt ) {
1364
			$date = $regdtt->reg_month. ' ' . $regdtt->reg_year;
1365
			$options[] = array(
1366
				'text' => $date,
1367
				'id' => $date
1368
				);
1369
		}
1370
1371
		return self::select_input('month_range', $options, $cur_date, '', 'wide' );
1372
	}
1373
1374
1375
1376
	/**
1377
	 * generates a month/year dropdown selector for all events matching the given criteria
1378
	 * Typically used for list table filter
1379
	 * @param  string $cur_date          any currently selected date can be entered here.
1380
	 * @param  string $status            "view" (i.e. all, today, month, draft)
1381
	 * @param  int    $evt_category      category event belongs to
1382
	 * @param  string $evt_active_status "upcoming", "expired", "active", or "inactive"
1383
	 * @return string                    html
1384
	 */
1385
	public static function generate_event_months_dropdown( $cur_date = '', $status = NULL, $evt_category = NULL, $evt_active_status = NULL ) {
1386
		//determine what post_status our condition will have for the query.
1387
		switch ( $status ) {
1388
			case 'month' :
1389
			case 'today' :
1390
			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...
1391
			case 'all' :
1392
				$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...
1393
				break;
1394
1395
			case 'draft' :
1396
				$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...
1397
1398
			default :
1399
				$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...
1400
		}
1401
1402
		//categories?
1403
1404
1405
		if ( !empty ( $evt_category ) ) {
1406
			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1407
			$where['Event.Term_Taxonomy.term_id'] = $evt_category;
1408
		}
1409
1410
1411
//		$where['DTT_is_primary'] = 1;
1412
1413
		$DTTS = EE_Registry::instance()->load_model('Datetime')->get_dtt_months_and_years($where, $evt_active_status );
0 ignored issues
show
Documentation Bug introduced by
The method get_dtt_months_and_years does not exist on object<EEM_Base>? Since you implemented __call, maybe consider adding a @method annotation.

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

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

class ParentClass {
    private $data = array();

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

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

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