Completed
Push — master ( 5d65dd...ebd649 )
by Jean-Christophe
03:28
created

Widget   B

Complexity

Total Complexity 40

Size/Duplication

Total Lines 277
Duplicated Lines 2.53 %

Coupling/Cohesion

Components 2
Dependencies 9

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 40
c 1
b 0
f 0
lcom 2
cbo 9
dl 7
loc 277
rs 8.2608

33 Methods

Rating   Name   Duplication   Size   Complexity  
A addInToolbar() 0 9 3
A addItemInToolbar() 0 6 2
A addItemsInToolbar() 0 12 4
A addDropdownInToolbar() 7 7 2
A addButtonInToolbar() 0 4 1
A addButtonsInToolbar() 0 4 1
A addLabelledIconButtonInToolbar() 0 5 1
A setCaptionCallback() 0 4 1
A setEdition() 0 4 1
A setDefaultValueFunction() 0 4 1
A __construct() 0 7 2
A _init() 0 6 1
A _getFieldIdentifier() 0 3 1
_setToolbarPosition() 0 1 ?
A show() 0 3 1
A getModel() 0 3 1
A setModel() 0 4 1
A getInstanceViewer() 0 3 1
A setInstanceViewer() 0 4 1
getHtmlComponent() 0 1 ?
A setColor() 0 3 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 getToolbar() 0 6 2
A jsDisabled() 0 3 1
A addEditButtonInToolbar() 0 7 1
A setToolbar() 0 4 1
A setToolbarPosition() 0 4 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 Widget 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 Widget, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ajax\common;
4
5
use Ajax\common\html\HtmlDoubleElement;
6
use Ajax\semantic\html\elements\HtmlButton;
7
use Ajax\semantic\widgets\datatable\PositionInTable;
8
use Ajax\semantic\html\collections\menus\HtmlMenu;
9
use Ajax\semantic\widgets\base\FieldAsTrait;
10
use Ajax\semantic\html\elements\HtmlButtonGroups;
11
use Ajax\semantic\widgets\base\InstanceViewer;
12
use Ajax\semantic\html\modules\HtmlDropdown;
13
use Ajax\service\JArray;
14
use Ajax\service\Javascript;
15
16
abstract class Widget extends HtmlDoubleElement {
17
	use FieldAsTrait;
18
19
	/**
20
	 * @var string classname
21
	 */
22
	protected $_model;
23
	protected $_modelInstance;
24
	/**
25
	 * @var InstanceViewer
26
	 */
27
	protected $_instanceViewer;
28
	/**
29
	 * @var HtmlMenu
30
	 */
31
	protected $_toolbar;
32
	/**
33
	 * @var PositionInTable
34
	 */
35
	protected $_toolbarPosition;
36
37
	protected $_edition;
38
39
40
	public function __construct($identifier,$model,$modelInstance=NULL) {
41
		parent::__construct($identifier);
42
		$this->_template="%wrapContentBefore%%content%%wrapContentAfter%";
43
		$this->setModel($model);
44
		if(isset($modelInstance));
45
			$this->show($modelInstance);
46
	}
47
48
	protected function _init($instanceViewer,$contentKey,$content,$edition){
49
		$this->_instanceViewer=$instanceViewer;
50
		$this->content=[$contentKey=>$content];
51
		$this->_toolbarPosition=PositionInTable::BEFORETABLE;
52
		$this->_edition=$edition;
53
	}
54
55
	protected function _getFieldIdentifier($prefix){
56
		return $this->identifier."-{$prefix}-".$this->_instanceViewer->getIdentifier();
57
	}
58
59
	abstract protected  function _setToolbarPosition($table,$captions=NULL);
60
61
	public function show($modelInstance){
62
		$this->_modelInstance=$modelInstance;
63
	}
64
65
	public function getModel() {
66
		return $this->_model;
67
	}
68
69
	public function setModel($_model) {
70
		$this->_model=$_model;
71
		return $this;
72
	}
73
74
	public function getInstanceViewer() {
75
		return $this->_instanceViewer;
76
	}
77
78
	public function setInstanceViewer($_instanceViewer) {
79
		$this->_instanceViewer=$_instanceViewer;
80
		return $this;
81
	}
82
83
	abstract public function getHtmlComponent();
84
85
	public function setColor($color){
86
		return $this->getHtmlComponent()->setColor($color);
87
	}
88
89
90
	public function setCaptions($captions){
91
		$this->_instanceViewer->setCaptions($captions);
92
		return $this;
93
	}
94
95
	public function setFields($fields){
96
		$this->_instanceViewer->setVisibleProperties($fields);
97
		return $this;
98
	}
99
100
	public function addField($field){
101
		$this->_instanceViewer->addField($field);
102
		return $this;
103
	}
104
105
	public function insertField($index,$field){
106
		$this->_instanceViewer->insertField($index, $field);
107
		return $this;
108
	}
109
110
	public function insertInField($index,$field){
111
		$this->_instanceViewer->insertInField($index, $field);
112
		return $this;
113
	}
114
115
	public function setValueFunction($index,$callback){
116
		$this->_instanceViewer->setValueFunction($index, $callback);
117
		return $this;
118
	}
119
120
	public function setIdentifierFunction($callback){
121
		$this->_instanceViewer->setIdentifierFunction($callback);
122
		return $this;
123
	}
124
125
	/**
126
	 * @return \Ajax\semantic\html\collections\menus\HtmlMenu
127
	 */
128
	public function getToolbar(){
129
		if(isset($this->_toolbar)===false){
130
			$this->_toolbar=new HtmlMenu("toolbar-".$this->identifier);
131
		}
132
		return $this->_toolbar;
133
	}
134
135
	/**
136
	 * Adds a new element in toolbar
137
	 * @param mixed $element
138
	 * @param callable $callback function to call on $element
139
	 * @return \Ajax\common\html\HtmlDoubleElement
140
	 */
141
	public function addInToolbar($element,$callback=NULL){
142
		$tb=$this->getToolbar();
143
		if(isset($callback)){
144
			if(\is_callable($callback)){
145
				$callback($element);
146
			}
147
		}
148
		return $tb->addItem($element);
149
	}
150
151
	/**
152
	 * @param string $caption
153
	 * @param string $icon
154
	 * @param callable $callback function($element)
155
	 * @return \Ajax\common\html\HtmlDoubleElement
156
	 */
157
	public function addItemInToolbar($caption,$icon=NULL,$callback=NULL){
158
		$result=$this->addInToolbar($caption,$callback);
159
		if(isset($icon))
160
			$result->addIcon($icon);
161
		return $result;
162
	}
163
164
	/**
165
	 * @param array $items
166
	 * @param callable $callback function($element)
167
	 * @return \Ajax\common\Widget
168
	 */
169
	public function addItemsInToolbar(array $items,$callback=NULL){
170
		if(JArray::isAssociative($items)){
171
			foreach ($items as $icon=>$item){
172
				$this->addItemInToolbar($item,$icon,$callback);
173
			}
174
		}else{
175
			foreach ($items as $item){
176
				$this->addItemInToolbar($item,null,$callback);
177
			}
178
		}
179
		return $this;
180
	}
181
182
	/**
183
	 * @param string $value
184
	 * @param array $items
185
	 * @param callable $callback function($element)
186
	 * @return \Ajax\common\html\HtmlDoubleElement
187
	 */
188 View Code Duplication
	public function addDropdownInToolbar($value,$items,$callback=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...
189
		$dd=$value;
190
		if (\is_string($value)) {
191
			$dd=new HtmlDropdown("dropdown-". $this->identifier."-".$value, $value, $items);
192
		}
193
		return $this->addInToolbar($dd,$callback);
194
	}
195
196
	/**
197
	 * @param unknown $caption
198
	 * @param callable $callback function($element)
199
	 * @return \Ajax\common\html\HtmlDoubleElement
200
	 */
201
	public function addButtonInToolbar($caption,$callback=NULL){
202
		$bt=new HtmlButton("",$caption);
203
		return $this->addInToolbar($bt,$callback);
204
	}
205
206
	/**
207
	 * @param array $captions
208
	 * @param boolean $asIcon
209
	 * @param callable $callback function($element)
210
	 * @return \Ajax\common\html\HtmlDoubleElement
211
	 */
212
	public function addButtonsInToolbar(array $captions,$asIcon=false,$callback=NULL){
213
		$bts=new HtmlButtonGroups("",$captions,$asIcon);
214
		return $this->addInToolbar($bts,$callback);
215
	}
216
217
	/**
218
	 * @param string $caption
219
	 * @param string $icon
220
	 * @param boolean $before
221
	 * @param boolean $labeled
222
	 * @return \Ajax\common\html\HtmlDoubleElement
223
	 */
224
	public function addLabelledIconButtonInToolbar($caption,$icon,$before=true,$labeled=false){
225
		$bt=new HtmlButton("",$caption);
226
		$bt->addIcon($icon,$before,$labeled);
227
		return $this->addInToolbar($bt);
228
	}
229
230
	/**
231
	 * Defines a callback function to call for modifying captions
232
	 * function parameters are $captions: the captions to modify and $instance: the active model instance
233
	 * @param callable $captionCallback
234
	 * @return Widget
235
	 */
236
	public function setCaptionCallback($captionCallback) {
237
		$this->_instanceViewer->setCaptionCallback($captionCallback);
238
		return $this;
239
	}
240
241
	/**
242
	 * Makes the input fields editable
243
	 * @param boolean $_edition
244
	 * @return \Ajax\common\Widget
245
	 */
246
	public function setEdition($_edition=true) {
247
		$this->_edition=$_edition;
248
		return $this;
249
	}
250
251
	/**
252
	 * Defines the default function which displays fields value
253
	 * @param callable $defaultValueFunction
254
	 * @return \Ajax\common\Widget
255
	 */
256
	public function setDefaultValueFunction($defaultValueFunction){
257
		$this->_instanceViewer->setDefaultValueFunction($defaultValueFunction);
258
		return $this;
259
	}
260
261
	/**
262
	 * @param string|boolean $disable
263
	 * @return string
264
	 */
265
	public function jsDisabled($disable=true){
266
		return "$('#".$this->identifier." .ui.input,#".$this->identifier." .ui.dropdown,#".$this->identifier." .ui.checkbox').toggleClass('disabled',".$disable.");";
267
	}
268
269
	/**
270
	 * @param string $caption
271
	 * @param callable $callback function($element)
272
	 * @return \Ajax\common\html\HtmlDoubleElement
273
	 */
274
	public function addEditButtonInToolbar($caption,$callback=NULL){
275
		$bt=new HtmlButton($this->identifier."-editBtn",$caption);
276
		$bt->setToggle();
277
		$bt->setActive($this->_edition);
278
		$bt->onClick($this->jsDisabled(Javascript::prep_value("!$(event.target).hasClass('active')")));
279
		return $this->addInToolbar($bt,$callback);
280
	}
281
282
	public function setToolbar(HtmlMenu $_toolbar) {
283
		$this->_toolbar=$_toolbar;
284
		return $this;
285
	}
286
287
	public function setToolbarPosition($_toolbarPosition) {
288
		$this->_toolbarPosition=$_toolbarPosition;
289
		return $this;
290
	}
291
292
}