Completed
Push — feature/controller ( 08e254...534c3a )
by René
09:48
created

Table   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 174
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 62.5%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 14
c 3
b 0
f 0
lcom 1
cbo 7
dl 0
loc 174
ccs 30
cts 48
cp 0.625
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A getTableName() 0 4 1
A update() 0 4 1
A delete() 0 4 1
A __construct() 0 18 4
A findAll() 0 7 1
A findBy() 0 21 2
A insert() 0 16 1
A createCommand() 0 10 1
A createEntitiesFromStatement() 0 12 2
1
<?php
2
3
namespace Zortje\MVC\Model\Table;
4
5
use Zortje\MVC\Model\SQLCommand;
6
use Zortje\MVC\Model\Table\Entity\Entity;
7
use Zortje\MVC\Model\Table\Entity\EntityFactory;
8
use Zortje\MVC\Model\Table\Entity\Exception\EntityClassNonexistentException;
9
use Zortje\MVC\Model\Table\Entity\Exception\EntityClassNotDefinedException;
10
use Zortje\MVC\Model\Table\Entity\Exception\InvalidEntityPropertyException;
11
use Zortje\MVC\Model\Table\Exception\TableNameNotDefinedException;
12
13
/**
14
 * Class Table
15
 *
16
 * @package Zortje\MVC\Model\Table
17
 */
18
abstract class Table
19
{
20
21
    /**
22
     * @var \PDO Connection
23
     */
24
    protected $pdo;
25
26
    /**
27
     * @var string Table name
28
     */
29
    protected $tableName;
30
31
    /**
32
     * @var String Entity class
33
     */
34
    protected $entityClass;
35
36
    /**
37
     * @var SQLCommand SQL Command
38
     */
39
    protected $sqlCommand;
40
41
    /**
42
     * Get table name
43
     *
44
     * @return string Table name
45
     */
46 1
    public function getTableName()
47
    {
48 1
        return $this->tableName;
49
    }
50
51
    /**
52
     * Find all entities
53
     *
54
     * @return Entity[] Entities
55
     */
56 1
    public function findAll()
57
    {
58 1
        $stmt = $this->pdo->prepare($this->sqlCommand->selectFrom());
59 1
        $stmt->execute();
60
61 1
        return $this->createEntitiesFromStatement($stmt);
62
    }
63
64
    /**
65
     * Find all entities where key is equal to the given value
66
     *
67
     * @param $key
68
     * @param $value
69
     *
70
     * @throws InvalidEntityPropertyException If entity does not have that property
71
     *
72
     * @return Entity[] Entities
73
     */
74 3
    public function findBy($key, $value)
75
    {
76
        /**
77
         * Check if entity have the property
78
         */
79 3
        $reflector = new \ReflectionClass($this->entityClass);
80
81 3
        $entity = $reflector->newInstanceWithoutConstructor();
82
83 3
        if (!isset($entity::getColumns()[$key])) {
84 1
            throw new InvalidEntityPropertyException([$this->entityClass, $key]);
85
        }
86
87
        /**
88
         * Execute with key-value condition
89
         */
90 2
        $stmt = $this->pdo->prepare($this->sqlCommand->selectFromWhere($key));
91 2
        $stmt->execute([":$key" => $value]);
92
93 2
        return $this->createEntitiesFromStatement($stmt);
94
    }
95
96
    /**
97
     * Insert entity into dabase
98
     *
99
     * @param Entity $entity Entity
100
     *
101
     * @return int Inserted entity ID
102
     */
103 1
    public function insert(Entity $entity)
104
    {
105 1
        $stmt = $this->pdo->prepare($this->sqlCommand->insertInto());
106
107 1
        $now = new \DateTime();
108 1
        $now = $now->format('Y-m-d H:i:s');
109
110 1
        $array = array_merge($entity->toArray(false), [
111 1
            'modified' => $now,
112 1
            'created'  => $now
113
        ]);
114
115 1
        $stmt->execute($array);
116
117 1
        return (int) $this->pdo->lastInsertId();
118
    }
119
120
    public function update(Entity $entity)
0 ignored issues
show
Unused Code introduced by
The parameter $entity is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
121
    {
122
        // @todo Implement
123
    }
124
125
    public function delete(Entity $entity)
0 ignored issues
show
Unused Code introduced by
The parameter $entity is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
126
    {
127
        // @todo Implement
128
    }
129
130
    /**
131
     * Creates an array of Entity objects from statement
132
     *
133
     * @param \PDOStatement $statement
134
     *
135
     * @return Entity[] Entities from statement
136
     */
137
    protected function createEntitiesFromStatement(\PDOStatement $statement)
138
    {
139
        $entities = [];
140
141
        $entityFactory = new EntityFactory($this->entityClass);
142
143
        foreach ($statement as $row) {
144
            $entities[] = $entityFactory->createFromArray($row);
145
        }
146
147
        return $entities;
148
    }
149
150
    /**
151
     * Create SQLCommand for this Table with provided Entity
152
     *
153
     * @return SQLCommand
154
     */
155
    protected function createCommand()
156
    {
157
        $reflector = new \ReflectionClass($this->entityClass);
158
159
        $entity = $reflector->newInstanceWithoutConstructor();
160
161
        $columns = $entity::getColumns();
162
163
        return new SQLCommand($this->tableName, $columns);
164
    }
165
166
    /**
167
     * @param \PDO $pdo
168
     *
169
     * @throws TableNameNotDefinedException If table name is not defined in subclass
170
     * @throws EntityClassNotDefinedException If entity class is not defined in subclass
171
     * @throws EntityClassNonexistentException If entity class is nonexistent
172
     */
173 1
    public function __construct(\PDO $pdo)
174
    {
175 1
        if ($this->tableName === null) {
176
            throw new TableNameNotDefinedException([get_class($this)]);
177
        }
178
179 1
        if ($this->entityClass === null) {
180
            throw new EntityClassNotDefinedException([get_class($this)]);
181 1
        } elseif (!class_exists($this->entityClass)) {
182
            throw new EntityClassNonexistentException([get_class($this), $this->entityClass]);
183
        }
184
185
        // @todo should check if `$this->entityClass` is subclass of Entity class
186
187 1
        $this->pdo = $pdo;
188
189 1
        $this->sqlCommand = $this->createCommand();
190 1
    }
191
}
192