Symfony2 中自定义字段类型的 Doctrine Timestampable

Doctrine Timestampable on custom field type in Symfony2

在 Symfony2 项目中,我使用自定义 Doctrine 类型 'unixtime' 来映射遗留数据库中存储为 unix 时间戳的日期字段:

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

现在我想使用 DoctrineExtensions 和 stof/doctrine-extensions-bundle 通过添加自动设置此 属性:

 * @Gedmo\Timestampable(on="create")

但这会导致异常,因为"unixtime"不在Gedmo\Timestampable\Mapping\Driver\Annotation中的$validTypes中:

Field - [created] type is not valid and must be 'date', 'datetime' or 'time' in class ...

当我将 'unixtime' 直接添加到该有效类型数组时,一切正常。

使 Timestampable 处理程序与我的自定义类型一起工作的最好和最少干扰的方法是什么?有没有办法配置这个?我需要继承吗?

经过广泛研究后,我想出了一个适合我的解决方案。没有我希望的那么优雅,但我还是想分享一下。

首先,我自己注册了TimestampableListener:

stof_doctrine_extensions:
    class:
        timestampable: MyProject\TimestampableListener

... 覆盖 getNamespace():

namespace MyProject;
class TimestampableListener extends \Gedmo\Timestampable\TimestampableListener
{
    protected function getNamespace()
    {
        return __NAMESPACE__;
    }
}

这将导致 DoctrineExtensions 也从我的命名空间加载注释映射驱动程序,因此我可以扩展它并将我的自定义类型添加到允许类型列表中:

namespace MyProject\Mapping\Driver;
class Annotation extends \Gedmo\Timestampable\Mapping\Driver\Annotation
{
    protected $validTypes = array(
        'date', 'time', 'datetime', 'datetimetz', 'timestamp',
        'zenddate', 'vardatetime', 'integer',
        // our custom field type:
        'unixtime',
    );
}

不幸的是,它还会导致从我的命名空间加载相应的字段适配器。所以我也必须添加那个。由于原始适配器 class 被声明为 final,我基本上被迫复制实现:

namespace MyProject\Mapping\Event\Adapter;
final class ORM extends BaseAdapterORM implements TimestampableAdapter
{
    public function getDateValue($meta, $field)
    {
        // code from Gedmo\Timestampable\Mapping\Event\Adapter::getDateValue()
        ...
    }
}