Skip to content

Commit

Permalink
[ORM] If no primary, ORM cannot set created #1153
Browse files Browse the repository at this point in the history
  • Loading branch information
asika32764 committed Dec 11, 2024
1 parent 78fc73d commit 23a3b94
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 32 deletions.
4 changes: 2 additions & 2 deletions packages/orm/src/Attributes/CreatedTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ public function filter(mixed $value): DateTimeImmutable

protected function getDefaultCaster(): callable
{
return function (mixed $value, ORM $orm, object $entity) {
return function (mixed $value, ORM $orm, object $entity, bool $isNew = false) {
$isNull = $value === null || $orm->getDb()->isNullDate($value);

$mapper = $orm->mapper($entity::class);

if ($isNull) {
if ($mapper->getMainKey()) {
if ($mapper->isNew($entity)) {
if ($isNew) {
$value = $this->getCurrent();
}
} else {
Expand Down
5 changes: 3 additions & 2 deletions packages/orm/src/Cast/CastManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ public function castToCallback(mixed $cast, int $options, string $direction = 'h

public function wrapCastCallback(callable $caster, int $options): \Closure
{
return function (mixed $value, ORM $orm, ?object $entity = null) use ($options, $caster) {
return function (mixed $value, ORM $orm, ?object $entity = null, bool $isNew = false) use ($options, $caster) {
if ($value === '' && ($options & Cast::EMPTY_STRING_TO_NULL)) {
$value = null;
}
Expand All @@ -252,7 +252,8 @@ public function wrapCastCallback(callable $caster, int $options): \Closure
$value,
'value' => $value,
'orm' => $orm,
'entity' => $entity
'entity' => $entity,
'isNew' => $isNew
]
);
};
Expand Down
61 changes: 33 additions & 28 deletions packages/orm/src/EntityMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
BeforeSaveEvent,
BeforeStoreEvent,
BeforeUpdateWhereEvent,
EnergizeEvent};
EnergizeEvent
};
use Windwalker\ORM\Hydrator\EntityHydrator;
use Windwalker\ORM\Iterator\ResultIterator;
use Windwalker\ORM\Metadata\EntityMetadata;
Expand Down Expand Up @@ -229,9 +230,9 @@ public function findColumn(string $column, mixed $conditions = []): Collection
}

/**
* @param string $column
* @param Conditions $conditions
* @param array|string|null $groups
* @param string $column
* @param Conditions $conditions
* @param array|string|null $groups
*
* @return int
*/
Expand All @@ -248,9 +249,9 @@ public function countColumn(string $column, mixed $conditions = [], array|string
}

/**
* @param string $column
* @param Conditions $conditions
* @param array|string|null $groups
* @param string $column
* @param Conditions $conditions
* @param array|string|null $groups
*
* @return float
*/
Expand Down Expand Up @@ -304,7 +305,7 @@ public function createOne(array|object $source = [], int $options = 0): object
$extra = $event->getExtra();
$entity = $this->hydrate($fullData, $this->toEntity($source));

$data = $this->castForSave($this->extract($entity), true, $entity);
$data = $this->castForSave($this->extract($entity), true, $entity, true);

$type = BeforeStoreEvent::TYPE_CREATE;
$event = $this->emitEvent(
Expand Down Expand Up @@ -502,9 +503,9 @@ public function updateOne(
/**
* updateMultiple
*
* @param iterable $items
* @param array|string|null $condFields
* @param int $options
* @param iterable $items
* @param array|string|null $condFields
* @param int $options
*
* @return StatementInterface[]
*/
Expand Down Expand Up @@ -591,9 +592,9 @@ public function updateBatch(array|object $data, mixed $conditions = null, int $o
}

/**
* @param iterable $items
* @param string|array|null $condFields
* @param int $options
* @param iterable $items
* @param string|array|null $condFields
* @param int $options
*
* @return iterable<T>
*
Expand Down Expand Up @@ -670,9 +671,9 @@ public function isNew(array|object $item): bool
}

/**
* @param array|object $item
* @param array|string|null $condFields
* @param int $options
* @param array|object $item
* @param array|string|null $condFields
* @param int $options
*
* @return object|T
*
Expand Down Expand Up @@ -899,9 +900,9 @@ public function flush(iterable $items, mixed $conditions = [], int $options = 0)
}

/**
* @param Conditions $conditions
* @param callable|iterable|null $newValue
* @param int $options
* @param Conditions $conditions
* @param callable|iterable|null $newValue
* @param int $options
*
* @return array<T>
* @throws JsonException
Expand Down Expand Up @@ -1435,16 +1436,20 @@ protected function handleConditionColumn(string $key, mixed $value): mixed
return $value;
}

protected function extractForSave(object|array $data, bool $updateNulls = true): array
protected function extractForSave(object|array $data, bool $updateNulls = true, bool $isNew = false): array
{
$data = $this->extract($data);
$entity = $this->toEntity($data);

return $this->castForSave($data, $updateNulls, $entity);
return $this->castForSave($data, $updateNulls, $entity, $isNew);
}

protected function castForSave(array $data, bool $updateNulls = true, ?object $entity = null): array
{
protected function castForSave(
array $data,
bool $updateNulls = true,
?object $entity = null,
bool $isNew = false
): array {
$entity ??= $this->toEntity($data);

$metadata = $this->getMetadata();
Expand All @@ -1459,7 +1464,7 @@ protected function castForSave(array $data, bool $updateNulls = true, ?object $e

// Handler property attributes
if ($prop = $metadata->getColumn($field)?->getProperty()) {
$value = $this->castProperty($prop, $value, $entity);
$value = $this->castProperty($prop, $value, $entity, $isNew);
}

if (!$updateNulls && $value === null) {
Expand Down Expand Up @@ -1514,20 +1519,20 @@ protected function castForSave(array $data, bool $updateNulls = true, ?object $e
return $item;
}

protected function castProperty(ReflectionProperty $prop, mixed $value, object $entity): mixed
protected function castProperty(ReflectionProperty $prop, mixed $value, object $entity, bool $isNew = false): mixed
{
$castManager = $this->getMetadata()->getCastManager();

AttributesAccessor::runAttributeIfExists(
$prop,
CastForSave::class,
function (CastForSave $attr) use ($entity, $castManager, &$value) {
function (CastForSave $attr) use ($isNew, $entity, $castManager, &$value) {
$caster = $castManager->wrapCastCallback(
$castManager->castToCallback($attr->getCaster() ?? $attr, $attr->options ?? 0),
$attr->options
);

$value = $caster($value, $this->getORM(), $entity);
$value = $caster($value, $this->getORM(), $entity, $isNew);
},
ReflectionAttribute::IS_INSTANCEOF
);
Expand Down

0 comments on commit 23a3b94

Please sign in to comment.