Skip to content

Commit 3b802de

Browse files
committed
feat: add toDatabase()/fromDatabase() to Entity
1 parent 7409bea commit 3b802de

File tree

1 file changed

+101
-2
lines changed

1 file changed

+101
-2
lines changed

system/Entity/Entity.php

Lines changed: 101 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@ public function toArray(bool $onlyChanged = false, bool $cast = true, bool $recu
205205
*
206206
* @param bool $onlyChanged If true, only return values that have changed since object creation
207207
* @param bool $recursive If true, inner entities will be cast as array as well.
208+
*
209+
* @deprecated 4.5.0 Use toDatabase() instead.
208210
*/
209211
public function toRawArray(bool $onlyChanged = false, bool $recursive = false): array
210212
{
@@ -245,6 +247,71 @@ public function toRawArray(bool $onlyChanged = false, bool $recursive = false):
245247
return $return;
246248
}
247249

250+
/**
251+
* Returns the values for database of the current attributes.
252+
*
253+
* @param bool $onlyChanged If true, only return values that have changed since object creation
254+
* @param bool $recursive If true, inner entities will be cast as array as well.
255+
*/
256+
public function toDatabase(bool $onlyChanged = false, bool $recursive = false): array
257+
{
258+
$return = [];
259+
260+
if (! $onlyChanged) {
261+
$data = $this->attributes;
262+
263+
// Cast values
264+
if ($this->_cast) {
265+
foreach (array_keys($this->casts) as $field) {
266+
if (isset($data[$field])) {
267+
$data[$field] = $this->castAs($data[$field], $field, 'toDatabase');
268+
}
269+
}
270+
}
271+
272+
if ($recursive) {
273+
return array_map(static function ($value) use ($onlyChanged, $recursive) {
274+
if ($value instanceof self) {
275+
$value = $value->toDatabase($onlyChanged, $recursive);
276+
} elseif (is_callable([$value, 'toDatabase'])) {
277+
// @TODO Should define Interface or Class.
278+
$value = $value->toDatabase();
279+
}
280+
281+
return $value;
282+
}, $data);
283+
}
284+
285+
return $data;
286+
}
287+
288+
foreach ($this->attributes as $key => $value) {
289+
if (! $this->hasChanged($key)) {
290+
continue;
291+
}
292+
293+
// Cast values
294+
if ($this->_cast) {
295+
if (isset($this->casts[$key])) {
296+
$value = $this->castAs($value, $key, 'toDatabase');
297+
}
298+
}
299+
300+
if ($recursive) {
301+
if ($value instanceof self) {
302+
$value = $value->toDatabase($onlyChanged, $recursive);
303+
} elseif (is_callable([$value, 'toDatabase'])) {
304+
// @TODO Should define Interface or Class.
305+
$value = $value->toDatabase();
306+
}
307+
}
308+
309+
$return[$key] = $value;
310+
}
311+
312+
return $return;
313+
}
314+
248315
/**
249316
* Ensures our "original" values match the current values.
250317
*
@@ -290,6 +357,8 @@ public function hasChanged(?string $key = null): bool
290357
* Set raw data array without any mutations
291358
*
292359
* @return $this
360+
*
361+
* @deprecated 4.5.0 No longer used. `fromDatabase()` is used.
293362
*/
294363
public function injectRawData(array $data)
295364
{
@@ -300,6 +369,35 @@ public function injectRawData(array $data)
300369
return $this;
301370
}
302371

372+
/**
373+
* Set data from database
374+
*
375+
* @return $this
376+
*/
377+
public function fromDatabase(array $data)
378+
{
379+
// Mutate dates
380+
foreach ($this->dates as $field) {
381+
if (isset($data[$field])) {
382+
$data[$field] = $this->mutateDate($data[$field]);
383+
}
384+
}
385+
386+
// Cast values
387+
if ($this->_cast) {
388+
foreach (array_keys($this->casts) as $field) {
389+
if (isset($data[$field])) {
390+
$data[$field] = $this->castAs($data[$field], $field, 'fromDatabase');
391+
}
392+
}
393+
}
394+
395+
$this->attributes = $data;
396+
$this->syncOriginal();
397+
398+
return $this;
399+
}
400+
303401
/**
304402
* Set raw data array without any mutations
305403
*
@@ -353,7 +451,8 @@ protected function mutateDate($value)
353451
*
354452
* @param bool|float|int|string|null $value Attribute value
355453
* @param string $attribute Attribute name
356-
* @param string $method Allowed to "get" and "set"
454+
* @param string $method Method name to run in the cast handler
455+
* @phpstan-param 'get'|'set'|'toDatabase'|'fromDatabase' $method
357456
*
358457
* @return array|bool|float|int|object|string|null
359458
*
@@ -383,7 +482,7 @@ protected function castAs($value, string $attribute, string $method = 'get')
383482
// json-array type, we transform the required one.
384483
$type = $type === 'json-array' ? 'json[array]' : $type;
385484

386-
if (! in_array($method, ['get', 'set'], true)) {
485+
if (! in_array($method, ['get', 'set', 'toDatabase', 'fromDatabase'], true)) {
387486
throw CastException::forInvalidMethod($method);
388487
}
389488

0 commit comments

Comments
 (0)