Passed
Branch test (a8b929)
by Roman
02:55
created

Table::truncate()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 13
ccs 12
cts 12
cp 1
rs 8.8571
cc 5
eloc 10
nc 5
nop 2
crap 5
1
<?php
2
3
namespace ToolkitLab\ASCII;
4
5
class Table {
6
7
    private $data = [];
8
    private $dimensionX;
9
    private $dimensionY;
10
    private $columnsMaxLenght = [];
11
12
    /**
13
     * Constructor
14
     * @param array $data
15
     * @param int $dimensionX
16
     * @param int $dimensionY
17
     */
18 40
    public function __construct($data, $dimensionX = null, $dimensionY = null) {
19 40
        $this->setData($data, $dimensionX, $dimensionY);
20 40
    }
21
    
22
    /**
23
     * Truncates the values, which are longer that $maxLength
24
     * @param int $maxLength
25
     * @param string $ending
26
     * @throws \InvalidArgumentException
27
     */
28 24
    public function truncate($maxLength, $ending = '...') {
29 24
        $acceptedTypes = ['integer', 'double', 'string'];
30 24
        foreach ($this->data as &$row) {
31 24
            foreach ($row as &$cell) {
32 24
                if (!in_array(gettype($cell), $acceptedTypes)) {
33 2
                    throw new \InvalidArgumentException(
34 2
                        'The values must be one of the following types: ' . implode(',', $acceptedTypes)
35 1
                    );
36
                }
37 22
                $cell = trim($cell);
38 22
                if (strlen($cell) > $maxLength) {
39 2
                    $cell = substr($cell, 0, $maxLength);
40 12
                    $cell = trim($cell, ';,. ') . $ending;
41 1
                }
42 11
            }
43 11
        }
44 22
    }
45
46
    /**
47
     * Returns the specified cell content
48
     * @param int $x
49
     * @param int $y
50
     * @return string
51
     * @throws \InvalidArgumentException
52
     */
53 28
    public function getCell($x, $y) {
54 28
        if ($x >= $this->dimensionX || $y >= $this->dimensionY) {
55 2
            throw new \InvalidArgumentException("Index Out of range");
56
        }
57 26
        if (!isset($this->data[$y][$x])) {
58 2
            return "";
59
        }
60 26
        return $this->data[$y][$x];
61
    }
62
63
    /**
64
     * Return the maximum length of the column
65
     * @param int $columnIndex
66
     * @return int
67
     */
68 22
    public function getColumnsMaxLenght($columnIndex) {
69 22
        if (isset($this->columnsMaxLenght[$columnIndex])) {
70 20
            return $this->columnsMaxLenght[$columnIndex];
71
        }
72 22
        $width = 0;
73 22
        for ($y = 0; $y < $this->dimensionY; $y++) {
74 22
            $len = strlen($this->getCell($columnIndex, $y));
75 22
            if ($len > $width) {
76 22
                $width = $len;
77 11
            }
78 11
        }
79 22
        $this->columnsMaxLenght[$columnIndex] = $width;
80 22
        return $width;
81
    }
82
83
    /**
84
     * Returns the data
85
     * @return array
86
     */
87 26
    public function getData() {
88 26
        return $this->data;
89
    }
90
91
    /**
92
     * Calculates the dimensions
93
     */
94 38
    private function calculateDimensions() {
95 38
        $this->dimensionY = $this->dimensionX = 0;
96 38
        foreach ($this->data as $row) {
97 38
            $cnt = count($row);
98 38
            if ($cnt > $this->dimensionX) {
99 38
                $this->dimensionX = $cnt;
100 19
            }
101 19
        }
102 38
        $this->dimensionY = count($this->data);
103 38
        $this->columnsMaxLenght = [];
104 38
    }
105
106
    /**
107
     * Sets the data and calculates the dimensions (if not specified)
108
     * @param array $data
109
     */
110 40
    public function setData($data, $dimensionX = null, $dimensionY = null) {
111 40
        $this->data = $data;
112 40
        if (is_null($dimensionX)) {
113 38
            $this->calculateDimensions();
114 19
        } else {
115 4
            $this->dimensionX = $dimensionX;
116 4
            $this->dimensionY = $dimensionY;
117
        }
118 40
    }
119
120
    /**
121
     * Return the length of the dimension X (width of the table)
122
     * @return int
123
     */
124 26
    public function getDimensionX() {
125 26
        return $this->dimensionX;
126
    }
127
128
    /**
129
     * Return the length of the dimension Y (height of the table)
130
     * @return int
131
     */
132 4
    public function getDimensionY() {
133 4
        return $this->dimensionY;
134
    }
135
    
136
    /**
137
     * Rotates the table
138
     * @param int $angle 90, 180, 270, -90, -180, -270
139
     * @return $this
140
     * @throws \InvalidArgumentException
141
     */
142 4
    public function rotate($angle) {
143 4
        if (in_array($angle, [90, -270])) {
144 2
            return $this->rotateClockwise();
145 4
        } elseif (in_array($angle, [-90, 270])) {
146 2
            return $this->rotateCounterclockwise();
147 4
        } elseif (in_array($angle, [180, -180])) {
148 2
            return $this->rotateClockwise()->rotateClockwise();
149
        }
150 2
        throw new \InvalidArgumentException("The angle should be one of the following: 90, 180, 270, -90, -180, -270");
151
    }
152
    
153
    /**
154
     * Rotates the data clockwise
155
     * @return $this
156
     */
157 2
    private function rotateClockwise() {
158 2
        $data = [];
159 2
        for ($i = count($this->data) - 1; $i >= 0; $i--) {
160 2
            foreach ($this->data[$i] as $key => $val) {
161 2
                $data[$key][] = $val;
162 1
            }
163 1
        }
164 2
        $this->setData($data);
165 2
        return $this;
166
    }
167
    
168
    /**
169
     * Rotates the data counterclockwise
170
     * @return $this
171
     */
172 2
    private function rotateCounterclockwise() {
173 2
        $data = [];
174 2
        for ($i = $this->getDimensionX() - 1; $i >= 0; $i--) {
175 2
            $row = [];
176 2
            foreach ($this->data as $val) {
177 2
                $row[] = $val[$i];
178 1
            }
179 2
            $data[] = $row;
180 1
        }
181 2
        $this->setData($data);
182 2
        return $this;
183
    }
184
185
}
186