|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Pyjac\ORM; |
|
4
|
|
|
|
|
5
|
|
View Code Duplication |
abstract class Model implements ModelInterface |
|
|
|
|
|
|
6
|
|
|
{ |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
protected $properties = []; |
|
10
|
|
|
|
|
11
|
|
|
/** |
|
12
|
|
|
* Store instance of database connection used. |
|
13
|
|
|
* @var [type] |
|
14
|
|
|
*/ |
|
15
|
|
|
protected $databaseConnection; |
|
16
|
|
|
|
|
17
|
|
|
public function __construct() |
|
18
|
|
|
{ |
|
19
|
|
|
$this->databaseConnection = DatabaseConnection::getInstance()->databaseConnection; |
|
20
|
|
|
//$databaseConnection->databaseConnection->connect(); |
|
|
|
|
|
|
21
|
|
|
} |
|
22
|
|
|
/** |
|
23
|
|
|
* @param string $key rep column name |
|
24
|
|
|
* @param string $val rep column value |
|
25
|
|
|
* sets into $propertie the $key => $value pairs |
|
26
|
|
|
*/ |
|
27
|
|
|
public function __set($key, $val) |
|
28
|
|
|
{ |
|
29
|
|
|
$this->properties[$key] = $val; |
|
30
|
|
|
} |
|
31
|
|
|
/** |
|
32
|
|
|
* @param string $key reps the column name |
|
33
|
|
|
* @return $key and $value |
|
|
|
|
|
|
34
|
|
|
*/ |
|
35
|
|
|
public function __get($key) |
|
36
|
|
|
{ |
|
37
|
|
|
return $this->properties[$key]; |
|
38
|
|
|
} |
|
39
|
|
|
/** |
|
40
|
|
|
* Get all the model properties |
|
41
|
|
|
* |
|
42
|
|
|
* @return array |
|
43
|
|
|
*/ |
|
44
|
|
|
public function getProperties() |
|
45
|
|
|
{ |
|
46
|
|
|
return $this->properties; |
|
47
|
|
|
} |
|
48
|
|
|
/** |
|
49
|
|
|
* Gets the name of the child class only |
|
50
|
|
|
* without the namespace |
|
51
|
|
|
* @var $className |
|
52
|
|
|
* @var $table |
|
53
|
|
|
* @return $table |
|
|
|
|
|
|
54
|
|
|
*/ |
|
55
|
|
|
public function getTableName() |
|
56
|
|
|
{ |
|
57
|
|
|
$className = explode('\\', get_called_class()); |
|
58
|
|
|
$table = strtolower(end($className) .'s'); |
|
59
|
|
|
return $table; |
|
60
|
|
|
} |
|
61
|
|
|
/** |
|
62
|
|
|
* returns a particular record |
|
63
|
|
|
* @param $id reps the record id |
|
64
|
|
|
* @param $connection initialised to null |
|
65
|
|
|
* @return object |
|
66
|
|
|
*/ |
|
67
|
|
|
public static function find($id) |
|
68
|
|
|
{ |
|
69
|
|
|
$model = new static; |
|
70
|
|
|
return $model->get($id); |
|
71
|
|
|
} |
|
72
|
|
|
/** |
|
73
|
|
|
* returns a particular record |
|
74
|
|
|
* @param $id reps the record id |
|
75
|
|
|
* @param $connection initialised to null |
|
76
|
|
|
* @return object |
|
77
|
|
|
*/ |
|
78
|
|
|
public function get($id) |
|
79
|
|
|
{ |
|
80
|
|
|
$sql = "SELECT * FROM {$this->getTableName()} WHERE id={$id}"; |
|
81
|
|
|
$sqlStatement = $this->databaseConnection->prepare($sql); |
|
82
|
|
|
$sqlStatement->setFetchMode($this->databaseConnection::FETCH_CLASS, get_called_class()); |
|
83
|
|
|
$sqlStatement->execute(); |
|
84
|
|
|
if($sqlStatement->rowCount() < 1){ |
|
85
|
|
|
throw new ModelNotFoundException($id); |
|
86
|
|
|
} |
|
87
|
|
|
return $sqlStatement->fetch(); |
|
88
|
|
|
} |
|
89
|
|
|
|
|
90
|
|
|
public static function getAll() |
|
91
|
|
|
{ |
|
92
|
|
|
$model = new static; |
|
93
|
|
|
return $model->all(); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
public function all() |
|
97
|
|
|
{ |
|
98
|
|
|
$sql = "SELECT * FROM {$this->getTableName()}"; |
|
99
|
|
|
$row = $this->databaseConnection->prepare($sql); |
|
100
|
|
|
$row->execute(); |
|
101
|
|
|
|
|
102
|
|
|
return $row->fetchAll($this->databaseConnection::FETCH_CLASS); |
|
103
|
|
|
|
|
104
|
|
|
} |
|
105
|
|
|
/** update table with instance properties |
|
106
|
|
|
* |
|
107
|
|
|
*/ |
|
108
|
|
|
private function update() |
|
109
|
|
|
{ |
|
110
|
|
|
$connection = $this->getConnection(); |
|
111
|
|
|
$columnNames = ""; |
|
|
|
|
|
|
112
|
|
|
$columnValues = ""; |
|
|
|
|
|
|
113
|
|
|
$count = 0; |
|
114
|
|
|
$update = "UPDATE " . $this->getTableName() . " SET " ; |
|
115
|
|
|
foreach ($this->properties as $key => $val) { |
|
116
|
|
|
$count++; |
|
117
|
|
|
if(($key == 'id')) continue; |
|
118
|
|
|
$update .= "$key = '$val'"; |
|
119
|
|
|
if ($count < count($this->properties) ) |
|
120
|
|
|
{ |
|
121
|
|
|
$update .=","; |
|
122
|
|
|
} |
|
123
|
|
|
} |
|
124
|
|
|
$update .= " WHERE id = " . $this->properties['id']; |
|
125
|
|
|
$stmt = $connection->prepare($update); |
|
126
|
|
|
foreach ($this->properties as $key => $val) { |
|
127
|
|
|
if($key == 'id') continue; |
|
128
|
|
|
} |
|
129
|
|
|
$stmt->execute(); |
|
130
|
|
|
return $stmt->rowCount(); |
|
131
|
|
|
} |
|
132
|
|
|
/** |
|
133
|
|
|
* insert instance data into the table |
|
134
|
|
|
*/ |
|
135
|
|
|
private function create() |
|
136
|
|
|
{ |
|
137
|
|
|
$connection = $this->getConnection(); |
|
138
|
|
|
$columnNames = ""; |
|
139
|
|
|
$columnValues = ""; |
|
140
|
|
|
$count = 0; |
|
141
|
|
|
$create = "INSERT" . " INTO " . $this->getTableName()." ("; |
|
142
|
|
|
foreach ($this->properties as $key => $val) { |
|
143
|
|
|
$columnNames .= $key; |
|
144
|
|
|
$columnValues .= ':' . $key; |
|
145
|
|
|
$count++; |
|
146
|
|
|
if ($count < count($this->properties)) |
|
147
|
|
|
{ |
|
148
|
|
|
$columnNames .= ', '; |
|
149
|
|
|
$columnValues .= ', '; |
|
150
|
|
|
} |
|
151
|
|
|
} |
|
152
|
|
|
$create .= $columnNames.') VALUES (' .$columnValues.')'; |
|
153
|
|
|
$stmt = $connection->prepare($create); |
|
154
|
|
|
foreach ($this->properties as $key => $val) { |
|
155
|
|
|
$stmt->bindValue(':'.$key, $val); |
|
156
|
|
|
} |
|
157
|
|
|
try { |
|
158
|
|
|
// if prop returned and props from db differ throw exception |
|
159
|
|
|
$stmt->execute(); |
|
160
|
|
|
} catch(PDOException $e){ |
|
|
|
|
|
|
161
|
|
|
return $e->getExceptionMessage(); |
|
162
|
|
|
} |
|
163
|
|
|
return $stmt->rowCount(); |
|
164
|
|
|
} |
|
165
|
|
|
/** |
|
166
|
|
|
* get db connection |
|
167
|
|
|
*/ |
|
168
|
|
|
public function getConnection($connection = null) |
|
169
|
|
|
{ |
|
170
|
|
|
if(is_null($connection)) |
|
171
|
|
|
{ |
|
172
|
|
|
return new Connection(); |
|
173
|
|
|
} |
|
174
|
|
|
} |
|
175
|
|
|
/** |
|
176
|
|
|
* checks if the id exists |
|
177
|
|
|
* update if exist |
|
178
|
|
|
* create if not exist |
|
179
|
|
|
*/ |
|
180
|
|
|
public function save() |
|
181
|
|
|
{ |
|
182
|
|
|
if ($this->id) { |
|
|
|
|
|
|
183
|
|
|
$this->update(); |
|
184
|
|
|
} else { |
|
185
|
|
|
$this->create(); |
|
186
|
|
|
} |
|
187
|
|
|
} |
|
188
|
|
|
/** |
|
189
|
|
|
* @param row reps record id |
|
190
|
|
|
* @param $connection initialised to null |
|
191
|
|
|
* @return boolean |
|
192
|
|
|
*/ |
|
193
|
|
|
public static function destroy($id) |
|
194
|
|
|
{ |
|
195
|
|
|
|
|
196
|
|
|
$sql = "DELETE" . " FROM " . self::getTableName()." WHERE id = ". $id; |
|
197
|
|
|
$delete = $connection->prepare($sql); |
|
|
|
|
|
|
198
|
|
|
$delete->execute(); |
|
199
|
|
|
$count = $delete->rowCount(); |
|
200
|
|
|
if ($count < 1) { |
|
201
|
|
|
throw new RecordNotFoundException('Record with id ' . $id . ' does not exist.'); |
|
202
|
|
|
} |
|
203
|
|
|
return ($count > 0) ? true : false; |
|
204
|
|
|
} |
|
205
|
|
|
|
|
206
|
|
|
/** |
|
207
|
|
|
* Handle dynamic static method calls into the method. |
|
208
|
|
|
* |
|
209
|
|
|
* @param string $method |
|
210
|
|
|
* @param array $parameters |
|
211
|
|
|
* @return mixed |
|
212
|
|
|
*/ |
|
213
|
|
|
public static function __callStatic($method, $parameters) |
|
|
|
|
|
|
214
|
|
|
{ |
|
215
|
|
|
exit("HERE"); |
|
216
|
|
|
$instance = new static; |
|
|
|
|
|
|
217
|
|
|
|
|
218
|
|
|
return call_user_func_array([$instance, $method], $parameters); |
|
219
|
|
|
} |
|
220
|
|
|
} |
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.