Completed
Pull Request — master (#4)
by Oyebanji Jacob
05:41 queued 03:17
created

Model::get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 12
rs 9.4285
cc 2
eloc 8
nc 2
nop 1
1
<?php
2
3
namespace Pyjac\ORM;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use PDO;
7
use Pyjac\ORM\Exception\ModelNotFoundException;
8
9
abstract class Model implements ModelInterface
10
{
11
    /**
12
     * The table associated with the model.
13
     *
14
     * @var string
15
     */
16
    protected $table;
17
18
    protected $properties = [];
19
20
    /**
21
     * Store instance of database connection used.
22
     *
23
     * @var Pyjac\ORM\DatabaseConnection
24
     */
25
    protected $databaseConnection;
26
27
     /**
28
      *  The id of the model.
29
      *
30
      * @property string $id
31
      */
32
33
     /**
34
      * Create a model instance.
35
      */
36
     public function __construct(DatabaseConnectionInterface $databaseConnection = null)
37
     {
38
         if ($databaseConnection == null) {
39
             $this->databaseConnection = DatabaseConnection::getInstance()->databaseConnection;
40
         } else {
41
             $this->databaseConnection = $databaseConnection;
0 ignored issues
show
Documentation Bug introduced by
It seems like $databaseConnection of type object<Pyjac\ORM\DatabaseConnectionInterface> is incompatible with the declared type object<Pyjac\ORM\Pyjac\ORM\DatabaseConnection> of property $databaseConnection.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
42
         }
43
     }
44
45
    /**
46
     * Sets into $properties the $key => $value pairs.
47
     *
48
     * @param string $key
49
     * @param string $val
50
     */
51
    public function __set($key, $val)
52
    {
53
        $this->properties[$key] = $val;
54
    }
55
56
    /**
57
     * @param string $key
58
     *
59
     * @return array
60
     */
61
    public function __get($key)
62
    {
63
        if (isset($this->properties[$key])) {
64
            return $this->properties[$key];
65
        }
66
    }
67
68
     /**
69
      * Get all the model properties.
70
      *
71
      * @return array
72
      */
73
     public function getProperties()
74
     {
75
         return $this->properties;
76
     }
77
78
     /**
79
      * Set model properties.
80
      */
81
     public function setProperties(array $properties)
82
     {
83
         $this->properties = $properties;
84
     }
85
86
    /**
87
     * Pluralize the name of the child class.
88
     *
89
     * @return string
90
     */
91
    public function getTableName()
92
    {
93
        if (isset($this->table) && !empty($this->table)) {
94
            return $this->table;
95
        }
96
        $className = explode('\\', get_called_class());
97
98
        return Inflector::pluralize(strtolower(end($className)));
99
    }
100
101
    /**
102
     * Find the particular model with the passed id.
103
     *
104
     * @param int $id
105
     *
106
     * @return object
107
     */
108
    public static function find($id)
109
    {
110
        $model = new static();
111
112
        return $model->get($id);
113
    }
114
115
    /**
116
     * Get the particular model with the passed id.
117
     *
118
     * @param int $id
119
     *
120
     * @return object
121
     */
122
    public function get($id)
123
    {
124
        $sql = "SELECT * FROM {$this->getTableName()} WHERE id={$id}";
125
        $sqlStatement = $this->databaseConnection->prepare($sql);
126
        $sqlStatement->setFetchMode(PDO::FETCH_CLASS, get_called_class());
127
        $sqlStatement->execute();
128
        if ($sqlStatement->rowCount() < 1) {
129
            throw new ModelNotFoundException($id);
130
        }
131
132
        return $sqlStatement->fetch();
133
    }
134
135
    /**
136
     * Get all the models from the database.
137
     *
138
     * @return array
139
     */
140
    public static function getAll()
141
    {
142
        $model = new static();
143
144
        return $model->all();
145
    }
146
147
    /**
148
     * Returns all the models from the database.
149
     *
150
     * @return array
151
     */
152
    public function all()
153
    {
154
        $sql = "SELECT * FROM {$this->getTableName()}";
155
        $sqlStatement = $this->databaseConnection->prepare($sql);
156
        $sqlStatement->execute();
157
158
        return $sqlStatement->fetchAll(PDO::FETCH_CLASS);
159
    }
160
161
    /**
162
     * Update the model in the database.
163
     *
164
     * @return int
165
     */
166
    public function update()
167
    {
168
        $bindNameParameters = [];
169
        $sqlUpdate = 'UPDATE '.$this->getTableName().' SET ';
170 View Code Duplication
        foreach ($this->properties as $columnName => $columnValue) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
171
            if ($columnName == 'id') {
172
                continue;
173
            }
174
            $bindColumnName = ':'.$columnName;
175
            $sqlUpdate .= "$columnName = $bindColumnName,";
176
            $bindNameParameters[$bindColumnName] = $columnValue;
177
        }
178
        //Remove the last comma in sql command then join it to the other query part.
179
        $sqlUpdate = substr($sqlUpdate, 0, -1).' WHERE id = :id';
180
        $sqlStatement = $this->databaseConnection->prepare($sqlUpdate);
181
        $bindNameParameters[':id'] = $this->properties['id'];
182
        $sqlStatement->execute($bindNameParameters);
183
184
        return $sqlStatement->rowCount();
185
    }
186
187
    /**
188
     * Insert the model values into the database.
189
     *
190
     * @return int
191
     */
192
    public function create()
193
    {
194
        $columnNames = '';
195
        $columnValues = '';
196
        $bindNameParameters = [];
197
        $sqlCreate = 'INSERT'.' INTO '.$this->getTableName().' (';
198 View Code Duplication
        foreach ($this->properties as $columnName => $columnValue) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
            $bindColumnName = ':'.$columnName;
200
            $columnNames .= $columnName.',';
201
            $columnValues .= $bindColumnName.',';
202
            $bindNameParameters[$bindColumnName] = $columnValue;
203
        }
204
        // Remove ending comma and whitespace.
205
        $columnNames = substr($columnNames, 0, -1);
206
        $columnValues = substr($columnValues, 0, -1);
207
208
        $sqlCreate .= $columnNames.') VALUES ('.$columnValues.')';
209
        $sqlStatement = $this->databaseConnection->prepare($sqlCreate);
210
        $sqlStatement->execute($bindNameParameters);
211
212
        return $sqlStatement->rowCount();
213
    }
214
215
    /**
216
     * Save the model data to the database.
217
     *
218
     * @return bool
219
     */
220
    public function save()
221
    {
222
        return isset($this->properties['id']) ? $this->update() : $this->create();
223
    }
224
225
    /**
226
     * Delete a model from the database.
227
     *
228
     * @param int $id
229
     *
230
     * @return bool
231
     */
232
    public static function destroy($id)
233
    {
234
        $model = new static();
235
236
        return $model->delete($id);
237
    }
238
239
    /**
240
     * Delete model from the database.
241
     *
242
     * @param int $id
243
     *
244
     * @return bool
245
     */
246
    public function delete($id)
247
    {
248
        $sql = 'DELETE'.' FROM '.self::getTableName().' WHERE id = '.$id;
249
        $sqlStatment = $this->databaseConnection->prepare($sql);
250
        $sqlStatment->execute();
251
252
        return ($sqlStatment->rowCount() > 0) ? true : false;
253
    }
254
}
255