Test Failed
Push — master ( c57eca...857f68 )
by Pierre
04:12
created

Core   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 169
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 54
c 2
b 0
f 0
dl 0
loc 169
ccs 0
cts 42
cp 0
rs 10
wmc 17

6 Methods

Rating   Name   Duplication   Size   Complexity  
B bindArray() 0 20 7
A run() 0 29 5
A getRowset() 0 3 1
A hydrate() 0 7 2
A __construct() 0 3 1
A fromOrm() 0 11 1
1
<?php
2
3
namespace App\Component\Db;
4
5
use App\Component\Model\Orm\Orm;
6
use App\Component\Db\Factory;
7
8
class Core
9
{
10
    /**
11
     * connection
12
     *
13
     * @var \PDO | boolean
14
     */
15
    protected $connection;
16
17
    /**
18
     * logger
19
     *
20
     * @var \Monolog\Logger
21
     */
22
    protected $logger;
23
24
    /**
25
     * sql
26
     *
27
     * @var string
28
     */
29
    protected $sql;
30
31
    /**
32
     * statement
33
     *
34
     * @var \PDOStatement
35
     */
36
    protected $statement;
37
38
    /**
39
     * fetch mode
40
     *
41
     * @var int
42
     */
43
    protected $fetchMode = \PDO::FETCH_ASSOC;
44
45
    /**
46
     * database name
47
     *
48
     * @var string
49
     */
50
    protected $database;
51
52
    /**
53
     * rowset result
54
     *
55
     * @var array
56
     */
57
    protected $rowset;
58
59
    /**
60
     * instanciate
61
     */
62
    public function __construct()
63
    {
64
        $this->rowset = [];
65
    }
66
67
    /**
68
     * set connection from Orm instance
69
     *
70
     * @param Orm $ormInstance
71
     * @return Core
72
     */
73
    public function fromOrm(Orm &$ormInstance): Core
74
    {
75
        $this->database = $ormInstance->getDatabase();
76
        $container = $ormInstance->getContainer();
77
        $this->logger = $container->getService(\Monolog\Logger::class);
78
        $factory = new Factory($container);
79
        $this->connection = $factory->getConnection(
80
            $ormInstance->getSlot(),
81
            $this->database
82
        );
83
        return $this;
84
    }
85
86
    /**
87
     * run query with bind values and types
88
     *
89
     * @param string $sql
90
     * @param array $bindParams
91
     * @param array $bindTypes
92
     * @return Core
93
     */
94
    public function run(
95
        string $sql,
96
        array $bindParams = [],
97
        array $bindTypes = []
98
    ): Core {
99
        $this->sql = $sql;
100
        try {
101
            $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...
102
            if ($this->statement instanceof \PDOStatement) {
103
                $this->statement->setFetchMode($this->fetchMode);
104
                if (!empty($bindParams)) {
105
                    $this->bindArray(
106
                        $this->statement,
107
                        $bindParams,
108
                        $bindTypes
109
                    );
110
                }
111
            }
112
        } catch (\PDOException $exc) {
113
            $this->logger->alert('Prepare failed');
114
            $this->logger->alert($exc->getMessage());
115
        }
116
        try {
117
            $this->statement->execute();
118
        } catch (\PDOException $exc) {
119
            $this->logger->alert('Execute failed');
120
            $this->logger->alert($exc->getMessage());
121
        }
122
        return $this;
123
    }
124
125
    /**
126
     * hydrate
127
     *
128
     * @return Core
129
     */
130
    public function hydrate(): Core
131
    {
132
        if ($this->statement instanceof \PDOStatement) {
0 ignored issues
show
introduced by
$this->statement is always a sub-type of PDOStatement.
Loading history...
133
            $this->rowset = $this->statement->fetchAll($this->fetchMode);
134
            $this->statement->closeCursor();
135
        }
136
        return $this;
137
    }
138
139
    /**
140
     * return run result
141
     *
142
     * @return array
143
     */
144
    public function getRowset(): array
145
    {
146
        return $this->rowset;
147
    }
148
149
    /**
150
     * bindArray
151
     *
152
     * @param \PDOStatement $poStatement
153
     * @param array $paArray
154
     * @param array $forcedTypes
155
     * @return $this
156
     */
157
    public function bindArray(\PDOStatement &$poStatement, array &$paArray, array $forcedTypes = [])
158
    {
159
        foreach ($paArray as $k => $v) {
160
            $type = (is_int($v)) ? \PDO::PARAM_INT : \PDO::PARAM_STR;
161
162
            if (isset($forcedTypes[$k])) {
163
                $type = $forcedTypes[$k];
164
                $v = ($type == \PDO::PARAM_INT) ? (int) $v : $v;
165
            }
166
            $value = is_array($v) ? serialize($v) : $v;
167
            $key =  $k;
168
            try {
169
                $poStatement->bindValue($key, $value, $type);
170
            } catch (\PDOException $exc) {
171
                $this->logger->alert(
172
                    'Sql Bind Error [' . $key . ':' . $value . ':' . $type . ']'
173
                );
174
            }
175
        }
176
        return $this;
177
    }
178
}
179