Doctrator Symfony Live 2011 Paris
-
Upload
pablodip -
Category
Technology
-
view
5.393 -
download
0
description
Transcript of Doctrator Symfony Live 2011 Paris
DoctratorPablo Díez
Symfony Live 2011 - Paris
viernes 4 de marzo de 2011
Pablo DíezCreator of Mondongo
ODM for MongoDB and PHPhttp://mondongo.es (in English :)
Creator of MondatorClass generator for PHP
Creator of Doctrator
http://twitter.com/pablodiphttp://github.com/pablodip
viernes 4 de marzo de 2011
What is Doctrator?
viernes 4 de marzo de 2011
Doctrator = Doctrine2 + Mondator
viernes 4 de marzo de 2011
Agile Development
viernes 4 de marzo de 2011
Agile Development
ActiveRecord
viernes 4 de marzo de 2011
ActiveRecord optional
Agile Development
viernes 4 de marzo de 2011
ActiveRecord
Behaviors
Agile Development
viernes 4 de marzo de 2011
Doctrator saves you a lot of time! ;)
ActiveRecord
Behaviors
Agile Development
viernes 4 de marzo de 2011
How does Doctrine2 work?
viernes 4 de marzo de 2011
“Doctrine2 provides transparent persistence for PHP objects.”
How does Doctrine2 work?
http://www.doctrine-project.org/docs/orm/2.0/en/reference/introduction.html
viernes 4 de marzo de 2011
namespace Model;
class User{ public $id; public $username; public $email;}
That is, persist PHP objects without restrictions of a base class, properties, methods.
viernes 4 de marzo de 2011
You only have to tell Doctrine2 (map) what you want to persist.
viernes 4 de marzo de 2011
With Docblock Annotations
/** * @Entity */class User{ /** * @Id * @Column(type="integer") */ public $id; /** * @Column(length=50) */ public $username; /** * @Column(length=100) */ public $email;}
You only have to tell Doctrine2 (map) what you want to persist.
viernes 4 de marzo de 2011
Entities\User: type: entity fields: id: { type: integer, id: true } username: { type: string(50) } email: { type: string(50) }
With YAML
You only have to tell Doctrine2 (map) what you want to persist.
viernes 4 de marzo de 2011
<?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="Model\User" 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>
With XML
You only have to tell Doctrine2 (map) what you want to persist.
viernes 4 de marzo de 2011
$metadata->mapField(array( 'id' => true, 'fieldName' => 'id', 'type' => 'integer'));
$metadata->mapField(array( 'fieldName' => 'username', 'type' => 'string'));
$metadata->mapField(array( 'fieldName' => 'email', 'type' => 'string'));
With PHP
You only have to tell Doctrine2 (map) what you want to persist.
viernes 4 de marzo de 2011
Then you are able to persist those objects.
You only have to tell Doctrine2 (map) what you want to persist.
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 = '[email protected]';
$entityManager->persist($user);$entityManager->flush();
viernes 4 de marzo de 2011
class User{ protected $id; protected $username; protected $password; protected $email;}
A Doctrine2 good practice is to use non public properties in the entities.
viernes 4 de marzo de 2011
Setters & Getters
You have to create methods to access to the properties.
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
useruser
id integer
username string
password string
email string
What do you need to work with this simple table?
viernes 4 de marzo de 2011
useruser
id integer
username string
password string
email string
namespace Model;
class User{}
Class
viernes 4 de marzo de 2011
useruser
id integer
username string
password string
email string
namespace Model;
class User{}
protected $id;protected $username;protected $password;protected $email;
ClassProperties
viernes 4 de marzo de 2011
useruser
id integer
username string
password string
email string
namespace Model;
class User{}
protected $id;protected $username;protected $password;protected $email;
ClassProperties
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;
Setters/Getters
viernes 4 de marzo de 2011
useruser
id integer
username string
password string
email string
namespace Model;
class User{}
protected $id;protected $username;protected $password;protected $email;
ClassProperties
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;
Setters/Getters
/** * @Entity */
/** * @Id * @Column(type="integer") */ /** * @Column(length=50) */ /** * @Column(length=100) */
Mapping
viernes 4 de marzo de 2011
useruser
id integer
username string
password string
email string
namespace Model;
/** * @Entity */class User{ /** * @Id * @Column(type="integer") */ protected $id; /** * @Column(length="50") */ protected $username; /** * @Column(length="40") */ protected $password; /** * @Column(length="100") */ protected $email;
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; }
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
useruser
id integer
username string
password string
email string
namespace Model;
/** * @Entity */class User{ /** * @Id * @Column(type="integer") */ protected $id; /** * @Column(length="50") */ protected $username; /** * @Column(length="40") */ protected $password; /** * @Column(length="100") */ protected $email;
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; }
public function getPassword() { return $this->password; }
public function setEmail($email) { $this->email = $email; }
public function getEmail() { return $this->email; }}
LORC
viernes 4 de marzo de 2011
LORC
Lines Of Repetitive Code
viernes 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
Doctrator generates classes and maps them with Doctrine2
What does Doctrator do?
viernes 4 de marzo de 2011
You only have to tell it the configuration of the classes.
Doctrator generates classes and maps them with Doctrine2
viernes 4 de marzo de 2011
array( 'Model\User' => 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), ), ),);
In PHP
viernes 4 de marzo de 2011
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
In YAML
viernes 4 de marzo de 2011
Model\User: 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.
class User{
protected $id;
protected $username;
protected $password;
protected $email;
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; }
public function getPassword() { return $this->password; }
public function setEmail($email)
This maps your object.
/** * @Entity */
/** * @Id * @Column(type="integer") */ /** * @Column(length=50) */ /** * @Column(length=100) */
viernes 4 de marzo de 2011
Model\User: 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 \Model\User();$user->setUsername('pagafantas');$user->setEmail('[email protected]');
$entityManager->persist($user);$entityManager->flush();
viernes 4 de marzo de 2011
How does Doctrator work?
viernes 4 de marzo de 2011
Doctrator uses Mondator to generate the classes for you.
How does Doctrator work?
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;
class User{ protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; }}
Definition
Properties
Methods
viernes 4 de marzo de 2011
use Mondongo\Mondator\Definition\Definition;use Mondongo\Mondator\Definition\Property;use Mondongo\Mondator\Definition\Method;
viernes 4 de marzo de 2011
namespace Model;
class User{}
$definition = new Definition('Model\User');
Full Class Name
viernes 4 de marzo de 2011
protected $username;
$property = new Property('protected', 'username');$definition->addProperty($property);
Visibility Name
viernes 4 de marzo de 2011
public function setUsername($username){ $this->username = $username;}
$method = new Method('public', 'setUsername', '$username', <<<EOF \$this->username = \$username;EOF);$definition->addMethod($method);
Visibility Name Arguments Code
viernes 4 de marzo de 2011
You can define any PHP class.
viernes 4 de marzo de 2011
$definition->setParentClass('\Model\Base\User');
$definition->addInterface('\ArrayAccess');
$definition->setIsAbstract(true);
Parent class
Interfaces
Abstract
viernes 4 de marzo de 2011
$property->setValue($defaultValue);
$property->setIsStatic(true);
Default value
Static
viernes 4 de marzo de 2011
$method->setIsAbstract(true);
$method->setIsStatic(true);
Abstract
Static
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
use \Mondongo\Mondator\Dumper;
$dumper = new Dumper($definition);$classCode = $dumper->dump();
echo $classCode;
Then you can export them with the Dumper.
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 Extensions
viernes 4 de marzo de 2011
Mondator uses extensions to generate similar classes in a powerful and flexible way.
Mondator Extensions
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
The Mondator Extensions process the config classes to define what classes will be generated.
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
Mondongo\Mondator\Definition\Definition
viernes 4 de marzo de 2011
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
use Mondongo\Mondator\Extension;
class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
viernes 4 de marzo de 2011
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
use Mondongo\Mondator\Extension;
class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
viernes 4 de marzo de 2011
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
use Mondongo\Mondator\Extension;
class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }}
viernes 4 de marzo de 2011
Model\User: columns: id: { id: auto, type: integer } username: { type: string, length: 50 } password: { type: string, length: 40 } email: { type: string, length: 100 }
use Mondongo\Mondator\Extension;
class Doctrator extends Extension{ protected function doClassProcess() { $this->class; $this->configClass; $this->definitions; }} Definitions to generate
viernes 4 de marzo de 2011
An extension can generate any definition.
viernes 4 de marzo de 2011
use Mondongo\Mondator\Extension;use Mondongo\Mondator\Definition\Definition;
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 \Mondongo\Mondator\Mondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new \Doctrator\Extension\Core($options), new \Doctrator\Extension\ArrayAccess(),));$mondator->process();
$article['title'] = 'Doctrator';echo $article['title']; // Doctrator
viernes 4 de marzo de 2011
$mondator = new \Mondongo\Mondator\Mondator();$mondator->setConfigClasses($configClasses);$mondator->setExtensions(array( new \Doctrator\Extension\Core($options), //new \Doctrator\Extension\ArrayAccess(),));$mondator->process();
$article['title'] = 'Doctrator';echo $article['title']; // Doctrator
viernes 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
Model\Article: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } behaviors: - class: Doctrator\Behavior\Timestampable 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 Extensions
viernes 4 de marzo de 2011
Core
ActiveRecordArrayAccess PropertyOverloading Behaviors
Doctrator Extensions
viernes 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
Model\Usernamespace Model;
class User extends \Model\Base\User{ // your code}
namespace Model\Base;
class User{ // generated code}
viernes 4 de marzo de 2011
Model\Article: 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: Model\Category, inversed: articles } indexes: slug: { columns: ['slug'], unique: true } date: { columns: ['is_active', 'date'] } events: preUpdate: ['updateDate']
viernes 4 de marzo de 2011
Model\Article: 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: Model\Category, inversed: articles } indexes: slug: { columns: ['slug'], unique: true } date: { columns: ['is_active', 'date'] } events: preUpdate: ['updateDate']
Associations
one_to_oneone_to_manymany_to_one
many_to_many
nameclass
mappedinversed
viernes 4 de marzo de 2011
Model\Article: 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: Model\Category, inversed: articles } indexes: slug: { columns: ['slug'], unique: true } date: { columns: ['is_active', 'date'] } events: preUpdate: ['updateDate']
Events
prePersistpostPersistpreUpdatepostUpdatepreRemovepostRemove
postLoad
viernes 4 de marzo de 2011
$category = new \Model\Category();$category->setName('Class Generator');$entityManager->persist($category);
$article = new \Model\Article();$article->setTitle('Doctrator');$article->setDate(new \DateTime('now'));$article->setCategory($category);$entityManager->persist($article);
$entityManager->flush();
viernes 4 de marzo de 2011
Useful methods.
Core
viernes 4 de marzo de 2011
$article->set('title', 'Doctrator');
echo $article->get('title'); // Doctrator
Set & Get by string
viernes 4 de marzo de 2011
$article->fromArray(array( 'title' => 'Doctrator', 'date' => new \DateTime('now')));
$array = $article->toArray();
fromArray & toArray
viernes 4 de marzo de 2011
Implements the ArrayAccess interface in the entities.
ArrayAccess
viernes 4 de marzo de 2011
$article = new \ModelArticle();$article['title'] = 'Doctrator';echo $article['title']; // Doctrator
viernes 4 de marzo de 2011
Allows you access to entity data like properties.
PropertyOverloading
viernes 4 de marzo de 2011
$article = new \ModelArticle();$article->title = 'Doctrator';echo $article->title; // Doctrator
viernes 4 de marzo de 2011
Implements the ActiveRecord pattern in your entities.
ActiveRecord
viernes 4 de marzo de 2011
$article = new \Model\Article();$article->setTitle('Doctrator');$article->save();
$article->refresh();
$article->delete();
viernes 4 de marzo de 2011
print_r($article);
viernes 4 de marzo de 2011
Model\Article Object( [id:protected] => 1 [title:protected] => Doctrator [content:protected] => Rocks!)
Doctrator entities are clean even with ActiveRecord!
print_r($article);
viernes 4 de marzo de 2011
$em = \Model\Article::entityManager();$articleRepository = \Model\Article::repository();$queryBuilder = \Model\Article::queryBuilder();
viernes 4 de marzo de 2011
$articles = \Model\Article::repository()->findAll();$article = \Model\Article::repository()->find($id);
$articles = $entityManager->getRepository('Model\Article')->findAll();$article = $entityManager->getRepository('Model\Article')->find($id);
viernes 4 de marzo de 2011
Behaviors
viernes 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 optionsChange config classes:• Columns• Associations• Indexes• Events• ...
Add new generated classesAdd properties and methods• Entities• Repositories• ...
viernes 4 de marzo de 2011
Saves the created and updated date.
Timestampable
created TRUE
created_column created_at
updated TRUE
updated_column updated_at
viernes 4 de marzo de 2011
Model\Article: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - Doctrator\Behavior\Timestampable
viernes 4 de marzo de 2011
$article = new \Model\Article();$article->setTitle('Doctrator');$article->save(); echo $article->getCreatedAt(); // nowecho $article->getUpdatedAt(); // null $article->setContent('Rocks!');$article->save(); echo $article->getCreatedAt(); // beforeecho $article->getUpdatedAt(); // now
viernes 4 de marzo de 2011
Saves the created and updated ip.
Ipable
created TRUE
created_column created_from
updated TRUE
updated_column updated_from
viernes 4 de marzo de 2011
Saves a unique hash in each entity.
IpableHashable
column hash
viernes 4 de marzo de 2011
Model\Article: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - Doctrator\Behavior\Hashable
viernes 4 de marzo de 2011
$article = new Article();$article->setTitle('Doctrator');
$entityManager->persist();$entityManager->flush();
echo $article->getHash();// da39a3ee5e6b4b0d3255bfef95601890afd80709
viernes 4 de marzo de 2011
Saves a slug from a field.
TimestampableSluggable
from_column *
slug_column slug
unique TRUE
update FALSE
viernes 4 de marzo de 2011
Model\Article: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - class: Doctrator\Behavior\Sluggable options: { from_column: title }
viernes 4 de marzo de 2011
$article = new \Model\Article();$article->setTitle('Doctrator Rocks!');$article->save(); echo $article->getSlug(); // doctrator-rocks
viernes 4 de marzo de 2011
Allows you to sort your entities.
column position
new_position bottom
Sortable
viernes 4 de marzo de 2011
$articles = array();for ($i = 0; $i <= 10; $i++) { $articles[$i] = $a = new \Model\Article(); $a->setTitle('Article '.$i); $a->save();} echo $articles[3]->getPosition(); // 3echo $articles[6]->getPosition(); // 6
viernes 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
Allows you to save tags in the entities.
SortableTaggable
viernes 4 de marzo de 2011
$article = new \Model\Article();$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
Allows you to translate entity columns.
columns *
SortableTaggableTranslatable
viernes 4 de marzo de 2011
Model\Article: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string } date: { type: date } behaviors: - class: Doctrator\Behavior\Translatable options: { columns: ['title', 'content'] }
viernes 4 de marzo de 2011
$article = new \Model\Article();$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 Symfony2
viernes 4 de marzo de 2011
DoctratorBundle
viernes 4 de marzo de 2011
doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true
validation: true
viernes 4 de marzo de 2011
doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true
validation: true
my_extension_id: true
viernes 4 de marzo de 2011
*Bundle/Resources/doctrator/*.yml
Config Classes
app/config/doctrator/*.yml
viernes 4 de marzo de 2011
Model\Article: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string }
Model\DoctratorUserBundle\User: columns: id: { id: auto, type: integer } username: { type: string, length: 20 }
Standard Namespace
viernes 4 de marzo de 2011
Model\Article: validation: - MyArticleClassValidator: ~ columns: id: { id: auto, type: integer } title: { type: string, length: 100 } content: { type: string, validation: [MaxLength: 2000] }
Validation integrated
viernes 4 de marzo de 2011
php app/console doctrator:generate
viernes 4 de marzo de 2011
Questions?
http://mondongo.es (English :)
You can contact me for Mondongo, Doctrator, consulting, development
viernes 4 de marzo de 2011