当"pageTitle"或"metaDescription"字段被修改时,我要做的是设置一个"seoUpdatedAt"字段。同时,我想通过Symfony2表单组件在后台呈现该字段的内容,而不提供编辑字段值的可能性(因为该值必须由时间戳扩展设置)。
我试图将字段设置为*read_only*,但值没有更新,条令扩展也没有更新(好像它被忽略了,这是有道理的)。
我还试图将字段设置为*datetime single_text*,但出现了两个问题:
- 管理员可以手动更改值
- 提交操作发生后,呈现的值看起来是旧的日期时间,尽管它在DB端进行了更新,就好像POST请求中的值覆盖了表单呈现流中的DB值一样。在不重新提交数据的情况下刷新页面显示更新值(由条令扩展更新)
我最终尝试禁用选项,但它没有按预期工作。
一小撮代码:
// in my entity
/**
* @var DateTime
* @GedmoTimestampable(on="change", field={"pageTitle", "metaDescription"})
* @ORMColumn(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
)
);
那么,你建议如何满足以下要求?
- 该值不应手动编辑
- 即使在表单提交之后,也必须始终使用更新后的值呈现该值
Doctrine事件的监听器?窗体事件的侦听器?一个新的表单类型扩展?
试试这个:在实体中为$seoUpdatedAt:添加一个空的setter方法
/**
* @var DateTime
* @GedmoTimestampable(on="change", field={"pageTitle", "metaDescription"})
* @ORMColumn(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,
)
);
我无法提供太多示例代码,因为我不了解Symfonie(我正在使用ZF)。
查看onPrePerstist
或onPreUpdate
事件:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#lifecycle-事件
http://symfony.com/doc/current/book/doctrine.html
它是这样的:
/**
* @ORMEntity
* @ORMHasLifecycleCallbacks
*/
class YourClass
/**
* @ORMPrePersist
* @ORMPreUpdate
*/
public function updateChanged() {
$this->updated = new DateTime();
}
每当更新字段时,它都会调用pre*方法并更新列。
更新:
为什么不这样做:
public function setMetaDescription($metaDescription) {
$this->metaDescription = $metaDescription;
$this->setUpdatedAt = new DateTime();
}
因此,每当字段更新时,它也会更新日期时间列。
通过从表单中删除时间戳字段来解决。我通过直接从分页对象获取数据来呈现它。
通过这种方式,应用程序满足所有要求:
- 日期时间字段由时间戳扩展更新
- 即使在表单提交之后,日期时间值也始终以其当前值呈现
- datetime值不能通过web界面更改
我希望这能帮助到其他人。