Completed
Push — master ( acbd35...e1ce60 )
by Jean-Christophe
03:14
created

HtmlTable   B

Complexity

Total Complexity 50

Size/Duplication

Total Lines 367
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
wmc 50
c 0
b 0
f 0
lcom 1
cbo 6
dl 0
loc 367
rs 8.6206

36 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 8 1
A getTable() 0 3 1
A getPart() 0 9 3
A getBody() 0 3 1
A getRowCount() 0 3 1
A getHeader() 0 3 1
A getFooter() 0 3 1
A hasPart() 0 3 1
A setRowCount() 0 4 1
A getCell() 0 3 1
A getRow() 0 3 1
A addRow() 0 5 1
A newRow() 0 3 1
A setValues() 0 4 1
A setHeaderValues() 0 3 1
A setFooterValues() 0 3 1
A setColValues() 0 4 1
A setRowValues() 0 4 1
A addColVariations() 0 3 1
A colCenter() 0 3 1
A colRight() 0 3 1
A colLeft() 0 3 1
A colAlign() 0 13 4
A conditionalCellFormat() 0 4 1
A conditionalRowFormat() 0 4 1
A applyCells() 0 4 1
A applyRows() 0 4 1
A compile() 0 8 2
A compile_once() 0 8 3
A fromDatabaseObject() 0 13 4
A setCompileParts() 0 4 1
A refresh() 0 4 1
A run() 0 6 2
A onNewRow() 0 4 1
A setActiveRowSelector() 0 4 1
A hideColumn() 0 10 3

How to fix   Complexity   

Complex Class

Complex classes like HtmlTable 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 HtmlTable, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Ajax\semantic\html\collections\table;
4
5
use Ajax\semantic\html\base\HtmlSemDoubleElement;
6
use Ajax\semantic\html\content\table\HtmlTableContent;
7
use Ajax\semantic\html\base\constants\Variation;
8
use Ajax\JsUtils;
9
10
use Ajax\service\JArray;
11
use Ajax\semantic\html\content\table\HtmlTR;
12
use Ajax\semantic\html\collections\table\traits\TableTrait;
13
use Ajax\semantic\html\content\table\HtmlTD;
14
15
/**
16
 * Semantic HTML Table component
17
 * @author jc
18
 *
19
 */
20
class HtmlTable extends HtmlSemDoubleElement {
21
	use TableTrait;
22
	private $_colCount;
23
	private $_compileParts;
24
	private $_footer;
25
	private $_afterCompileEvents;
26
	private $_activeRowSelector;
27
28
	public function __construct($identifier, $rowCount, $colCount) {
29
		parent::__construct($identifier, "table", "ui table");
30
		$this->content=array ();
31
		$this->setRowCount($rowCount, $colCount);
32
		$this->_variations=[ Variation::CELLED,Variation::PADDED,Variation::COMPACT ];
33
		$this->_compileParts=["thead","tbody","tfoot"];
34
		$this->_afterCompileEvents=[];
35
	}
36
37
	/**
38
	 * {@inheritDoc}
39
	 * @see TableTrait::getTable()
40
	 */
41
	protected function getTable() {
42
		return $this;
43
	}
44
45
	/**
46
	 * Returns/create eventually a part of the table corresponding to the $key : thead, tbody or tfoot
47
	 * @param string $key
48
	 * @return HtmlTableContent
49
	 */
50
	public function getPart($key) {
51
		if (\array_key_exists($key, $this->content) === false) {
52
			$this->content[$key]=new HtmlTableContent("", $key);
53
			if ($key !== "tbody") {
54
				$this->content[$key]->setRowCount(1, $this->_colCount);
55
			}
56
		}
57
		return $this->content[$key];
58
	}
59
60
	/**
61
	 * Returns/create eventually the body of the table
62
	 * @return HtmlTableContent
63
	 */
64
	public function getBody() {
65
		return $this->getPart("tbody");
66
	}
67
68
	/**
69
	 * Returns the number of rows (TR)
70
	 * @return int
71
	 */
72
	public function getRowCount() {
73
		return $this->getPart("tbody")->count();
74
	}
75
76
	/**
77
	 * Returns/create eventually the header of the table
78
	 * @return HtmlTableContent
79
	 */
80
	public function getHeader() {
81
		return $this->getPart("thead");
82
	}
83
84
	/**
85
	 * Returns/create eventually the footer of the table
86
	 * @return \Ajax\semantic\html\content\table\HtmlTableContent
87
	 */
88
	public function getFooter() {
89
		return $this->getPart("tfoot");
90
	}
91
92
	/**
93
	 * Checks if the part corresponding to $key exists
94
	 * @param string $key
95
	 * @return boolean
96
	 */
97
	public function hasPart($key) {
98
		return \array_key_exists($key, $this->content) === true;
99
	}
100
101
	/**
102
	 *
103
	 * @param int $rowCount
104
	 * @param int $colCount
105
	 * @return HtmlTableContent
106
	 */
107
	public function setRowCount($rowCount, $colCount) {
108
		$this->_colCount=$colCount;
109
		return $this->getBody()->setRowCount($rowCount, $colCount);
110
	}
111
112
	/**
113
	 * Returns the cell (HtmlTD) at position $row,$col
114
	 * @param int $row
115
	 * @param int $col
116
	 * @return HtmlTD
117
	 */
118
	public function getCell($row, $col) {
119
		return $this->getBody()->getCell($row, $col);
120
	}
121
122
	/**
123
	 * Retuns the row at $rowIndex
124
	 * @param int $rowIndex
125
	 * @return HtmlTR
126
	 */
127
	public function getRow($rowIndex) {
128
		return $this->getBody()->getRow($rowIndex);
129
	}
130
131
	/**
132
	 * Adds a new row and sets $values to his cols
133
	 * @param array $values
134
	 * @return HtmlTR
135
	 */
136
	public function addRow($values=array()) {
137
		$row=$this->getBody()->addRow($this->_colCount);
138
		$row->setValues(\array_values($values));
139
		return $row;
140
	}
141
142
	/**
143
	 * adds and returns a new row
144
	 * @return HtmlTR
145
	 */
146
	public function newRow() {
147
		return $this->getBody()->newRow($this->_colCount);
148
	}
149
150
	/**
151
	 * Sets the tbody values
152
	 * @param array $values values in an array of array
153
	 * @return HtmlTable
154
	 */
155
	public function setValues($values=array()) {
156
		$this->getBody()->setValues($values);
157
		return $this;
158
	}
159
160
	/**
161
	 * Sets the header values
162
	 * @param array $values
163
	 * @return HtmlTableContent
164
	 */
165
	public function setHeaderValues($values=array()) {
166
		return $this->getHeader()->setValues($values);
167
	}
168
169
	/**
170
	 * Sets the footer values
171
	 * @param array $values
172
	 * @return HtmlTableContent
173
	 */
174
	public function setFooterValues($values=array()) {
175
		return $this->getFooter()->setValues($values);
176
	}
177
178
	/**
179
	 * Sets values to the col at index $colIndex
180
	 * @param int $colIndex
181
	 * @param array $values
182
	 * @return HtmlTable
183
	 */
184
	public function setColValues($colIndex, $values=array()) {
185
		$this->getBody()->setColValues($colIndex, $values);
186
		return $this;
187
	}
188
189
	/**
190
	 * Sets values to the row at index $rowIndex
191
	 * @param int $rowIndex
192
	 * @param array $values
193
	 * @return HtmlTable
194
	 */
195
	public function setRowValues($rowIndex, $values=array()) {
196
		$this->getBody()->setRowValues($rowIndex, $values);
197
		return $this;
198
	}
199
200
	public function addColVariations($colIndex, $variations=array()) {
201
		return $this->getBody()->addColVariations($colIndex, $variations);
202
	}
203
204
	/**
205
	 * Sets the col alignment to center
206
	 * @param int $colIndex
207
	 * @return HtmlTable
208
	 */
209
	public function colCenter($colIndex) {
210
		return $this->colAlign($colIndex, "colCenter");
211
	}
212
213
	/**
214
	 * Sets the col alignment to right
215
	 * @param int $colIndex
216
	 * @return HtmlTable
217
	 */
218
	public function colRight($colIndex) {
219
		return $this->colAlign($colIndex, "colRight");
220
	}
221
222
	/**
223
	 * Sets col alignment to left
224
	 * @param int $colIndex
225
	 * @return HtmlTable
226
	 */
227
	public function colLeft($colIndex) {
228
		return $this->colAlign($colIndex, "colLeft");
229
	}
230
231
	private function colAlign($colIndex, $function) {
232
		if (\is_array($colIndex)) {
233
			foreach ( $colIndex as $cIndex ) {
234
				$this->colAlign($cIndex, $function);
235
			}
236
		} else {
237
			if ($this->hasPart("thead")) {
238
				$this->getHeader()->$function($colIndex);
239
			}
240
			$this->getBody()->$function($colIndex);
241
		}
242
		return $this;
243
	}
244
245
	/**
246
	 * Applies a format on each cell when $callback returns true
247
	 * @param callable $callback function with the cell as parameter, must return a boolean
248
	 * @param string $format css class to apply
249
	 * @return HtmlTable
250
	 */
251
	public function conditionalCellFormat($callback, $format) {
252
		$this->getBody()->conditionalCellFormat($callback, $format);
253
		return $this;
254
	}
255
256
	/**
257
	 * Applies a format on each row when $callback returns true
258
	 * @param callable $callback function with the row as parameter, must return a boolean
259
	 * @param string $format css class to apply
260
	 * @return HtmlTable
261
	 */
262
	public function conditionalRowFormat($callback, $format) {
263
		$this->getBody()->conditionalRowFormat($callback, $format);
264
		return $this;
265
	}
266
267
	/**
268
	 * Applies a callback function on each cell
269
	 * @param callable $callback
270
	 * @return HtmlTable
271
	 */
272
	public function applyCells($callback) {
273
		$this->getBody()->applyCells($callback);
274
		return $this;
275
	}
276
277
	/**
278
	 * Applies a callback function on each row
279
	 * @param callable $callback
280
	 * @return HtmlTable
281
	 */
282
	public function applyRows($callback) {
283
		$this->getBody()->applyRows($callback);
284
		return $this;
285
	}
286
287
	/**
288
	 *
289
	 * {@inheritDoc}
290
	 *
291
	 * @see HtmlSemDoubleElement::compile()
292
	 */
293
	public function compile(JsUtils $js=NULL, &$view=NULL) {
294
		if(\sizeof($this->_compileParts)<3){
295
			$this->_template="%content%";
296
			$this->refresh();
297
		}
298
		$this->content=JArray::sortAssociative($this->content, $this->_compileParts);
299
		return parent::compile($js, $view);
300
	}
301
302
	protected function compile_once(JsUtils $js=NULL, &$view=NULL) {
303
		if ($this->propertyContains("class", "sortable")) {
304
			$this->addEvent("execute", "$('#" . $this->identifier . "').tablesort().data('tablesort').sort($('th.default-sort'));");
305
		}
306
		if(isset($this->_activeRowSelector)){
307
			$this->_activeRowSelector->compile();
308
		}
309
	}
310
311
	/**
312
	 *
313
	 * {@inheritDoc}
314
	 *
315
	 * @see BaseHtml::fromDatabaseObject()
316
	 */
317
	public function fromDatabaseObject($object, $function) {
318
		$result=$function($object);
319
		if (\is_array($result)) {
320
			$result= $this->addRow($function($object));
321
		} else {
322
			$result= $this->getBody()->_addRow($result);
323
		}
324
		if(isset($this->_afterCompileEvents["onNewRow"])){
325
			if(\is_callable($this->_afterCompileEvents["onNewRow"]))
326
				$this->_afterCompileEvents["onNewRow"]($result,$object);
327
		}
328
		return $result;
329
	}
330
331
	/**
332
	 * Sets the parts of the Table to compile
333
	 * @param array $parts array of thead,tbody,tfoot
334
	 * @return HtmlTable
335
	 */
336
	public function setCompileParts($parts=["tbody"]) {
337
		$this->_compileParts=$parts;
338
		return $this;
339
	}
340
341
	public function refresh(){
342
		$this->_footer=$this->getFooter();
343
		$this->addEvent("execute", '$("#'.$this->identifier.' tfoot").replaceWith("'.\addslashes($this->_footer).'");');
344
	}
345
346
	public function run(JsUtils $js){
347
		$result= parent::run($js);
348
		if(isset($this->_footer))
349
			$this->_footer->run($js);
350
		return $result;
351
	}
352
353
	/**
354
	 * The callback function called after the insertion of each row when fromDatabaseObjects is called
355
	 * callback function takes the parameters $row : the row inserted and $object: the instance of model used
356
	 * @param callable $callback
357
	 * @return HtmlTable
358
	 */
359
	public function onNewRow($callback) {
360
		$this->_afterCompileEvents["onNewRow"]=$callback;
361
		return $this;
362
	}
363
364
	/**
365
	 * Defines how a row is selectable
366
	 * @param string $class
367
	 * @param string $event
368
	 * @param boolean $multiple
369
	 * @return HtmlTable
370
	 */
371
	public function setActiveRowSelector($class="active",$event="click",$multiple=false){
372
		$this->_activeRowSelector=new ActiveRow($this,$class,$event,$multiple);
373
		return $this;
374
	}
375
376
	public function hideColumn($colIndex){
377
		if($this->hasPart("thead")){
378
			$this->getHeader()->hideColumn($colIndex);
379
		}
380
		$this->getBody()->hideColumn($colIndex);
381
		if($this->hasPart("tfoot")){
382
			$this->getFooter()->hideColumn($colIndex);
383
		}
384
		return $this;
385
	}
386
}