Completed
Push — master ( 5ec30c...b92773 )
by Jean-Christophe
03:32
created

DataTable   F

Complexity

Total Complexity 83

Size/Duplication

Total Lines 444
Duplicated Lines 5.63 %

Coupling/Cohesion

Components 1
Dependencies 14

Importance

Changes 0
Metric Value
wmc 83
lcom 1
cbo 14
dl 25
loc 444
rs 2.6956
c 0
b 0
f 0

54 Methods

Rating   Name   Duplication   Size   Complexity  
A run() 0 9 3
A __construct() 0 6 1
D compile() 0 38 10
A _generateContent() 0 19 3
A _generatePagination() 0 9 1
B _setToolbarPosition() 0 12 7
A afterCompile() 0 4 1
A addToolbarRow() 0 5 1
A getInstanceViewer() 0 3 1
A setInstanceViewer() 0 4 1
A setCaptions() 0 4 1
A setFields() 0 4 1
A addField() 0 4 1
A insertField() 0 4 1
A insertInField() 0 4 1
A setValueFunction() 0 4 1
A setIdentifierFunction() 0 4 1
A getHtmlComponent() 0 3 1
A getUrls() 0 3 1
A setUrls() 0 4 1
A paginate() 0 3 1
A getHasCheckboxes() 0 3 1
A setHasCheckboxes() 0 4 1
A refresh() 0 4 1
A getFieldButtonCallable() 0 3 1
A getCallable() 0 11 3
A getFieldButton() 0 5 1
A addFieldButton() 0 4 1
A insertFieldButton() 0 4 1
A insertInFieldButton() 0 4 1
A addDefaultButton() 0 5 1
A insertDefaultButtonIn() 0 5 1
A getDefaultButton() 0 7 2
A addDeleteButton() 0 3 1
A addEditButton() 0 3 1
A addEditDeleteButtons() 0 6 1
A insertDeleteButtonIn() 0 3 1
A insertEditButtonIn() 0 3 1
A setSelectable() 0 4 1
A getToolbar() 0 7 2
A addInToolbar() 0 4 1
A addItemInToolbar() 0 5 1
A addButtonInToolbar() 0 4 1
A addLabelledIconButtonInToolbar() 0 5 1
A addSearchInToolbar() 0 3 1
A getSearchField() 0 7 2
A setSortable() 0 4 1
A fieldAsImage() 0 8 2
A fieldAsAvatar() 0 4 1
A fieldAsRadio() 0 11 2
A fieldAsInput() 13 13 2
A fieldAsCheckbox() 12 12 2
A fieldAsDropDown() 0 11 2
A _getFieldIdentifier() 0 3 1

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 DataTable 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 DataTable, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ajax\semantic\widgets\datatable;
4
5
use Ajax\common\Widget;
6
use Ajax\JsUtils;
7
use Ajax\semantic\html\collections\HtmlTable;
8
use Ajax\semantic\html\elements\HtmlInput;
9
use Ajax\semantic\html\collections\menus\HtmlPaginationMenu;
10
use Ajax\semantic\html\modules\checkbox\HtmlCheckbox;
11
use Ajax\semantic\html\elements\HtmlButton;
12
use Ajax\semantic\html\collections\menus\HtmlMenu;
13
use Ajax\semantic\html\base\constants\Direction;
14
use Ajax\service\JArray;
15
use Ajax\semantic\html\elements\HtmlImage;
16
use Ajax\semantic\html\base\constants\Size;
17
use Ajax\semantic\html\modules\HtmlDropdown;
18
use Ajax\service\JString;
19
use Ajax\semantic\html\modules\checkbox\HtmlRadio;
20
21
class DataTable extends Widget {
22
23
	protected $_searchField;
24
	protected $_urls;
25
	protected $_pagination;
26
	protected $_hasCheckboxes;
27
	protected $_toolbar;
28
	protected $_compileParts;
29
	protected $_toolbarPosition;
30
31
	public function run(JsUtils $js){
32
		if($this->_hasCheckboxes && isset($js)){
33
			$js->execOn("change", "#".$this->identifier." [name='selection[]']", "
34
		var \$parentCheckbox=\$('#ck-main-ck-{$this->identifier}'),\$checkbox=\$('#{$this->identifier} [name=\"selection[]\"]'),allChecked=true,allUnchecked=true;
35
		\$checkbox.each(function() {if($(this).prop('checked')){allUnchecked = false;}else{allChecked = false;}});
36
		if(allChecked) {\$parentCheckbox.checkbox('set checked');}else if(allUnchecked){\$parentCheckbox.checkbox('set unchecked');}else{\$parentCheckbox.checkbox('set indeterminate');}");
37
		}
38
		parent::run($js);
39
	}
40
41
	public function __construct($identifier,$model,$modelInstance=NULL) {
42
		parent::__construct($identifier, $model,$modelInstance);
43
		$this->_instanceViewer=new InstanceViewer();
44
		$this->content=["table"=>new HtmlTable($identifier, 0,0)];
45
		$this->_toolbarPosition=PositionInTable::BEFORETABLE;
46
	}
47
48
	public function compile(JsUtils $js=NULL,&$view=NULL){
49
		$this->_instanceViewer->setInstance($this->_model);
50
		$captions=$this->_instanceViewer->getCaptions();
51
52
		$table=$this->content["table"];
53
54
		if($this->_hasCheckboxes){
55
			$ck=new HtmlCheckbox("main-ck-".$this->identifier,"");
56
			$ck->setOnChecked("$('#".$this->identifier." [name=%quote%selection[]%quote%]').prop('checked',true);");
57
			$ck->setOnUnchecked("$('#".$this->identifier." [name=%quote%selection[]%quote%]').prop('checked',false);");
58
			\array_unshift($captions, $ck);
59
		}
60
61
		$table->setRowCount(0, \sizeof($captions));
62
		$table->setHeaderValues($captions);
63
		if(isset($this->_compileParts))
64
			$table->setCompileParts($this->_compileParts);
65
		if(isset($this->_searchField)){
66
			if(isset($js))
67
				$this->_searchField->postOn("change", $this->_urls,"{'s':$(this).val()}","-#".$this->identifier." tbody",["preventDefault"=>false]);
68
		}
69
70
		$this->_generateContent($table);
71
72
		if($this->_hasCheckboxes){
73
			if($table->hasPart("thead"))
74
				$table->getHeader()->getCell(0, 0)->addToProperty("class","no-sort");
75
		}
76
77
		if(isset($this->_pagination) && $this->_pagination->getVisible()){
78
			$this->_generatePagination($table);
79
		}
80
		if(isset($this->_toolbar)){
81
			$this->_setToolbarPosition($table, $captions);
82
		}
83
		$this->content=JArray::sortAssociative($this->content, [PositionInTable::BEFORETABLE,"table",PositionInTable::AFTERTABLE]);
84
		return parent::compile($js,$view);
85
	}
86
87
	private function _generateContent($table){
88
		$objects=$this->_modelInstance;
89
		if(isset($this->_pagination)){
90
			$objects=$this->_pagination->getObjects($this->_modelInstance);
91
		}
92
		InstanceViewer::setIndex(0);
93
		$table->fromDatabaseObjects($objects, function($instance){
94
			$this->_instanceViewer->setInstance($instance);
95
			$result= $this->_instanceViewer->getValues();
96
			if($this->_hasCheckboxes){
97
				$ck=new HtmlCheckbox("ck-".$this->identifier,"");
98
				$field=$ck->getField();
99
				$field->setProperty("value",$this->_instanceViewer->getIdentifier());
100
				$field->setProperty("name", "selection[]");
101
				\array_unshift($result, $ck);
102
			}
103
			return $result;
104
		});
105
	}
106
107
	private function _generatePagination($table){
108
		$footer=$table->getFooter();
109
		$footer->mergeCol();
110
		$menu=new HtmlPaginationMenu("pagination-".$this->identifier,$this->_pagination->getPagesNumbers());
111
		$menu->floatRight();
112
		$menu->setActiveItem($this->_pagination->getPage()-1);
113
		$footer->setValues($menu);
114
		$menu->postOnClick($this->_urls,"{'p':$(this).attr('data-page')}","-#".$this->identifier." tbody",["preventDefault"=>false]);
115
	}
116
117
	private function _setToolbarPosition($table,$captions){
118
		switch ($this->_toolbarPosition){
119
			case PositionInTable::BEFORETABLE:case PositionInTable::AFTERTABLE:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
120
				if(isset($this->_compileParts)===false){
121
					$this->content[$this->_toolbarPosition]=$this->_toolbar;
122
				}
123
				break;
124
			case PositionInTable::HEADER:case PositionInTable::FOOTER: case PositionInTable::BODY:
0 ignored issues
show
Coding Style introduced by
The case body in a switch statement must start on the line following the statement.

According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.

switch ($expr) {
case "A":
    doSomething(); //right
    break;
case "B":

    doSomethingElse(); //wrong
    break;

}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
125
				$this->addToolbarRow($this->_toolbarPosition,$table, $captions);
126
				break;
127
		}
128
	}
129
130
	/**
131
	 * Associates a $callback function after the compilation of the field at $index position
132
	 * The $callback function can take the following arguments : $field=>the compiled field, $index: the field position, $instance : the active instance of the object
133
	 * @param int $index postion of the compiled field
134
	 * @param callable $callback function called after the field compilation
135
	 * @return \Ajax\semantic\widgets\datatable\DataTable
136
	 */
137
	public function afterCompile($index,$callback){
138
		$this->_instanceViewer->afterCompile($index,$callback);
139
		return $this;
140
	}
141
142
	private function addToolbarRow($part,$table,$captions){
143
		$row=$table->getPart($part)->addRow(\sizeof($captions));
144
		$row->mergeCol();
145
		$row->setValues([$this->_toolbar]);
146
	}
147
148
	public function getInstanceViewer() {
149
		return $this->_instanceViewer;
150
	}
151
152
	public function setInstanceViewer($_instanceViewer) {
153
		$this->_instanceViewer=$_instanceViewer;
154
		return $this;
155
	}
156
157
	public function setCaptions($captions){
158
		$this->_instanceViewer->setCaptions($captions);
159
		return $this;
160
	}
161
162
	public function setFields($fields){
163
		$this->_instanceViewer->setVisibleProperties($fields);
164
		return $this;
165
	}
166
167
	public function addField($field){
168
		$this->_instanceViewer->addField($field);
169
		return $this;
170
	}
171
172
	public function insertField($index,$field){
173
		$this->_instanceViewer->insertField($index, $field);
174
		return $this;
175
	}
176
177
	public function insertInField($index,$field){
178
		$this->_instanceViewer->insertInField($index, $field);
179
		return $this;
180
	}
181
182
	public function setValueFunction($index,$callback){
183
		$this->_instanceViewer->setValueFunction($index, $callback);
184
		return $this;
185
	}
186
187
	public function setIdentifierFunction($callback){
188
		$this->_instanceViewer->setIdentifierFunction($callback);
189
		return $this;
190
	}
191
192
	public function getHtmlComponent(){
193
		return $this->content["table"];
194
	}
195
196
	public function getUrls() {
197
		return $this->_urls;
198
	}
199
200
	public function setUrls($urls) {
201
		$this->_urls=$urls;
202
		return $this;
203
	}
204
205
	public function paginate($items_per_page=10,$page=1){
206
		$this->_pagination=new Pagination($items_per_page,4,$page);
207
	}
208
209
	public function getHasCheckboxes() {
210
		return $this->_hasCheckboxes;
211
	}
212
213
	public function setHasCheckboxes($_hasCheckboxes) {
214
		$this->_hasCheckboxes=$_hasCheckboxes;
215
		return $this;
216
	}
217
218
	public function refresh($compileParts=["tbody"]){
219
		$this->_compileParts=$compileParts;
220
		return $this;
221
	}
222
	/**
223
	 * @param string $caption
224
	 * @param callable $callback
225
	 * @return callable
226
	 */
227
	private function getFieldButtonCallable($caption,$callback=null){
228
		return $this->getCallable($this->getFieldButton($caption),$callback);
229
	}
230
231
	/**
232
	 * @param mixed $object
233
	 * @param callable $callback
234
	 * @return callable
235
	 */
236
	private function getCallable($object,$callback=null){
237
		$result=function($instance) use($object,$callback){
238
			if(isset($callback)){
239
				if(\is_callable($callback)){
240
					$callback($object,$instance);
241
				}
242
			}
243
			return $object;
244
		};
245
		return $result;
246
	}
247
248
	/**
249
	 * @param string $caption
250
	 * @return HtmlButton
251
	 */
252
	private function getFieldButton($caption){
253
			$bt=new HtmlButton("",$caption);
254
			$bt->setProperty("data-ajax",$this->_instanceViewer->getIdentifier());
255
			return $bt;
256
	}
257
258
	/**
259
	 * Inserts a new Button for each row
260
	 * @param string $caption
261
	 * @param callable $callback
262
	 * @return \Ajax\semantic\widgets\datatable\DataTable
263
	 */
264
	public function addFieldButton($caption,$callback=null){
265
		$this->addField($this->getFieldButtonCallable($caption,$callback));
266
		return $this;
267
	}
268
269
	/**
270
	 * Inserts a new Button for each row at col $index
271
	 * @param int $index
272
	 * @param string $caption
273
	 * @param callable $callback
274
	 * @return \Ajax\semantic\widgets\datatable\DataTable
275
	 */
276
	public function insertFieldButton($index,$caption,$callback=null){
277
		$this->insertField($index, $this->getFieldButtonCallable($caption,$callback));
278
		return $this;
279
	}
280
281
	/**
282
	 * Inserts a new Button for each row in col at $index
283
	 * @param int $index
284
	 * @param string $caption
285
	 * @param callable $callback
286
	 * @return \Ajax\semantic\widgets\datatable\DataTable
287
	 */
288
	public function insertInFieldButton($index,$caption,$callback=null){
289
		$this->insertInField($index, $this->getFieldButtonCallable($caption,$callback));
290
		return $this;
291
	}
292
293
	private function addDefaultButton($icon,$class=null,$callback=null){
294
		$bt=$this->getDefaultButton($icon,$class);
295
		$this->addField($this->getCallable($bt,$callback));
296
		return $this;
297
	}
298
299
	private function insertDefaultButtonIn($index,$icon,$class=null,$callback=null){
300
		$bt=$this->getDefaultButton($icon,$class);
301
		$this->insertInField($index,$this->getCallable($bt,$callback));
302
		return $this;
303
	}
304
305
	private function getDefaultButton($icon,$class=null){
306
		$bt=$this->getFieldButton("");
307
		$bt->asIcon($icon);
308
		if(isset($class))
309
			$bt->addToProperty("class", $class);
310
		return $bt;
311
	}
312
313
	public function addDeleteButton($callback=null){
314
		return $this->addDefaultButton("remove","delete red basic",$callback);
315
	}
316
317
	public function addEditButton($callback=null){
318
		return $this->addDefaultButton("edit","edit basic",$callback);
319
	}
320
321
	public function addEditDeleteButtons($callbackEdit=null,$callbackDelete=null){
322
		$this->addEditButton($callbackEdit);
323
		$index=$this->_instanceViewer->visiblePropertiesCount()-1;
324
		$this->insertDeleteButtonIn($index,$callbackDelete);
325
		return $this;
326
	}
327
328
	public function insertDeleteButtonIn($index,$callback=null){
329
		return $this->insertDefaultButtonIn($index,"remove","delete red basic",$callback);
330
	}
331
332
	public function insertEditButtonIn($index,$callback=null){
333
		return $this->insertDefaultButtonIn($index,"edit","edit basic",$callback);
334
	}
335
336
	public function setSelectable(){
337
		$this->content["table"]->setSelectable();
338
		return $this;
339
	}
340
341
	/**
342
	 * @return \Ajax\semantic\html\collections\menus\HtmlMenu
343
	 */
344
	public function getToolbar(){
345
		if(isset($this->_toolbar)===false){
346
			$this->_toolbar=new HtmlMenu("toolbar-".$this->identifier);
347
			$this->_toolbar->setSecondary();
348
		}
349
		return $this->_toolbar;
350
	}
351
352
	/**
353
	 * @param unknown $element
354
	 * @return \Ajax\common\html\HtmlDoubleElement
355
	 */
356
	public function addInToolbar($element){
357
		$tb=$this->getToolbar();
358
		return $tb->addItem($element);
359
	}
360
361
	public function addItemInToolbar($caption,$icon=NULL){
362
		$result=$this->addInToolbar($caption);
363
		$result->addIcon($icon);
364
		return $result;
365
	}
366
367
	public function addButtonInToolbar($caption){
368
		$bt=new HtmlButton("",$caption);
369
		return $this->addInToolbar($bt);
0 ignored issues
show
Documentation introduced by
$bt is of type object<Ajax\semantic\html\elements\HtmlButton>, but the function expects a object<Ajax\semantic\widgets\datatable\unknown>.

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...
370
	}
371
372
	public function addLabelledIconButtonInToolbar($caption,$icon,$before=true,$labeled=false){
373
		$bt=new HtmlButton("",$caption);
374
		$bt->addIcon($icon,$before,$labeled);
375
		return $this->addInToolbar($bt);
0 ignored issues
show
Documentation introduced by
$bt is of type object<Ajax\semantic\html\elements\HtmlButton>, but the function expects a object<Ajax\semantic\widgets\datatable\unknown>.

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...
376
	}
377
378
379
	public function addSearchInToolbar(){
380
		return $this->addInToolbar($this->getSearchField())->setPosition("right");
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Ajax\common\html\HtmlDoubleElement as the method setPosition() does only exist in the following sub-classes of Ajax\common\html\HtmlDoubleElement: Ajax\bootstrap\html\content\HtmlGridCol, Ajax\semantic\html\colle...menus\HtmlAccordionMenu, Ajax\semantic\html\collections\menus\HtmlIconMenu, Ajax\semantic\html\colle...nus\HtmlLabeledIconMenu, Ajax\semantic\html\collections\menus\HtmlMenu, Ajax\semantic\html\colle...enus\HtmlPaginationMenu, Ajax\semantic\html\content\HtmlAccordionMenuItem, Ajax\semantic\html\content\HtmlDropdownItem, Ajax\semantic\html\content\HtmlMenuItem, Ajax\semantic\html\modules\HtmlPopup. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
381
	}
382
383
	public function getSearchField(){
384
		if(isset($this->_searchField)===false){
385
			$this->_searchField=new HtmlInput("search-".$this->identifier,"search","","Search...");
386
			$this->_searchField->addIcon("search",Direction::RIGHT);
387
		}
388
		return $this->_searchField;
389
	}
390
391
	public function setSortable($colIndex=NULL) {
392
		$this->content["table"]->setSortable($colIndex);
393
		return $this;
394
	}
395
396
	public function fieldAsImage($index,$size=Size::SMALL,$circular=false){
397
		$this->setValueFunction($index,function($img) use($size,$circular){
398
			$image=new HtmlImage($this->_getFieldIdentifier("image"),$img);$image->setSize($size);if($circular)$image->setCircular();
399
			return $image;
400
			}
401
		);
402
		return $this;
403
	}
404
405
	public function fieldAsAvatar($index){
406
		$this->setValueFunction($index,function($img){return (new HtmlImage("",$img))->asAvatar();});
407
		return $this;
408
	}
409
410
	public function fieldAsRadio($index,$name=NULL){
411
		$this->setValueFunction($index,function($value)use ($index,$name){
412
			if(isset($name)===false){
413
				$name=$this->_instanceViewer->getCaption($index)."[]";
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $name, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
414
			}
415
			$radio=new HtmlRadio($this->_getFieldIdentifier("radio"),$name,$value,$value);
416
			return $radio;
417
			}
418
		);
419
		return $this;
420
	}
421
422 View Code Duplication
	public function fieldAsInput($index,$name=NULL,$type="text",$placeholder=""){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
423
		$this->setValueFunction($index,function($value) use($index,$name,$type,$placeholder){
424
			$input=new HtmlInput($this->_getFieldIdentifier("input"),$type,$value,$placeholder);
425
			if(isset($name)===false){
426
				$name=$this->_instanceViewer->getCaption($index)."[]";
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $name, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
427
			}
428
			$input->getField()->setProperty("name", $name);
429
			$input->setFluid();
430
			return $input;
431
			}
432
		);
433
		return $this;
434
	}
435
436 View Code Duplication
	public function fieldAsCheckbox($index,$name=NULL){
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
437
		$this->setValueFunction($index,function($value) use($index,$name){
438
			$checkbox=new HtmlCheckbox($this->_getFieldIdentifier("ck"),"",$value);
439
			$checkbox->setChecked(JString::isBooleanTrue($value));
440
			if(isset($name)===false){
441
				$name=$this->_instanceViewer->getCaption($index)."[]";
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $name, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
442
			}
443
			$checkbox->getField()->setProperty("name", $name);
444
			return $checkbox;}
445
		);
446
		return $this;
447
	}
448
449
	public function fieldAsDropDown($index,$elements=[],$multiple=false,$name=NULL){
450
		$this->setValueFunction($index,function($value) use($index,$elements,$multiple,$name){
451
			$dd=new HtmlDropdown($this->_getFieldIdentifier("dd"),$value,$elements);
452
			if(isset($name)===false){
453
				$name=$this->_instanceViewer->getCaption($index)."[]";
0 ignored issues
show
Bug introduced by
Consider using a different name than the imported variable $name, or did you forget to import by reference?

It seems like you are assigning to a variable which was imported through a use statement which was not imported by reference.

For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope.

Change not visible in outer-scope

$x = 1;
$callable = function() use ($x) {
    $x = 2; // Not visible in outer scope. If you would like this, how
            // about using a different variable name than $x?
};

$callable();
var_dump($x); // integer(1)

Change visible in outer-scope

$x = 1;
$callable = function() use (&$x) {
    $x = 2;
};

$callable();
var_dump($x); // integer(2)
Loading history...
454
			}
455
			$dd->asSelect($name,$multiple);
456
			return $dd;}
457
		);
458
		return $this;
459
	}
460
461
	private function _getFieldIdentifier($prefix){
462
		return $this->identifier."-{$prefix}-".$this->_instanceViewer->getIdentifier();
463
	}
464
}