1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file contains the skeleton for all of the database objects |
4
|
|
|
* |
5
|
|
|
* @package BZiON\Models |
6
|
|
|
* @license https://github.com/allejo/bzion/blob/master/LICENSE.md GNU General Public License Version 3 |
7
|
|
|
*/ |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* A database object (e.g. A player or a team) |
11
|
|
|
* @package BZiON\Models |
12
|
|
|
*/ |
13
|
|
|
abstract class Model extends CachedModel |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* Generates a string with the object's type and ID |
17
|
|
|
*/ |
18
|
|
|
public function __toString() |
19
|
|
|
{ |
20
|
|
|
return get_class($this) . " #" . $this->getId(); |
21
|
|
|
} |
22
|
|
|
|
23
|
|
|
/** |
24
|
|
|
* Find if the model is in the trash can (or doesn't exist) |
25
|
|
|
* |
26
|
|
|
* @return bool True if the model has been deleted |
27
|
|
|
*/ |
28
|
|
|
public function isDeleted() |
29
|
|
|
{ |
30
|
|
|
if (!$this->isValid() || $this->is_deleted || $this->getStatus() == 'deleted') { |
|
|
|
|
31
|
|
|
return true; |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
return false; |
35
|
|
|
} |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* Find if the model is active (i.e. visible to everyone) |
39
|
|
|
* |
40
|
|
|
* @return bool |
41
|
|
|
*/ |
42
|
|
|
public function isActive() |
43
|
|
|
{ |
44
|
|
|
if (static::DELETED_COLUMN !== null) { |
45
|
|
|
return (!$this->is_deleted); |
46
|
|
|
} |
47
|
|
|
|
48
|
|
|
@trigger_error(sprintf('Update the "%s" model to use the DELETED_* constants instead of the "status" column.', get_called_class()), E_USER_DEPRECATED); |
|
|
|
|
49
|
|
|
|
50
|
|
|
return in_array($this->getStatus(), $this->getActiveStatuses()); |
|
|
|
|
51
|
|
|
} |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* Get the models's status |
55
|
|
|
* |
56
|
|
|
* @deprecated 0.11.0 Use isDeleted() for checking for deleted models instead. |
57
|
|
|
* |
58
|
|
|
* @return string |
59
|
|
|
*/ |
60
|
|
|
public function getStatus() |
61
|
|
|
{ |
62
|
|
|
@trigger_error(sprintf('The "status" of models has been deprecated. Use %s::isDeleted() for checking for deleted models.', get_called_class()), E_USER_DEPRECATED); |
|
|
|
|
63
|
|
|
|
64
|
|
|
if (!isset($this->status)) { |
65
|
|
|
$this->status = static::DEFAULT_STATUS; |
|
|
|
|
66
|
|
|
} |
67
|
|
|
|
68
|
|
|
return $this->status; |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* Find if two objects represent the same model |
73
|
|
|
* |
74
|
|
|
* @param object $model The model to compare |
75
|
|
|
* @return bool |
76
|
|
|
*/ |
77
|
|
|
public function isSameAs($model) |
78
|
|
|
{ |
79
|
|
|
if (!$model instanceof Model) { |
80
|
|
|
return false; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
if (!$this->valid || !$model->valid) { |
84
|
|
|
return false; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
$sameType = $this instanceof $model || $model instanceof $this; |
88
|
|
|
|
89
|
|
|
return $sameType && $this->id === $model->id; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* Get the possible statuses representing an active model (visible to everyone) |
94
|
|
|
* |
95
|
|
|
* @return string[] |
96
|
|
|
*/ |
97
|
|
|
public static function getActiveStatuses() |
98
|
|
|
{ |
99
|
|
|
return [static::DEFAULT_STATUS]; |
|
|
|
|
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* Converts an array of IDs to an array of Models |
104
|
|
|
* @param int[] $idArray The list of IDs |
105
|
|
|
* @return static[] An array of models |
106
|
|
|
*/ |
107
|
|
|
public static function arrayIdToModel($idArray) |
108
|
|
|
{ |
109
|
|
|
$return = array(); |
110
|
|
|
foreach ($idArray as $id) { |
111
|
|
|
$return[] = static::get($id); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
return $return; |
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
/** |
118
|
|
|
* Converts an array of Models to an array of IDs |
119
|
|
|
* |
120
|
|
|
* All model type information is lost |
121
|
|
|
* |
122
|
|
|
* @param ModelInterface[] $modelArray The list of models |
123
|
|
|
* @return int[] An array of IDs |
124
|
|
|
*/ |
125
|
|
|
public static function mapToIDs($modelArray) |
126
|
|
|
{ |
127
|
|
|
return array_map(function (ModelInterface $model) { |
128
|
|
|
return $model->getId(); |
129
|
|
|
}, $modelArray); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
/** |
133
|
|
|
* Update a property and the corresponding database column |
134
|
|
|
* |
135
|
|
|
* @param mixed $property The protected class property to update |
136
|
|
|
* @param string $dbColumn The name of the database column to update |
137
|
|
|
* @param mixed $value The value to insert |
138
|
|
|
* @param string $type The mysqli type of the value (s, i, d, b) |
139
|
|
|
* |
140
|
|
|
* @return static Returns the model itself to allow method chaining |
141
|
|
|
*/ |
142
|
|
|
protected function updateProperty(&$property, $dbColumn, $value, $type = 'i') |
|
|
|
|
143
|
|
|
{ |
144
|
|
|
// Don't waste time with mysql if there aren't any changes |
145
|
|
|
if ($property !== $value) { |
146
|
|
|
$property = $value; |
147
|
|
|
|
148
|
|
|
if ($value instanceof TimeDate) { |
149
|
|
|
$value = $value->toMysql(); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
$this->update($dbColumn, $value); |
153
|
|
|
} |
154
|
|
|
|
155
|
|
|
return $this; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* Gets the type of the model |
160
|
|
|
* @return string The type of the model, e.g. "server" |
161
|
|
|
*/ |
162
|
|
|
public static function getType() |
163
|
|
|
{ |
164
|
|
|
return self::toSnakeCase(get_called_class()); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
/** |
168
|
|
|
* Gets a human-readable format of the model's type |
169
|
|
|
* @return string |
170
|
|
|
*/ |
171
|
|
|
public static function getTypeForHumans() |
172
|
|
|
{ |
173
|
|
|
return self::getType(); |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Change a parameter if a model is not valid |
178
|
|
|
* |
179
|
|
|
* Useful for form validation |
180
|
|
|
* |
181
|
|
|
* @param string $property The name of the property to change |
182
|
|
|
* @param mixed $value The value of the property |
183
|
|
|
* @return self |
184
|
|
|
*/ |
185
|
|
|
protected function inject($property, $value) |
186
|
|
|
{ |
187
|
|
|
if (!$this->isValid()) { |
188
|
|
|
$this->{$property} = $value; |
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Takes a CamelCase string and converts it to a snake_case one |
196
|
|
|
* @param string $input The string to convert |
197
|
|
|
* @return string |
198
|
|
|
*/ |
199
|
|
|
private static function toSnakeCase($input) |
200
|
|
|
{ |
201
|
|
|
preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!', $input, $matches); |
202
|
|
|
$ret = $matches[0]; |
203
|
|
|
|
204
|
|
|
foreach ($ret as &$match) { |
205
|
|
|
$match = ($match == strtoupper($match)) ? strtolower($match) : lcfirst($match); |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
return implode('_', $ret); |
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/** |
212
|
|
|
* Escape special HTML characters from a string |
213
|
|
|
* @param string $string |
214
|
|
|
* @return string |
215
|
|
|
*/ |
216
|
|
|
public static function escape($string) |
217
|
|
|
{ |
218
|
|
|
return htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* Create a single model object from a database result |
223
|
|
|
* |
224
|
|
|
* @param array $result The MySQL row of the model |
225
|
|
|
* |
226
|
|
|
* @return static |
227
|
|
|
*/ |
228
|
|
|
public static function createFromDatabaseResult(&$result) |
229
|
|
|
{ |
230
|
|
|
$model = new static($result['id'], $result); |
231
|
|
|
$model->storeInCache(); |
232
|
|
|
|
233
|
|
|
return $model; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Create model objects, given their MySQL entries |
238
|
|
|
* |
239
|
|
|
* @param array $results The MySQL rows of the model |
240
|
|
|
* @return static[] |
241
|
|
|
*/ |
242
|
|
|
public static function createFromDatabaseResults(&$results) |
243
|
|
|
{ |
244
|
|
|
$models = array(); |
245
|
|
|
|
246
|
|
|
foreach ($results as $result) { |
247
|
|
|
$models[] = self::createFromDatabaseResult($result); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
return $models; |
251
|
|
|
} |
252
|
|
|
} |
253
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.