Doctrator Symfony Live 2011 Paris
Upcoming SlideShare
Loading in...5
×
 

Doctrator Symfony Live 2011 Paris

on

  • 5,705 views

 

Statistics

Views

Total Views
5,705
Views on SlideShare
2,381
Embed Views
3,324

Actions

Likes
10
Downloads
94
Comments
0

13 Embeds 3,324

http://www.lafermeduweb.net 2488
http://www.developpez.net 405
http://www.symfony.es 193
http://blogdwich.fr 134
http://pocky.github.com 62
http://www.emmanuelpereira.com 16
http://www.sfexception.com 9
http://pocky.github.io 7
http://webcache.googleusercontent.com 5
http://symfony2developer.com 2
http://static.slidesharecdn.com 1
http://translate.googleusercontent.com 1
http://symfony.es 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Doctrator Symfony Live 2011 Paris Doctrator Symfony Live 2011 Paris Presentation Transcript

  • Doctrator Pablo Díez Symfony Live 2011 - Parisviernes 4 de marzo de 2011
  • Pablo Díez Creator of Mondongo ODM for MongoDB and PHP http://mondongo.es (in English :) Creator of Mondator Class generator for PHP Creator of Doctrator http://twitter.com/pablodip http://github.com/pablodipviernes 4 de marzo de 2011
  • What is Doctrator?viernes 4 de marzo de 2011
  • Doctrator = Doctrine2 + Mondatorviernes 4 de marzo de 2011
  • Agile Developmentviernes 4 de marzo de 2011
  • Agile Development ActiveRecordviernes 4 de marzo de 2011
  • Agile Development ActiveRecord optionalviernes 4 de marzo de 2011
  • Agile Development ActiveRecord Behaviorsviernes 4 de marzo de 2011
  • Agile Development ActiveRecord Behaviors Doctrator saves you a lot of time! ;)viernes 4 de marzo de 2011
  • How does Doctrine2 work?viernes 4 de marzo de 2011
  • How does Doctrine2 work? “Doctrine2 provides transparent persistence for PHP objects.” http://www.doctrine-project.org/docs/orm/2.0/en/reference/introduction.htmlviernes 4 de marzo de 2011
  • That is, persist PHP objects without restrictions of a base class, properties, methods. namespace Model; class User { public $id; public $username; public $email; }viernes 4 de marzo de 2011
  • You only have to tell Doctrine2 (map) what you want to persist.viernes 4 de marzo de 2011
  • 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; }viernes 4 de marzo de 2011
  • 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) }viernes 4 de marzo de 2011
  • 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>viernes 4 de marzo de 2011
  • 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 ));viernes 4 de marzo de 2011
  • You only have to tell Doctrine2 (map) what you want to persist. Then you are able to persist those objects.viernes 4 de marzo de 2011
  • 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();viernes 4 de marzo de 2011
  • A Doctrine2 good practice is to use non public properties in the entities. class User { protected $id; protected $username; protected $password; protected $email; }viernes 4 de marzo de 2011
  • 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;viernes 4 de marzo de 2011
  • What do you need to work with this simple table? user id integer username string password string email stringviernes 4 de marzo de 2011
  • namespace Model; class User { } Class user id integer username string password string email stringviernes 4 de marzo de 2011
  • namespace Model; protected $id; class User protected $username; { protected $password; } protected $email; Class Properties user id integer username string password string email stringviernes 4 de marzo de 2011
  • namespace Model; protected $id; class User protected $username; { protected $password; } protected $email; Class Properties user id integer username string public function setId($id) { } $this->id = $id; password string public 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;viernes 4 de marzo de 2011
  • 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;viernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • LORC Lines Of Repetitive Codeviernes 4 de marzo de 2011
  • LORC Lines Of Repetitive Code ... and we still don’t have any features! :)viernes 4 de marzo de 2011
  • How many LORC do we need in a real database?viernes 4 de marzo de 2011
  • How many LORC do we need in a real database? ...viernes 4 de marzo de 2011
  • What does Doctrator do?viernes 4 de marzo de 2011
  • What does Doctrator do? Doctrator generates classes and maps them with Doctrine2viernes 4 de marzo de 2011
  • Doctrator generates classes and maps them with Doctrine2 You only have to tell it the configuration of the classes.viernes 4 de marzo de 2011
  • In PHP array( 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), ), ), );viernes 4 de marzo de 2011
  • In YAML ModelUser: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }viernes 4 de marzo de 2011
  • 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)viernes 4 de marzo de 2011
  • 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();viernes 4 de marzo de 2011
  • How does Doctrator work?viernes 4 de marzo de 2011
  • How does Doctrator work? Doctrator uses Mondator to generate the classes for you.viernes 4 de marzo de 2011
  • Mondator defines PHP classes.viernes 4 de marzo de 2011
  • namespace Model; class User { protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; } }viernes 4 de marzo de 2011
  • namespace Model; Definition class User { Properties protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; } } Methodsviernes 4 de marzo de 2011
  • use MondongoMondatorDefinitionDefinition; use MondongoMondatorDefinitionProperty; use MondongoMondatorDefinitionMethod;viernes 4 de marzo de 2011
  • namespace Model; class User { } Full Class Name $definition = new Definition(ModelUser);viernes 4 de marzo de 2011
  • protected $username; Visibility Name $property = new Property(protected, username); $definition->addProperty($property);viernes 4 de marzo de 2011
  • 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);viernes 4 de marzo de 2011
  • You can define any PHP class.viernes 4 de marzo de 2011
  • Parent class $definition->setParentClass(ModelBaseUser); Interfaces $definition->addInterface(ArrayAccess); Abstract $definition->setIsAbstract(true);viernes 4 de marzo de 2011
  • Default value $property->setValue($defaultValue); Static $property->setIsStatic(true);viernes 4 de marzo de 2011
  • Abstract $method->setIsAbstract(true); Static $method->setIsStatic(true);viernes 4 de marzo de 2011
  • Even with comments.viernes 4 de marzo de 2011
  • $definition->setDocComment(<<<EOF /** * User Class. */ EOF ); $method->setDocComment(<<<EOF /** * Set the username. * * @param string $username The username. */ EOF );viernes 4 de marzo de 2011
  • Then you can export them with the Dumper. use MondongoMondatorDumper; $dumper = new Dumper($definition); $classCode = $dumper->dump(); echo $classCode;viernes 4 de marzo de 2011
  • /** * 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; } }viernes 4 de marzo de 2011
  • And save them in files. file_put_contents($file, $codeClass);viernes 4 de marzo de 2011
  • Mondator Extensionsviernes 4 de marzo de 2011
  • Mondator Extensions Mondator uses extensions to generate similar classes in a powerful and flexible way.viernes 4 de marzo de 2011
  • The Mondator Extensions process the config classes to define what classes will be generated.viernes 4 de marzo de 2011
  • 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. MondongoMondatorDefinitionDefinitionviernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • 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 generateviernes 4 de marzo de 2011
  • An extension can generate any definition.viernes 4 de marzo de 2011
  • 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; } }viernes 4 de marzo de 2011
  • foreach ($this->configClass[columns] as $name => $column) { $property = new Property(protected, $name); $this->definitions[entity]->addProperty($property); }viernes 4 de marzo de 2011
  • 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); }viernes 4 de marzo de 2011
  • Different extensions can modify the same definition.viernes 4 de marzo de 2011
  • 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); // ... } }viernes 4 de marzo de 2011
  • An extension can have options.viernes 4 de marzo de 2011
  • 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(); } } }viernes 4 de marzo de 2011
  • You can process the extensions that you want.viernes 4 de marzo de 2011
  • $mondator = new MondongoMondatorMondator(); $mondator->setConfigClasses($configClasses); $mondator->setExtensions(array( new DoctratorExtensionCore($options), new DoctratorExtensionArrayAccess(), )); $mondator->process(); $article[title] = Doctrator; echo $article[title]; // Doctratorviernes 4 de marzo de 2011
  • $mondator = new MondongoMondatorMondator(); $mondator->setConfigClasses($configClasses); $mondator->setExtensions(array( new DoctratorExtensionCore($options), //new DoctratorExtensionArrayAccess(), )); $mondator->process(); $article[title] = Doctrator; echo $article[title]; // Doctratorviernes 4 de marzo de 2011
  • An extension can change the config class to extend another extension.viernes 4 de marzo de 2011
  • 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, ) } }viernes 4 de marzo de 2011
  • You can even use extensions in the config classes.viernes 4 de marzo de 2011
  • ModelArticle: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } behaviors: - class: DoctratorBehaviorTimestampable options: { }viernes 4 de marzo de 2011
  • And you can combine all these things to do what you want.viernes 4 de marzo de 2011
  • Generated code is not necessarily magic code.viernes 4 de marzo de 2011
  • Doctrator Extensionsviernes 4 de marzo de 2011
  • Doctrator Extensions Core ArrayAccess PropertyOverloading ActiveRecord Behaviorsviernes 4 de marzo de 2011
  • Core Generates and maps objects with Doctrine2.viernes 4 de marzo de 2011
  • Doctrator uses base classes to separate generated code from your code.viernes 4 de marzo de 2011
  • ModelUser namespace Model; class User extends ModelBaseUser { // your code } namespace ModelBase; class User { // generated code }viernes 4 de marzo de 2011
  • 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]viernes 4 de marzo de 2011
  • Associations ModelArticle: 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]viernes 4 de marzo de 2011
  • 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]viernes 4 de marzo de 2011
  • $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();viernes 4 de marzo de 2011
  • Core Useful methods.viernes 4 de marzo de 2011
  • Set & Get by string $article->set(title, Doctrator); echo $article->get(title); // Doctratorviernes 4 de marzo de 2011
  • fromArray & toArray $article->fromArray(array( title => Doctrator, date => new DateTime(now) )); $array = $article->toArray();viernes 4 de marzo de 2011
  • ArrayAccess Implements the ArrayAccess interface in the entities.viernes 4 de marzo de 2011
  • $article = new ModelArticle(); $article[title] = Doctrator; echo $article[title]; // Doctratorviernes 4 de marzo de 2011
  • PropertyOverloading Allows you access to entity data like properties.viernes 4 de marzo de 2011
  • $article = new ModelArticle(); $article->title = Doctrator; echo $article->title; // Doctratorviernes 4 de marzo de 2011
  • ActiveRecord Implements the ActiveRecord pattern in your entities.viernes 4 de marzo de 2011
  • $article = new ModelArticle(); $article->setTitle(Doctrator); $article->save(); $article->refresh(); $article->delete();viernes 4 de marzo de 2011
  • print_r($article);viernes 4 de marzo de 2011
  • print_r($article); ModelArticle Object ( [id:protected] => 1 [title:protected] => Doctrator [content:protected] => Rocks! ) Doctrator entities are clean even with ActiveRecord!viernes 4 de marzo de 2011
  • $em = ModelArticle::entityManager(); $articleRepository = ModelArticle::repository(); $queryBuilder = ModelArticle::queryBuilder();viernes 4 de marzo de 2011
  • $articles = $entityManager->getRepository(Model Article)->findAll(); $article = $entityManager->getRepository(Model Article)->find($id); $articles = ModelArticle::repository()->findAll(); $article = ModelArticle::repository()->find($id);viernes 4 de marzo de 2011
  • Behaviorsviernes 4 de marzo de 2011
  • Behaviors Reuse features.viernes 4 de marzo de 2011
  • A behavior is simply a Mondator extension.viernes 4 de marzo de 2011
  • A behavior can Have options Change config classes: • Columns • Associations • Indexes • Events • ... Add new generated classes Add properties and methods • Entities • Repositories • ...viernes 4 de marzo de 2011
  • Timestampable Saves the created and updated date. created TRUE created_column created_at updated TRUE updated_column updated_atviernes 4 de marzo de 2011
  • ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorTimestampableviernes 4 de marzo de 2011
  • $article = new ModelArticle(); $article->setTitle(Doctrator); $article->save(); echo $article->getCreatedAt(); // now echo $article->getUpdatedAt(); // null $article->setContent(Rocks!); $article->save(); echo $article->getCreatedAt(); // before echo $article->getUpdatedAt(); // nowviernes 4 de marzo de 2011
  • Ipable Saves the created and updated ip. created TRUE created_column created_from updated TRUE updated_column updated_fromviernes 4 de marzo de 2011
  • Hashable Ipable Saves a unique hash in each entity. column hashviernes 4 de marzo de 2011
  • ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorHashableviernes 4 de marzo de 2011
  • $article = new Article(); $article->setTitle(Doctrator); $entityManager->persist(); $entityManager->flush(); echo $article->getHash(); // da39a3ee5e6b4b0d3255bfef95601890afd80709viernes 4 de marzo de 2011
  • Timestampable Sluggable Saves a slug from a field. from_column * slug_column slug unique TRUE update FALSEviernes 4 de marzo de 2011
  • ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - class: DoctratorBehaviorSluggable options: { from_column: title }viernes 4 de marzo de 2011
  • $article = new ModelArticle(); $article->setTitle(Doctrator Rocks!); $article->save(); echo $article->getSlug(); // doctrator-rocksviernes 4 de marzo de 2011
  • Sortable Allows you to sort your entities. column position new_position bottomviernes 4 de marzo de 2011
  • $articles = array(); for ($i = 0; $i <= 10; $i++) { $articles[$i] = $a = new ModelArticle(); $a->setTitle(Article .$i); $a->save(); } echo $articles[3]->getPosition(); // 3 echo $articles[6]->getPosition(); // 6viernes 4 de marzo de 2011
  • // 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();viernes 4 de marzo de 2011
  • Taggable Sortable Allows you to save tags in the entities.viernes 4 de marzo de 2011
  • $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();viernes 4 de marzo de 2011
  • Translatable Taggable Sortable Allows you to translate entity columns. columns *viernes 4 de marzo de 2011
  • 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] }viernes 4 de marzo de 2011
  • $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();viernes 4 de marzo de 2011
  • Doctrator in Symfony2viernes 4 de marzo de 2011
  • DoctratorBundleviernes 4 de marzo de 2011
  • doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true validation: trueviernes 4 de marzo de 2011
  • doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true validation: true my_extension_id: trueviernes 4 de marzo de 2011
  • Config Classes app/config/doctrator/*.yml *Bundle/Resources/doctrator/*.ymlviernes 4 de marzo de 2011
  • Standard Namespace ModelArticle: 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 }viernes 4 de marzo de 2011
  • ModelArticle: validation: - MyArticleClassValidator: ~ columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string, validation: [MaxLength: 2000] } Validation integratedviernes 4 de marzo de 2011
  • php app/console doctrator:generateviernes 4 de marzo de 2011
  • Questions? http://mondongo.es (English :) You can contact me for Mondongo, Doctrator, consulting, development pablodip@gmail.comviernes 4 de marzo de 2011