1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Class EntityModel |
5
|
|
|
* |
6
|
|
|
* This class have only one instance - i.e. is a service |
7
|
|
|
* Describes persistent entity - which can be loaded from/stored to storage |
8
|
|
|
* |
9
|
|
|
* @property int|float|string $dbId EntityModel unique ID for entire entities' set |
10
|
|
|
*/ |
11
|
|
|
class EntityModel { |
12
|
|
|
/** |
13
|
|
|
* Service to work with rows |
14
|
|
|
* |
15
|
|
|
* ALL DB ACCESS SHOULD BE DONE VIA ROW OPERATOR! NO DIRECT ACCESS TO DB IS ALLOWED! |
16
|
|
|
* |
17
|
|
|
* @var \DbRowDirectOperator $rowOperator |
18
|
|
|
*/ |
19
|
|
|
protected $rowOperator; |
20
|
|
|
/** |
21
|
|
|
* Name of table for this entity |
22
|
|
|
* |
23
|
|
|
* @var string $tableName |
24
|
|
|
*/ |
25
|
|
|
protected $tableName = '_table'; |
26
|
|
|
/** |
27
|
|
|
* Name of key field field in this table |
28
|
|
|
* |
29
|
|
|
* @var string $idField |
30
|
|
|
*/ |
31
|
|
|
protected $idField = 'id'; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Name of exception class that would be thrown |
35
|
|
|
* |
36
|
|
|
* Uses for calling when you don't know which exact exception should be called |
37
|
|
|
* On EntityModel's children should be used exception class name |
38
|
|
|
* |
39
|
|
|
* @var string $exceptionClass |
40
|
|
|
*/ |
41
|
|
|
protected $exceptionClass = 'EntityException'; |
42
|
|
|
protected $entityContainerClass = '\EntityContainer'; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* Property list and description |
46
|
|
|
* |
47
|
|
|
* propertyName => array( |
48
|
|
|
* P_DB_FIELD => 'dbFieldName', - directly converts property to field and vice versa |
49
|
|
|
* ) |
50
|
|
|
* |
51
|
|
|
* @var array[] $properties |
52
|
|
|
*/ |
53
|
|
|
protected $properties = array(); |
54
|
|
|
|
55
|
|
|
/** |
56
|
|
|
* Array of accessors - getters/setters/etc |
57
|
|
|
* |
58
|
|
|
* @var callable[][] |
59
|
|
|
*/ |
60
|
|
|
protected $accessors = array(); |
61
|
|
|
|
62
|
1 |
View Code Duplication |
protected function assignAccessor($varName, $type, $callable) { |
|
|
|
|
63
|
1 |
|
if (empty($callable)) { |
64
|
|
|
return; |
65
|
|
|
} |
66
|
|
|
|
67
|
1 |
|
if (is_callable($callable)) { |
68
|
1 |
|
$this->accessors[$varName][$type] = $callable; |
69
|
1 |
|
} else { |
70
|
|
|
throw new \Exception('Error assigning callable in ' . get_called_class() . '! Callable typed [' . $type . '] is not a callable or not accessible in the scope'); |
71
|
|
|
} |
72
|
1 |
|
} |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* EntityModel constructor. |
77
|
|
|
* |
78
|
|
|
* @param \Common\GlobalContainer $gc |
79
|
|
|
*/ |
80
|
1 |
|
public function __construct($gc) { |
81
|
|
|
// Here own rowOperator can be made - if needed to operate other, non-global, DB |
82
|
1 |
|
$this->rowOperator = $gc->dbGlobalRowOperator; |
|
|
|
|
83
|
1 |
|
} |
84
|
|
|
|
85
|
|
|
/** |
86
|
|
|
* @return \DbRowDirectOperator |
87
|
|
|
*/ |
88
|
|
|
public function getRowOperator() { |
89
|
|
|
return $this->rowOperator; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @param string $value |
94
|
|
|
*/ |
95
|
|
|
public function setTableName($value) { |
96
|
|
|
$this->tableName = $value; |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* Gets entity's table name |
101
|
|
|
* |
102
|
|
|
* @return string |
103
|
|
|
*/ |
104
|
|
|
public function getTableName() { |
105
|
|
|
return $this->tableName; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @param string $value |
110
|
|
|
*/ |
111
|
|
|
public function setIdFieldName($value) { |
112
|
|
|
$this->idField = $value; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
/** |
116
|
|
|
* Gets entity's DB ID field name (which is unique within entity set) |
117
|
|
|
* |
118
|
|
|
* @return string |
119
|
|
|
*/ |
120
|
|
|
public function getIdFieldName() { |
121
|
|
|
return $this->idField; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @param array $array |
127
|
|
|
* |
128
|
|
|
* @return \EntityContainer |
129
|
|
|
*/ |
130
|
|
|
public function fromArray($array) { |
131
|
|
|
/** |
132
|
|
|
* @var EntityContainer $cEntity |
133
|
|
|
*/ |
134
|
|
|
$cEntity = $this->getContainer(); |
135
|
|
|
$cEntity->importRow($array); |
136
|
|
|
|
137
|
|
|
return $cEntity; |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* Exports object properties to DB row state WITHOUT ID |
143
|
|
|
* |
144
|
|
|
* Useful for INSERT operations |
145
|
|
|
* |
146
|
|
|
* @param \EntityContainer $cEntity |
147
|
|
|
* |
148
|
|
|
* @return array |
149
|
|
|
*/ |
150
|
|
|
protected function exportRow($cEntity) { |
151
|
|
|
return $cEntity->exportRow(); |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
/** |
155
|
|
|
* Exports object properties to DB row state with ID |
156
|
|
|
* |
157
|
|
|
* @param \EntityContainer $cEntity |
158
|
|
|
* |
159
|
|
|
* @return array |
160
|
|
|
*/ |
161
|
|
|
protected function exportRowNoId($cEntity) { |
162
|
|
|
$row = $this->exportRow($cEntity); |
163
|
|
|
|
164
|
|
|
unset($row[$this->getIdFieldName()]); |
165
|
|
|
|
166
|
|
|
return $row; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
|
170
|
|
|
/** |
171
|
|
|
* @return \EntityContainer |
172
|
|
|
*/ |
173
|
1 |
|
public function getContainer() { |
174
|
|
|
/** |
175
|
|
|
* @var \EntityContainer $container |
176
|
|
|
*/ |
177
|
1 |
|
$container = new $this->entityContainerClass(); |
178
|
1 |
|
$container->setProperties($this->properties); |
179
|
1 |
|
$container->setAccessors($this->accessors); |
180
|
|
|
|
181
|
1 |
|
return $container; |
182
|
|
|
} |
183
|
|
|
|
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* @param int|string $dbId |
187
|
|
|
* |
188
|
|
|
* @return \EntityContainer|false |
189
|
|
|
*/ |
190
|
|
|
public function loadById($dbId) { |
191
|
|
|
$row = $this->rowOperator->getById($this, $dbId); |
192
|
|
|
if (empty($row)) { |
193
|
|
|
return false; |
194
|
|
|
} else { |
195
|
|
|
$cEntity = $this->fromArray($row); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
return $cEntity; |
199
|
|
|
} |
200
|
|
|
|
201
|
|
|
/** |
202
|
|
|
* @param EntityContainer $cEntity |
203
|
|
|
* |
204
|
|
|
* @return bool |
205
|
|
|
*/ |
206
|
|
|
public function isEmpty($cEntity) { |
207
|
|
|
return $cEntity->isEmpty(); |
208
|
|
|
} |
209
|
|
|
|
210
|
|
|
/** |
211
|
|
|
* @param EntityContainer $cEntity |
212
|
|
|
* |
213
|
|
|
* @return bool |
214
|
|
|
*/ |
215
|
|
|
public function isNew($cEntity) { |
216
|
|
|
return $cEntity->isEmpty(); |
217
|
|
|
} |
218
|
|
|
|
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.