Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Using interfaces to give an alternative to extending from BaseEntity …

…and/or BaseSession
  • Loading branch information...
commit d8eaf7babfe69ddea4973586d451a5a7e4011171 1 parent 09d9ad9
Mariano Iglesias authored
68 README.md
Source Rendered
@@ -58,6 +58,9 @@ advantage of choosing the later is that your models will have lithium's
58 58 validation support, and can be better integrated with the custom adapters
59 59 provided by this library (such as for session management or for authorization.)
60 60
  61 + If you still want validation support but do not wish to extend `BaseEntity`
  62 + your models should implement the `li3_doctrine2\models\IModel` interface.
  63 +
61 64 Let us create a `User` model. Following doctrine's [basic mapping guide]
62 65 [doctrine-mapping-guide] we'll use annotations to define the properties, and
63 66 we will also include lithium validation rules (that's why we are choosing to
@@ -267,7 +270,7 @@ try {
267 270 }
268 271 ```
269 272
270   -In this last example, if lithium's form helper is bound to the record instance,
  273 +In this last example, if lithium's Form helper is bound to the record instance,
271 274 it will properly show validation errors. The following view code uses the
272 275 `$user` variable from the example above to bind the form to its validation
273 276 errors:
@@ -284,7 +287,7 @@ errors:
284 287 # Extensions #
285 288
286 289 li3\_doctrine2 also offers a set of extensions to integrate different parts
287   -of your application with your doctrine models.
  290 +of your lithium application with your doctrine models.
288 291
289 292 ## Session ##
290 293
@@ -292,7 +295,7 @@ Some installations require session data to be stored on a centralized location.
292 295 While there are powerful, storage-centric solutions for session storage, using
293 296 the database is still a popular choice.
294 297
295   -If you wish to store your session data on the database, using Doctrine models,
  298 +If you wish to store your session data on the database using Doctrine models,
296 299 then you will need to use li3\_doctrine2's session adapter. You start by
297 300 creating the model that the library will use to represent a session record.
298 301 For example, create a file named `Session.php` and place it in your
@@ -312,12 +315,22 @@ class Session extends \li3_doctrine2\models\BaseSession {
312 315 ```
313 316
314 317 We are extending from `BaseSession` since it provides us with the needed
315   -methods the session adapter will expect it to have. Remember to create the
316   -schema for this model.
  318 +methods the session adapter will expect it to have.
  319 +
  320 + If you still want to use the session adapter with your own Doctrine models,
  321 + but do not wish to extend `BaseSession`, then your session model should
  322 + implement the `li3_doctrine2\models\ISession` interface. You should also
  323 + note that if you do not pass the `entityManager` setting to the session
  324 + configuration, then your session model should implement a static method
  325 + named `getEntityManager()` that should return Doctrine's entity manager
  326 + for the session model. This method is not part of the interface signature
  327 + because it is optional, and is only used if you don't set the
  328 + `entityManager` session configuration setting.
317 329
318   -The final step is configuring the session. Edit your
319   -`app/config/bootstrap/session.php` file and use the following to configure the
320   -session:
  330 +
  331 +Once the model is created, create its database table using the doctrine
  332 +console. Finally, edit your `app/config/bootstrap/session.php` file and use the
  333 +following to configure the session:
321 334
322 335 ```php
323 336 Session::config(array(
@@ -353,11 +366,17 @@ Session::config(array(
353 366 Even when you could easily build your own authentication library, using
354 367 [lithium's implementation] [lithium-authentication] is highly recommended. If
355 368 you wish to go this route, you'll need li3\_doctrine's Form adapter for
356   -authentication, since it allows it to interact with Doctrine models.
357   -
358   -The model you wish to use should extend from `BaseEntity` (you could still make
359   -it work without extending from it if you implement the needed methods). We will
360   -use the `User` model we created earlier.
  369 +authentication, since it allows it to interact with Doctrine models. The model
  370 +you wish to use should extend from `BaseEntity`.
  371 +
  372 + If you still want to use the Form adapter but do not wish to extend
  373 + `BaseEntity`, then your model should implement the
  374 + `li3_doctrine2\models\IUser` interface. You should also note that if you do
  375 + not pass the `entityManager` setting to the auth configuration, then your
  376 + model should implement a static method named `getEntityManager()` that
  377 + should return Doctrine's entity manager for the model. This method is not
  378 + part of the interface signature because it is optional, and is only used if
  379 + you don't set the `entityManager` session configuration setting.
361 380
362 381 Once you have your model, you need to configure `Auth`. Edit your
363 382 `app/config/bootstrap/session.php` and add the following to the end:
@@ -379,8 +398,8 @@ Once this is done, you can use `Auth` as usual.
379 398 # Integrating libraries #
380 399
381 400 In this section I'll cover some of the doctrine extension libraries out there,
382   -and how to integrate them with li3\_doctrine2, and also how to let
383   -li3\_doctrine2 work with other lithium extensions that may be usable.
  401 +how to integrate them with li3\_doctrine2, and how to let li3\_doctrine2 work
  402 +with other lithium libraries that might be of use for your application.
384 403
385 404 ## DoctrineExtensions ##
386 405
@@ -396,10 +415,10 @@ switch to the core directory holding your lithium application, and do:
396 415 $ git submodule add https://github.com/l3pp4rd/DoctrineExtensions.git libraries/_source/DoctrineExtensions
397 416 ```
398 417
399   -Next you would use your connection configuration (in `app/config/connections.php`)
400   -to configure Doctrine with your desired behaviors. For example, if you wish
401   -to use Timestampable and Sluggable, you would first add the library in
402   -`app/config/libraries.php`:
  418 +You would then use your connection configuration (in
  419 +`app/config/connections.php`) to configure Doctrine with your desired behaviors.
  420 +For example, if you wish to use Timestampable and Sluggable, you would first add
  421 +the library in `app/config/libraries.php`:
403 422
404 423 ```php
405 424 Libraries::add('Gedmo', array(
@@ -407,7 +426,7 @@ Libraries::add('Gedmo', array(
407 426 ));
408 427 ```
409 428
410   -And then you would filter the `createEntityManager` method in the `Doctrine`
  429 +And then you would filter the `createEntityManager()` method in the `Doctrine`
411 430 datasource to add the behaviors. Edit your `app/config/connections.php` file
412 431 and add the following right below the connection definition:
413 432
@@ -467,7 +486,7 @@ class Li3PerfSQLLogger implements SQLLogger {
467 486 ?>
468 487 ```
469 488
470   -Now, we need to filter the `createEntityManager` method of the `Doctrine`
  489 +Now, we need to filter the `createEntityManager()` method of the `Doctrine`
471 490 datasource. Edit your `app/config/connections.php` file and add the following
472 491 right below the connection definition:
473 492
@@ -476,8 +495,8 @@ Connections::get('default')->applyFilter('createEntityManager',
476 495 function($self, $params, $chain) {
477 496 if (\lithium\core\Libraries::get('li3_perf')) {
478 497 $params['configuration']->setSQLLogger(
479   - new \app\libraries\_source\Li3PerfSQLLogger()
480   - );
  498 + new \app\libraries\_source\Li3PerfSQLLogger()
  499 + );
481 500 }
482 501 return $chain->next($self, $params, $chain);
483 502 }
@@ -485,8 +504,7 @@ Connections::get('default')->applyFilter('createEntityManager',
485 504 ```
486 505
487 506 Notice how we are only using the logger we created if the li3\_perf library
488   -is activated. If so, you should now see your queries on the performance
489   -toolbar.
  507 +is activated. You should now see your queries on the performance toolbar.
490 508
491 509 [lithium]: http://lithify.me
492 510 [doctrine2]: http://www.doctrine-project.org
5 extensions/adapter/security/auth/Form.php
@@ -80,6 +80,11 @@ public function __construct(array $config = array()) {
80 80 throw new ConfigException("The model {$config['model']} must define a getEntityManager() static method, or you must set the entityManager auth config variable");
81 81 }
82 82
  83 + $reflection = new \ReflectionClass($config['model']);
  84 + if (!$reflection->implementsInterface('li3_doctrine2\models\IUser')) {
  85 + throw new ConfigException("The model {$config['model']} must implement IUser");
  86 + }
  87 +
83 88 $entityManager = $config['entityManager'] ?:
84 89 call_user_func($config['model'] . '::getEntityManager');
85 90 if (!isset($entityManager) || !($entityManager instanceof EntityManager)) {
5 extensions/adapter/session/Entity.php
@@ -102,6 +102,11 @@ public function __construct(array $config = array()) {
102 102 throw new ConfigException("The session model {$this->config['model']} must define a getEntityManager() static method, or you must set the entityManager session config variable");
103 103 }
104 104
  105 + $reflection = new \ReflectionClass($this->config['model']);
  106 + if (!$reflection->implementsInterface('li3_doctrine2\models\ISession')) {
  107 + throw new ConfigException("The model {$this->config['model']} must implement ISession");
  108 + }
  109 +
105 110 $this->entityManager = $this->config['entityManager'] ?:
106 111 call_user_func($this->config['model'] . '::getEntityManager');
107 112 if (!isset($this->entityManager) || !($this->entityManager instanceof EntityManager)) {
17 models/BaseEntity.php
@@ -17,7 +17,7 @@
17 17 * This class can be used as the base class of your doctrine models, to allow
18 18 * for lithium validation to work on doctrine models.
19 19 */
20   -abstract class BaseEntity extends \lithium\data\entity\Record {
  20 +abstract class BaseEntity extends \lithium\data\Entity implements IModel, IUser {
21 21 /**
22 22 * Criteria for data validation.
23 23 *
@@ -65,6 +65,7 @@ public function __construct() {
65 65 * Get the entity manager linked to the connection defined in the property
66 66 * `$connectionName`
67 67 *
  68 + * @see IModel::getEntityManager()
68 69 * @return EntityManager entity manager
69 70 */
70 71 public static function getEntityManager() {
@@ -79,6 +80,7 @@ public static function getEntityManager() {
79 80 /**
80 81 * Get the repository for this model
81 82 *
  83 + * @see IModel::getRepository()
82 84 * @return EntityRepository entity repository
83 85 */
84 86 public static function getRepository() {
@@ -123,11 +125,9 @@ public function onPreUpdate(PreUpdateEventArgs $eventArgs) {
123 125 /**
124 126 * Perform validation
125 127 *
126   - * @see lithium\data\Model::validates()
  128 + * @see IModel::validates()
127 129 * @param array $options Options
128   - * @return boolean Returns `true` if all validation rules on all fields succeed, otherwise
129   - * `false`. After validation, the messages for any validation failures
130   - * are accessible through the `errors()` method.
  130 + * @return boolean Success
131 131 */
132 132 public function validates(array $options = array()) {
133 133 $defaults = array(
@@ -153,6 +153,7 @@ public function validates(array $options = array()) {
153 153 * $record->set(array('title' => 'Lorem Ipsum', 'value' => 42));
154 154 * }}}
155 155 *
  156 + * @see IModel::validates()
156 157 * @param array $data An associative array of fields and values to assign to this instance.
157 158 */
158 159 public function set(array $data) {
@@ -177,6 +178,7 @@ public function set(array $data) {
177 178 * Access the data fields of the record. Can also access a $named field.
178 179 * Only returns data for fields that have a getter method defined.
179 180 *
  181 + * @see IModel::validates()
180 182 * @param string $name Optionally included field name.
181 183 * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
182 184 */
@@ -188,6 +190,11 @@ public function data($name = null) {
188 190 return $data;
189 191 }
190 192
  193 + /**
  194 + * Get the entity fields
  195 + *
  196 + * @return array
  197 + */
191 198 protected function _getEntityFields() {
192 199 static $entityFields;
193 200 if (!isset($entityFields)) {
33 models/BaseSession.php
@@ -18,7 +18,23 @@
18 18 * Base class for session models to use with the doctrine session adapter. You
19 19 * can extend from this class to provide your own session model.
20 20 */
21   -abstract class BaseSession extends BaseEntity {
  21 +abstract class BaseSession implements ISession {
  22 + /**
  23 + * Class dependencies.
  24 + *
  25 + * @var array
  26 + */
  27 + protected static $_classes = array(
  28 + 'connections' => 'lithium\data\Connections'
  29 + );
  30 +
  31 + /**
  32 + * Connection name used for persisting / loading this record
  33 + *
  34 + * @var string
  35 + */
  36 + protected static $connectionName = 'default';
  37 +
22 38 /**
23 39 * @Id
24 40 * @Column(type="string")
@@ -36,12 +52,19 @@
36 52 protected $expires;
37 53
38 54 /**
39   - * Get ID
  55 + * Get the entity manager linked to the connection defined in the property
  56 + * `$connectionName`
40 57 *
41   - * @return string
  58 + * @see IModel::getEntityManager()
  59 + * @return EntityManager entity manager
42 60 */
43   - public function getId() {
44   - return $this->id;
  61 + public static function getEntityManager() {
  62 + static $entityManager;
  63 + if (!isset($entityManager)) {
  64 + $connections = static::$_classes['connections'];
  65 + $entityManager = $connections::get(static::$connectionName)->getEntityManager();
  66 + }
  67 + return $entityManager;
45 68 }
46 69
47 70 /**
87 models/IModel.php
... ... @@ -0,0 +1,87 @@
  1 +<?php
  2 +/**
  3 + * Lithium: the most rad php framework
  4 + *
  5 + * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
  6 + * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7 + */
  8 +
  9 +namespace li3_doctrine2\models;
  10 +
  11 +/**
  12 + * This interface defines the basic behavior a Doctrine model should implement
  13 + * to be able to use Lithium's validation & form system.
  14 + */
  15 +interface IModel {
  16 + /**
  17 + * Get the entity manager for this model
  18 + *
  19 + * @return EntityManager entity manager
  20 + */
  21 + public static function getEntityManager();
  22 +
  23 + /**
  24 + * Get the repository for this model
  25 + *
  26 + * @return EntityRepository entity repository
  27 + */
  28 + public static function getRepository();
  29 +
  30 + /**
  31 + * Returns the model which this entity is bound to.
  32 + * Usually this would be the fully qualified class name this method belongs
  33 + * to.
  34 + *
  35 + * @return string The fully qualified model class name.
  36 + */
  37 + public function model();
  38 +
  39 + /**
  40 + * A flag indicating whether or not this record exists.
  41 + *
  42 + * @return boolean `True` if the record was `read` from the data-source, or has been `create`d
  43 + * and `save`d. Otherwise `false`.
  44 + */
  45 + public function exists();
  46 +
  47 + /**
  48 + * Allows several properties to be assigned at once, i.e.:
  49 + * {{{
  50 + * $record->set(array('title' => 'Lorem Ipsum', 'value' => 42));
  51 + * }}}
  52 + *
  53 + * @param array $data An associative array of fields and values to assign to this instance.
  54 + */
  55 + public function set(array $data);
  56 +
  57 + /**
  58 + * Access the data fields of the record. Can also access a $named field.
  59 + * Only returns data for fields that have a getter method defined.
  60 + *
  61 + * @param string $name Optionally included field name.
  62 + * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
  63 + */
  64 + public function data($name = null);
  65 +
  66 + /**
  67 + * Perform validation
  68 + *
  69 + * @see lithium\data\Model::validates()
  70 + * @param array $options Options
  71 + * @return boolean Returns `true` if all validation rules on all fields succeed, otherwise
  72 + * `false`. After validation, the messages for any validation failures
  73 + * are accessible through the `errors()` method.
  74 + */
  75 + public function validates(array $options = array());
  76 +
  77 + /**
  78 + * Access the errors of the record.
  79 + *
  80 + * @param array|string $field If an array, overwrites `$this->_errors`. If a string, and
  81 + * `$value` is not `null`, sets the corresponding key in `$this->_errors` to `$value`.
  82 + * @param string $value Value to set.
  83 + * @return mixed Either the `$this->_errors` array, or single value from it.
  84 + */
  85 + public function errors($field = null, $value = null);
  86 +}
  87 +?>
44 models/ISession.php
... ... @@ -0,0 +1,44 @@
  1 +<?php
  2 +/**
  3 + * Lithium: the most rad php framework
  4 + *
  5 + * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
  6 + * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7 + */
  8 +
  9 +namespace li3_doctrine2\models;
  10 +
  11 +/**
  12 + * This interface defines the basic behavior a Doctrine model should implement
  13 + * to be able to be used as the model for li3_doctrine2's session adapter.
  14 + */
  15 +interface ISession {
  16 + /**
  17 + * Set ID
  18 + *
  19 + * @param string $id ID
  20 + */
  21 + public function setId($id);
  22 +
  23 + /**
  24 + * Get data
  25 + *
  26 + * @return string
  27 + */
  28 + public function getData();
  29 +
  30 + /**
  31 + * Set data
  32 + *
  33 + * @param string $data Data
  34 + */
  35 + public function setData($data);
  36 +
  37 + /**
  38 + * Set expiration date
  39 + *
  40 + * @param DateTime $expires Expiration date
  41 + */
  42 + public function setExpires(\DateTime $expires);
  43 +}
  44 +?>
25 models/IUser.php
... ... @@ -0,0 +1,25 @@
  1 +<?php
  2 +/**
  3 + * Lithium: the most rad php framework
  4 + *
  5 + * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
  6 + * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7 + */
  8 +
  9 +namespace li3_doctrine2\models;
  10 +
  11 +/**
  12 + * This interface defines the basic behavior a Doctrine model should implement
  13 + * to be able to be used as the model for the Form auth session adapter.
  14 + */
  15 +interface IUser {
  16 + /**
  17 + * Access the data fields of the record. Can also access a $named field.
  18 + * Only returns data for fields that have a getter method defined.
  19 + *
  20 + * @param string $name Optionally included field name.
  21 + * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
  22 + */
  23 + public function data($name = null);
  24 +}
  25 +?>

0 comments on commit d8eaf7b

Please sign in to comment.
Something went wrong with that request. Please try again.