PdoTrait::fetchList()   A
last analyzed

Complexity

Conditions 6
Paths 16

Size

Total Lines 30
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6.0106

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 14
c 1
b 0
f 0
nc 16
nop 5
dl 0
loc 30
ccs 14
cts 15
cp 0.9333
crap 6.0106
rs 9.2222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace LibraryCatalog\Service\Repository;
6
7
trait PdoTrait
8
{
9
    /** @var \PDO */
10
    protected \PDO $pdo;
11
    /** @var bool */
12
    protected bool $pdoReady = false;
13
    /** @var \Closure */
14
    protected \Closure $connection;
15
16
    /**
17
     * @param string $host
18
     * @param string $user
19
     * @param string $password
20
     * @param string $dbname
21
     */
22
    protected function prepareConnection(string $host, string $user, string $password, string $dbname): void
23
    {
24
        $this->connection = function () use ($host, $user, $password, $dbname): \PDO {
25
            if (!$this->pdoReady) {
26
                $this->pdo = new \PDO(
27
                    sprintf('mysql:dbname=%s;host=%s', $dbname, $host),
28
                    $user,
29
                    $password,
30
                    array(\PDO::ATTR_PERSISTENT => true)
31
                );
32
                $this->pdoReady = true;
33
            }
34
            return $this->pdo;
35
        };
36
    }
37
38
    /**
39
     * @param string $table
40
     * @param mixed $id
41
     * @return array|null
42
     * @throws Exception
43
     */
44 7
    protected function fetchOne(string $table, $id): ?array
45
    {
46
        /** @var \PDO $pdo */
47 7
        $pdo = ($this->connection)();
48
49 7
        $stmt = $pdo->prepare("SELECT * FROM $table WHERE id = ? LIMIT 1");
50 7
        if ($stmt === false) {
51
            throw new Exception("Can not init PDO: " . json_encode($pdo->errorInfo()), (int)$pdo->errorCode());
52
        }
53 7
        $stmt->execute([$id]);
54 7
        $res = $stmt->fetch(\PDO::FETCH_ASSOC);
55
        // Convert false to null.
56 7
        return $res ?: null;
57
    }
58
59
    /**
60
     * @param string $table
61
     * @param string $condition
62
     * @param array $conditionData
63
     * @param int $limit
64
     * @param string $order
65
     * @return array
66
     * @throws Exception
67
     */
68 4
    protected function fetchList(
69
        string $table,
70
        string $condition = '',
71
        array $conditionData = [],
72
        int $limit = 1000,
73
        string $order = ''
74
    ): array {
75
        /** @var \PDO $pdo */
76 4
        $pdo = ($this->connection)();
77
78
        // Prepare SQL with params.
79 4
        $sql = "SELECT * FROM $table";
80 4
        if ($condition != '') {
81 4
            $sql .= ' WHERE ' . $condition;
82
        }
83 4
        if ($order != '') {
84 3
            $sql .= ' ORDER BY ' . $order;
85
        }
86 4
        if ($limit > 0) {
87 4
            $sql .= ' LIMIT ' . $limit;
88
        }
89
90 4
        $stmt = $pdo->prepare($sql);
91 4
        if ($stmt === false) {
92
            throw new Exception("Can not init PDO: " . json_encode($pdo->errorInfo()), (int)$pdo->errorCode());
93
        }
94 4
        $stmt->execute($conditionData);
95 4
        $res = $stmt->fetchAll(\PDO::FETCH_ASSOC);
96
        // Convert false to empty result.
97 4
        return $res ?: [];
98
    }
99
100
    /**
101
     * Inserts data and returns its ID.
102
     *
103
     * @param string $table
104
     * @param array $data
105
     * @return mixed
106
     * @throws Exception
107
     */
108 4
    protected function insert(string $table, array $data)
109
    {
110 4
        $rowNames = '';
111 4
        $rowValues = '';
112 4
        foreach ($data as $name => $value) {
113 4
            if ($value !== null) {
114 4
                if ($rowNames !== '') {
115 4
                    $rowNames .= ',';
116
                }
117 4
                if ($rowValues !== '') {
118 4
                    $rowValues .= ',';
119
                }
120 4
                $rowNames .= $name;
121 4
                $rowValues .= ':' . $name;
122
            } else {
123 1
                unset($data[$name]);
124
            }
125
        }
126
127
        /** @var \PDO $pdo */
128 4
        $pdo = ($this->connection)();
129 4
        $stmt = $pdo->prepare("INSERT INTO $table ($rowNames) VALUES ($rowValues)");
130 4
        if ($stmt === false) {
131
            throw new Exception("Can not init PDO: " . json_encode($pdo->errorInfo()), (int)$pdo->errorCode());
132
        }
133 4
        if (!$stmt->execute($data)) {
134
            throw new Exception("Can not insert data in PDO: " . json_encode($pdo->errorInfo()), (int)$pdo->errorCode());
135
        }
136
137 4
        return $pdo->lastInsertId();
138
    }
139
}
140