Completed
Push — master ( f292c4...94b19c )
by Pierre
03:27
created

Core::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 7
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Component\Db;
4
5
use App\Component\Model\Orm\Orm;
6
use App\Component\Db\Factory;
7
use App\Component\Container;
8
9
class Core
10
{
11
    /**
12
     * connection
13
     *
14
     * @var \PDO | boolean
15
     */
16
    protected $connection;
17
18
    /**
19
     * container
20
     *
21
     * @var Container
22
     */
23
    protected $container;
24
25
    /**
26
     * factory
27
     *
28
     * @var Factory
29
     */
30
    protected $factory;
31
32
    /**
33
     * logger
34
     *
35
     * @var \Monolog\Logger
36
     */
37
    protected $logger;
38
39
    /**
40
     * sql
41
     *
42
     * @var string
43
     */
44
    protected $sql;
45
46
    /**
47
     * statement
48
     *
49
     * @var \PDOStatement
50
     */
51
    protected $statement;
52
53
    /**
54
     * fetch mode
55
     *
56
     * @var int
57
     */
58
    protected $fetchMode = \PDO::FETCH_ASSOC;
59
60
    /**
61
     * rowset result
62
     *
63
     * @var array
64
     */
65
    protected $rowset;
66
67
    /**
68
     * error
69
     *
70
     * @var boolean
71
     */
72
    protected $error;
73
74
    /**
75
     * code error
76
     *
77
     * @var string
78
     */
79
    protected $errorCode;
80
81
    /**
82
     * error message
83
     *
84
     * @var string
85
     */
86
    protected $errorMessage;
87
88
    /**
89
     * instanciate
90
     */
91 11
    public function __construct(Container $container)
92
    {
93 11
        $this->container = $container;
94 11
        $this->factory = new Factory($this->container);
95 11
        $this->logger = $this->container->getService(\Monolog\Logger::class);
96 11
        $this->rowset = [];
97 11
        $this->resetError();
98
    }
99
100
    /**
101
     * set connection from Orm instance
102
     *
103
     * @param Orm $ormInstance
104
     * @return Core
105
     */
106 2
    public function fromOrm(Orm &$ormInstance): Core
107
    {
108 2
        $this->connection = $this->factory->getConnection(
109 2
            $ormInstance->getSlot(),
110 2
            $ormInstance->getDatabase()
111
        );
112 2
        return $this;
113
    }
114
115
    /**
116
     * run query with bind values and types
117
     *
118
     * @param string $sql
119
     * @param array $bindParams
120
     * @param array $bindTypes
121
     * @return Core
122
     */
123 3
    public function run(
124
        string $sql,
125
        array $bindParams = [],
126
        array $bindTypes = []
127
    ): Core {
128 3
        $this->sql = $sql;
129 3
        $this->resetError();
130
        try {
131 3
            $this->statement = $this->connection->prepare($sql);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->connection->prepare($sql) can also be of type boolean. However, the property $statement is declared as type PDOStatement. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
132
            if ($this->statement instanceof \PDOStatement) {
133
                $this->statement->setFetchMode($this->fetchMode);
134
                if (!empty($bindParams)) {
135
                    $this->bindArray(
136
                        $this->statement,
137
                        $bindParams,
138
                        $bindTypes
139
                    );
140
                }
141
            }
142 3
        } catch (\PDOException $e) {
143 3
            $this->setError(true, $e->getCode(), $e->getMessage());
144 3
            $this->logger->alert('Core Db : Run failed');
145 3
            $this->logger->alert($this->errorMessage);
146
        }
147 3
        return $this;
148
    }
149
150
    /**
151
     * hydrate
152
     *
153
     * @return Core
154
     */
155 2
    public function hydrate(): Core
156
    {
157 2
        if ($this->statement instanceof \PDOStatement) {
0 ignored issues
show
introduced by
$this->statement is always a sub-type of PDOStatement.
Loading history...
158
            $this->rowset = $this->statement->fetchAll($this->fetchMode);
159
            $this->statement->closeCursor();
160
        }
161 2
        return $this;
162
    }
163
164
    /**
165
     * return run result
166
     *
167
     * @return array
168
     */
169 1
    public function getRowset(): array
170
    {
171 1
        return $this->rowset;
172
    }
173
174
    /**
175
     * bindArray
176
     *
177
     * @param \PDOStatement $poStatement
178
     * @param array $paArray
179
     * @param array $forcedTypes
180
     * @return $this
181
     */
182
    public function bindArray(\PDOStatement &$poStatement, array &$paArray, array $forcedTypes = [])
183
    {
184
        foreach ($paArray as $k => $v) {
185
            $type = (is_int($v)) ? \PDO::PARAM_INT : \PDO::PARAM_STR;
186
187
            if (isset($forcedTypes[$k])) {
188
                $type = $forcedTypes[$k];
189
                $v = ($type == \PDO::PARAM_INT) ? (int) $v : $v;
190
            }
191
            $value = is_array($v) ? serialize($v) : $v;
192
            $key =  $k;
193
            try {
194
                $poStatement->bindValue($key, $value, $type);
195
            } catch (\PDOException $e) {
196
                $this->setError(true, $e->getCode(), $e->getMessage());
197
                $this->logger->alert(
198
                    'Sql Bind Error [' . $key . ':' . $value . ':' . $type . ']'
199
                );
200
            }
201
        }
202
        return $this;
203
    }
204
205
    /**
206
     * set connection
207
     *
208
     * @param \PDO $connection
209
     * @return Core
210
     */
211 1
    protected function setConnection(\PDO $connection): Core
212
    {
213 1
        $this->connection = $connection;
214 1
        return $this;
215
    }
216
217
    /**
218
     * return true if error
219
     *
220
     * @return boolean
221
     */
222 4
    protected function isError(): bool
223
    {
224 4
        return $this->error === true;
225
    }
226
227
    /**
228
     * reset last error
229
     *
230
     * @return Core
231
     */
232 1
    protected function resetError(): Core
233
    {
234 1
        $this->setError(false, 0, '');
235 1
        return $this;
236
    }
237
238
    /**
239
     * get error code
240
     *
241
     * @return mixed
242
     */
243 1
    protected function getErrorCode()
244
    {
245 1
        return $this->errorCode;
246
    }
247
248
    /**
249
     * get error message
250
     *
251
     * @return string
252
     */
253 1
    protected function getErrorMessage(): string
254
    {
255 1
        return $this->errorMessage;
256
    }
257
258
    /**
259
     * set error status, code and message
260
     *
261
     * @param boolean $status
262
     * @param integer | string $code
263
     * @param string $message
264
     * @return Core
265
     */
266 1
    protected function setError(bool $status, $code, string $message): Core
267
    {
268 1
        $this->error = $status;
269 1
        $this->errorCode = $code;
270 1
        $this->errorMessage = $message;
271 1
        return $this;
272
    }
273
}
274