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

时间:2016-07-21 11:39:56

标签: php symfony doctrine-orm doctrine-extensions

在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”不属于$validTypes中的Gedmo\Timestampable\Mapping\Driver\Annotation

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

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

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

1 个答案:

答案 0 :(得分:0)

经过一番广泛的研究,我想出了一个适合我的解决方案。不像我希望的那样优雅,但无论如何我想分享。

首先,我注册了自己的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',
    );
}

不幸的是,它还会导致从我的命名空间加载相应的字段适配器。所以我也要补充一点。由于原始适配器类被声明为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()
        ...
    }
}