В проекте 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 работать с моим пользовательским типом? Есть ли способ настроить это? Нужно ли подкласс?
После некоторых обширных исследований я нашел решение, которое работает для меня. Не так элегантно, как хотелось бы, но я бы все равно поделился.
Сначала я зарегистрировал свой собственный 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()
...
}
}
Других решений пока нет …