Completed
Push — master ( f662ec...5059ab )
by Jean-Christophe
02:58
created

HtmlTableContent::getCell()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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