Integration of Doctrine2 and Zend framework

Time does not stand still, and need to run for time.
Now and ZF2 on the way. Released the first milestone. Zend Framework 2.0.0dev1 Release. Doctrine2 BETA3 — was on Friday.
A good programmer never stand still — there is no time. Lag behind and go for it — do the table — "Code for the Food".

It was evening there was nothing to do...

Downloading the library source codes began to play. The goal is to create models while maintaining the structure of ZF and work through the Doctrine2 connection.
First we need to put in the include_path classes that are part of Doctrine2.

the library/Doctrine
libray/Symfony


Symfony will need to use a tool out of the box to work Doctrine2 (the two components of the Console and Yaml).
In configs/application.append the ini data for the auto loader.
autoloadernamespaces.doctrine = "Doctrine"
autoloadernamespaces.symfony = "Symfony"


Continuation under the cut. What options need to be set in application.ini. How to connect Doctrine2, the source code of the resource plug-in.


For your application I chose
appnamespace = "Ecom"

At the moment I have not found a more "beautiful" way to set the path to the resource plugins.
pluginpaths.Ecom\Application\Resources = APPLICATION_PATH "/resources"


Configuration options Doctrine2, for me it's just a configuration konekta to the database (until I bolshego and not necessary).
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"


In the plugin resource must be namespace — Ecom\Application\Resources; And the class name must match the name in the 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->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 method());
echo __METHOD__;
}

public function postUpdate(Common\EventArgs $e)
{
echo __METHOD__;
}


}

$entityModels contains a list of existing modules in the system, the same mechanism is used in the Frontcontroller resource plugin-a to load the modules.
$options['connection'] — parameters database connection for Doctrine2.
When generating the schemas Doctrine2 will look for the data in the folder ModuleName/Model, to use the schema for a database based on the php-doc of the model class.

Create the controller and an example of creating a new model object.

    <?php

    namespace Catalog; the

  1. use Zend\Controller;
  2. the
  3. use Core\Model\Entity;
  4. the
  5. use Catalog\Model;
  6. 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');

    }

    }



There should be all simple and clear. You should pay attention only to the fact that the use of namespace Catalog; the name of the module.

The class of models of the product.

    <?php

    namespace Catalog\Model;

    the

  1. use Core\Model\Entity;
  2. the
  3. /**
  4. * @Entity

    * @HasLifecycleCallbacks

    * @Table(name="catalog_product") the

  5. */
  6. class Product extends Model\Entity { the

  7. /**
  8. * @var integer

    * @Id @Column(type="integer")

    * @GeneratedValue(strategy="AUTO") the

  9. */
  10. the

  11. /**
  12. * @var string

    * @Column(type="string", length=255) the

  13. */
  14. private $name;

    the

  15. /**
  16. * @var string

    * @Column(type="string", length=255, unique=true, nullable=false) the

  17. */
  18. private $sku;

    the

  19. /**
  20. * @var string

    * @Column(type="datetime", nullable=true) the

  21. */
  22. private $created;

    the

  23. /**
  24. * @var string

    * @Column(type="datetime", nullable=true) the

  25. */
  26. private $updated;

    the

  27. /**
  28. * @return the integer $id the

  29. */
  30. public function getId() {

    return $this->id;

    }

    the

  31. /**
  32. * @return the string $name the

  33. */
  34. public function getName() {

    return $this->getProperty('name');

    }

    the

  35. /**
  36. * @param string $name the $name to set the

  37. */
  38. public function setName($name) {

    $this->name = $name;

    return $this;

    }

    the

  39. /**
  40. * @return string the $created the

  41. */
  42. the
  43. /**
  44. * @return the $sku the

  45. */
  46. public function getSku(){

    return $this->getProperty('sku');

    }

    the

  47. /**
  48. * @param $sku the $sku to set the

  49. */
  50. public function setSku($sku){

    $this->sku = $sku;

    return $this;

    }

    public function getCreated(){

    return $this->getProperty('created');

    }

    the

  51. /**
  52. * @param $created the $created to set the

  53. */
  54. public function setCreated($created){

    $this->created = $created;

    return $this;

    }

    the

  55. /**
  56. * @return the $updated

    public function getUpdated(){

    return $this->getProperty('updated');

    }

    the

  57. /**
  58. * @param $updated the $updated to set the

  59. */
  60. public function setUpdated($updated){

    $this->updated = $updated;

    return $this;

    }

    }



Again, it is worth noting — namespace Catalog\Model; mandatory manual for the class model.

My thoughts — I love it all. PHP has climbed yet another notch as the language for the corporate sector.
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Briefly on how to make your Qt geoservice plugin

Database replication PostgreSQL-based SymmetricDS

Yandex.Widget + adjustIFrameHeight + MooTools