ZF & Doctrine 2 ODM                  Doctrine
WHO IS RYAN MAUGER?•   Zend Framework Contributor•   Zend Framework CR Team Member•   Co-Author of Zend Framework 2 in Act...
What is the ODM?
What is the ODM? Object Document Mapper
What is the ODM? Object Document Mapper    Similar to an ORM
What is the ODM?     Object Document Mapper        Similar to an ORMBut works with a Document Database
What is the ODM?     Object Document Mapper        Similar to an ORMBut works with a Document Database
Whats the advantage?• Schema-less design (no complicated ALTER TABLE statements, just save your data!• Works with JSON obj...
Whats the advantage?• Schema-less design (no complicated ALTER  TABLE statements, just save your data!• Works with JSON ob...
Whats the advantage?                     Doctrine 2• Uses the Data Mapper pattern• Simplifies your domain, removes the pers...
Getting started with the                   ODMPersistence operations revolve around the Document Manager Mapping of proper...
<?phpnamespace ApplicationBlog;/**  * @Document(db="blog", collection="posts")  */class Post{     /**      * @Id      */  ...
<?phpnamespace ApplicationBlog;/**  * @Document(db="blog", collection="posts")  */class Post{     /**      * @Id      */  ...
Using your entity                                                      Create                    <?php                    ...
Using your entity                                                     Update                <?php                class Ind...
Using your entity                                           Add an comment                <?php                class Index...
Using your entity                                                     Delete            <?php            class IndexContro...
Available Annotationshttp://www.doctrine-project.org/docs/mongodb_odm/1.0/en/           reference/annotations-reference.html
Available Annotationshttp://www.doctrine-project.org/docs/mongodb_odm/1.0/en/           reference/annotations-reference.ht...
Integrating with ZF
Integrating with ZFExample Sandbox: http://github.com/bittarman/zf-d2-odm           Includes all (PHP) dependencies       ...
The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader,    DoctrineCommonAnnotationsAnnotationReader...
The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader,    DoctrineCommonAnnotationsAnnotationReader...
The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader,    DoctrineCommonAnnotationsAnnotationReader...
The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader,    DoctrineCommonAnnotationsAnnotationReader...
The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader,    DoctrineCommonAnnotationsAnnotationReader...
[production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi m...
[production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi m...
[production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi m...
Base Controller• Provide an easy method to access the DocumentManager, and perhaps a service layer / repository• Not using...
<?phpnamespace LupiController;                                                               Base Controllerabstract class...
Simplified controller code<?phpuse LupiController as controller;class IndexController extends controllerAction{            ...
Simplified controller code<?phpuse LupiController as controller;class IndexController extends controllerAction{            ...
Managing change
Managing change• For adding a new property, mostly, you don’t need to do much
Managing change• The db is schema-less
Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready
Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready...
Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready...
Managing changeMake use of the annotations!
Changing a property name               From                                            To<?php                            ...
Changing a property name               From                                                            To                 ...
Transforming a property               From                                                                           To   ...
Transforming a property               From                                             <?php                              ...
NOTE!• When searching, your queries will not know about the old name!• Include old and new fields in your searches if possi...
NOTE!• The ODM is still in BETA3, there are still some glitches, but its well worth having a good look now.• http://www.do...
Useful information• Official docs: http://www.doctrine-project.org/ docs/mongodb_odm/1.0/en/• Mongodb: http://www.mongodb.or...
Thanks for listening Catch me on twitter: @Bittarman      Slides will be available on slideshare         http://slideshare...
Upcoming SlideShare
Loading in...5
×

Zend Framework and the Doctrine2 MongoDB ODM (ZF1)

9,547

Published on

A short introduction to using and integrating the Doctrine 2 ODM for mongodb in your Zend Framework Applications

Published in: Technology
1 Comment
5 Likes
Statistics
Notes
No Downloads
Views
Total Views
9,547
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
164
Comments
1
Likes
5
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Zend Framework and the Doctrine2 MongoDB ODM (ZF1)

    1. 1. ZF & Doctrine 2 ODM Doctrine
    2. 2. WHO IS RYAN MAUGER?• Zend Framework Contributor• Zend Framework CR Team Member• Co-Author of Zend Framework 2 in Action (With Rob Allen)• Technical Editor for Zend Framework: A Beginners Guide• Community Supporter• Zend Certified PHP5 Engineer• Lead Developer at Lupimedia and trainer at Lupijuice
    3. 3. What is the ODM?
    4. 4. What is the ODM? Object Document Mapper
    5. 5. What is the ODM? Object Document Mapper Similar to an ORM
    6. 6. What is the ODM? Object Document Mapper Similar to an ORMBut works with a Document Database
    7. 7. What is the ODM? Object Document Mapper Similar to an ORMBut works with a Document Database
    8. 8. Whats the advantage?• Schema-less design (no complicated ALTER TABLE statements, just save your data!• Works with JSON objects, familiar with what your already doing• Simple!
    9. 9. Whats the advantage?• Schema-less design (no complicated ALTER TABLE statements, just save your data!• Works with JSON objects, familiar with what your already doing• Simple! (at least to get started)
    10. 10. Whats the advantage? Doctrine 2• Uses the Data Mapper pattern• Simplifies your domain, removes the persistence logic• Entities are free to do their job• Defines a framework by which your domain model will work, improving consistency
    11. 11. Getting started with the ODMPersistence operations revolve around the Document Manager Mapping of properties is carried out through annotations in your entities, or through xml/yaml mappings
    12. 12. <?phpnamespace ApplicationBlog;/** * @Document(db="blog", collection="posts") */class Post{ /** * @Id */ private $id; An example entity /** * @Field(type="string") */ private $title; /** * @String */ Properties private $content; /** /** * @EmbedMany(targetDocument="ApplicationBlogComment") */ * @Id private $comments = array(); */ public function getId() private $id; { return $this->id; } /** public function setId($id) * @Field(type="string") { $this->id = (string) $id; */ return $this; private $title; } public function getTitle() { /** return $this->title; * @String } */ public function setTitle($title) private $content; { $this->title = (string) $title; } return $this; /** * @EmbedMany(targetDocument="ApplicationBlogComment") public function getContent() { */ return $this->content; private $comments = array(); } public function setContent($content) { $this->content = (string) $content; return $this; } public function getComments() { return $this->comments; } public function addComment(ApplicationBlogComment $comment) { $this->comments[] = $comment; return $this; }}
    13. 13. <?phpnamespace ApplicationBlog;/** * @Document(db="blog", collection="posts") */class Post{ /** * @Id */ private $id; An example entity /** * @Field(type="string") */ private $title; /** * @String */ Methods private $content; /** * @EmbedMany(targetDocument="ApplicationBlogComment") public function getContent() */ { private $comments = array(); return $this->content; public function getId() } { return $this->id; } public function setContent($content) public function setId($id) { { $this->id = (string) $id; $this->content = (string) $content; return $this; return $this; } } public function getTitle() { return $this->title; public function getComments() } { public function setTitle($title) return $this->comments; { $this->title = (string) $title; } return $this; } public function addComment(ApplicationBlogComment $comment) public function getContent() { { return $this->content; $this->comments[] = $comment; } return $this; public function setContent($content) { } $this->content = (string) $content; return $this; } public function getComments() { return $this->comments; } public function addComment(ApplicationBlogComment $comment) { $this->comments[] = $comment; return $this; }}
    14. 14. Using your entity Create <?php class IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { $documentManager = $this->getInvokeArg(bootstrap)->getResource(odm); $post = new ApplicationBlogPost(); $post->setTitle(My Interesting Post) ->setContent(I have somethnng very interesting to say); $documentManager->persist($post); $documentManager->flush(); } }> use blogswitched to db blog> db.posts.find();{ "_id" : ObjectId("4dde4067fbd2237df1000000"), "title" : "My Interesting Post", "content" : "I have somethnng veryinteresting to say" }
    15. 15. Using your entity Update <?php class IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { $documentManager = $this->getInvokeArg(bootstrap)->getResource(odm); $post = $documentManager->getRepository(ApplicationBlogPost) ->find(4dde4067fbd2237df1000000); $post->setTitle(My Interesting Post) ->setContent(I have something very interesting to say); $documentManager->persist($post); $documentManager->flush(); } }> db.posts.find();{ "_id" : ObjectId("4dde4067fbd2237df1000000"), "title" : "My Interesting Post", "content" : "I have something veryinteresting to say" }
    16. 16. Using your entity Add an comment <?php class IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { $documentManager = $this->getInvokeArg(bootstrap)->getResource(odm); $post = $documentManager->getRepository(ApplicationBlogPost) ->find(4dde4067fbd2237df1000000); $comment = new ApplicationBlogComment(); $comment->setEmail(foo@example.com) ->setComment(Nice post!); $post->addComment($comment); $documentManager->persist($post); $documentManager->flush(); } }> db.posts.find();{ "_id" : ObjectId("4dde4067fbd2237df1000000"), "comments" : [ { "_id" : ObjectId("4dde439afbd22380f1000000"), "email" : "foo@example.com", "comment" : "Nice post!" }], "content" : "I have something very interesting to say", "title" : "My Interesting Post" }
    17. 17. Using your entity Delete <?php class IndexController extends Zend_Controller_Action { public function init() { /* Initialize action controller here */ } public function indexAction() { $documentManager = $this->getInvokeArg(bootstrap)->getResource(odm); $post = $documentManager->getRepository(ApplicationBlogPost) ->find(4dde4067fbd2237df1000000); $documentManager->remove($post); $documentManager->flush(); } }> db.posts.find();>
    18. 18. Available Annotationshttp://www.doctrine-project.org/docs/mongodb_odm/1.0/en/ reference/annotations-reference.html
    19. 19. Available Annotationshttp://www.doctrine-project.org/docs/mongodb_odm/1.0/en/ reference/annotations-reference.html @Field(type="string" name="origin") Field Mappings. Many aliases are available: @String, @Date, @Int, @Float etc. @EmbedOne / @EmbedMany Embedded Documents, stores the document inside the current document @ReferenceOne / @ReferenceMany Referenced Documents, stores a reference to one or more documents outside the current document @Document / @EmbeddedDocument Marks entities which are allowed to be managed by the document manager. additionally EmbeddedDocuments may not be saved independently, and must be a child of an @Document @HasLifecycleCallbacks & @PrePersist, @PostPersist etc. Marks an entity as having callbacks such as PrePersist which will be called automatically by the DocumentManager during the entities lifetime. (see reference for list)
    20. 20. Integrating with ZF
    21. 21. Integrating with ZFExample Sandbox: http://github.com/bittarman/zf-d2-odm Includes all (PHP) dependencies Requires the mongo pecl extension $ sudo pecl install mongo Install Doctrine from PEAR $ sudo pear channel-discover pear.doctrine-project.org $ sudo pear install pear.doctrine-project.org/DoctrineMongoDBODM-1.0.0BETA3 Checkout from Github $ git clone git://github.com/doctrine/mongodb-odm.git mongodb_odm $ cd mongodb_odm $ git checkout 1.0.0BETA3
    22. 22. The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader, DoctrineCommonAnnotationsAnnotationReader, DoctrineODMMongoDB, DoctrineODMMongoDBDocumentManager, DoctrineODMMongoDBMongo, DoctrineODMMongoDBMappingDriverAnnotationDriver;/** * Doctrine 2 ODM Resource Plugin * * @author Ryan Mauger * @copyright Ryan Mauger 2012 */class Lupi_Resource_Odm extends Zend_Application_Resource_ResourceAbstract{ public function init() { $options = $this->getOptions(); $this->registerAutoloaders($options); // Config $config = new DoctrineODMMongoDBConfiguration(); foreach ($options[config] as $option => $value) { $method = "set" . ucfirst($option); $config->{$method}($value); } // Annotation reader $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace(DoctrineODMMongoDBMapping); $config->setMetadataDriverImpl(new AnnotationDriver($reader, $options[documents][dir])); $dm = DocumentManager::create(new DoctrineMongoDBConnection(new Mongo), $config); return $dm; } public function registerAutoloaders($options) { $autoloader = Zend_Loader_Autoloader::getInstance(); // Document classes $classLoader = new ClassLoader($options[documents][namespace], $options[documents][dir]); $autoloader->pushAutoloader(array($classLoader, loadClass), $options[documents][namespace]); }}
    23. 23. The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader, DoctrineCommonAnnotationsAnnotationReader, DoctrineODMMongoDB, DoctrineODMMongoDBDocumentManager, DoctrineODMMongoDBMongo, DoctrineODMMongoDBMappingDriverAnnotationDriver;/** * Doctrine 2 ODM Resource Plugin * * @author Ryan Mauger * @copyright Ryan Mauger 2012 */class Lupi_Resource_Odm extends Zend_Application_Resource_ResourceAbstract{ public function init() { $options = $this->getOptions(); $this->registerAutoloaders($options); Set up class loaders. // Config $config = new DoctrineODMMongoDBConfiguration(); foreach ($options[config] as $option => $value) { $method = "set" . ucfirst($option); Use the Doctrine $config->{$method}($value); } // Annotation reader loaders for ease $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace(DoctrineODMMongoDBMapping); $config->setMetadataDriverImpl(new AnnotationDriver($reader, $options[documents][dir])); $dm = DocumentManager::create(new DoctrineMongoDBConnection(new Mongo), $config); return $dm; } public function registerAutoloaders($options) { $autoloader = Zend_Loader_Autoloader::getInstance(); // Document classes $classLoader = new ClassLoader($options[documents][namespace], $options[documents][dir]); $autoloader->pushAutoloader(array($classLoader, loadClass), $options[documents][namespace]); }}
    24. 24. The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader, DoctrineCommonAnnotationsAnnotationReader, DoctrineODMMongoDB, DoctrineODMMongoDBDocumentManager, DoctrineODMMongoDBMongo, DoctrineODMMongoDBMappingDriverAnnotationDriver;/** * Doctrine 2 ODM Resource Plugin * * @author Ryan Mauger * @copyright Ryan Mauger 2012 */class Lupi_Resource_Odm extends Zend_Application_Resource_ResourceAbstract{ public function init() { $options = $this->getOptions(); $this->registerAutoloaders($options); // Config $config = new DoctrineODMMongoDBConfiguration(); foreach ($options[config] as $option => $value) { Set up the config object $method = "set" . ucfirst($option); $config->{$method}($value); } // Annotation reader $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace(DoctrineODMMongoDBMapping); $config->setMetadataDriverImpl(new AnnotationDriver($reader, $options[documents][dir])); $dm = DocumentManager::create(new DoctrineMongoDBConnection(new Mongo), $config); return $dm; } public function registerAutoloaders($options) { $autoloader = Zend_Loader_Autoloader::getInstance(); // Document classes $classLoader = new ClassLoader($options[documents][namespace], $options[documents][dir]); $autoloader->pushAutoloader(array($classLoader, loadClass), $options[documents][namespace]); }}
    25. 25. The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader, DoctrineCommonAnnotationsAnnotationReader, DoctrineODMMongoDB, DoctrineODMMongoDBDocumentManager, DoctrineODMMongoDBMongo, DoctrineODMMongoDBMappingDriverAnnotationDriver;/** * Doctrine 2 ODM Resource Plugin * * @author Ryan Mauger * @copyright Ryan Mauger 2012 */class Lupi_Resource_Odm extends Zend_Application_Resource_ResourceAbstract{ public function init() { Set up the Annotation $options = $this->getOptions(); $this->registerAutoloaders($options); // Config Reader, or mapping driver $config = new DoctrineODMMongoDBConfiguration(); foreach ($options[config] as $option => $value) { $method = "set" . ucfirst($option); $config->{$method}($value); should you prefer YAML / } // Annotation reader XML $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace(DoctrineODMMongoDBMapping); $config->setMetadataDriverImpl(new AnnotationDriver($reader, $options[documents][dir])); $dm = DocumentManager::create(new DoctrineMongoDBConnection(new Mongo), $config); return $dm; } public function registerAutoloaders($options) { $autoloader = Zend_Loader_Autoloader::getInstance(); // Document classes $classLoader = new ClassLoader($options[documents][namespace], $options[documents][dir]); $autoloader->pushAutoloader(array($classLoader, loadClass), $options[documents][namespace]); }}
    26. 26. The Plugin Resource<?php/* Import namespaces */use DoctrineCommonClassLoader, DoctrineCommonAnnotationsAnnotationReader, DoctrineODMMongoDB, DoctrineODMMongoDBDocumentManager, DoctrineODMMongoDBMongo, DoctrineODMMongoDBMappingDriverAnnotationDriver;/** * Doctrine 2 ODM Resource Plugin * * @author Ryan Mauger * @copyright Ryan Mauger 2012 */class Lupi_Resource_Odm extends Zend_Application_Resource_ResourceAbstract{ public function init() { $options = $this->getOptions(); $this->registerAutoloaders($options); // Config Create and return the $config = new DoctrineODMMongoDBConfiguration(); foreach ($options[config] as $option => $value) { $method = "set" . ucfirst($option); $config->{$method}($value); Document manager } // Annotation reader $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace(DoctrineODMMongoDBMapping); $config->setMetadataDriverImpl(new AnnotationDriver($reader, $options[documents][dir])); $dm = DocumentManager::create(new DoctrineMongoDBConnection(new Mongo), $config); return $dm; } public function registerAutoloaders($options) { $autoloader = Zend_Loader_Autoloader::getInstance(); // Document classes $classLoader = new ClassLoader($options[documents][namespace], $options[documents][dir]); $autoloader->pushAutoloader(array($classLoader, loadClass), $options[documents][namespace]); }}
    27. 27. [production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi mongoodm resource ConfigurationpluginPaths.Lupi_Resource = APPLICATION_PATH "/../library/Lupi/Resource"; Library include paths & namespacesincludePaths.library = APPLICATION_PATH "/../library"autoloaderNamespaces[] = "Lupi"autoloaderNamespaces[] = "Doctrine"; Bootstrap optionsbootstrap.path = APPLICATION_PATH "/Bootstrap.php"bootstrap.class = "Bootstrap"; Applicaiton Setupappnamespace = "Application"resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"resources.frontController.params.displayExceptions = 0; ODM settingsresources.odm.documents.dir = APPLICATION_PATH "/entities"resources.odm.documents.namespace = "Application"resources.odm.config.proxyDir = APPLICATION_PATH "/cache/proxies"resources.odm.config.proxyNamespace = "proxies"resources.odm.config.hydratorDir = APPLICATION_PATH "/cache/hydrators"resources.odm.config.hydratorNamespace = "hydrators"[staging : production][testing : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1[development : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1resources.frontController.params.displayExceptions = 1
    28. 28. [production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi mongoodm resource ConfigurationpluginPaths.Lupi_Resource = APPLICATION_PATH "/../library/Lupi/Resource"; Library include paths & namespacesincludePaths.library = APPLICATION_PATH "/../library"autoloaderNamespaces[] = "Lupi"autoloaderNamespaces[] = "Doctrine"; Bootstrap options Tell it where to load the plugin resourcebootstrap.path = APPLICATION_PATH "/Bootstrap.php"bootstrap.class = "Bootstrap"; Applicaiton Setupappnamespace = "Application"resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"resources.frontController.params.displayExceptions = 0; ODM settingsresources.odm.documents.dir = APPLICATION_PATH "/entities"resources.odm.documents.namespace = "Application"resources.odm.config.proxyDir = APPLICATION_PATH "/cache/proxies"resources.odm.config.proxyNamespace = "proxies"resources.odm.config.hydratorDir = APPLICATION_PATH "/cache/hydrators"resources.odm.config.hydratorNamespace = "hydrators"[staging : production][testing : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1[development : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1resources.frontController.params.displayExceptions = 1
    29. 29. [production]; PHP settingsphpSettings.display_startup_errors = 0phpSettings.display_errors = 0; Set Plugin path for lupi mongoodm resource ConfigurationpluginPaths.Lupi_Resource = APPLICATION_PATH "/../library/Lupi/Resource"; Library include paths & namespacesincludePaths.library = APPLICATION_PATH "/../library"autoloaderNamespaces[] = "Lupi"autoloaderNamespaces[] = "Doctrine"; Bootstrap options Minimal config to get startedbootstrap.path = APPLICATION_PATH "/Bootstrap.php"bootstrap.class = "Bootstrap"; Applicaiton Setupappnamespace = "Application"resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"resources.frontController.params.displayExceptions = 0; ODM settingsresources.odm.documents.dir = APPLICATION_PATH "/entities"resources.odm.documents.namespace = "Application"resources.odm.config.proxyDir = APPLICATION_PATH "/cache/proxies"resources.odm.config.proxyNamespace = "proxies"resources.odm.config.hydratorDir = APPLICATION_PATH "/cache/hydrators"resources.odm.config.hydratorNamespace = "hydrators"[staging : production][testing : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1[development : production]phpSettings.display_startup_errors = 1phpSettings.display_errors = 1resources.frontController.params.displayExceptions = 1
    30. 30. Base Controller• Provide an easy method to access the DocumentManager, and perhaps a service layer / repository• Not using an action helper because we will be likely to be using this tightly everywhere, so it avoids writing _helper a few hundred times!• You could use an action helper and use IOC or similar to replace this, this is for simplicity
    31. 31. <?phpnamespace LupiController; Base Controllerabstract class Action extends Zend_Controller_Action{ /** * @var Zend_Application */ Override the constructor at this point! protected $bootstrap; /** * @var DoctrineODMMongoDBDocumentManager */ protected $dm; It’s useful to leave public function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array()) init() for the final { $this->setRequest($request) ->setResponse($response) implementation so ->_setInvokeArgs($invokeArgs); $this->_helper = new Zend_Controller_Action_HelperBroker($this); $this->dm = $this->getBootstrap()->getResource(odm); you don’t need to $this->init(); } remember to always public function getBootstrap() { if (null === $this->bootstrap) { call parent::init() $this->bootstrap = $this->getInvokeArg(bootstrap); } return $this->bootstrap; }}
    32. 32. Simplified controller code<?phpuse LupiController as controller;class IndexController extends controllerAction{ Common repository for /** * @var DoctrineODMMongoDBDocumentRepository */ the controller, set it in protected $repository; public function init() the init { $this->repository = $this->dm->getRepository(ApplicationBlogPost); } public function indexAction() { $post = $this->repository->find(4dde4067fbd2237df1000000); $comment = new ApplicationBlogComment(); $comment->setEmail(foo@test.com) ->setComment(nice post!); $post->addComment($comment); $this->dm->persist($post); $this->dm->flush(); }}
    33. 33. Simplified controller code<?phpuse LupiController as controller;class IndexController extends controllerAction{ Common repository for /** * @var DoctrineODMMongoDBDocumentRepository */ the controller, set it in protected $repository; public function init() the init { $this->repository = $this->dm->getRepository(ApplicationBlogPost); } public function indexAction() { $post = $this->repository->find(4dde4067fbd2237df1000000); $comment = new ApplicationBlogComment(); $comment->setEmail(foo@test.com) ->setComment(nice post!); $post->addComment($comment); $this->dm->persist($post); $this->dm->flush(); }} Nice verbose code!
    34. 34. Managing change
    35. 35. Managing change• For adding a new property, mostly, you don’t need to do much
    36. 36. Managing change• The db is schema-less
    37. 37. Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready
    38. 38. Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready• Simply add the property, and update old objects through your usual admin interface
    39. 39. Managing change• The db is schema-less• You can add properties, without needing to update the old objects until your ready• Simply add the property, and update old objects through your usual admin interface• Objects without the new property will simply have a null value until you change them
    40. 40. Managing changeMake use of the annotations!
    41. 41. Changing a property name From To<?php <?phpnamespace ApplicationBlog; namespace ApplicationBlog;/** /** * @Document(db="blog", collection="posts") * @Document(db="blog", collection="posts") */ */class Post class Post{ { /** /** * @Id * @Id */ */ private $id; private $id; /** /** * @Field(type="string") * @Field(type="string") */ */ private $name; private $title; /** /** * @String * @String */ */ private $content; private $content;} }
    42. 42. Changing a property name From To <?php<?php namespace ApplicationBlog;namespace ApplicationBlog; /**/** * @Document(db="blog", collection="posts") * @Document(db="blog", collection="posts") */ */ class Postclass Post {{ /** * @Id Add @AlsoLoad /** * @Id */ */ private $id; private $id; /** /** * @Field(type="string") * @Field(type="string") * @AlsoLoad({“name”}) */ */ private $name; private $title; /** /** * @String * @String */ */ private $content; private $content;} }
    43. 43. Transforming a property From To <?php namespace ApplicationBlog;<?php /**namespace ApplicationBlog; * @Document(db="blog", collection="posts") *//** class User * @Document(db="blog", collection="posts") { */ /**class User * @Id{ */ /** private $id; * @Id */ /** private $id; * @Field(type="string") */ /** private $firstname; * @Field(type="string") */ /** private $fullname; * @Field(type="string") */ /** private $lastname; * @ReferenceMany(targetDocument=”ApplicationBlogPost”) */ /** private $posts; * @ReferenceMany(targetDocument=”ApplicationBlogPost”)} */ private $posts; }
    44. 44. Transforming a property From <?php To namespace ApplicationBlog; /** * @Document(db="blog", collection="posts")<?php */namespace ApplicationBlog; class User {/** /** * @Id * @Document(db="blog", collection="posts") */ */ private $id;class User{ /** * @Field(type="string") /** */ * @Id private $firstname; */ private $id; /** * @Field(type="string") */ /** private $lastname; * @Field(type="string") */ /** * @ReferenceMany(targetDocument=”ApplicationBlogPost”) private $fulllname; */ private $posts; /** * @ReferenceMany(targetDocument=”ApplicationBlogPost”) /** * @AlsoLoad({“fullname”}) */ */ private $posts; public function populateNameProperties($fullname)} { $name = explode(‘ ‘, $fullname); $this->firstname = $name[0]; $this->lastname = $name[1]; Use a method to migrate using } } @AlsoLoad
    45. 45. NOTE!• When searching, your queries will not know about the old name!• Include old and new fields in your searches if possible until all data has been migrated
    46. 46. NOTE!• The ODM is still in BETA3, there are still some glitches, but its well worth having a good look now.• http://www.doctrine-project.org/ and follow progress
    47. 47. Useful information• Official docs: http://www.doctrine-project.org/ docs/mongodb_odm/1.0/en/• Mongodb: http://www.mongodb.org/ excellent intro to mongodb• The example sandbox: http://github.com/ bittarman/zf-d2-odm
    48. 48. Thanks for listening Catch me on twitter: @Bittarman Slides will be available on slideshare http://slideshare.com/rmaugerZF & Doctrine 2 ODM Doctrine
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×