Как-то поверхностно я с Doctrine2 разобрался. Уже несколько раз ловил себя на мысли, что использую далеко не все возможности, а о многих наверное и не в курсе. Поэтому решил поковырять её более предметно.
Разворачиваем Doctrine2 + sandbox
Тянем доктрину с оригинального репозитория и инициализируем/обновляем сабмодули.
/var/www/test/doctrine2 $ git clone git@github.com:doctrine/doctrine2.git . /var/www/test/doctrine2 $ git submodule init /var/www/test/doctrine2 $ git submodule update --recursive |
В файле tools/sandbox/cli-config.php и tools/sandbox/index.php правим конфиг DBAL:
// Database connection information $connectionOptions = array( 'driver' => 'pdo_mysql', 'dbname' => 'doctrine2', 'user' => 'root', 'password' => '', 'host' => 'localhost', ); |
После этого можно запускать CLI скрипт tools/sandbox/doctrine и создавать схему БД:
/var/www/test/doctrine/tools/sandbox $ ./doctrine orm:schema-tool:create ATTENTION: This operation should not be executed in an production enviroment. Creating database schema... Database schema created successfully! |
Doctrine2 Behavioral Extensions
Для начала решил разобраться с Doctrine2 Behavioral Extensions. В первой Doctrine они назывались Doctrine Templates и мы довольно активно использовали I18n, NestedSet, Sluggable, Timestampable, а возможно даже Versionable и SoftDelete. Помню ещё были шаблоны от сторонних разработчиков, но не могу сейчас найти их на сайте доктрины.
Итак в Doctrine2 эти самые Behavioral Extensions вынесли отдельно. Сопровождением стандартного набора экстеншенов занимается Gediminas Morkevicius из KnpLabs. Они лежат в репо https://github.com/l3pp4rd/DoctrineExtensions и я подключил их через сабмодули.
Чтобы экстеншен заработал нужно для начала натравить автолоадер доктрины/сифони/зф/свой/чужой на скачанные либы. В нашем случае это выглядит вот так:
$classLoader = new \Doctrine\Common\ClassLoader('Gedmo', realpath(__DIR__ . '/../../lib/vendor/doctrine-extensions/lib')); $classLoader->register(); |
После этого цепляем обработчики нужных экстеншенов к EventManager’у нашего EntityManager’а:
// Create EntityManager $em = EntityManager::create($connectionOptions, $config); // timestable $em->getEventManager()->addEventSubscriber(new \Gedmo\Timestampable\TimestampableListener()); |
Для Symfony2 можно использовать DoctrineExtensionsBundle, а для ZF я видел решение на http://zendframework.ru/forum/.
Timestable
Первым шаблон, который я использовал в Doctrine был именно Timestable, Довольно часто нужно фиксировать время создания/редактирования сущности и писать эту логику в каждой модели не есть гуд.
Итак, добавим к модели \Entities\User поле created, значение для которого будет устанавливать Timestampable:
/** * @var datetime $created * * @gedmo:Timestampable(on="create") * @Column(type="date") */ private $created; public function getCreated() { return $this->created; } |
А эту логику нужно поместить в скрипт tools/sandbox/index.php после строк “## PUT YOUR TEST CODE BELOW”:
$user = new User; $user->setName('Stepan Tanasiychuk'); $address = new Address; $address->setStreet('Lenina street'); $user->setAddress($address); $em->persist($user); $em->persist($address); $em->flush(); var_dump($user); |
Если на выходе получился следующий фрагмент, то все ок:
object(Entities\User)[25] private 'id' => int 1 private 'name' => string 'Stepan Tanasiychuk' (length=18) private 'address' => object(Entities\Address)[26] private 'id' => int 1 private 'street' => string 'Lenina street' (length=13) private 'user' => &object(Entities\User)[25] private 'created' => object(DateTime)[33] public 'date' => string '2011-04-16 00:55:53' (length=19) public 'timezone_type' => int 3 public 'timezone' => string 'Europe/Kiev' (length=11) |
Дальше я подключил Sluggable и разобрался по какому принципу работают бехевиор экстеншены, но писать об этом уже лень. Давайте хоть то что есть опубликую 🙂