Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
99.13% covered (success)
99.13%
114 / 115
92.31% covered (success)
92.31%
12 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
Table
99.13% covered (success)
99.13%
114 / 115
92.31% covered (success)
92.31%
12 / 13
48
0.00% covered (danger)
0.00%
0 / 1
 getNumberOfRows
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getRows
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasRows
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 rows
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 toArray
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 select
97.22% covered (success)
97.22%
35 / 36
0.00% covered (danger)
0.00%
0 / 1
23
 insert
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
4
 insertRows
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
1 / 1
5
 update
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
5
 delete
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
3
 setRows
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 count
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getIterator
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Pop PHP Framework (http://www.popphp.org/)
4 *
5 * @link       https://github.com/popphp/popphp-framework
6 * @author     Nick Sagona, III <dev@nolainteractive.com>
7 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
8 * @license    http://www.popphp.org/license     New BSD License
9 */
10
11/**
12 * @namespace
13 */
14namespace Pop\Db\Gateway;
15
16use Pop\Db\Db;
17use Pop\Db\Sql\Parser;
18use ArrayIterator;
19
20/**
21 * Table gateway class
22 *
23 * @category   Pop
24 * @package    Pop\Db
25 * @author     Nick Sagona, III <dev@nolainteractive.com>
26 * @copyright  Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com)
27 * @license    http://www.popphp.org/license     New BSD License
28 * @version    6.5.0
29 */
30class Table extends AbstractGateway implements \Countable, \IteratorAggregate
31{
32
33    /**
34     * Result rows
35     * @var array
36     */
37    protected array $rows = [];
38
39    /**
40     * Get the number of result rows
41     *
42     * @return int
43     */
44    public function getNumberOfRows(): int
45    {
46        return count($this->rows);
47    }
48
49    /**
50     * Get the result rows
51     *
52     * @return array
53     */
54    public function getRows(): array
55    {
56        return $this->rows;
57    }
58
59    /**
60     * Has rows
61     *
62     * @return bool
63     */
64    public function hasRows(): bool
65    {
66        return (count($this->rows) > 0);
67    }
68
69    /**
70     * Get the result rows (alias method)
71     *
72     * @return array
73     */
74    public function rows(): array
75    {
76        return $this->rows;
77    }
78
79    /**
80     * Method to convert table gateway to an array (alias method)
81     *
82     * @return array
83     */
84    public function toArray(): array
85    {
86        return $this->rows;
87    }
88
89    /**
90     * Select rows from the table
91     *
92     * @param  ?array $columns
93     * @param  mixed  $where
94     * @param  ?array $parameters
95     * @param  ?array $options
96     * @return array
97     */
98    public function select(?array $columns = null, mixed $where = null, ?array $parameters = null, ?array $options = null): array
99    {
100        $this->rows = [];
101
102        $db  = Db::getDb($this->table);
103        $sql = $db->createSql();
104
105        if ($columns === null) {
106            $columns = [$this->table . '.*'];
107        }
108
109        $sql->select($columns)->from($this->table);
110
111        if ($where !== null) {
112            $sql->select()->where($where);
113        }
114
115        if (($options !== null) && isset($options['limit'])) {
116            $sql->select()->limit((int)$options['limit']);
117        }
118
119        if (($options !== null) && isset($options['offset'])) {
120            $sql->select()->offset((int)$options['offset']);
121        }
122
123        if (($options !== null) && isset($options['join'])) {
124            $joins = (is_array($options['join']) && isset($options['join']['table'])) ?
125                [$options['join']] : $options['join'];
126
127            foreach ($joins as $join) {
128                if (isset($join['type']) && method_exists($sql->select(), $join['type'])) {
129                    $joinMethod = $join['type'];
130                    $sql->select()->{$joinMethod}($join['table'], $join['columns']);
131                } else {
132                    $sql->select()->leftJoin($join['table'], $join['columns']);
133                }
134            }
135        }
136
137        if (($options !== null) && isset($options['order'])) {
138            if (!is_array($options['order'])) {
139                $orders = (strpos($options['order'], ',') !== false) ?
140                    explode(',', $options['order']) : [$options['order']];
141            } else {
142                $orders = $options['order'];
143            }
144            foreach ($orders as $order) {
145                $ord = Parser\Order::parse(trim($order));
146                $sql->select()->orderBy($ord['by'], $db->escape($ord['order']));
147            }
148        }
149
150        if (($options !== null) && isset($options['group'])) {
151            $sql->select()->groupBy($options['group']);
152        }
153
154        $db->prepare((string)$sql);
155
156        if (($parameters !== null) && (count($parameters) > 0)) {
157            $db->bindParams($parameters);
158        }
159
160        $db->execute();
161
162        $this->rows = $db->fetchAll();
163
164        return $this->rows;
165    }
166
167    /**
168     * Insert a row of values into the table
169     *
170     * @param  array $columns
171     * @return Table
172     */
173    public function insert(array $columns): Table
174    {
175        $this->rows = [];
176
177        $db     = Db::getDb($this->table);
178        $sql    = $db->createSql();
179        $values = [];
180        $params = [];
181        $i      = 1;
182
183        foreach ($columns as $column => $value) {
184            $placeholder = $sql->getPlaceholder();
185
186            if ($placeholder == ':') {
187                $placeholder .= $column;
188            } else if ($placeholder == '$') {
189                $placeholder .= $i;
190            }
191            $values[$column] = $placeholder;
192            $params[$column] = $value;
193            $i++;
194        }
195
196        $sql->insert($this->table)->values($values);
197
198        $db->prepare((string)$sql)
199           ->bindParams($params)
200           ->execute();
201
202        return $this;
203    }
204
205    /**
206     * Insert rows of values into the table
207     *
208     * @param  array $values
209     * @return Table
210     */
211    public function insertRows(array $values): Table
212    {
213        $this->rows   = [];
214        $db           = Db::getDb($this->table);
215        $sql          = $db->createSql();
216        $placeholders = [];
217        $columns      = array_keys($values[0]);
218
219        foreach ($columns as $i => $column) {
220            $placeholder = $sql->getPlaceholder();
221
222            if ($placeholder == ':') {
223                $placeholder .= $column;
224            } else if ($placeholder == '$') {
225                $placeholder .= ($i + 1);
226            }
227            $placeholders[$column] = $placeholder;
228        }
229
230        $sql->insert($this->table)->values($placeholders);
231        $db->prepare((string)$sql);
232
233        foreach ($values as $rowValues) {
234            $db->bindParams($rowValues)->execute();
235        }
236
237        return $this;
238    }
239
240    /**
241     * Update a table
242     *
243     * @param  array  $columns
244     * @param  mixed  $where
245     * @param  ?array $parameters
246     * @return Table
247     */
248    public function update(array $columns, mixed $where = null, ?array $parameters = []): Table
249    {
250        $this->rows = [];
251
252        $db     = Db::getDb($this->table);
253        $sql    = $db->createSql();
254        $values = [];
255        $params = [];
256        $i      = 1;
257
258        foreach ($columns as $column => $value) {
259            $placeholder = $sql->getPlaceholder();
260
261            if ($placeholder == ':') {
262                $placeholder .= $column;
263            } else if ($placeholder == '$') {
264                $placeholder .= $i;
265            }
266            $values[$column] = $placeholder;
267            $params[$column] = $value;
268            $i++;
269        }
270
271        $sql->update($this->table)->values($values);
272
273        if ($where !== null) {
274            $sql->update()->where($where);
275        }
276
277        $db->prepare((string)$sql)
278           ->bindParams($params + $parameters)
279           ->execute();
280
281        return $this;
282    }
283
284    /**
285     * Delete from a table
286     *
287     * @param  mixed $where
288     * @param  array $parameters
289     * @return Table
290     */
291    public function delete(mixed $where = null, array $parameters = []): Table
292    {
293        $this->rows = [];
294
295        $db  = Db::getDb($this->table);
296        $sql = $db->createSql();
297
298        $sql->delete($this->table);
299
300        if ($where !== null) {
301            $sql->delete()->where($where);
302        }
303
304        $db->prepare((string)$sql);
305
306        if (count($parameters) > 0) {
307            $db->bindParams($parameters);
308        }
309
310        $db->execute();
311
312        return $this;
313    }
314
315    /**
316     * Set all the table rows at once
317     *
318     * @param  array  $rows
319     * @return Table
320     */
321    public function setRows(array $rows = []): Table
322    {
323        $this->rows = $rows;
324        return $this;
325    }
326
327    /**
328     * Method to get the count of items in the collection
329     *
330     * @return int
331     */
332    public function count(): int
333    {
334        return count($this->rows);
335    }
336
337    /**
338     * Method to iterate over the table rows
339     *
340     * @return ArrayIterator
341     */
342    public function getIterator(): ArrayIterator
343    {
344        return new ArrayIterator($this->rows);
345    }
346
347}