SlideShare uma empresa Scribd logo
1 de 135
Baixar para ler offline
Doctrator
                                    Pablo Díez




                             Symfony Live 2011 - Paris


viernes 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/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
Agile Development

                               ActiveRecord      optional




viernes 4 de marzo de 2011
Agile Development
                               ActiveRecord
                                 Behaviors




viernes 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.html


viernes 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          string




viernes 4 de marzo de 2011
namespace Model;

                                class User
                                {
                                }



                                             Class

                                      user
                                id             integer
                             username           string
                             password           string
                              email             string




viernes 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             string




viernes 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 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
What does Doctrator do?

       Doctrator generates classes and maps them with Doctrine2




viernes 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;
                        }
           }
                                                                 Methods
viernes 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 Extensions




viernes 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.


                             MondongoMondatorDefinitionDefinition




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;
                   }
         }


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 generate


viernes 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']; // Doctrator




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']; // 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
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 Extensions




viernes 4 de marzo de 2011
Doctrator Extensions

                                           Core

              ArrayAccess      PropertyOverloading   ActiveRecord   Behaviors




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
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'); // Doctrator




viernes 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']; // Doctrator




viernes 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; // Doctrator




viernes 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
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 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_at




viernes 4 de marzo de 2011
ModelArticle:
             columns:
                 id:    { id: auto, type: integer }
                 title: { type: name, length: 100 }
             behaviors:
                 - DoctratorBehaviorTimestampable




viernes 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(); // now




viernes 4 de marzo de 2011
Ipable



                             Saves the created and updated ip.
                                           created TRUE
                                   created_column created_from
                                          updated TRUE
                                   updated_column updated_from




viernes 4 de marzo de 2011
Hashable
                                            Ipable



                             Saves a unique hash in each entity.
                                         column hash




viernes 4 de marzo de 2011
ModelArticle:
             columns:
                 id:    { id: auto, type: integer }
                 title: { type: name, length: 100 }
             behaviors:
                 - DoctratorBehaviorHashable




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
Timestampable
                                        Sluggable



                             Saves a slug from a field.
                                 from_column *
                                 slug_column slug
                                      unique TRUE
                                      update FALSE




viernes 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-rocks




viernes 4 de marzo de 2011
Sortable



                             Allows you to sort your entities.
                                          column position
                                     new_position bottom




viernes 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(); // 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
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 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
Config Classes


                                 app/config/doctrator/*.yml
                             *Bundle/Resources/doctrator/*.yml




viernes 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 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
                                   pablodip@gmail.com




viernes 4 de marzo de 2011

Mais conteúdo relacionado

Mais procurados

Doctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San FranciscoDoctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San Franciscopablodip
 
Object-Oriented Programming with C#
Object-Oriented Programming with C#Object-Oriented Programming with C#
Object-Oriented Programming with C#Svetlin Nakov
 
Using and Abusing Magic methods in Python
Using and Abusing Magic methods in PythonUsing and Abusing Magic methods in Python
Using and Abusing Magic methods in PythonSlater Victoroff
 
psnreddy php-oops
psnreddy  php-oopspsnreddy  php-oops
psnreddy php-oopssatya552
 
Object Oriented Programming in Python
Object Oriented Programming in PythonObject Oriented Programming in Python
Object Oriented Programming in PythonSujith Kumar
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPWildan Maulana
 
How to write you first class in c++ object oriented programming
How to write you first class in c++ object oriented programmingHow to write you first class in c++ object oriented programming
How to write you first class in c++ object oriented programmingSyed Faizan Hassan
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHPLorna Mitchell
 
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITK
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITKAdvanced CPP Lecture 1- Summer School 2014 - ACA CSE IITK
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITKPankaj Prateek
 
Advanced php
Advanced phpAdvanced php
Advanced phphamfu
 
14. Defining Classes
14. Defining Classes14. Defining Classes
14. Defining ClassesIntro C# Book
 

Mais procurados (20)

Doctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San FranciscoDoctrator Symfony Live 2011 San Francisco
Doctrator Symfony Live 2011 San Francisco
 
Python oop third class
Python oop   third classPython oop   third class
Python oop third class
 
Python Metaclasses
Python MetaclassesPython Metaclasses
Python Metaclasses
 
Object-Oriented Programming with C#
Object-Oriented Programming with C#Object-Oriented Programming with C#
Object-Oriented Programming with C#
 
Using and Abusing Magic methods in Python
Using and Abusing Magic methods in PythonUsing and Abusing Magic methods in Python
Using and Abusing Magic methods in Python
 
psnreddy php-oops
psnreddy  php-oopspsnreddy  php-oops
psnreddy php-oops
 
Object Oriented Programming in Python
Object Oriented Programming in PythonObject Oriented Programming in Python
Object Oriented Programming in Python
 
Python programming : Classes objects
Python programming : Classes objectsPython programming : Classes objects
Python programming : Classes objects
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Class and object in C++ By Pawan Thakur
Class and object in C++ By Pawan ThakurClass and object in C++ By Pawan Thakur
Class and object in C++ By Pawan Thakur
 
Python classes objects
Python classes objectsPython classes objects
Python classes objects
 
Python programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphismPython programming : Inheritance and polymorphism
Python programming : Inheritance and polymorphism
 
Python: Basic Inheritance
Python: Basic InheritancePython: Basic Inheritance
Python: Basic Inheritance
 
How to write you first class in c++ object oriented programming
How to write you first class in c++ object oriented programmingHow to write you first class in c++ object oriented programming
How to write you first class in c++ object oriented programming
 
Object Oriented Programming in PHP
Object Oriented Programming in PHPObject Oriented Programming in PHP
Object Oriented Programming in PHP
 
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITK
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITKAdvanced CPP Lecture 1- Summer School 2014 - ACA CSE IITK
Advanced CPP Lecture 1- Summer School 2014 - ACA CSE IITK
 
Advanced php
Advanced phpAdvanced php
Advanced php
 
Ch8(oop)
Ch8(oop)Ch8(oop)
Ch8(oop)
 
Spsl v unit - final
Spsl v unit - finalSpsl v unit - final
Spsl v unit - final
 
14. Defining Classes
14. Defining Classes14. Defining Classes
14. Defining Classes
 

Destaque (20)

10
1010
10
 
Program conf 2014
Program conf 2014Program conf 2014
Program conf 2014
 
Case1
Case1Case1
Case1
 
AP 3D intro
AP 3D introAP 3D intro
AP 3D intro
 
Instructiunea if
Instructiunea ifInstructiunea if
Instructiunea if
 
Constructia while
Constructia whileConstructia while
Constructia while
 
Constructia for
Constructia forConstructia for
Constructia for
 
650 de ani de la formarea statului moldovensc
650 de ani de la formarea statului moldovensc650 de ani de la formarea statului moldovensc
650 de ani de la formarea statului moldovensc
 
Instructiunea If
Instructiunea IfInstructiunea If
Instructiunea If
 
Fused glass Unit
Fused glass UnitFused glass Unit
Fused glass Unit
 
Boletin
BoletinBoletin
Boletin
 
Boletin
BoletinBoletin
Boletin
 
Boletin
BoletinBoletin
Boletin
 
Copia
CopiaCopia
Copia
 
Afip
AfipAfip
Afip
 
Alimentos
AlimentosAlimentos
Alimentos
 
Amparo
AmparoAmparo
Amparo
 
Boletin
BoletinBoletin
Boletin
 
Boletin
BoletinBoletin
Boletin
 
140
140140
140
 

Semelhante a Doctrator = Doctrine2 + Mondator

international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPsmueller_sandsmedia
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기형우 안
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Ext GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesExt GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesSencha
 
A Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemA Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemLeonard Axelsson
 
Write a program that asks the user for the name of a file. The progr.pdf
Write a program that asks the user for the name of a file. The progr.pdfWrite a program that asks the user for the name of a file. The progr.pdf
Write a program that asks the user for the name of a file. The progr.pdfarri2009av
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisJonathan Wage
 
Declarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPDeclarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPStephan Schmidt
 
Declarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPDeclarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPstubbles
 
Java Generics.ppt
Java Generics.pptJava Generics.ppt
Java Generics.pptbrayazar
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPAlena Holligan
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real WorldJonathan Wage
 
Pursuing Domain-Driven Design practices in PHP
Pursuing Domain-Driven Design practices in PHPPursuing Domain-Driven Design practices in PHP
Pursuing Domain-Driven Design practices in PHPGiorgio Sironi
 
PHP-05-Objects.ppt
PHP-05-Objects.pptPHP-05-Objects.ppt
PHP-05-Objects.pptrani marri
 

Semelhante a Doctrator = Doctrine2 + Mondator (20)

international PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHPinternational PHP2011_ilia alshanetsky_Hidden Features of PHP
international PHP2011_ilia alshanetsky_Hidden Features of PHP
 
잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기잘 알려지지 않은 Php 코드 활용하기
잘 알려지지 않은 Php 코드 활용하기
 
Libertyvasion2010
Libertyvasion2010Libertyvasion2010
Libertyvasion2010
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Active domain
Active domainActive domain
Active domain
 
Ext GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced TemplatesExt GWT 3.0 Advanced Templates
Ext GWT 3.0 Advanced Templates
 
A Tour Through the Groovy Ecosystem
A Tour Through the Groovy EcosystemA Tour Through the Groovy Ecosystem
A Tour Through the Groovy Ecosystem
 
Hacking XPATH 2.0
Hacking XPATH 2.0Hacking XPATH 2.0
Hacking XPATH 2.0
 
Write a program that asks the user for the name of a file. The progr.pdf
Write a program that asks the user for the name of a file. The progr.pdfWrite a program that asks the user for the name of a file. The progr.pdf
Write a program that asks the user for the name of a file. The progr.pdf
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 Paris
 
Declarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPDeclarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHP
 
Declarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHPDeclarative Development Using Annotations In PHP
Declarative Development Using Annotations In PHP
 
Dynamic Python
Dynamic PythonDynamic Python
Dynamic Python
 
Java Generics.ppt
Java Generics.pptJava Generics.ppt
Java Generics.ppt
 
When?, Why? and What? of MongoDB
When?, Why? and What? of MongoDBWhen?, Why? and What? of MongoDB
When?, Why? and What? of MongoDB
 
Demystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHPDemystifying Object-Oriented Programming - Lone Star PHP
Demystifying Object-Oriented Programming - Lone Star PHP
 
Sequel @ madrid-rb
Sequel @  madrid-rbSequel @  madrid-rb
Sequel @ madrid-rb
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real World
 
Pursuing Domain-Driven Design practices in PHP
Pursuing Domain-Driven Design practices in PHPPursuing Domain-Driven Design practices in PHP
Pursuing Domain-Driven Design practices in PHP
 
PHP-05-Objects.ppt
PHP-05-Objects.pptPHP-05-Objects.ppt
PHP-05-Objects.ppt
 

Último

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 

Último (20)

Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 

Doctrator = Doctrine2 + Mondator

  • 1. Doctrator Pablo Díez Symfony Live 2011 - Paris viernes 4 de marzo de 2011
  • 2. 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/pablodip viernes 4 de marzo de 2011
  • 3. What is Doctrator? viernes 4 de marzo de 2011
  • 4. Doctrator = Doctrine2 + Mondator viernes 4 de marzo de 2011
  • 5. Agile Development viernes 4 de marzo de 2011
  • 6. Agile Development ActiveRecord viernes 4 de marzo de 2011
  • 7. Agile Development ActiveRecord optional viernes 4 de marzo de 2011
  • 8. Agile Development ActiveRecord Behaviors viernes 4 de marzo de 2011
  • 9. Agile Development ActiveRecord Behaviors Doctrator saves you a lot of time! ;) viernes 4 de marzo de 2011
  • 10. How does Doctrine2 work? viernes 4 de marzo de 2011
  • 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 viernes 4 de marzo de 2011
  • 12. 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
  • 13. You only have to tell Doctrine2 (map) what you want to persist. viernes 4 de marzo de 2011
  • 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; } viernes 4 de marzo de 2011
  • 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) } viernes 4 de marzo de 2011
  • 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> viernes 4 de marzo de 2011
  • 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' )); viernes 4 de marzo de 2011
  • 18. 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
  • 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(); viernes 4 de marzo de 2011
  • 20. 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
  • 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; viernes 4 de marzo de 2011
  • 22. What do you need to work with this simple table? user id integer username string password string email string viernes 4 de marzo de 2011
  • 23. namespace Model; class User { } Class user id integer username string password string email string viernes 4 de marzo de 2011
  • 24. namespace Model; protected $id; class User protected $username; { protected $password; } protected $email; Class Properties user id integer username string password string email string viernes 4 de marzo de 2011
  • 25. 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
  • 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; viernes 4 de marzo de 2011
  • 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; } } viernes 4 de marzo de 2011
  • 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; } } viernes 4 de marzo de 2011
  • 29. LORC Lines Of Repetitive Code viernes 4 de marzo de 2011
  • 30. LORC Lines Of Repetitive Code ... and we still don’t have any features! :) viernes 4 de marzo de 2011
  • 31. How many LORC do we need in a real database? viernes 4 de marzo de 2011
  • 32. How many LORC do we need in a real database? ... viernes 4 de marzo de 2011
  • 33. What does Doctrator do? viernes 4 de marzo de 2011
  • 34. What does Doctrator do? Doctrator generates classes and maps them with Doctrine2 viernes 4 de marzo de 2011
  • 35. 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
  • 36. 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
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. How does Doctrator work? viernes 4 de marzo de 2011
  • 41. How does Doctrator work? Doctrator uses Mondator to generate the classes for you. viernes 4 de marzo de 2011
  • 42. Mondator defines PHP classes. viernes 4 de marzo de 2011
  • 43. 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
  • 44. namespace Model; Definition class User { Properties protected $username; public function setUsername($username) { $this->username = $username; } public function getUsername() { return $this->username; } } Methods viernes 4 de marzo de 2011
  • 45. use MondongoMondatorDefinitionDefinition; use MondongoMondatorDefinitionProperty; use MondongoMondatorDefinitionMethod; viernes 4 de marzo de 2011
  • 46. namespace Model; class User { } Full Class Name $definition = new Definition('ModelUser'); viernes 4 de marzo de 2011
  • 47. protected $username; Visibility Name $property = new Property('protected', 'username'); $definition->addProperty($property); viernes 4 de marzo de 2011
  • 48. 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
  • 49. You can define any PHP class. viernes 4 de marzo de 2011
  • 50. Parent class $definition->setParentClass('ModelBaseUser'); Interfaces $definition->addInterface('ArrayAccess'); Abstract $definition->setIsAbstract(true); viernes 4 de marzo de 2011
  • 51. Default value $property->setValue($defaultValue); Static $property->setIsStatic(true); viernes 4 de marzo de 2011
  • 52. Abstract $method->setIsAbstract(true); Static $method->setIsStatic(true); viernes 4 de marzo de 2011
  • 53. Even with comments. viernes 4 de marzo de 2011
  • 54. $definition->setDocComment(<<<EOF /** * User Class. */ EOF ); $method->setDocComment(<<<EOF /** * Set the username. * * @param string $username The username. */ EOF ); viernes 4 de marzo de 2011
  • 55. 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
  • 56. /** * 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
  • 57. And save them in files. file_put_contents($file, $codeClass); viernes 4 de marzo de 2011
  • 58. Mondator Extensions viernes 4 de marzo de 2011
  • 59. Mondator Extensions Mondator uses extensions to generate similar classes in a powerful and flexible way. viernes 4 de marzo de 2011
  • 60. The Mondator Extensions process the config classes to define what classes will be generated. viernes 4 de marzo de 2011
  • 61. 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 viernes 4 de marzo de 2011
  • 62. 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
  • 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; } } viernes 4 de marzo de 2011
  • 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; } } viernes 4 de marzo de 2011
  • 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; } } Definitions to generate viernes 4 de marzo de 2011
  • 66. An extension can generate any definition. viernes 4 de marzo de 2011
  • 67. 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
  • 68. foreach ($this->configClass['columns'] as $name => $column) { $property = new Property('protected', $name); $this->definitions['entity']->addProperty($property); } viernes 4 de marzo de 2011
  • 69. 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
  • 70. Different extensions can modify the same definition. viernes 4 de marzo de 2011
  • 71. 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
  • 72. An extension can have options. viernes 4 de marzo de 2011
  • 73. 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
  • 74. You can process the extensions that you want. viernes 4 de marzo de 2011
  • 75. $mondator = new MondongoMondatorMondator(); $mondator->setConfigClasses($configClasses); $mondator->setExtensions(array( new DoctratorExtensionCore($options), new DoctratorExtensionArrayAccess(), )); $mondator->process(); $article['title'] = 'Doctrator'; echo $article['title']; // Doctrator viernes 4 de marzo de 2011
  • 76. $mondator = new MondongoMondatorMondator(); $mondator->setConfigClasses($configClasses); $mondator->setExtensions(array( new DoctratorExtensionCore($options), //new DoctratorExtensionArrayAccess(), )); $mondator->process(); $article['title'] = 'Doctrator'; echo $article['title']; // Doctrator viernes 4 de marzo de 2011
  • 77. An extension can change the config class to extend another extension. viernes 4 de marzo de 2011
  • 78. 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
  • 79. You can even use extensions in the config classes. viernes 4 de marzo de 2011
  • 80. ModelArticle: columns: id: { id: auto, type: integer } title: { type: string, length: 100 } behaviors: - class: DoctratorBehaviorTimestampable options: { } viernes 4 de marzo de 2011
  • 81. And you can combine all these things to do what you want. viernes 4 de marzo de 2011
  • 82. Generated code is not necessarily magic code. viernes 4 de marzo de 2011
  • 83. Doctrator Extensions viernes 4 de marzo de 2011
  • 84. Doctrator Extensions Core ArrayAccess PropertyOverloading ActiveRecord Behaviors viernes 4 de marzo de 2011
  • 85. Core Generates and maps objects with Doctrine2. viernes 4 de marzo de 2011
  • 86. Doctrator uses base classes to separate generated code from your code. viernes 4 de marzo de 2011
  • 87. ModelUser namespace Model; class User extends ModelBaseUser { // your code } namespace ModelBase; class User { // generated code } viernes 4 de marzo de 2011
  • 88. 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
  • 89. 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
  • 90. 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
  • 91. $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
  • 92. Core Useful methods. viernes 4 de marzo de 2011
  • 93. Set & Get by string $article->set('title', 'Doctrator'); echo $article->get('title'); // Doctrator viernes 4 de marzo de 2011
  • 94. fromArray & toArray $article->fromArray(array( 'title' => 'Doctrator', 'date' => new DateTime('now') )); $array = $article->toArray(); viernes 4 de marzo de 2011
  • 95. ArrayAccess Implements the ArrayAccess interface in the entities. viernes 4 de marzo de 2011
  • 96. $article = new ModelArticle(); $article['title'] = 'Doctrator'; echo $article['title']; // Doctrator viernes 4 de marzo de 2011
  • 97. PropertyOverloading Allows you access to entity data like properties. viernes 4 de marzo de 2011
  • 98. $article = new ModelArticle(); $article->title = 'Doctrator'; echo $article->title; // Doctrator viernes 4 de marzo de 2011
  • 99. ActiveRecord Implements the ActiveRecord pattern in your entities. viernes 4 de marzo de 2011
  • 100. $article = new ModelArticle(); $article->setTitle('Doctrator'); $article->save(); $article->refresh(); $article->delete(); viernes 4 de marzo de 2011
  • 102. 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
  • 103. $em = ModelArticle::entityManager(); $articleRepository = ModelArticle::repository(); $queryBuilder = ModelArticle::queryBuilder(); viernes 4 de marzo de 2011
  • 104. $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
  • 105. Behaviors viernes 4 de marzo de 2011
  • 106. Behaviors Reuse features. viernes 4 de marzo de 2011
  • 107. A behavior is simply a Mondator extension. viernes 4 de marzo de 2011
  • 108. 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
  • 109. Timestampable Saves the created and updated date. created TRUE created_column created_at updated TRUE updated_column updated_at viernes 4 de marzo de 2011
  • 110. ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorTimestampable viernes 4 de marzo de 2011
  • 111. $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(); // now viernes 4 de marzo de 2011
  • 112. Ipable Saves the created and updated ip. created TRUE created_column created_from updated TRUE updated_column updated_from viernes 4 de marzo de 2011
  • 113. Hashable Ipable Saves a unique hash in each entity. column hash viernes 4 de marzo de 2011
  • 114. ModelArticle: columns: id: { id: auto, type: integer } title: { type: name, length: 100 } behaviors: - DoctratorBehaviorHashable viernes 4 de marzo de 2011
  • 115. $article = new Article(); $article->setTitle('Doctrator'); $entityManager->persist(); $entityManager->flush(); echo $article->getHash(); // da39a3ee5e6b4b0d3255bfef95601890afd80709 viernes 4 de marzo de 2011
  • 116. Timestampable Sluggable Saves a slug from a field. from_column * slug_column slug unique TRUE update FALSE viernes 4 de marzo de 2011
  • 117. 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
  • 118. $article = new ModelArticle(); $article->setTitle('Doctrator Rocks!'); $article->save(); echo $article->getSlug(); // doctrator-rocks viernes 4 de marzo de 2011
  • 119. Sortable Allows you to sort your entities. column position new_position bottom viernes 4 de marzo de 2011
  • 120. $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(); // 6 viernes 4 de marzo de 2011
  • 121. // 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
  • 122. Taggable Sortable Allows you to save tags in the entities. viernes 4 de marzo de 2011
  • 123. $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
  • 124. Translatable Taggable Sortable Allows you to translate entity columns. columns * viernes 4 de marzo de 2011
  • 125. 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
  • 126. $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
  • 127. Doctrator in Symfony2 viernes 4 de marzo de 2011
  • 129. doctrator.config: extensions: array_access: false property_overloading: false active_record: true behaviors: true validation: true viernes 4 de marzo de 2011
  • 130. 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
  • 131. Config Classes app/config/doctrator/*.yml *Bundle/Resources/doctrator/*.yml viernes 4 de marzo de 2011
  • 132. 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
  • 133. ModelArticle: 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
  • 135. Questions? http://mondongo.es (English :) You can contact me for Mondongo, Doctrator, consulting, development pablodip@gmail.com viernes 4 de marzo de 2011