Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Using interfaces to give an alternative to extending from BaseEntity …

…and/or BaseSession
  • Loading branch information...
commit d8eaf7babfe69ddea4973586d451a5a7e4011171 1 parent 09d9ad9
@mariano authored
View
68 README.md
@@ -58,6 +58,9 @@ advantage of choosing the later is that your models will have lithium's
validation support, and can be better integrated with the custom adapters
provided by this library (such as for session management or for authorization.)
+ If you still want validation support but do not wish to extend `BaseEntity`
+ your models should implement the `li3_doctrine2\models\IModel` interface.
+
Let us create a `User` model. Following doctrine's [basic mapping guide]
[doctrine-mapping-guide] we'll use annotations to define the properties, and
we will also include lithium validation rules (that's why we are choosing to
@@ -267,7 +270,7 @@ try {
}
```
-In this last example, if lithium's form helper is bound to the record instance,
+In this last example, if lithium's Form helper is bound to the record instance,
it will properly show validation errors. The following view code uses the
`$user` variable from the example above to bind the form to its validation
errors:
@@ -284,7 +287,7 @@ errors:
# Extensions #
li3\_doctrine2 also offers a set of extensions to integrate different parts
-of your application with your doctrine models.
+of your lithium application with your doctrine models.
## Session ##
@@ -292,7 +295,7 @@ Some installations require session data to be stored on a centralized location.
While there are powerful, storage-centric solutions for session storage, using
the database is still a popular choice.
-If you wish to store your session data on the database, using Doctrine models,
+If you wish to store your session data on the database using Doctrine models,
then you will need to use li3\_doctrine2's session adapter. You start by
creating the model that the library will use to represent a session record.
For example, create a file named `Session.php` and place it in your
@@ -312,12 +315,22 @@ class Session extends \li3_doctrine2\models\BaseSession {
```
We are extending from `BaseSession` since it provides us with the needed
-methods the session adapter will expect it to have. Remember to create the
-schema for this model.
+methods the session adapter will expect it to have.
+
+ If you still want to use the session adapter with your own Doctrine models,
+ but do not wish to extend `BaseSession`, then your session model should
+ implement the `li3_doctrine2\models\ISession` interface. You should also
+ note that if you do not pass the `entityManager` setting to the session
+ configuration, then your session model should implement a static method
+ named `getEntityManager()` that should return Doctrine's entity manager
+ for the session model. This method is not part of the interface signature
+ because it is optional, and is only used if you don't set the
+ `entityManager` session configuration setting.
-The final step is configuring the session. Edit your
-`app/config/bootstrap/session.php` file and use the following to configure the
-session:
+
+Once the model is created, create its database table using the doctrine
+console. Finally, edit your `app/config/bootstrap/session.php` file and use the
+following to configure the session:
```php
Session::config(array(
@@ -353,11 +366,17 @@ Session::config(array(
Even when you could easily build your own authentication library, using
[lithium's implementation] [lithium-authentication] is highly recommended. If
you wish to go this route, you'll need li3\_doctrine's Form adapter for
-authentication, since it allows it to interact with Doctrine models.
-
-The model you wish to use should extend from `BaseEntity` (you could still make
-it work without extending from it if you implement the needed methods). We will
-use the `User` model we created earlier.
+authentication, since it allows it to interact with Doctrine models. The model
+you wish to use should extend from `BaseEntity`.
+
+ If you still want to use the Form adapter but do not wish to extend
+ `BaseEntity`, then your model should implement the
+ `li3_doctrine2\models\IUser` interface. You should also note that if you do
+ not pass the `entityManager` setting to the auth configuration, then your
+ model should implement a static method named `getEntityManager()` that
+ should return Doctrine's entity manager for the model. This method is not
+ part of the interface signature because it is optional, and is only used if
+ you don't set the `entityManager` session configuration setting.
Once you have your model, you need to configure `Auth`. Edit your
`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.
# Integrating libraries #
In this section I'll cover some of the doctrine extension libraries out there,
-and how to integrate them with li3\_doctrine2, and also how to let
-li3\_doctrine2 work with other lithium extensions that may be usable.
+how to integrate them with li3\_doctrine2, and how to let li3\_doctrine2 work
+with other lithium libraries that might be of use for your application.
## DoctrineExtensions ##
@@ -396,10 +415,10 @@ switch to the core directory holding your lithium application, and do:
$ git submodule add https://github.com/l3pp4rd/DoctrineExtensions.git libraries/_source/DoctrineExtensions
```
-Next you would use your connection configuration (in `app/config/connections.php`)
-to configure Doctrine with your desired behaviors. For example, if you wish
-to use Timestampable and Sluggable, you would first add the library in
-`app/config/libraries.php`:
+You would then use your connection configuration (in
+`app/config/connections.php`) to configure Doctrine with your desired behaviors.
+For example, if you wish to use Timestampable and Sluggable, you would first add
+the library in `app/config/libraries.php`:
```php
Libraries::add('Gedmo', array(
@@ -407,7 +426,7 @@ Libraries::add('Gedmo', array(
));
```
-And then you would filter the `createEntityManager` method in the `Doctrine`
+And then you would filter the `createEntityManager()` method in the `Doctrine`
datasource to add the behaviors. Edit your `app/config/connections.php` file
and add the following right below the connection definition:
@@ -467,7 +486,7 @@ class Li3PerfSQLLogger implements SQLLogger {
?>
```
-Now, we need to filter the `createEntityManager` method of the `Doctrine`
+Now, we need to filter the `createEntityManager()` method of the `Doctrine`
datasource. Edit your `app/config/connections.php` file and add the following
right below the connection definition:
@@ -476,8 +495,8 @@ Connections::get('default')->applyFilter('createEntityManager',
function($self, $params, $chain) {
if (\lithium\core\Libraries::get('li3_perf')) {
$params['configuration']->setSQLLogger(
- new \app\libraries\_source\Li3PerfSQLLogger()
- );
+ new \app\libraries\_source\Li3PerfSQLLogger()
+ );
}
return $chain->next($self, $params, $chain);
}
@@ -485,8 +504,7 @@ Connections::get('default')->applyFilter('createEntityManager',
```
Notice how we are only using the logger we created if the li3\_perf library
-is activated. If so, you should now see your queries on the performance
-toolbar.
+is activated. You should now see your queries on the performance toolbar.
[lithium]: http://lithify.me
[doctrine2]: http://www.doctrine-project.org
View
5 extensions/adapter/security/auth/Form.php
@@ -80,6 +80,11 @@ public function __construct(array $config = array()) {
throw new ConfigException("The model {$config['model']} must define a getEntityManager() static method, or you must set the entityManager auth config variable");
}
+ $reflection = new \ReflectionClass($config['model']);
+ if (!$reflection->implementsInterface('li3_doctrine2\models\IUser')) {
+ throw new ConfigException("The model {$config['model']} must implement IUser");
+ }
+
$entityManager = $config['entityManager'] ?:
call_user_func($config['model'] . '::getEntityManager');
if (!isset($entityManager) || !($entityManager instanceof EntityManager)) {
View
5 extensions/adapter/session/Entity.php
@@ -102,6 +102,11 @@ public function __construct(array $config = array()) {
throw new ConfigException("The session model {$this->config['model']} must define a getEntityManager() static method, or you must set the entityManager session config variable");
}
+ $reflection = new \ReflectionClass($this->config['model']);
+ if (!$reflection->implementsInterface('li3_doctrine2\models\ISession')) {
+ throw new ConfigException("The model {$this->config['model']} must implement ISession");
+ }
+
$this->entityManager = $this->config['entityManager'] ?:
call_user_func($this->config['model'] . '::getEntityManager');
if (!isset($this->entityManager) || !($this->entityManager instanceof EntityManager)) {
View
17 models/BaseEntity.php
@@ -17,7 +17,7 @@
* This class can be used as the base class of your doctrine models, to allow
* for lithium validation to work on doctrine models.
*/
-abstract class BaseEntity extends \lithium\data\entity\Record {
+abstract class BaseEntity extends \lithium\data\Entity implements IModel, IUser {
/**
* Criteria for data validation.
*
@@ -65,6 +65,7 @@ public function __construct() {
* Get the entity manager linked to the connection defined in the property
* `$connectionName`
*
+ * @see IModel::getEntityManager()
* @return EntityManager entity manager
*/
public static function getEntityManager() {
@@ -79,6 +80,7 @@ public static function getEntityManager() {
/**
* Get the repository for this model
*
+ * @see IModel::getRepository()
* @return EntityRepository entity repository
*/
public static function getRepository() {
@@ -123,11 +125,9 @@ public function onPreUpdate(PreUpdateEventArgs $eventArgs) {
/**
* Perform validation
*
- * @see lithium\data\Model::validates()
+ * @see IModel::validates()
* @param array $options Options
- * @return boolean Returns `true` if all validation rules on all fields succeed, otherwise
- * `false`. After validation, the messages for any validation failures
- * are accessible through the `errors()` method.
+ * @return boolean Success
*/
public function validates(array $options = array()) {
$defaults = array(
@@ -153,6 +153,7 @@ public function validates(array $options = array()) {
* $record->set(array('title' => 'Lorem Ipsum', 'value' => 42));
* }}}
*
+ * @see IModel::validates()
* @param array $data An associative array of fields and values to assign to this instance.
*/
public function set(array $data) {
@@ -177,6 +178,7 @@ public function set(array $data) {
* Access the data fields of the record. Can also access a $named field.
* Only returns data for fields that have a getter method defined.
*
+ * @see IModel::validates()
* @param string $name Optionally included field name.
* @return mixed Entire data array if $name is empty, otherwise the value from the named field.
*/
@@ -188,6 +190,11 @@ public function data($name = null) {
return $data;
}
+ /**
+ * Get the entity fields
+ *
+ * @return array
+ */
protected function _getEntityFields() {
static $entityFields;
if (!isset($entityFields)) {
View
33 models/BaseSession.php
@@ -18,7 +18,23 @@
* Base class for session models to use with the doctrine session adapter. You
* can extend from this class to provide your own session model.
*/
-abstract class BaseSession extends BaseEntity {
+abstract class BaseSession implements ISession {
+ /**
+ * Class dependencies.
+ *
+ * @var array
+ */
+ protected static $_classes = array(
+ 'connections' => 'lithium\data\Connections'
+ );
+
+ /**
+ * Connection name used for persisting / loading this record
+ *
+ * @var string
+ */
+ protected static $connectionName = 'default';
+
/**
* @Id
* @Column(type="string")
@@ -36,12 +52,19 @@
protected $expires;
/**
- * Get ID
+ * Get the entity manager linked to the connection defined in the property
+ * `$connectionName`
*
- * @return string
+ * @see IModel::getEntityManager()
+ * @return EntityManager entity manager
*/
- public function getId() {
- return $this->id;
+ public static function getEntityManager() {
+ static $entityManager;
+ if (!isset($entityManager)) {
+ $connections = static::$_classes['connections'];
+ $entityManager = $connections::get(static::$connectionName)->getEntityManager();
+ }
+ return $entityManager;
}
/**
View
87 models/IModel.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_doctrine2\models;
+
+/**
+ * This interface defines the basic behavior a Doctrine model should implement
+ * to be able to use Lithium's validation & form system.
+ */
+interface IModel {
+ /**
+ * Get the entity manager for this model
+ *
+ * @return EntityManager entity manager
+ */
+ public static function getEntityManager();
+
+ /**
+ * Get the repository for this model
+ *
+ * @return EntityRepository entity repository
+ */
+ public static function getRepository();
+
+ /**
+ * Returns the model which this entity is bound to.
+ * Usually this would be the fully qualified class name this method belongs
+ * to.
+ *
+ * @return string The fully qualified model class name.
+ */
+ public function model();
+
+ /**
+ * A flag indicating whether or not this record exists.
+ *
+ * @return boolean `True` if the record was `read` from the data-source, or has been `create`d
+ * and `save`d. Otherwise `false`.
+ */
+ public function exists();
+
+ /**
+ * Allows several properties to be assigned at once, i.e.:
+ * {{{
+ * $record->set(array('title' => 'Lorem Ipsum', 'value' => 42));
+ * }}}
+ *
+ * @param array $data An associative array of fields and values to assign to this instance.
+ */
+ public function set(array $data);
+
+ /**
+ * Access the data fields of the record. Can also access a $named field.
+ * Only returns data for fields that have a getter method defined.
+ *
+ * @param string $name Optionally included field name.
+ * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
+ */
+ public function data($name = null);
+
+ /**
+ * Perform validation
+ *
+ * @see lithium\data\Model::validates()
+ * @param array $options Options
+ * @return boolean Returns `true` if all validation rules on all fields succeed, otherwise
+ * `false`. After validation, the messages for any validation failures
+ * are accessible through the `errors()` method.
+ */
+ public function validates(array $options = array());
+
+ /**
+ * Access the errors of the record.
+ *
+ * @param array|string $field If an array, overwrites `$this->_errors`. If a string, and
+ * `$value` is not `null`, sets the corresponding key in `$this->_errors` to `$value`.
+ * @param string $value Value to set.
+ * @return mixed Either the `$this->_errors` array, or single value from it.
+ */
+ public function errors($field = null, $value = null);
+}
+?>
View
44 models/ISession.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_doctrine2\models;
+
+/**
+ * This interface defines the basic behavior a Doctrine model should implement
+ * to be able to be used as the model for li3_doctrine2's session adapter.
+ */
+interface ISession {
+ /**
+ * Set ID
+ *
+ * @param string $id ID
+ */
+ public function setId($id);
+
+ /**
+ * Get data
+ *
+ * @return string
+ */
+ public function getData();
+
+ /**
+ * Set data
+ *
+ * @param string $data Data
+ */
+ public function setData($data);
+
+ /**
+ * Set expiration date
+ *
+ * @param DateTime $expires Expiration date
+ */
+ public function setExpires(\DateTime $expires);
+}
+?>
View
25 models/IUser.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2012, Mariano Iglesias (http://marianoiglesias.com.ar)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_doctrine2\models;
+
+/**
+ * This interface defines the basic behavior a Doctrine model should implement
+ * to be able to be used as the model for the Form auth session adapter.
+ */
+interface IUser {
+ /**
+ * Access the data fields of the record. Can also access a $named field.
+ * Only returns data for fields that have a getter method defined.
+ *
+ * @param string $name Optionally included field name.
+ * @return mixed Entire data array if $name is empty, otherwise the value from the named field.
+ */
+ public function data($name = null);
+}
+?>
Please sign in to comment.
Something went wrong with that request. Please try again.