Completed
Push — master ( 18e8f7...34fb15 )
by Jean-Christophe
02:32
created

HtmlTableContent::__construct()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 2
nop 4
1
<?php
2
3
namespace Ajax\semantic\html\content\table;
4
5
use Ajax\semantic\html\base\HtmlSemCollection;
6
use Ajax\service\JArray;
7
8
/**
9
 * a table content (thead, tbody or tfoot)
10
 * @author jc
11
 *
12
 */
13
class HtmlTableContent extends HtmlSemCollection {
14
	protected $_tdTagNames=[ "thead" => "th","tbody" => "td","tfoot" => "th" ];
15
16
	/**
17
	 *
18
	 * @param string $identifier
19
	 * @param string $tagName
20
	 * @param int $rowCount
21
	 * @param int $colCount
22
	 */
23
	public function __construct($identifier, $tagName="tbody", $rowCount=NULL, $colCount=NULL) {
24
		parent::__construct($identifier, $tagName, "");
25
		if (isset($rowCount) && isset($colCount))
26
			$this->setRowCount($rowCount, $colCount);
27
	}
28
29
	/**
30
	 *
31
	 * @param int $rowCount
32
	 * @param int $colCount
33
	 * @return HtmlTableContent
34
	 */
35
	public function setRowCount($rowCount, $colCount) {
36
		$count=$this->count();
37
		for($i=$count; $i < $rowCount; $i++) {
38
			$this->addItem($colCount);
39
		}
40
		return $this;
41
	}
42
43
	public function getTdTagName($tagName) {
0 ignored issues
show
Unused Code introduced by
The parameter $tagName 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...
44
		return $this->_tdTagNames[$this->tagName];
45
	}
46
47
	/**
48
	 *
49
	 * {@inheritDoc}
50
	 *
51
	 * @see \Ajax\common\html\HtmlCollection::createItem()
52
	 * @return HtmlTR
53
	 */
54
	protected function createItem($value) {
55
		$count=$this->count();
56
		$tr=new HtmlTR("", $value);
0 ignored issues
show
Unused Code introduced by
The call to HtmlTR::__construct() has too many arguments starting with $value.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
57
		$tr->setContainer($this, $count);
58
		$tr->setTdTagName($this->_tdTagNames[$this->tagName]);
59
		if (isset($value) === true) {
60
			$tr->setColCount($value);
61
		}
62
		return $tr;
63
	}
64
65
	public function newRow($value) {
66
		return $this->createItem($value);
67
	}
68
69
	/**
70
	 * @param int $colCount
71
	 * @return HtmlTR
72
	 */
73
	public function addRow($colCount) {
74
		return $this->addItem($colCount);
75
	}
76
77
	/**
78
	 * @param mixed $row
79
	 * @return HtmlTR
80
	 */
81
	public function _addRow($row) {
82
		return $this->addItem($row);
83
	}
84
85
	/**
86
	 * Returns the cell (HtmlTD) at position $row,$col
87
	 * @param int $row
88
	 * @param int $col
89
	 * @return HtmlTD
90
	 */
91
	public function getCell($row, $col) {
92
		$row=$this->getItem($row);
93
		if (isset($row)) {
94
			$col=$row->getItem($col);
95
		}
96
		return $col;
97
	}
98
99
	/**
100
	 *
101
	 * @param int $index
102
	 * @return HtmlTR
103
	 */
104
	public function getRow($index) {
105
		return $this->getItem($index);
106
	}
107
108
	/**
109
	 *
110
	 * @param int $row
111
	 * @param int $col
112
	 * @param mixed $value
113
	 * @return HtmlTableContent
114
	 */
115
	public function setCellValue($row, $col, $value="") {
116
		$cell=$this->getCell($row, $col);
117
		if (isset($cell) === true) {
118
			$cell->setValue($value);
119
		}
120
		return $this;
121
	}
122
123
	/**
124
	 * Sets the cells values
125
	 * @param mixed $values
126
	 */
127
	public function setValues($values=array()) {
128
		return $this->_addOrSetValues($values, function(HtmlTR $row,$_values){$row->setValues($_values);});
129
	}
130
131
	/**
132
	 * Adds the cells values
133
	 * @param mixed $values
134
	 */
135
	public function addValues($values=array()) {
136
		return $this->_addOrSetValues($values, function(HtmlTR $row,$_values){$row->addValues($_values);});
137
	}
138
139
	/**
140
	 * Adds or sets the cells values
141
	 * @param mixed $values
142
	 * @param callable $callback
143
	 */
144
	protected function _addOrSetValues($values,$callback) {
145
		$count=$this->count();
146
		$isArray=true;
147
		if (!\is_array($values)) {
148
			$values=\array_fill(0, $count, $values);
149
			$isArray=false;
150
		}
151
		if (JArray::dimension($values) == 1 && $isArray)
152
			$values=[ $values ];
153
154
		$count=\min(\sizeof($values), $count);
155
156 View Code Duplication
		for($i=0; $i < $count; $i++) {
157
			$row=$this->content[$i];
158
			$callback($row,$values[$i]);
159
		}
160
		return $this;
161
	}
162
163
	public function setColValues($colIndex, $values=array()) {
164
		$count=$this->count();
165
		if (!\is_array($values)) {
166
			$values=\array_fill(0, $count, $values);
167
		}
168
		$count=\min(\sizeof($values), $count);
169
		for($i=0; $i < $count; $i++) {
170
			$this->getCell($i, $colIndex)->setValue($values[$i]);
171
		}
172
		return $this;
173
	}
174
175
	public function addColVariations($colIndex, $variations=array()) {
176
		$count=$this->count();
177
		for($i=0; $i < $count; $i++) {
178
			$this->getCell($i, $colIndex)->addVariations($variations);
179
		}
180
		return $this;
181
	}
182
183
	public function setRowValues($rowIndex, $values=array()) {
184
		$count=$this->count();
185
		if (!\is_array($values)) {
186
			$values=\array_fill(0, $count, $values);
187
		}
188
		$this->getItem($rowIndex)->setValues($values);
189
		return $this;
190
	}
191
192
	private function colAlign($colIndex, $function) {
193
		$count=$this->count();
194
		for($i=0; $i < $count; $i++) {
195
			$index=$this->content[$i]->getColPosition($colIndex);
196
			if ($index !== NULL)
197
				$this->getCell($i, $index)->$function();
198
		}
199
		return $this;
200
	}
201
202
	public function colCenter($colIndex) {
203
		return $this->colAlign($colIndex, "textCenterAligned");
204
	}
205
206
	public function colRight($colIndex) {
207
		return $this->colAlign($colIndex, "textRightAligned");
208
	}
209
210
	public function colLeft($colIndex) {
211
		return $this->colAlign($colIndex, "textLeftAligned");
212
	}
213
214
	/**
215
	 * Returns the number of rows (TR)
216
	 * @return int
217
	 */
218
	public function getRowCount() {
219
		return $this->count();
220
	}
221
222
	/**
223
	 * Returns the number of columns (TD)
224
	 * @return int
225
	 */
226
	public function getColCount() {
227
		$result=0;
228
		if ($this->count() > 0)
229
			$result=$this->getItem(0)->count();
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 count() does only exist in the following sub-classes of Ajax\common\html\HtmlDoubleElement: Ajax\common\html\HtmlCollection, Ajax\common\html\html5\HtmlList, Ajax\semantic\html\base\HtmlSemCollection, Ajax\semantic\html\base\HtmlSemNavElement, Ajax\semantic\html\collections\HtmlBreadcrumb, Ajax\semantic\html\collections\HtmlGrid, Ajax\semantic\html\collections\form\HtmlForm, Ajax\semantic\html\collections\form\HtmlFormFields, 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\HtmlGridRow, Ajax\semantic\html\content\table\HtmlTR, Ajax\semantic\html\content\table\HtmlTableContent, Ajax\semantic\html\content\view\HtmlViewGroups, Ajax\semantic\html\elements\HtmlButtonGroups, Ajax\semantic\html\elements\HtmlIconGroups, Ajax\semantic\html\elements\HtmlLabelGroups, Ajax\semantic\html\elements\HtmlList, Ajax\semantic\html\elements\HtmlSegmentGroups, Ajax\semantic\html\elements\HtmlStep, Ajax\semantic\html\modules\HtmlAccordion, Ajax\semantic\html\modules\HtmlDropdown, Ajax\semantic\html\modules\HtmlShape, Ajax\semantic\html\modules\HtmlTab, Ajax\semantic\html\views\HtmlCardGroups, Ajax\semantic\html\views\HtmlItems. 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...
230
		return $result;
231
	}
232
233
	/**
234
	 * Removes the cell at position $rowIndex,$colIndex
235
	 * @param int $rowIndex
236
	 * @param int $colIndex
237
	 * @return HtmlTableContent
238
	 */
239
	public function delete($rowIndex, $colIndex=NULL) {
240
		if (isset($colIndex)) {
241
			$row=$this->getItem($rowIndex);
242
			if (isset($row) === true) {
243
				$row->delete($colIndex);
244
			}
245
		} else {
246
			$this->removeItem($rowIndex);
247
		}
248
		return $this;
249
	}
250
251
	public function toDelete($rowIndex, $colIndex){
252
		$row=$this->getItem($rowIndex);
253
		if (isset($row) === true)
254
			$row->toDelete($colIndex);
255
		return $this;
256
	}
257
258
	public function mergeCol($rowIndex=0, $colIndex=0) {
259
		return $this->getItem($rowIndex)->mergeCol($colIndex);
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 mergeCol() does only exist in the following sub-classes of Ajax\common\html\HtmlDoubleElement: Ajax\semantic\html\content\table\HtmlTD, Ajax\semantic\html\content\table\HtmlTR, Ajax\semantic\html\content\table\HtmlTableContent. 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...
260
	}
261
262
	public function mergeRow($rowIndex=0, $colIndex=0) {
263
		return $this->getItem($rowIndex)->mergeRow($colIndex);
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 mergeRow() does only exist in the following sub-classes of Ajax\common\html\HtmlDoubleElement: Ajax\semantic\html\content\table\HtmlTD, Ajax\semantic\html\content\table\HtmlTR, Ajax\semantic\html\content\table\HtmlTableContent. 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...
264
	}
265
266
	public function setFullWidth() {
267
		return $this->addToProperty("class", "full-width");
268
	}
269
270
	public function sort($colIndex) {
271
		$this->content[0]->getItem($colIndex)->addToProperty("class", "default-sort");
272
		return $this;
273
	}
274
275
	/**
276
	 * @param mixed $callback
277
	 * @param string $format
278
	 * @return HtmlTableContent
279
	 */
280
	public function conditionalCellFormat($callback, $format) {
281
		$rows=$this->content;
282
		foreach ( $rows as $row ) {
283
			$row->conditionalCellFormat($callback, $format);
284
		}
285
		return $this;
286
	}
287
288
	public function conditionalColFormat($colIndex,$callback,$format){
289
		$rows=$this->content;
290
		foreach ( $rows as $row ) {
291
			$cell=$row->getItem($colIndex);
292
			$cell->conditionnalCellFormat($callback,$format);
293
		}
294
		return $this;
295
	}
296
297
	/**
298
	 * @param mixed $callback
299
	 * @param string $format
300
	 * @return HtmlTableContent
301
	 */
302
	public function conditionalRowFormat($callback, $format) {
303
		$rows=$this->content;
304
		foreach ( $rows as $row ) {
305
			$row->conditionalRowFormat($callback, $format);
306
		}
307
		return $this;
308
	}
309
310
	public function hideColumn($colIndex){
311
		$rows=$this->content;
312
		foreach ( $rows as $row ) {
313
			$cell=$row->getItem($colIndex);
314
			$cell->addToProperty("style","display:none;");
315
		}
316
		return $this;
317
	}
318
319
	/**
320
	 * @param mixed $callback
321
	 * @return HtmlTableContent
322
	 */
323
	public function applyCells($callback) {
324
		$rows=$this->content;
325
		foreach ( $rows as $row ) {
326
			$row->applyCells($callback);
327
		}
328
		return $this;
329
	}
330
331
	/**
332
	 * @param mixed $callback
333
	 * @return HtmlTableContent
334
	 */
335
	public function applyRows($callback) {
336
		$rows=$this->content;
337
		foreach ( $rows as $row ) {
338
			$row->apply($callback);
339
		}
340
		return $this;
341
	}
342
343
	public function mergeIdentiqualValues($colIndex,$function="strip_tags"){
344
		$rows=$this->content;
345
		$identiqual=null;
346
		$counter=0;
347
		$cellToMerge=null;
348
		$functionExists=\function_exists($function);
349
		foreach ( $rows as $row ) {
350
			$cell=$row->getItem($colIndex);
351
			$value=$cell->getContent();
352
			if($functionExists)
353
				$value=\call_user_func($function,$value);
354
			if($value!==$identiqual){
355
				if($counter>0 && isset($cellToMerge)){
356
					$cellToMerge->setRowspan($counter);
357
				}
358
				$counter=0;
359
				$cellToMerge=$cell;
360
				$identiqual=$value;
361
			}
362
			$counter++;
363
		}
364
		if($counter>0 && isset($cellToMerge)){
365
			$cellToMerge->setRowspan($counter);
366
		}
367
		return $this;
368
	}
369
}
370