Security update for permissions_by_term
[yaffs-website] / vendor / behat / gherkin / src / Behat / Gherkin / Node / TableNode.php
1 <?php
2
3 /*
4  * This file is part of the Behat Gherkin.
5  * (c) Konstantin Kudryashov <ever.zet@gmail.com>
6  *
7  * For the full copyright and license information, please view the LICENSE
8  * file that was distributed with this source code.
9  */
10
11 namespace Behat\Gherkin\Node;
12
13 use ArrayIterator;
14 use Behat\Gherkin\Exception\NodeException;
15 use Iterator;
16 use IteratorAggregate;
17
18 /**
19  * Represents Gherkin Table argument.
20  *
21  * @author Konstantin Kudryashov <ever.zet@gmail.com>
22  */
23 class TableNode implements ArgumentInterface, IteratorAggregate
24 {
25     /**
26      * @var array
27      */
28     private $table;
29     /**
30      * @var integer
31      */
32     private $maxLineLength = array();
33
34     /**
35      * Initializes table.
36      *
37      * @param array $table Table in form of [$rowLineNumber => [$val1, $val2, $val3]]
38      *
39      * @throws NodeException If the given table is invalid
40      */
41     public function __construct(array $table)
42     {
43         $this->table = $table;
44         $columnCount = null;
45
46         foreach ($this->getRows() as $row) {
47             if ($columnCount === null) {
48                 $columnCount = count($row);
49             }
50
51             if (count($row) !== $columnCount) {
52                 throw new NodeException('Table does not have same number of columns in every row.');
53             }
54
55             if (!is_array($row)) {
56                 throw new NodeException('Table is not two-dimensional.');
57             }
58
59             foreach ($row as $column => $string) {
60                 if (!isset($this->maxLineLength[$column])) {
61                     $this->maxLineLength[$column] = 0;
62                 }
63
64                 if (!is_scalar($string)) {
65                     throw new NodeException('Table is not two-dimensional.');
66                 }
67
68                 $this->maxLineLength[$column] = max($this->maxLineLength[$column], mb_strlen($string, 'utf8'));
69             }
70         }
71     }
72
73     /**
74      * Creates a table from a given list.
75      *
76      * @param array $list One-dimensional array
77      *
78      * @return TableNode
79      *
80      * @throws NodeException If the given list is not a one-dimensional array
81      */
82     public static function fromList(array $list)
83     {
84         if (count($list) !== count($list, COUNT_RECURSIVE)) {
85             throw new NodeException('List is not a one-dimensional array.');
86         }
87
88         array_walk($list, function (&$item) {
89             $item = array($item);
90         });
91         return new self($list);
92     }
93
94     /**
95      * Returns node type.
96      *
97      * @return string
98      */
99     public function getNodeType()
100     {
101         return 'Table';
102     }
103
104     /**
105      * Returns table hash, formed by columns (ColumnsHash).
106      *
107      * @return array
108      */
109     public function getHash()
110     {
111         return $this->getColumnsHash();
112     }
113
114     /**
115      * Returns table hash, formed by columns.
116      *
117      * @return array
118      */
119     public function getColumnsHash()
120     {
121         $rows = $this->getRows();
122         $keys = array_shift($rows);
123
124         $hash = array();
125         foreach ($rows as $row) {
126             $hash[] = array_combine($keys, $row);
127         }
128
129         return $hash;
130     }
131
132     /**
133      * Returns table hash, formed by rows.
134      *
135      * @return array
136      */
137     public function getRowsHash()
138     {
139         $hash = array();
140
141         foreach ($this->getRows() as $row) {
142             $hash[array_shift($row)] = (1 == count($row)) ? $row[0] : $row;
143         }
144
145         return $hash;
146     }
147
148     /**
149      * Returns numerated table lines.
150      * Line numbers are keys, lines are values.
151      *
152      * @return array
153      */
154     public function getTable()
155     {
156         return $this->table;
157     }
158
159     /**
160      * Returns table rows.
161      *
162      * @return array
163      */
164     public function getRows()
165     {
166         return array_values($this->table);
167     }
168
169     /**
170      * Returns table definition lines.
171      *
172      * @return array
173      */
174     public function getLines()
175     {
176         return array_keys($this->table);
177     }
178
179     /**
180      * Returns specific row in a table.
181      *
182      * @param integer $index Row number
183      *
184      * @return array
185      *
186      * @throws NodeException If row with specified index does not exist
187      */
188     public function getRow($index)
189     {
190         $rows = $this->getRows();
191
192         if (!isset($rows[$index])) {
193             throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
194         }
195
196         return $rows[$index];
197     }
198
199     /**
200      * Returns specific column in a table.
201      *
202      * @param integer $index Column number
203      *
204      * @return array
205      *
206      * @throws NodeException If column with specified index does not exist
207      */
208     public function getColumn($index)
209     {
210         if ($index >= count($this->getRow(0))) {
211             throw new NodeException(sprintf('Column #%d does not exist in table.', $index));
212         }
213
214         $rows = $this->getRows();
215         $column = array();
216
217         foreach ($rows as $row) {
218             $column[] = $row[$index];
219         }
220
221         return $column;
222     }
223
224     /**
225      * Returns line number at which specific row was defined.
226      *
227      * @param integer $index
228      *
229      * @return integer
230      *
231      * @throws NodeException If row with specified index does not exist
232      */
233     public function getRowLine($index)
234     {
235         $lines = array_keys($this->table);
236
237         if (!isset($lines[$index])) {
238             throw new NodeException(sprintf('Rows #%d does not exist in table.', $index));
239         }
240
241         return $lines[$index];
242     }
243
244     /**
245      * Converts row into delimited string.
246      *
247      * @param integer $rowNum Row number
248      *
249      * @return string
250      */
251     public function getRowAsString($rowNum)
252     {
253         $values = array();
254         foreach ($this->getRow($rowNum) as $column => $value) {
255             $values[] = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
256         }
257
258         return sprintf('|%s|', implode('|', $values));
259     }
260
261     /**
262      * Converts row into delimited string.
263      *
264      * @param integer  $rowNum  Row number
265      * @param callable $wrapper Wrapper function
266      *
267      * @return string
268      */
269     public function getRowAsStringWithWrappedValues($rowNum, $wrapper)
270     {
271         $values = array();
272         foreach ($this->getRow($rowNum) as $column => $value) {
273             $value = $this->padRight(' ' . $value . ' ', $this->maxLineLength[$column] + 2);
274
275             $values[] = call_user_func($wrapper, $value, $column);
276         }
277
278         return sprintf('|%s|', implode('|', $values));
279     }
280
281     /**
282      * Converts entire table into string
283      *
284      * @return string
285      */
286     public function getTableAsString()
287     {
288         $lines = array();
289         for ($i = 0; $i < count($this->getRows()); $i++) {
290             $lines[] = $this->getRowAsString($i);
291         }
292
293         return implode("\n", $lines);
294     }
295
296     /**
297      * Returns line number at which table was started.
298      *
299      * @return integer
300      */
301     public function getLine()
302     {
303         return $this->getRowLine(0);
304     }
305
306     /**
307      * Converts table into string
308      *
309      * @return string
310      */
311     public function __toString()
312     {
313         return $this->getTableAsString();
314     }
315
316     /**
317      * Retrieves a hash iterator.
318      *
319      * @return Iterator
320      */
321     public function getIterator()
322     {
323         return new ArrayIterator($this->getHash());
324     }
325
326     /**
327      * Pads string right.
328      *
329      * @param string  $text   Text to pad
330      * @param integer $length Length
331      *
332      * @return string
333      */
334     protected function padRight($text, $length)
335     {
336         while ($length > mb_strlen($text, 'utf8')) {
337             $text = $text . ' ';
338         }
339
340         return $text;
341     }
342 }