Timestampable

Timestampable

Зберігає час створення і останньої зміни сутності.

Сутність

use Doctrine\ORM\Mapping as ORM;
use Ufo\DoctrineBehaviors\Contract\Entity\TimestampableInterface;
use Ufo\DoctrineBehaviors\Model\Timestampable\TimestampableTrait;

#[ORM\Entity]
class Category implements TimestampableInterface
{
    use TimestampableTrait;

    #[ORM\Id, ORM\GeneratedValue, ORM\Column]
    private ?int $id = null;
}

Як це працює

  • Під час loadClassMetadata бандл мапить createdAt і updatedAt (nullable, тип із параметра doctrine_behaviors_timestampable_date_field_type, за замовчуванням datetime) і додає lifecycle callback updateTimestamps() на prePersist і preUpdate. Атрибут #[ORM\HasLifecycleCallbacks] не потрібен.
  • updateTimestamps() ставить createdAt, якщо він ще null, і завжди оновлює updatedAt. Час береться з мікросекундами, у часовому поясі date_default_timezone_get().
  • preUpdate Doctrine викликає лише для сутностей зі зміненими полями — flush() без змін updatedAt не чіпає.
  • #[ORM\MappedSuperclass] пропускається; колонки отримують сутності-нащадки.

Використання

$category = new Category();
$entityManager->persist($category);
$entityManager->flush();

$category->getCreatedAt(); // DateTime
$category->getUpdatedAt(); // DateTime

setCreatedAt() і setUpdatedAt() дозволяють задати значення вручну; заданий createdAt при збереженні не перезаписується.

Налаштування

# config/services.yaml
parameters:
    doctrine_behaviors_timestampable_date_field_type: datetimetz

Трейт записує DateTime, тому підходять лише змінювані типи — datetime і datetimetz. Типи *_immutable очікують DateTimeImmutable і не сумісні.