如何在Symfony2表单中呈现Doctrine Timestampable字段

时间:2014-03-03 15:18:00

标签: php forms symfony doctrine-orm

我要做的是在修改“pageTitle”或“metaDescription”字段时设置“seoUpdatedAt”字段。 同时我想通过Symfony2表单组件在后台渲染这个字段的内容,而不必编辑字段值(因为该值必须由timestampable扩展名设置)。

我尝试将字段设置为* read_only *但是值不会更新,并且教条扩展也没有(就好像它被忽略而且有意义)。

我还尝试将字段设置为* datetime single_text *,但出现了两个问题:

  1. 管理员可以手动更改值
  2. 在提交操作发生后,呈现的值似乎是旧的日期时间,尽管它已在数据库端更新,就好像POST请求中的值覆盖了表单呈现流程中的DB值一样。刷新页面而不重新提交数据显示更新的值(由学说扩展更新)
  3. 我最终尝试使用已禁用选项,但它没有按预期工作。

    一撮代码:

    // in my entity
    
    /**
     * @var \DateTime
     * @Gedmo\Timestampable(on="change", field={"pageTitle", "metaDescription"})
     * @ORM\Column(name="seo_updated_at", type="datetime", nullable=true)
     */
    private $seoUpdatedAt;
    

    这里有表格:

    // in my form type
    
    $builder
        ->add('pageTitle', 'text', array('required' => false))
        ->add('metaDescription', 'textarea', array('required' => false))
        ->add(
            'seoUpdatedAt',
            'datetime',
            array(
                'widget' => 'single_text',
                'format' => 'dd-MM-yyyy HH:mm:ss',
                'required' => false
            )
        );
    

    那么,您如何建议满足以下要求?

    • 该值不应手动编辑
    • 即使在表单提交后,也必须始终使用更新的值呈现值

    关于学说事件的听众?表格活动的听众?新的表单类型扩展名?

3 个答案:

答案 0 :(得分:1)

试试这个: 在你的实体中为$ seoUpdatedAt添加一个空的setter方法:

/**
 * @var \DateTime
 * @Gedmo\Timestampable(on="change", field={"pageTitle", "metaDescription"})
 * @ORM\Column(name="seo_updated_at", type="datetime", nullable=true)
 */
private $seoUpdatedAt;

public function setSeoUpdatedAt(\DateTime $seoUpdatedAt)
{
    //empty
}

并在表单构建器对象中添加seoUpdatedAt定义中的'by_reference'选项:

$builder
    ->add('pageTitle', 'text', array('required' => false))
    ->add('metaDescription', 'textarea', array('required' => false))
    ->add(
        'seoUpdatedAt',
        'datetime',
        array(
            'widget' => 'single_text',
            'format' => 'dd-MM-yyyy HH:mm:ss',
            'required' => false,
            'by_reference' => false,
        )
    );

答案 1 :(得分:0)

我无法提供很多示例代码,因为我不知道Symfonie(我正在使用ZF)。

查看onPrePerstistonPreUpdate事件:

http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-events

http://symfony.com/doc/current/book/doctrine.html

它是这样的:

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks
 */
class YourClass



/**
 * @ORM\PrePersist
 * @ORM\PreUpdate
 */
public function updateChanged() {
    $this->updated = new \DateTime();
}

每当您更新字段时,它都会调用pre *方法并更新您的列。

<强>更新

为什么不能这样:

public function setMetaDescription($metaDescription) {
    $this->metaDescription = $metaDescription;
    $this->setUpdatedAt    = new \DateTime();
}

因此,只要字段更新,它也会更新日期时间列。

答案 2 :(得分:0)

通过从表单中删除timestampable字段来解决此问题。我直接从分页对象渲染数据。

以这种方式,应用程序满足所有要求:

  • datetime字段由timestampable扩展名
  • 更新
  • 即使在表单提交后
  • ,也始终使用其当前值呈现日期时间值
  • 无法通过网络界面更改日期时间值

我希望这可能有助于其他人。