Hammerbot
Hammerbot

Reputation: 16344

HasLifecycleCallbacks on a MappedSuperclass Entity

I am trying to make an abstract class to extend my entity from in order to give them some basic functionalities such as automatic timestamp.

So I created this abstract class:

/**
 * Class Model
 * @package AppBundle
 * @ORM\MappedSuperclass
 */
abstract class Model 
{
    /**
     * @var \DateTime $created_at
     *
     * @ORM\Column(type="datetime")
     */
    protected $created_at;

    /**
     * @var \DateTime $updated_at
     *
     * @ORM\Column(type="datetime")
     */
    protected $updated_at;

    /**
     *
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function updatedTimestamps()
    {
        $this->setUpdatedAt(new \DateTime('now'));

        if ($this->getCreatedAt() == null) {
            $this->setCreatedAt(new \DateTime('now'));
        }
    }

   public function getUpdatedAt()
   {
       return $this->updated_at;
   }

   public function setUpdatedAt($updated_at)
   {
       $this->updated_at = $updated_at;
   }

   public function getCreatedAt()
   {
       return $this->created_at;
   }

   public function setCreatedAt($created_at)
   {
       $this->created_at = $created_at;
       return $this;
   }

}

So now, I just need to extend my entity from this class:

class MyEntity extends Model 
{
    ....
}

However, if I want my timestamps to work, I still need to add the @ORM\HasLifecycleCallbacks on top of MyEntity class to trigger the updatedTimestamps() method on persist and on update.

I tried to add the annotation on top of my super class but it does not work.

Would someone have a solution to avoid to add the annotation on top of every entity?

I just want to extend my superclass and that's it...

Thank you for your answers and have a nice day!

Upvotes: 1

Views: 2236

Answers (1)

Al Foиce    ѫ
Al Foиce ѫ

Reputation: 4315

I implements it on a previous project, the annotation on MappedSuperclass work. The anotation I used is @ORM\HasLifecycleCallbacks() with the parenthesis, and not @ORM\HasLifecycleCallbacks.

This is how I done it (I give all the MappedSuperclass code in a didactic way):

AbstractGenericEntity.php

namespace Services\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass
 * @ORM\HasLifecycleCallbacks()
 */
class AbstractGenericEntity
{
    /**
     * @var \DateTime
     *
     * @ORM\Column(name="Z_CREATION_DATE", type="datetime", nullable=false)
     */
    private $dateCreation;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="Z_UPDATE_DATE", type="datetime", nullable=false)
     */
    private $dateMaj;


    // I just need this getter
    public function getUpdateDate($format= 'Y-m-d h:i:s:u') {
        return $this->dateMaj->format($format) ;
    }

    /**
     * @return AbstractGenericEntity
     * @ORM\PreUpdate
     */
    public function preUpdateCallback()
    {
        $this->dateMaj = new \DateTime("now");
        return $this;
    }

    /**
     * @return AbstractGenericEntity
     * @ORM\PrePersist
     */
    public function prePersistCallback()
    {
        $this->preUpdateCallback();
        $this->dateCreation = new \DateTime("now");
        return $this;
    }
}

And all my entities inherit of this super-class, without any special other annotation:

namespace Services\Entity;

use Doctrine\ORM\Mapping as ORM;
use Services\Entity\AbstractGenericEntity;

/**
 * @ORM\Table(name="MY_TABLE_NAME")
 * @ORM\Entity (repositoryClass="Services\Repositories\MyEntityRepository")
 */
class MyEntity extends AbstractGenericEntity
{
    public function __construct()
    {
        $this->id = uniqid('', true);
    }

    /**
     * @var string
     *
     * @ORM\Column(name="ID", type="string", length=23, nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     *
     */
    private $id;

    // etc, as usual...

Upvotes: 1

Related Questions