web-dev-qa-db-ja.com

symfony-> Doctrineで作成および変更されたフィールドを動的にする方法は?

私はSymfony2(またはSymfony3)を使い始めたばかりですが、doctrine(アノテーション設定を使用))を設定して、フィールドを「作成」または「変更」したときにエンティティに自動的に保存する方法を見つけることができません。

24
dctremblay

ここでこの後の私の解決策...

これをあなたのエンティティクラスに直接入れるだけです:

/**
 * @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());
    }

    //....    
}

実際にうまくいきます

41
dctremblay

StofDoctrineExtensionsBundle を使用できます。これは symfonyクックブック で説明されています。 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')));
    }
}
_

___constructor_を呼び出す必要はありません。 getterおよびsetterプロパティcreatedmodifiedを作成するだけで、それですべてです。

すべての更新で最初にsetCreated()を設定すると、created列も更新されます。だから最初に置くsetModifedAt()

10
Ivan

さらに2つの例(Yamlまたは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

そして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

他の回答は、ifステートメント(プロパティ名を繰り返すことを意味します)の使用と、使用されない可能性があるコンストラクター内のプロパティ設定ロジックの使用を提案しています。

または、必要に応じて呼び出されるonAddおよびonUpdateメソッドを使用することもできます。

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

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