Completed
Push — master ( b39b01...f31af2 )
by Oscar
08:50
created

SimpleCrud::has()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
namespace SimpleCrud;
4
5
use Exception;
6
use PDO;
7
8
class SimpleCrud
9
{
10
    protected $connection;
11
    protected $inTransaction = false;
12
    protected $entityFactory;
13
    protected $entities = [];
14
    protected $attributes = [];
15
16
    /**
17
     * Set the connection and the entityFactory.
18
     *
19
     * @param PDO           $connection
20
     * @param EntityFactory $entityFactory
21
     */
22
    public function __construct(PDO $connection, EntityFactory $entityFactory = null)
23
    {
24
        $this->connection = $connection;
25
        $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
26
27
        $this->setEntityFactory($entityFactory ?: (new EntityFactory())->setAutocreate());
28
    }
29
30
    /**
31
     * Set the EntityFactory instance used to create all entities.
32
     *
33
     * @param EntityFactory $entityFactory
34
     */
35
    public function setEntityFactory(EntityFactory $entityFactory)
36
    {
37
        $entityFactory->setDb($this);
38
39
        $this->entityFactory = $entityFactory;
40
    }
41
42
    /**
43
     * Returns the EntityFactory instance used.
44
     *
45
     * @return EntityFactory
46
     */
47
    public function getEntityFactory()
48
    {
49
        return $this->entityFactory;
50
    }
51
52
    /**
53
     * Returns an entity.
54
     *
55
     * @param string $name The entity name
56
     *
57
     * @throws SimpleCrudException If the entity cannot be instantiated
58
     *
59
     * @return null|Entity
60
     */
61
    public function get($name)
62
    {
63
        if (isset($this->entities[$name])) {
64
            return $this->entities[$name];
65
        }
66
67
        return $this->entities[$name] = $this->entityFactory->get($name);
68
    }
69
70
    /**
71
     * Check whether an entity exists.
72
     *
73
     * @param string $name The entity name
74
     *
75
     * @throws SimpleCrudException If the entity cannot be instantiated
76
     *
77
     * @return null|Entity
78
     */
79
    public function has($name)
80
    {
81
        return isset($this->entities[$name]) || $this->entityFactory->has($name);
82
    }
83
84
    /**
85
     * Magic method to initialize the entities in lazy mode.
86
     *
87
     * @param string $name The entity name
88
     *
89
     * @throws SimpleCrudException If the entity cannot be instantiated
90
     *
91
     * @return null|Entity
92
     */
93
    public function __get($name)
94
    {
95
        return $this->get($name);
96
    }
97
98
    /**
99
     * Magic method to check if a entity exists or not.
100
     *
101
     * @param string $name
102
     *
103
     * @return bool
104
     */
105
    public function __isset($name)
106
    {
107
        return $this->has($name);
108
    }
109
110
    /**
111
     * Execute a query and returns the statement object with the result.
112
     *
113
     * @param string $query The Mysql query to execute
114
     * @param array  $marks The marks passed to the statement
115
     *
116
     * @throws Exception On error preparing or executing the statement
117
     *
118
     * @return PDOStatement The result
119
     */
120
    public function execute($query, array $marks = null)
121
    {
122
        $query = (string) $query;
123
124
        if (!empty($marks)) {
125
            foreach ($marks as $name => $mark) {
126
                if (is_array($mark)) {
127
                    foreach ($mark as &$val) {
128
                        $val = $this->connection->quote($val);
129
                    }
130
131
                    $query = str_replace($name, implode(', ', $mark), $query);
132
                    unset($marks[$name]);
133
                }
134
            }
135
            if (empty($marks)) {
136
                $marks = null;
137
            }
138
        }
139
140
        $statement = $this->connection->prepare($query);
141
        $statement->execute($marks);
142
143
        return $statement;
144
    }
145
146
    /**
147
     * Execute a callable inside a transaction.
148
     *
149
     * @param callable $callable The function with all operations
150
     *
151
     * @return mixed The callable returned value
152
     */
153
    public function executeTransaction(callable $callable)
154
    {
155
        try {
156
            $transaction = $this->beginTransaction();
157
158
            $return = $callable();
159
160
            if ($transaction) {
161
                $this->commit();
162
            }
163
        } catch (Exception $exception) {
164
            if ($transaction) {
165
                $this->rollBack();
166
            }
167
168
            throw $exception;
169
        }
170
171
        return $return;
172
    }
173
174
    /**
175
     * Returns the last insert id.
176
     *
177
     * @return string
178
     */
179
    public function lastInsertId()
180
    {
181
        return $this->connection->lastInsertId();
182
    }
183
184
    /**
185
     * Starts a transaction if it's not started yet.
186
     *
187
     * @return bool True if a the transaction is started or false if don't
188
     */
189
    public function beginTransaction()
190
    {
191
        if (!$this->inTransaction()) {
192
            $this->connection->beginTransaction();
193
194
            return $this->inTransaction = true;
195
        }
196
197
        return false;
198
    }
199
200
    /**
201
     * Commits the changes of the transaction to the database.
202
     */
203
    public function commit()
204
    {
205
        if ($this->inTransaction()) {
206
            $this->connection->commit();
207
            $this->inTransaction = false;
208
        }
209
    }
210
211
    /**
212
     * RollBack a transaction.
213
     */
214
    public function rollBack()
215
    {
216
        if ($this->inTransaction()) {
217
            $this->connection->rollBack();
218
            $this->inTransaction = false;
219
        }
220
    }
221
222
    /**
223
     * Check if there is a transaction opened currently in this adapter.
224
     */
225
    public function inTransaction()
226
    {
227
        return ($this->inTransaction === true) && ($this->connection->inTransaction() === true);
228
    }
229
230
    /**
231
     * Saves a new attribute.
232
     *
233
     * @param string $name
234
     * @param mixed  $value
235
     *
236
     * @return $this
237
     */
238
    public function setAttribute($name, $value)
239
    {
240
        $this->attributes[$name] = $value;
241
242
        return $this;
243
    }
244
245
    /**
246
     * Returns an attribute.
247
     *
248
     * @param string|int $name
249
     *
250
     * @return null|mixed
251
     */
252
    public function getAttribute($name)
253
    {
254
        if (is_int($name)) {
255
            return $this->connection->getAttribute($name);
256
        }
257
258
        return isset($this->attributes[$name]) ? $this->attributes[$name] : null;
259
    }
260
261
    /**
262
     * Returns all tables.
263
     *
264
     * @return array
265
     */
266
    public function getTables()
267
    {
268
        $class = 'SimpleCrud\\Queries\\'.ucfirst($this->getAttribute(PDO::ATTR_DRIVER_NAME)).'\\DbInfo';
269
270
        return $class::getTables($this);
271
    }
272
273
    /**
274
     * Returns the field info of a table.
275
     *
276
     * @param string $table
277
     *
278
     * @return array
279
     */
280
    public function getFields($table)
281
    {
282
        $class = 'SimpleCrud\\Queries\\'.ucfirst($this->getAttribute(PDO::ATTR_DRIVER_NAME)).'\\DbInfo';
283
284
        return $class::getFields($this, $table);
285
    }
286
}
287