-
-
Save ollieread/49bf20f16f92286807da5b0fd6e77bdf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
declare(strict_types=1); | |
namespace App; | |
use Illuminate\Database\Eloquent\Model as BaseModel; | |
abstract class Model extends BaseModel | |
{ | |
private static array $identityMap = []; | |
public static function clearIdentityMap(?string $class = null): void | |
{ | |
self::$identityMap[$class ?? static::class] = []; | |
} | |
public static function addToIdentityMap(self $model): void | |
{ | |
if ($model->exists === false || $model->getKey() === null) { | |
throw new \InvalidArgumentException('Model must exist and have a key to be added to the identity map.'); | |
} | |
self::$identityMap[$model::class][$model->getKey()] = $model; | |
} | |
public static function removeFromIdentityMap(self $model): void | |
{ | |
unset(self::$identityMap[$model::class][$model->getKey()]); | |
} | |
public static function getFromIdentityMap(int|string $key, ?string $class = null): ?static | |
{ | |
return self::$identityMap[$class ?? static::class][$key] ?? null; | |
} | |
public static function existsInIdentityMap(int|string $key, ?string $class = null): bool | |
{ | |
return self::getFromIdentityMap($key, $class) !== null; | |
} | |
public function newFromBuilder($attributes = [], $connection = null): static | |
{ | |
$attributes = (array)$attributes; | |
$key = $attributes[$this->getKeyName()] ?? null; | |
if ($key !== null) { | |
$existing = static::getFromIdentityMap($key); | |
if ($existing !== null) { | |
$existing->setRawAttributes($attributes, true); | |
$existing->fireModelEvent('synced', false); | |
return $existing; | |
} | |
} | |
$model = parent::newFromBuilder($attributes, $connection); | |
if ($model->exists && $model->getKey()) { | |
static::addToIdentityMap($model); | |
} | |
return $model; | |
} | |
protected static function booted(): void | |
{ | |
parent::booted(); | |
static::created(static function (self $model) { | |
if ($model->exists && $model->getKey()) { | |
static::addToIdentityMap($model); | |
} | |
}); | |
static::deleting(static function (self $model) { | |
if ($model->exists && $model->getKey()) { | |
if (! method_exists($this, 'isForceDeleting') || $this->isForceDeleting()) { | |
static::removeFromIdentityMap($model); | |
} | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment