Doctrator           Pablo DíezSymfony Live 2011 - San Francisco
Pablo DíezCreator of Mondongo  ODM for MongoDB and PHP  http://mondongo.es (in English :)Creator of Mondator  Class genera...
What is Doctrator?
Doctrator = Doctrine2 + Mondator
Agile Development
Agile Development  ActiveRecord
Agile Development  ActiveRecord      optional
Agile Development  ActiveRecord    Behaviors
Agile Development          ActiveRecord             BehaviorsDoctrator saves you a lot of time! ;)
How does Doctrine2 work?
How does Doctrine2 work?“Doctrine2 provides transparent persistence for PHP objects.”                            http://ww...
That is, persist PHP objects without restrictions of a base class,                      properties, methods.              ...
You only have to tell Doctrine2 (map) what you want to persist.
You only have to tell Doctrine2 (map) what you want to persist.                 With Docblock Annotations                 ...
You only have to tell Doctrine2 (map) what you want to persist.                            With YAML            EntitiesUs...
You only have to tell Doctrine2 (map) what you want to persist.                                          With XML    <?xml...
You only have to tell Doctrine2 (map) what you want to persist.                              With PHP                     ...
You only have to tell Doctrine2 (map) what you want to persist.      Then you are able to persist those objects.
Then you are able to persist those objects.         $user = new User();         $user->username = pablodip;         $user-...
A Doctrine2 best practice is to use non public         properties in the entities.              class User              { ...
You have to create methods to access to the properties.                     Setters & Getters                public functi...
What do you need to work with this simple table?                         user                   id           integer      ...
namespace Model;   class User   {   }                Class         user   id             integerusername           stringp...
namespace Model;protected   $id;            class Userprotected   $username;      {protected   $password;      }protected ...
namespace Model;   protected       $id;                             class User   protected       $username;               ...
namespace Model;   protected       $id;                             class User   protected       $username;               ...
namespace Model;                          /**                            * @Entity                            */          ...
namespace Model;                          /**                            * @Entity                            */          ...
LORCLines Of Repetitive Code
LORC      Lines Of Repetitive Code... and we still don’t have any features! :)
How many LORC do we need in a real database?
How many LORC do we need in a real database?                    ...
Doctrator’s principle is to avoid writing LORC
What does Doctrator do?
What does Doctrator do?Doctrator generates classes and maps them with Doctrine2
Doctrator generates classes and maps them with Doctrine2    You only have to tell it the configuration of the classes.
In PHParray(    ModelUser => array(        columns => array(            id       => array(id => auto, type => integer),   ...
In YAMLModelUser:    columns:        id:         {   id: auto, type: integer }        username:   {   type: string, length...
ModelUser:                                         columns:                                             id:         {   id...
ModelUser:    columns:        id:         {   id: auto, type: integer }        username:   {   type: string, length: 50 } ...
How does Doctrator work?
How does Doctrator work?Doctrator uses Mondator to generate the classes for you.
Mondator defines PHP classes.
namespace Model;class User{    protected $username;    public function setUsername($username)    {        $this->username ...
namespace Model;           Definitionclass User{                                      Properties    protected $username;   ...
use MondongoMondatorDefinitionDefinition;use MondongoMondatorDefinitionProperty;use MondongoMondatorDefinitionMethod;
namespace Model;class User{}                              Full Class Name$definition = new Definition(ModelUser);
protected $username;                            Visibility   Name$property = new Property(protected, username);$definition...
public function setUsername($username){    $this->username = $username;}                      Visibility   Name         Ar...
You can define any PHP class.
Parent class$definition->setParentClass(ModelBaseUser);                    Interfaces$definition->addInterface(ArrayAccess...
Default value$property->setValue($defaultValue);                      Static$property->setIsStatic(true);
Abstract$method->setIsAbstract(true);                      Static$method->setIsStatic(true);
Even with comments.
$definition->setDocComment(<<<EOF/** * User Class. */EOF);$method->setDocComment(<<<EOF    /**     * Set the username.    ...
Then you can export them with the Dumper.      use MondongoMondatorDumper;      $dumper = new Dumper($definition);      $c...
/**  * User entity.  */class User{     protected $username;    /**      * Set the username.      *      * @param string $u...
And save them in files.file_put_contents($file, $codeClass);
Mondator Extensions
Mondator ExtensionsMondator uses extensions to generate similar classes          in a powerful and flexible way.
The Mondator Extensions process the config classes     to define what classes will be generated.
ModelUser:               columns:                   id:         {   id: auto, type: integer }                   username: ...
ModelUser:            columns:                id:         {   id: auto, type: integer }                username:   {   typ...
ModelUser:            columns:                id:         {   id: auto, type: integer }                username:   {   typ...
ModelUser:            columns:                id:         {   id: auto, type: integer }                username:   {   typ...
ModelUser:            columns:                id:         {   id: auto, type: integer }                username:   {   typ...
An extension can generate any definition.
use MondongoMondatorExtension;use MondongoMondatorDefinitionDefinition;class Doctrator extends Extension{    protected fun...
foreach ($this->configClass[columns] as $name => $column) {    $property = new Property(protected, $name);    $this->defin...
foreach ($this->configClass[columns] as $name => $column) {      $setterName = set.Inflector::camelize($name);      $sette...
Different extensions can modify the same definition.
class Doctrator extends Extension{    protected function doClassProcess()    {        $definition = new Definition($this->...
An extension can have options.
class Doctrator extends Extension{    protected function setUp()    {        $this->addOptions(array(            columns  ...
You can process the extensions that you want.
$mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array(    ...
$mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array(    ...
$mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array(    ...
$mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array(    ...
An extension can change the config class to extend               another extension.
class Doctrator extends Extension{    protected function doClassProcess()    {        foreach ($this->configClass[columns]...
You can even use extensions in the config classes.
ModelArticle:    columns:        id:     { id: auto, type: integer }        title: { type: string, length: 100 }    behavi...
And you can combine all these things to do what you                      want.
Generated code is not necessarily magic code.
Doctrator’s generated code is really simple, non-                 magical code.
Code even with PHPDoc.
You can use IDE Autocompletion.
Doctrator Extensions
Doctrator Extensions                          CoreArrayAccess   PropertyOverloading   ActiveRecord   Behaviors
CoreGenerates and maps objects with Doctrine2.
Doctrator uses base classes to separate generated             code from your code.
ModelUsernamespace Model;class User extends ModelBaseUser{    // your code}namespace ModelBase;class User{    // generated...
ModelArticle:    table_name: articles    columns:        id:        { id: auto, type: integer }        title:     { type: ...
AssociationsModelArticle:    table_name: articles     one_to_one                            one_to_many    columns:       ...
ModelArticle:               Events    table_name: articles    columns:                  prePersist        id:      { id: a...
$category = new ModelCategory();$category->setName(Class Generator);$entityManager->persist($category);$article = new Mode...
CoreUseful methods.
Set & Get by string$article->set(title, Doctrator);echo $article->get(title); // Doctrator
fromArray & toArray$article->fromArray(array(    title => Doctrator,    date => new DateTime(now)));$array = $article->toA...
ArrayAccessImplements the ArrayAccess interface in the entities.
$article = new ModelArticle();$article[title] = Doctrator;echo $article[title]; // Doctrator
PropertyOverloadingAllows you access to entity data like properties.
$article = new ModelArticle();$article->title = Doctrator;echo $article->title; // Doctrator
ActiveRecordImplements the ActiveRecord pattern in your entities.
$article = new ModelArticle();$article->setTitle(Doctrator);$article->save();$article->refresh();$article->delete();
print_r($article);
print_r($article); ModelArticle Object (     [id:protected] => 1     [title:protected] => Doctrator     [content:protected...
Doctrator uses a global object to save the EntityManager  use DoctratorEntityManagerContainer;  EntityManagerContainer::se...
$em = ModelArticle::entityManager();$articleRepository = ModelArticle::repository();$queryBuilder = ModelArticle::queryBui...
$articles = $entityManager->getRepository(ModelArticle)->findAll();$article = $entityManager->getRepository(ModelArticle)-...
Behaviors
BehaviorsReuse features.
A behavior is simply a Mondator extension.
A behavior canHave optionsChange config classes: •   Columns •   Associations •   Indexes •   Events •   ...Add new generat...
TimestampableSaves the created and updated date.                created TRUE        created_column created_at             ...
ModelArticle:    columns:        id:    { id: auto, type: integer }        title: { type: name, length: 100 }    behaviors...
$article = new ModelArticle();$article->setTitle(Doctrator);$article->save();echo $article->getCreatedAt(); // nowecho $ar...
IpableSaves the created and updated ip.              created TRUE      created_column created_from             updated TRU...
Hashable               IpableSaves a unique hash in each entity.            column hash
ModelArticle:    columns:        id:    { id: auto, type: integer }        title: { type: name, length: 100 }    behaviors...
$article = new Article();$article->setTitle(Doctrator);$entityManager->persist();$entityManager->flush();echo $article->ge...
Timestampable           SluggableSaves a slug from a field.    from_column *    slug_column slug         unique TRUE       ...
ModelArticle:    columns:        id:     { id: auto, type: integer }        title: { type: name, length: 100 }    behavior...
$article = new ModelArticle();$article->setTitle(Doctrator Rocks!);$article->save();echo $article->getSlug(); // doctrator...
SortableAllows you to sort your entities.             column position        new_position bottom
$articles = array();for ($i = 0; $i <= 10; $i++) {    $articles[$i] = $a = new ModelArticle();    $a->setTitle(Article .$i...
// some methods$articles[1]->isFirst();$articles[1]->isLast();$articles[1]->getNext();$articles[1]->getPrevious();$article...
Taggable                 SortableAllows you to save tags in the entities.
$article = new ModelArticle();$article->setTitle(My Title);$article->save();// methods$article->addTags(foobar, barfoo);$a...
Translatable                 Taggable                 SortableAllows you to translate entity columns.              columns *
ModelArticle:    columns:        id:       { id: auto, type: integer }        title:    { type: string, length: 100 }     ...
$article = new ModelArticle();$article->setDate(new DateTime());// en$article->translation(en)->setTitle(My Title);$articl...
Doctrator in Symfony2
DoctratorBundle
doctrator.config:    extensions:        array_access:           false        property_overloading:   false        active_r...
doctrator.config:    extensions:        array_access:           false        property_overloading:   false        active_r...
Config Classes    app/config/doctrator/*.yml*Bundle/Resources/doctrator/*.yml
Standard NamespaceModelArticle:    columns:        id:      { id: auto, type: integer }        title:   { type: string, le...
ModelArticle:    validation:        - MyArticleClassValidator: ~    columns:        id:      { id: auto, type: integer }  ...
php app/console doctrator:generate
Questions?                 http://mondongo.es (English :)You can contact me for Mondongo, Doctrator, consulting, developme...
Upcoming SlideShare
Loading in...5
×

Doctrator Symfony Live 2011 San Francisco

5,198

Published on

Published in: Technology, Business
0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
5,198
On Slideshare
0
From Embeds
0
Number of Embeds
4
Actions
Shares
0
Downloads
0
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide

Transcript of "Doctrator Symfony Live 2011 San Francisco"

  1. 1. Doctrator Pablo DíezSymfony Live 2011 - San Francisco
  2. 2. Pablo DíezCreator of Mondongo ODM for MongoDB and PHP http://mondongo.es (in English :)Creator of Mondator Class generator for PHPCreator of Doctratorhttp://twitter.com/pablodiphttp://github.com/pablodip
  3. 3. What is Doctrator?
  4. 4. Doctrator = Doctrine2 + Mondator
  5. 5. Agile Development
  6. 6. Agile Development ActiveRecord
  7. 7. Agile Development ActiveRecord optional
  8. 8. Agile Development ActiveRecord Behaviors
  9. 9. Agile Development ActiveRecord BehaviorsDoctrator saves you a lot of time! ;)
  10. 10. How does Doctrine2 work?
  11. 11. How does Doctrine2 work?“Doctrine2 provides transparent persistence for PHP objects.” http://www.doctrine-project.org/docs/orm/2.0/en/reference/introduction.html
  12. 12. That is, persist PHP objects without restrictions of a base class, properties, methods. namespace Model; class User { public $id; public $username; public $email; }
  13. 13. You only have to tell Doctrine2 (map) what you want to persist.
  14. 14. You only have to tell Doctrine2 (map) what you want to persist. With Docblock Annotations /** * @Entity */ class User { /** * @Id * @Column(type="integer") */ public $id; /** * @Column(length=50) */ public $username; /** * @Column(length=100) */ public $email; }
  15. 15. You only have to tell Doctrine2 (map) what you want to persist. With YAML EntitiesUser: type: entity fields: id: { type: integer, id: true } username: { type: string(50) } email: { type: string(50) }
  16. 16. You only have to tell Doctrine2 (map) what you want to persist. With XML <?xml version="1.0" encoding="UTF-8"?> <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://www.doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entity name="ModelUser" table="user"> <id name="id" type="integer" column="id"> <generator strategy="AUTO"/> </id> <field name="username" type="string" length="50" /> <field name="email" type="string" length="100" /> </entity> </doctrine-mapping>
  17. 17. You only have to tell Doctrine2 (map) what you want to persist. With PHP $metadata->mapField(array( id => true, fieldName => id, type => integer )); $metadata->mapField(array( fieldName => username, type => string )); $metadata->mapField(array( fieldName => email, type => string ));
  18. 18. You only have to tell Doctrine2 (map) what you want to persist. Then you are able to persist those objects.
  19. 19. Then you are able to persist those objects. $user = new User(); $user->username = pablodip; $user->password = pa$$word; $user->email = pablodip@gmail.com; $entityManager->persist($user); $entityManager->flush();
  20. 20. A Doctrine2 best practice is to use non public properties in the entities. class User { protected $id; protected $username; protected $password; protected $email; }
  21. 21. You have to create methods to access to the properties. Setters & Getters public function setId($id) { $this->id = $id; } public function getId() { return $this->id; } public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; } public function setPassword($password) { $this->password = $password;
  22. 22. What do you need to work with this simple table? user id integer username string password string email string
  23. 23. namespace Model; class User { } Class user id integerusername stringpassword string email string
  24. 24. namespace Model;protected $id; class Userprotected $username; {protected $password; }protected $email; Class Properties user id integer username string password string email string
  25. 25. namespace Model; protected $id; class User protected $username; { protected $password; } protected $email; Class Properties user id integer username stringpublic function setId($id){} $this->id = $id; password stringpublic function getId(){ return $this->id; email string}public function setUsername($username){ $this->username = $username; Setters/Getters}public function getUsername(){ return $this->username;}public function setPassword($password){ $this->password = $password;
  26. 26. namespace Model; protected $id; class User protected $username; { protected $password; } protected $email; Class Mapping Properties user id integer /** * @Entity username string */public function setId($id){ /**} $this->id = $id; password string * @Id * @Column(type="integer") */public function getId(){ return $this->id; email string /** * @Column(length=50)} */public function setUsername($username){ $this->username = $username; Setters/Getters /** * @Column(length=100)} */public function getUsername(){ return $this->username;}public function setPassword($password){ $this->password = $password;
  27. 27. namespace Model; /** * @Entity */ class User { /** * @Id * @Column(type="integer") */ protected $id; /** * @Column(length="50") */ protected $username; /** * @Column(length="40") */ protected $password; /** user * @Column(length="100") */ protected $email; id integer public function setId($id) { $this->id = $id; }username string public function getId() { return $this->id;password string } public function setUsername($username) { email string } $this->username = $username; public function getUsername() { return $this->username; } public function setPassword($password) { $this->password = $password; } public function getPassword() { return $this->password; } public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } }
  28. 28. namespace Model; /** * @Entity */ class User { /** * @Id * @Column(type="integer") */ protected $id; /** * @Column(length="50") */ protected $username; /** * @Column(length="40") */ protected $password; /** user * @Column(length="100") */ protected $email; id integer public function setId($id) { $this->id = $id; LORC }username string public function getId() { return $this->id;password string } public function setUsername($username) { email string } $this->username = $username; public function getUsername() { return $this->username; } public function setPassword($password) { $this->password = $password; } public function getPassword() { return $this->password; } public function setEmail($email) { $this->email = $email; } public function getEmail() { return $this->email; } }
  29. 29. LORCLines Of Repetitive Code
  30. 30. LORC Lines Of Repetitive Code... and we still don’t have any features! :)
  31. 31. How many LORC do we need in a real database?
  32. 32. How many LORC do we need in a real database? ...
  33. 33. Doctrator’s principle is to avoid writing LORC
  34. 34. What does Doctrator do?
  35. 35. What does Doctrator do?Doctrator generates classes and maps them with Doctrine2
  36. 36. Doctrator generates classes and maps them with Doctrine2 You only have to tell it the configuration of the classes.
  37. 37. In PHParray( ModelUser => array( columns => array( id => array(id => auto, type => integer), username => array(type => string, length => 50), password => array(type => string, length => 40), email => array(type => string, length => 100), ), ),);
  38. 38. In YAMLModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
  39. 39. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }This generates your object. This maps your object. class User { protected $id; protected $username; /** protected $password; * @Entity protected $email; */ public function setId($id) { $this->id = $id; } /** public function getId() * @Id { return $this->id; * @Column(type="integer") } */ public function setUsername($username) { $this->username = $username; } /** public function getUsername() * @Column(length=50) { return $this->username; */ } public function setPassword($password) { /** } $this->password = $password; * @Column(length=100) public function getPassword() */ { return $this->password; } public function setEmail($email)
  40. 40. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 } You can start to work.$user = new ModelUser();$user->setUsername(pagafantas);$user->setEmail(pagafantas@gmail.com);$entityManager->persist($user);$entityManager->flush();
  41. 41. How does Doctrator work?
  42. 42. How does Doctrator work?Doctrator uses Mondator to generate the classes for you.
  43. 43. Mondator defines PHP classes.
  44. 44. namespace Model;class User{ protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; }}
  45. 45. namespace Model; Definitionclass User{ Properties protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; }} Methods
  46. 46. use MondongoMondatorDefinitionDefinition;use MondongoMondatorDefinitionProperty;use MondongoMondatorDefinitionMethod;
  47. 47. namespace Model;class User{} Full Class Name$definition = new Definition(ModelUser);
  48. 48. protected $username; Visibility Name$property = new Property(protected, username);$definition->addProperty($property);
  49. 49. public function setUsername($username){ $this->username = $username;} Visibility Name Arguments Code$method = new Method(public, setUsername, $username, <<<EOF $this->username = $username;EOF);$definition->addMethod($method);
  50. 50. You can define any PHP class.
  51. 51. Parent class$definition->setParentClass(ModelBaseUser); Interfaces$definition->addInterface(ArrayAccess); Abstract$definition->setIsAbstract(true);
  52. 52. Default value$property->setValue($defaultValue); Static$property->setIsStatic(true);
  53. 53. Abstract$method->setIsAbstract(true); Static$method->setIsStatic(true);
  54. 54. Even with comments.
  55. 55. $definition->setDocComment(<<<EOF/** * User Class. */EOF);$method->setDocComment(<<<EOF /** * Set the username. * * @param string $username The username. */EOF);
  56. 56. Then you can export them with the Dumper. use MondongoMondatorDumper; $dumper = new Dumper($definition); $classCode = $dumper->dump(); echo $classCode;
  57. 57. /** * User entity. */class User{ protected $username; /** * Set the username. * * @param string $username The username. */ public function setUsername($username) { $this->username = $username; } /** * Returns the username. * * @return string The username. */ public function getUsername() { return $this->username; }}
  58. 58. And save them in files.file_put_contents($file, $codeClass);
  59. 59. Mondator Extensions
  60. 60. Mondator ExtensionsMondator uses extensions to generate similar classes in a powerful and flexible way.
  61. 61. The Mondator Extensions process the config classes to define what classes will be generated.
  62. 62. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }The Mondator Extensions process the config classes to define what classes will be generated. MondongoMondatorDefinitionDefinition
  63. 63. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }use MondongoMondatorExtension;class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
  64. 64. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }use MondongoMondatorExtension;class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
  65. 65. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }use MondongoMondatorExtension;class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
  66. 66. ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }use MondongoMondatorExtension;class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }} Definitions to generate
  67. 67. An extension can generate any definition.
  68. 68. use MondongoMondatorExtension;use MondongoMondatorDefinitionDefinition;class Doctrator extends Extension{ protected function doClassProcess() { $definition = new Definition($this->class); $this->definitions[entity] = $definition; $definition = new Definition($this->class.Repository); $this->definitions[repository] = $definition; }}
  69. 69. foreach ($this->configClass[columns] as $name => $column) { $property = new Property(protected, $name); $this->definitions[entity]->addProperty($property);}
  70. 70. foreach ($this->configClass[columns] as $name => $column) { $setterName = set.Inflector::camelize($name); $setter = new Method(public, $setterName, $value, <<<EOF $this->$name = $value;EOF ); $this->definitions[entity]->addMethod($setter);}
  71. 71. Different extensions can modify the same definition.
  72. 72. class Doctrator extends Extension{ protected function doClassProcess() { $definition = new Definition($this->class); $this->definitions[entity] = $defintion; $this->processColumns(); }}class ArrayAccess extends Extension{ protected function doClassProcess() { $this->definitions[entity]->addInterface(ArrayAccess); $method = new Method(public, offsetGet, $name, $code); $this->definitions[entity]->addMethod($method); // ... }}
  73. 73. An extension can have options.
  74. 74. class Doctrator extends Extension{ protected function setUp() { $this->addOptions(array( columns => true, array_access => true, )); } protected function doClassProcess() { if ($this->getOption(columns)) { $this->processColumns(); } if ($this->getOption(array_access)) { $this->processArrayAccess(); } }}
  75. 75. You can process the extensions that you want.
  76. 76. $mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new DoctratorExtensionCore($options),));$mondator->process();
  77. 77. $mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new DoctratorExtensionCore($options), new DoctratorExtensionArrayAccess(),));$mondator->process();
  78. 78. $mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new DoctratorExtensionCore($options), new DoctratorExtensionArrayAccess(),));$mondator->process();$article[title] = Doctrator;echo $article[title]; // Doctrator
  79. 79. $mondator = new MondongoMondatorMondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new DoctratorExtensionCore($options), //new DoctratorExtensionArrayAccess(),));$mondator->process();$article[title] = Doctrator;echo $article[title]; // Doctrator
  80. 80. An extension can change the config class to extend another extension.
  81. 81. class Doctrator extends Extension{ protected function doClassProcess() { foreach ($this->configClass[columns] as $name => $column) { // ... } }}class DateColumn extends Extension{ protected function doConfigClassProcess() { $this->configClass[columns][date] = array( type => date, ) }}
  82. 82. You can even use extensions in the config classes.
  83. 83. ModelArticle: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } behaviors: - class: DoctratorBehaviorTimestampable options: { }
  84. 84. And you can combine all these things to do what you want.
  85. 85. Generated code is not necessarily magic code.
  86. 86. Doctrator’s generated code is really simple, non- magical code.
  87. 87. Code even with PHPDoc.
  88. 88. You can use IDE Autocompletion.
  89. 89. Doctrator Extensions
  90. 90. Doctrator Extensions CoreArrayAccess PropertyOverloading ActiveRecord Behaviors
  91. 91. CoreGenerates and maps objects with Doctrine2.
  92. 92. Doctrator uses base classes to separate generated code from your code.
  93. 93. ModelUsernamespace Model;class User extends ModelBaseUser{ // your code}namespace ModelBase;class User{ // generated code}
  94. 94. ModelArticle: table_name: articles columns: id: { id: auto, type: integer } title: { type: string, length: 100 } slug: { type: string, length: 100 } content: { type: string } is_active: { type: boolean, default: true } date: { type: date } many_to_one: category: { class: ModelCategory, inversed: articles } indexes: slug: { columns: [slug], unique: true } date: { columns: [is_active, date] } events: preUpdate: [updateDate]
  95. 95. AssociationsModelArticle: table_name: articles one_to_one one_to_many columns: many_to_one id: { id: auto,many_to_many type: integer } title: { type: string, length: 100 } slug: { type: string, length: 100 } name content: { type: string class } mapped is_active: { type: boolean, default: true } date: { type: date }inversed many_to_one: category: { class: ModelCategory, inversed: articles } indexes: slug: { columns: [slug], unique: true } date: { columns: [is_active, date] } events: preUpdate: [updateDate]
  96. 96. ModelArticle: Events table_name: articles columns: prePersist id: { id: auto, type: integer } postPersist title: { type: string, length: 100 } preUpdate slug: postUpdate { type: string, length: 100 } preRemove content: { type: string } postRemove is_active: { type: boolean, default: true } postLoad date: { type: date } many_to_one: category: { class: ModelCategory, inversed: articles } indexes: slug: { columns: [slug], unique: true } date: { columns: [is_active, date] } events: preUpdate: [updateDate]
  97. 97. $category = new ModelCategory();$category->setName(Class Generator);$entityManager->persist($category);$article = new ModelArticle();$article->setTitle(Doctrator);$article->setDate(new DateTime(now));$article->setCategory($category);$entityManager->persist($article);$entityManager->flush();
  98. 98. CoreUseful methods.
  99. 99. Set & Get by string$article->set(title, Doctrator);echo $article->get(title); // Doctrator
  100. 100. fromArray & toArray$article->fromArray(array( title => Doctrator, date => new DateTime(now)));$array = $article->toArray();
  101. 101. ArrayAccessImplements the ArrayAccess interface in the entities.
  102. 102. $article = new ModelArticle();$article[title] = Doctrator;echo $article[title]; // Doctrator
  103. 103. PropertyOverloadingAllows you access to entity data like properties.
  104. 104. $article = new ModelArticle();$article->title = Doctrator;echo $article->title; // Doctrator
  105. 105. ActiveRecordImplements the ActiveRecord pattern in your entities.
  106. 106. $article = new ModelArticle();$article->setTitle(Doctrator);$article->save();$article->refresh();$article->delete();
  107. 107. print_r($article);
  108. 108. print_r($article); ModelArticle Object ( [id:protected] => 1 [title:protected] => Doctrator [content:protected] => Rocks! )Doctrator entities are clean even with ActiveRecord!
  109. 109. Doctrator uses a global object to save the EntityManager use DoctratorEntityManagerContainer; EntityManagerContainer::set($entityManager);
  110. 110. $em = ModelArticle::entityManager();$articleRepository = ModelArticle::repository();$queryBuilder = ModelArticle::queryBuilder();
  111. 111. $articles = $entityManager->getRepository(ModelArticle)->findAll();$article = $entityManager->getRepository(ModelArticle)->find($id);$articles = ModelArticle::repository()->findAll();$article = ModelArticle::repository()->find($id);
  112. 112. Behaviors
  113. 113. BehaviorsReuse features.
  114. 114. A behavior is simply a Mondator extension.
  115. 115. A behavior canHave optionsChange config classes: • Columns • Associations • Indexes • Events • ...Add new generated classesAdd properties and methods • Entities • Repositories • ...
  116. 116. TimestampableSaves the created and updated date. created TRUE created_column created_at updated TRUE updated_column updated_at
  117. 117. ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorTimestampable
  118. 118. $article = new ModelArticle();$article->setTitle(Doctrator);$article->save();echo $article->getCreatedAt(); // nowecho $article->getUpdatedAt(); // null$article->setContent(Rocks!);$article->save();echo $article->getCreatedAt(); // beforeecho $article->getUpdatedAt(); // now
  119. 119. IpableSaves the created and updated ip. created TRUE created_column created_from updated TRUE updated_column updated_from
  120. 120. Hashable IpableSaves a unique hash in each entity. column hash
  121. 121. ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorHashable
  122. 122. $article = new Article();$article->setTitle(Doctrator);$entityManager->persist();$entityManager->flush();echo $article->getHash();// da39a3ee5e6b4b0d3255bfef95601890afd80709
  123. 123. Timestampable SluggableSaves a slug from a field. from_column * slug_column slug unique TRUE update FALSE
  124. 124. ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - class: DoctratorBehaviorSluggable options: { from_column: title }
  125. 125. $article = new ModelArticle();$article->setTitle(Doctrator Rocks!);$article->save();echo $article->getSlug(); // doctrator-rocks
  126. 126. SortableAllows you to sort your entities. column position new_position bottom
  127. 127. $articles = array();for ($i = 0; $i <= 10; $i++) { $articles[$i] = $a = new ModelArticle(); $a->setTitle(Article .$i); $a->save();}echo $articles[3]->getPosition(); // 3echo $articles[6]->getPosition(); // 6
  128. 128. // some methods$articles[1]->isFirst();$articles[1]->isLast();$articles[1]->getNext();$articles[1]->getPrevious();$articles[1]->swapWith($articles[2]);$articles[1]->moveUp();$articles[1]->moveDown(); $repository->getMinPosition();$repository->getMaxPosition();
  129. 129. Taggable SortableAllows you to save tags in the entities.
  130. 130. $article = new ModelArticle();$article->setTitle(My Title);$article->save();// methods$article->addTags(foobar, barfoo);$article->removeTags(foobar);$article->removeAllTags(); // saved and not saved$article->getSavedTags();$article->getTags(); // saved and not saved$article->setTags(array(foo, bar));$article->saveTags();$repository->getTags();$repository->getTagsWithCount();
  131. 131. Translatable Taggable SortableAllows you to translate entity columns. columns *
  132. 132. ModelArticle: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string } date: { type: date } behaviors: - class: DoctratorBehaviorTranslatable options: { columns: [title, content] }
  133. 133. $article = new ModelArticle();$article->setDate(new DateTime());// en$article->translation(en)->setTitle(My Title);$article->translation(en)->setContent(My Content);// es$article->translation(es)->setTitle(Mi Título);$article->translation(es)->setContent(Mi Contenido);$article->save();
  134. 134. Doctrator in Symfony2
  135. 135. DoctratorBundle
  136. 136. doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true validation: true
  137. 137. doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true validation: true my_extension_id: true
  138. 138. Config Classes app/config/doctrator/*.yml*Bundle/Resources/doctrator/*.yml
  139. 139. Standard NamespaceModelArticle: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string }ModelDoctratorUserBundleUser: columns: id: { id: auto, type: integer } username: { type: string, length: 20 }
  140. 140. ModelArticle: validation: - MyArticleClassValidator: ~ columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string, validation: [MaxLength: 2000] } Validation integrated
  141. 141. php app/console doctrator:generate
  142. 142. Questions? http://mondongo.es (English :)You can contact me for Mondongo, Doctrator, consulting, development pablodip@gmail.com

×