Время не стоит на месте, и надо бежать за временем.
Вот уже и ZF2 на подходе. Выпущен первый milestone. Zend Framework 2.0.0dev1 Release. Doctrine2 BETA3 — был в пятницу.
А хороший программист никогда не стоит на месте — времени нету. Отстанет и вперёд — делай таблицы — «Code for the Food».
Дело было вечером делать было нечего…
Скачав исходные коды библиотек начали играться. Цель — получить возможность создание моделей сохраняя структуру ZF и работать через подключение Doctrine2.
Для начала нам нужно поместить в include_path классы, которые являются частью Doctrine2.
Symfony нужно будет, что бы использовать инструмент из коробки для работы Doctrine2 (два компонента Console и Yaml).
В configs/application.ini прописываем данные для авто загрузчика.
Продолжение под катом. Какие опции нужно прописать в application.ini. Как подключить Doctrine2, исходный код ресурс плагина.
Для своего приложения я выбрал
На данный момент я не нашёл более «красивого» способа прописать путь к ресурс плагинам.
Параметры конфигурации Doctrine2, для меня это просто конфигурация конекта к базе данных (пока мне большеего и не нужно).
В плагине ресурса обязательно должен быть namespace — Ecom\Application\Resources; И название класса должно совпадать с названием в application.ini.
$entityModels содержит в себе список существующих модулей в системе, такой же механизм используется в ресурс плагине Frontcontroller-a для загрузки модулей.
$options['connection'] — параметры подключения к базе данных для Doctrine2.
При генерации схемы Doctrine2 будет искать данные в папке ModuleName/Model, использовать схему для базы данных основываясь на php-doc класса модели.
Создание контроллера и пример создания нового объекта модели.
Тут должно быть всё просто и понятно. Стоит обратить внимание только на то что, обязательно использование namespace Catalog; — имя модуля.
Класс самой модели продукта
Опять же, стоит заметить — namespace Catalog\Model; обязательная инструкция для класса модели.
Мои мысли — мне всё это нравится. PHP поднялся на ещё одну ступеньку выше как язык для корпоративного сектора.
Вот уже и ZF2 на подходе. Выпущен первый milestone. Zend Framework 2.0.0dev1 Release. Doctrine2 BETA3 — был в пятницу.
А хороший программист никогда не стоит на месте — времени нету. Отстанет и вперёд — делай таблицы — «Code for the Food».
Дело было вечером делать было нечего…
Скачав исходные коды библиотек начали играться. Цель — получить возможность создание моделей сохраняя структуру ZF и работать через подключение Doctrine2.
Для начала нам нужно поместить в include_path классы, которые являются частью Doctrine2.
library/Doctrine
libray/Symfony
Symfony нужно будет, что бы использовать инструмент из коробки для работы Doctrine2 (два компонента Console и Yaml).
В configs/application.ini прописываем данные для авто загрузчика.
autoloadernamespaces.doctrine = "Doctrine"
autoloadernamespaces.symfony = "Symfony"
Продолжение под катом. Какие опции нужно прописать в application.ini. Как подключить Doctrine2, исходный код ресурс плагина.
Для своего приложения я выбрал
appnamespace = "Ecom"
На данный момент я не нашёл более «красивого» способа прописать путь к ресурс плагинам.
pluginpaths.Ecom\Application\Resources = APPLICATION_PATH "/resources"
Параметры конфигурации Doctrine2, для меня это просто конфигурация конекта к базе данных (пока мне большеего и не нужно).
resources.doctrine2.connection.driver = "pdo_mysql"
resources.doctrine2.connection.host = "localhost"
resources.doctrine2.connection.user = "root"
resources.doctrine2.connection.password = ""
resources.doctrine2.connection.dbname = "doctrinedb"
В плагине ресурса обязательно должен быть namespace — Ecom\Application\Resources; И название класса должно совпадать с названием в application.ini.
<?php
namespace Ecom\Application\Resources;
use Doctrine\Common\Util;
use Ecom\Document;
use Doctrine\ORM;
use Doctrine\DBAL;
use Doctrine\Common;
use Doctrine\Common\Cache;
use Zend\Application\Resource;
class Doctrine2 extends Resource\AbstractResource {
public function init() {
$front = $this->getBootstrap()->getResource('frontcontroller');
$modules = $front->getControllerDirectory();
$entityModels = array();
foreach ($modules as $module => $moduleDirectory) {
$dir = dirname($moduleDirectory) . "/models";
if (is_dir($dir)) {
$entityModels[] = $dir;
}
}
$options = $this->getOptions();
$config = new ORM\Configuration();
$config->setProxyDir(APPLICATION_PATH . '/proxies');
$config->setProxyNamespace('Ecom\Proxy');
$config->setAutoGenerateProxyClasses($this->getBootstrap()->getEnvironment() == "development");
$driverImpl = $config->newDefaultAnnotationDriver($entityModels);
$config->setMetadataDriverImpl($driverImpl);
if ($this->getBootstrap()->getEnvironment() == "development") {
$cache = new Cache\ArrayCache();
} else {
$cache = new Cache\ApcCache();
}
$config->setMetadataCacheImpl($cache);
$config->setQueryCacheImpl($cache);
$evm = new Common\EventManager();
$entityManager = ORM\EntityManager::create($options['connection'], $config, $evm);
$eventDocument = new EventDocument($entityManager->getEventManager());
return $entityManager;
}
}
class EventDocument {
private $evm;
public $preFooInvoked = false;
public $postFooInvoked = false;
public function __construct($evm)
{
$this->evm = $evm;
// $evm->addEventListener(array(ORM\Events::preRemove), $this);
// $evm->addEventListener(array(ORM\Events::postRemove), $this);
// $evm->addEventListener(array(ORM\Events::prePersist), $this);
$evm->addEventListener(array(ORM\Events::postPersist, ORM\Events::postUpdate), $this);
// $evm->addEventListener(array(ORM\Events::preUpdate), $this);
// $evm->addEventListener(array(ORM\Events::postUpdate), $this);
// $evm->addEventListener(array(ORM\Events::postLoad), $this);
// $evm->addEventListener(array(ORM\Events::loadClassMetadata), $this);
// $evm->addEventListener(array(ORM\Events::onFlush), $this);
}
public function postPersist(Common\EventArgs $e)
{
\Doctrine\Common\Util\Debug::dump($e->getEntity());
echo __METHOD__;
}
public function postUpdate(Common\EventArgs $e)
{
echo __METHOD__;
}
}
$entityModels содержит в себе список существующих модулей в системе, такой же механизм используется в ресурс плагине Frontcontroller-a для загрузки модулей.
$options['connection'] — параметры подключения к базе данных для Doctrine2.
При генерации схемы Doctrine2 будет искать данные в папке ModuleName/Model, использовать схему для базы данных основываясь на php-doc класса модели.
Создание контроллера и пример создания нового объекта модели.
- <?php
- namespace Catalog;
- use Zend\Controller;
- use Core\Model\Entity;
- use Catalog\Model;
- class IndexController extends Controller\Action
- {
- public function init()
- {
- /* Initialize action controller here */
- }
- public function indexAction() {
- $product = new Model\Product();
- $product->setName('test');
- $product->setSku('test'.mktime());
- /* @var $em Doctrine\ORM\EntityManager */
- $em = $this->getInvokeArg('bootstrap')->getResource('doctrine2');
- $em->persist($product);
- $em->flush();
- $this->_helper->layout->setLayout('layout');
- }
- }
Тут должно быть всё просто и понятно. Стоит обратить внимание только на то что, обязательно использование namespace Catalog; — имя модуля.
Класс самой модели продукта
- <?php
- namespace Catalog\Model;
- use Core\Model\Entity;
- /**
- * @Entity
- * @HasLifecycleCallbacks
- * @Table(name="catalog_product")
- */
- class Product extends Model\Entity {
- /**
- * @var integer
- * @Id @Column(type="integer")
- * @GeneratedValue(strategy="AUTO")
- */
- private $id;
- /**
- * @var string
- * @Column(type="string", length=255)
- */
- private $name;
- /**
- * @var string
- * @Column(type="string", length=255, unique=true, nullable=false)
- */
- private $sku;
- /**
- * @var string
- * @Column(type="datetime", nullable=true)
- */
- private $created;
- /**
- * @var string
- * @Column(type="datetime", nullable=true)
- */
- private $updated;
- /**
- * @return integer the $id
- */
- public function getId() {
- return $this->id;
- }
- /**
- * @return string the $name
- */
- public function getName() {
- return $this->getProperty('name');
- }
- /**
- * @param string $name the $name to set
- */
- public function setName($name) {
- $this->name = $name;
- return $this;
- }
- /**
- * @return string the $created
- */
- /**
- * @return the $sku
- */
- public function getSku(){
- return $this->getProperty('sku');
- }
- /**
- * @param $sku the $sku to set
- */
- public function setSku($sku){
- $this->sku = $sku;
- return $this;
- }
- public function getCreated(){
- return $this->getProperty('created');
- }
- /**
- * @param $created the $created to set
- */
- public function setCreated($created){
- $this->created = $created;
- return $this;
- }
- /**
- * @return the $updated
- */
- public function getUpdated(){
- return $this->getProperty('updated');
- }
- /**
- * @param $updated the $updated to set
- */
- public function setUpdated($updated){
- $this->updated = $updated;
- return $this;
- }
- }
Опять же, стоит заметить — namespace Catalog\Model; обязательная инструкция для класса модели.
Мои мысли — мне всё это нравится. PHP поднялся на ещё одну ступеньку выше как язык для корпоративного сектора.