Table::calculateDimensions()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

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