HtmlTR::getColPosition()   B
last analyzed

Complexity

Conditions 7
Paths 16

Size

Total Lines 21
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 21
rs 7.551
cc 7
eloc 17
nc 16
nop 1
1
<?php
2
3
namespace Ajax\semantic\html\content\table;
4
5
use Ajax\semantic\html\base\HtmlSemCollection;
6
use Ajax\semantic\html\base\constants\State;
7
use Ajax\semantic\html\base\traits\TableElementTrait;
8
use Ajax\service\JArray;
9
10
/**
11
 *
12
 * @author jc
13
 *
14
 */
15
class HtmlTR extends HtmlSemCollection {
16
	use TableElementTrait;
17
	private $_tdTagName;
18
	private $_container;
19
	private $_row;
20
21
	public function __construct($identifier) {
22
		parent::__construct($identifier, "tr", "");
23
		$this->_states=[ State::ACTIVE,State::POSITIVE,State::NEGATIVE,State::WARNING,State::ERROR,State::DISABLED ];
24
	}
25
26
	public function setColCount($colCount) {
27
		$count=$this->count();
28
		for($i=$count; $i < $colCount; $i++) {
29
			$item=$this->addItem(NULL);
30
			$item->setTagName($this->_tdTagName);
31
		}
32
		return $this;
33
	}
34
35
	/**
36
	 *
37
	 * {@inheritDoc}
38
	 *
39
	 * @see \Ajax\common\html\HtmlCollection::createItem()
40
	 */
41
	protected function createItem($value) {
42
		$count=$this->count();
43
		$td=new HtmlTD("", $value, $this->_tdTagName);
44
		$td->setContainer($this->_container, $this->_row, $count);
45
		return $td;
46
	}
47
48
	public function setTdTagName($tagName="td") {
49
		$this->_tdTagName=$tagName;
50
	}
51
52
	/**
53
	 * Define the container (HtmlTableContent) and the num of the row
54
	 * @param HtmlTableContent $container
55
	 * @param int $row
56
	 */
57
	public function setContainer($container, $row) {
58
		$this->_container=$container;
59
		$this->_row=$row;
60
	}
61
62
	/**
63
	 * Sets values to the row cols
64
	 * @param mixed $values
65
	 */
66
	public function setValues($values=array()) {
67
		$count=$this->count();
68
		if (\is_array($values) === false) {
69
			$values=\array_fill(0, $count, $values);
70
		} else {
71
			if (JArray::isAssociative($values) === true) {
72
				$values=\array_values($values);
73
			}
74
		}
75
		$count=\min(\sizeof($values), $count);
76
		
77
		for($i=0; $i < $count; $i++) {
78
			$cell=$this->content[$i];
79
			$cell->setValue($values[$i]);
80
		}
81
	}
82
83
	/**
84
	 * Removes the col at $index
85
	 * @param int $index the index of the col to remove
86
	 * @return \Ajax\semantic\html\content\table\HtmlTR
87
	 */
88
	public function delete($index) {
89
		$this->removeItem($index);
90
		return $this;
91
	}
92
93
	public function mergeCol($colIndex=0) {
94
		return $this->getItem($colIndex)->mergeCol();
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...
95
	}
96
97
	public function mergeRow($colIndex=0) {
98
		return $this->getItem($colIndex)->mergeRow();
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...
99
	}
100
101
	public function getColPosition($colIndex) {
102
		$pos=0;
103
		$rows=$this->_container->getContent();
104
		for($i=0; $i < $this->_row; $i++) {
105
			$max=\min($colIndex, $rows[$i]->count());
106
			for($j=0; $j < $max; $j++) {
107
				$rowspan=$rows[$i]->getItem($j)->getRowspan();
108
				if ($rowspan + $i > $this->_row)
109
					$pos++;
110
			}
111
		}
112
		if ($pos > $colIndex)
113
			return NULL;
114
		$count=$this->count();
115
		for($i=0; $i < $count; $i++) {
116
			$pos+=$this->content[$i]->getColspan();
117
			if ($pos >= $colIndex + 1)
118
				return $i;
119
		}
120
		return null;
121
	}
122
123
	public function conditionalCellFormat($callback, $format) {
124
		$cells=$this->content;
125
		foreach ( $cells as $cell ) {
126
			$cell->conditionalCellFormat($callback, $format);
127
		}
128
		return $this;
129
	}
130
131
	public function conditionalRowFormat($callback, $format) {
132
		if ($callback($this)) {
133
			$this->addToProperty("class", $format);
134
		}
135
		return $this;
136
	}
137
138
	public function containsStr($needle) {
139
		$cells=$this->content;
140
		foreach ( $cells as $cell ) {
141
			if (\strpos($cell->getContent(), $needle) !== false)
142
				return true;
143
		}
144
		return false;
145
	}
146
147
	public function apply($callback) {
148
		$callback($this);
149
		return $this;
150
	}
151
152
	public function applyCells($callback) {
153
		$cells=$this->content;
154
		foreach ( $cells as $cell ) {
155
			$cell->apply($callback);
156
		}
157
		return $this;
158
	}
159
}