Completed
Pull Request — master (#71)
by Toni Hermoso
22:26
created

SemanticFormsSelectInput::getHTML()   F

Complexity

Conditions 33
Paths > 20000

Size

Total Lines 163

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 163
rs 0
c 0
b 0
f 0
cc 33
nc 614400
nop 5

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * @license GNU GPL v2+
5
 * @since 1.3
6
 *
7
 * @author Jason Zhang
8
 * @author Toni Hermoso Pulido
9
 * @author Alexander Gesinn
10
 */
11
12
namespace SFS;
13
14
use SMWQueryProcessor as QueryProcessor;
15
use Parser;
16
use PFFormInput;
17
use MWDebug;
18
19
class SemanticFormsSelectInput extends PFFormInput {
20
21
	/**
22
	 * Internal data container
23
	 *
24
	 * @var array
25
	 */
26
	private static $data = [];
0 ignored issues
show
Unused Code introduced by
The property $data is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
27
28
	private $mSelectField;
29
30
	public function __construct( $inputNumber, $curValue, $inputName, $disabled, $otherArgs ) {
0 ignored issues
show
Coding Style introduced by
__construct uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

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

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
31
		parent::__construct( $inputNumber, $curValue, $inputName, $disabled, $otherArgs );
32
33
		// SelectField is a simple value object - we accept creating it in the constructor
34
		$this->mSelectField = new SelectField( $GLOBALS['wgParser'] );
35
	}
36
37
	public static function getName() {
38
		return 'SF_Select';
39
	}
40
41
	public static function getParameters() {
42
		$params = parent::getParameters();
43
		return $params;
44
	}
45
46
	public function getResourceModuleNames() {
47
		/**
48
		 * Loading modules this way currently fails with:
49
		 * "mw.loader.state({"ext.sf_select.scriptselect":"loading"});"
50
		 */
51
52
		return [
53
			'ext.sf_select.scriptselect'
54
		];
55
	}
56
57
	/**
58
	 * Returns the HTML code to be included in the output page for this input.
59
	 * This is currently just a wrapper for getHTML().
60
	 */
61
	public function getHtmlText() {
62
		return self::getHTML( $this->mCurrentValue, $this->mInputName, $this->mIsMandatory, $this->mIsDisabled,
0 ignored issues
show
Deprecated Code introduced by
The method SFS\SemanticFormsSelectInput::getHTML() has been deprecated with message: use getHtmlText() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
63
			$this->mOtherArgs );
64
	}
65
66
	/**
67
	 * Returns the HTML code to be included in the output page for this input.
68
	 * @deprecated use getHtmlText() instead
69
	 *
70
	 * @param    string $cur_value A single value or a list of values with separator
71
	 * @param    string $input_name Name of the input including the template, e.g. Building[Part Of Site]
72
	 * @param            $is_mandatory
73
	 * @param            $is_disabled
74
	 * @param    string[] $other_args Array of other field parameters
75
	 * @return string
76
	 */
77
	public function getHTML( $cur_value = "", $input_name = "", $is_mandatory, $is_disabled, Array $other_args ) {
0 ignored issues
show
Unused Code introduced by
The parameter $is_disabled 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...
78
		global $sfgFieldNum, $wgUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
79
80
		// shortcut to the SelectField object
81
		$selectField = $this->mSelectField;
82
83
		// get 'delimiter' before 'query' or 'function'
84
		$selectField->setDelimiter( $other_args );
85
86
		if ( array_key_exists( "query", $other_args ) ) {
87
			$selectField->setQuery( $other_args );
88
		} elseif ( array_key_exists( "function", $other_args ) ) {
89
			$selectField->setFunction( $other_args );
90
		}
91
		
92
		if ( array_key_exists( "label", $other_args ) ) {
93
			$selectField->setLabel( $other_args );
94
		}
95
96
		// parameters are only required if values needs to be retrieved dynamically
97
		if ( !$selectField->hasStaticValues() ) {
98
			$selectField->setSelectIsMultiple( $other_args );
99
			$selectField->setSelectTemplate( $input_name );
100
			$selectField->setSelectField( $input_name );
101
			$selectField->setValueTemplate( $other_args );
102
			$selectField->setValueField( $other_args );
103
			$selectField->setSelectRemove( $other_args );
104
105
			$item = Output::addToHeadItem( $selectField->getData() );
0 ignored issues
show
Unused Code introduced by
$item is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
106
		}
107
108
		Output::commitToParserOutput();
109
110
		// prepare the html input tag
111
112
		$extraatt = "";
113
		$is_list = false;
114
115
		if ( array_key_exists( 'is_list', $other_args ) && $other_args['is_list'] == true ) {
0 ignored issues
show
Bug Best Practice introduced by
It seems like you are loosely comparing $other_args['is_list'] of type string to the boolean true. If you are specifically checking for a non-empty string, consider using the more explicit !== '' instead.
Loading history...
116
			$is_list = true;
117
		}
118
119
		if ( $is_list ) {
120
			$extraatt = ' multiple="multiple" ';
121
		}
122
123
		if ( array_key_exists( "size", $other_args ) ) {
124
			$extraatt .= " size=\"{$other_args['size']}\"";
125
		}
126
127
		$classes = [];
128
		if ( $is_mandatory ) {
129
			$classes[] = "mandatoryField";
130
		}
131
		if ( array_key_exists( "class", $other_args ) ) {
132
			$classes[] = $other_args['class'];
133
		}
134
		if ( $classes ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classes of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
135
			$cstr = implode( " ", $classes );
136
			$extraatt .= " class=\"$cstr\"";
137
		}
138
139
		$inname = $input_name;
140
		if ( $is_list ) {
141
			$inname .= '[]';
142
		}
143
144
		// TODO Use Html::
145
146
		$spanextra = $is_mandatory ? 'mandatoryFieldSpan' : '';
147
		$is_single_select = (!$is_list) ? 'select-sfs-single' : '' ;
148
		$ret = "<span class=\"inputSpan select-sfs $is_single_select $spanextra\"><select name='$inname' id='input_$sfgFieldNum' $extraatt>";
149
150
		$curvalues = null;
0 ignored issues
show
Unused Code introduced by
$curvalues is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
151
		if ( $cur_value ) {
152
			if ( $cur_value === 'current user' ) {
153
				$cur_value = $wgUser->getName();
154
			}
155
			if ( is_array( $cur_value ) ) {
156
				$curvalues = $cur_value;
157
			} else {
158
				// delimiter for $cur_value is always ',' - PF seems to ignore $wgPageFormsListSeparator
159
				$curvalues = array_map( "trim", explode( $selectField->getDelimiter(), $cur_value ) );
160
			}
161
162
		} else {
163
			$curvalues = [];
164
		}
165
166
		
167
		$labelArray = [];
168
		if ( array_key_exists( "label", $other_args ) && $curvalues ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $curvalues of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
169
			// $labelArray = $this->getLabels( $curvalues );
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
170
		}
171
172
		// TODO handle empty value case.
173
		$ret .= "<option></option>";
174
175
		if ( $selectField->hasStaticValues() ) {
176
			
177
			$values = $selectField->getValues();
178
			
179
			if ( array_key_exists( "label", $other_args ) && $values ) {
180
				$labelArray = $this->getLabels( $values );
181
			}
182
			
183
			if ( is_array( $values ) ) {
184
				
185
				foreach ( $values as $val ) {
186
					
187
					$selected = "";
188
											
189
					if ( array_key_exists( $val, $labelArray ) ) {
190
					
191
						if ( in_array( $labelArray[ $val ][0], $curvalues ) ) {
192
							$selected = " selected='selected'";
193
						}
194
						
195
						$ret.="<option".$selected." value='".$labelArray[ $val ][0]."'>".$labelArray[ $val ][1]."</option>";
196
					
197
					} else {
198
						
199
						if ( in_array( $val, $curvalues ) ) {
200
							$selected = " selected='selected'";
201
						}
202
203
						$ret .= "<option".$selected.">$val</option>";
204
					}
205
				}
206
			}
207
		} else {
208
			
209
			foreach ( $curvalues as $cur ) {
210
				$selected = "";
211
				
212
				if ( array_key_exists( $cur, $labelArray ) ) {
213
					
214
					if ( in_array( $labelArray[ $cur ][0], $curvalues ) ) {
215
						$selected = " selected='selected'";
216
					}
217
					
218
					$ret.="<option".$selected." value='".$labelArray[ $cur ][0]."'>".$labelArray[ $cur ][1]."</option>";
219
					
220
				} else {
221
					if ( in_array( $cur, $curvalues ) ) {
222
						$selected = " selected='selected'";
223
					}
224
					$ret.="<option".$selected.">$cur</option>";
225
				}
226
			}
227
228
		}
229
230
		$ret .= "</select></span>";
231
		$ret .= "<span id=\"info_$sfgFieldNum\" class=\"errorMessage\"></span>";
232
233
		if ( $other_args["is_list"] ) {
234
			$hiddenname = $input_name . '[is_list]';
235
			$ret .= "<input type='hidden' name='$hiddenname' value='1' />";
236
		}
237
238
		return $ret;
239
	}
240
	
241
		
242
	private function getLabels( $labels ) {
243
		
244
		$labelArray = [ ];
245
246
		if ( is_array( $labels ) ) {
247
			foreach ( $labels as $label ) {
248
				
249
				$labelKey = $label;
250
				$labelValue = $label;
251
				
252
				// Tricky thing if ( ) already in name
253
				if ( strpos( $label, ")" ) && strpos( $label, "(" ) ) {
254
				
255
					// Check Break
256
					$openBr = 0;
257
					$doneBr = 0;
258
					$num = 0;
259
					
260
					$labelArr = str_split ( $label );
261
					
262
					$end = count( $labelArr ) - 1;
263
					$iter = $end;
264
					
265
					$endBr = $end;
266
					$startBr = 0;
267
					
268
					while ( $doneBr == 0 && $iter >= 0 ) {
269
					
270
						$char = $labelArr[ $iter ];
271
						
272
						if ( $char == ")" ) {
273
							$openBr = $openBr - 1;
274
							
275
							if ( $num == 0 ) {
276
								$endBr = $iter;
277
								$num = $num + 1;
278
							}
279
						}
280
						
281
						if ( $char == "(" ) {
282
							$openBr = $openBr + 1;
283
							
284
							if ( $num > 0 && $openBr == 0 ) {
285
								$startBr = $iter;
286
								$doneBr = 1;
287
							}
288
						}
289
						
290
						$iter = $iter - 1;
291
						
292
					}
293
					
294
					$labelValue = implode( "", array_slice( $labelArr, $startBr+1, $endBr-$startBr-1 ) );			
295
					$labelKey = implode( "", array_slice( $labelArr, 0, $startBr-1 ) );
296
				
297
				}
298
				
299
				$labelArray[ $label ] = [ $labelKey, $labelValue ] ;
300
			}
301
		
302
		}
303
		
304
		return $labelArray;
305
		
306
	}
307
}
308