web-dev-qa-db-fra.com

Symfony -> Comment dynamiser les champs créés et modifiés avec Doctrine?

Je suis nouveau sur Symfony2 (ou Symfony3) et je ne trouve pas comment définir doctrine (avec la configuration des annotations) pour l'enregistrer automatiquement dans mes entités lors de la création ou de la modification des champs .

24
dctremblay

Voici ma solution après ce temps ...

Vous avez juste besoin de mettre cela directement dans votre classe d'entité:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class MyEntity {

   //....

    public function __construct() {
        // we set up "created"+"modified"
        $this->setCreated(new \DateTime());
        if ($this->getModified() == null) {
            $this->setModified(new \DateTime());
        }
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function updateModifiedDatetime() {
        // update the modified time
        $this->setModified(new \DateTime());
    }

    //....    
}

Ça marche bien en fait

41
dctremblay

Vous pouvez utiliser StofDoctrineExtensionsBundle . Ceci est décrit dans livre de recettes symfony . Il contient le comportement Timestampable .

/**
 * @var datetime $created
 *
 * @Gedmo\Timestampable(on="create")
 * @ORM\Column(type="datetime")
 */
private $created;

/**
 * @var datetime $updated
 *
 * @Gedmo\Timestampable(on="update")
 * @ORM\Column(type="datetime")
 */
private $updated;
24
Alexey B.
/**
 *
 * @ORM\PrePersist
 * @ORM\PreUpdate
 */
public function updatedTimestamps()
{
    $this->setModifiedAt(new \DateTime(date('Y-m-d H:i:s')));

    if($this->getCreatedAt() == null)
    {
        $this->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
    }
}

Vous n'avez pas besoin d'appeler __constructor Quoi que ce soit. Créez simplement les propriétés getter et settercreated, modified et c'est tout.

Si vous définissez d'abord setCreated() à chaque mise à jour, vous mettrez également à jour created colum. Mettez donc en premier setModifedAt()

10
Ivan

Deux autres exemples (si vous utilisez le mappage Yaml ou Xml):

Entity\Product:
  type: entity
  table: products
  id:
    id:
      type: integer
      generator:
        strategy: AUTO
  fields:
    name:
      type: string
      length: 32
    created_at:
      type: date
      gedmo:
        timestampable:
          on: create
    updated_at:
      type: datetime
      gedmo:
        timestampable:
          on: update

Et xml:

<?xml version="1.0" encoding="UTF-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping"
                  xmlns:gedmo="http://gediminasm.org/schemas/orm/doctrine-extensions-mapping">

    <entity name="Mapping\Fixture\Xml\Timestampable" table="timestampables">
        <id name="id" type="integer" column="id">
            <generator strategy="AUTO"/>
        </id>

        <field name="created_at" type="datetime">
            <gedmo:timestampable on="create"/>
        </field>
        <field name="updated_at" type="datetime">
            <gedmo:timestampable on="update"/>
        </field>
    </entity>

</doctrine-mapping>
5
NHG

Les autres réponses suggèrent d'utiliser des instructions if (ce qui signifie répéter les noms de vos propriétés) et d'avoir une logique de définition des propriétés dans le constructeur qui pourrait ne jamais être utilisée.

Vous pouvez également avoir des méthodes onAdd et onUpdate qui sont appelées en cas de besoin:

/**
 * @ORM\PrePersist
 */
public function onAdd()
{
    $this->setAdded(new DateTime('now'));
}

/**
 * @ORM\PrePersist
 * @ORM\PreUpdate
 */
public function onUpdate()
{
    $this->setUpdated(new DateTime('now'));
}
2
rybo111