Permalink
Browse files

Refactoring lazy initialization for model metadata

  • Loading branch information...
1 parent f4c5bd2 commit 26d230731f2fa7abcccb549b3a61dbbb588afbbc @jails jails committed Sep 21, 2012
Showing with 94 additions and 25 deletions.
  1. +23 −25 data/Model.php
  2. +71 −0 tests/cases/data/ModelTest.php
View
@@ -309,7 +309,14 @@ class Model extends \lithium\core\StaticObject {
* @see lithium\data\Model::config()
* @var array
*/
- protected static $_autoConfig = array('meta', 'finders', 'query', 'schema', 'classes');
+ protected static $_autoConfig = array(
+ 'meta',
+ 'finders',
+ 'query',
+ 'schema',
+ 'classes',
+ 'initializers'
+ );
/**
* Configures the model for use. This method will set the `Model::$_schema`, `Model::$_meta`,
@@ -367,6 +374,7 @@ protected static function _init($class) {
$schema = array();
$source = array();
$classes = static::$_classes;
+ $initializers = array();
foreach (static::_parents() as $parent) {
$parentConfig = get_class_vars($parent);
@@ -390,26 +398,25 @@ protected static function _init($class) {
$source = (($conn) ? $conn->configureClass($class) : array()) + $source;
}
static::$_classes = $classes;
- $name = static::_name();
- $local = compact('class', 'name') + $self->_meta;
+ $local = compact('class') + $self->_meta;
$self->_meta = ($local + $source['meta'] + $meta);
$meta =& $self->_meta;
if (is_object($schema)) {
$schema = $schema->fields();
}
$self->_initializers += array(
- 'source' => function() use (&$meta) {
- return Inflector::tableize($meta['name']);
+ 'name' => function($self) {
+ return basename(str_replace('\\', '/', $self));
+ },
+ 'source' => function($self) {
+ return Inflector::tableize($self::meta('name'));
},
- 'title' => function() use (&$meta) {
+ 'title' => function($self) {
$titleKeys = array('title', 'name');
-
- if (isset($meta['key'])) {
- $titleKeys = array_merge($titleKeys, (array) $meta['key']);
- }
- return $meta['class']::hasField($titleKeys);
+ $titleKeys = array_merge($titleKeys, (array) $self::meta('key'));
+ return $self::hasField($titleKeys);
}
);
@@ -594,14 +601,15 @@ protected function _getMetaKey($key = null) {
if (!$key) {
$all = array_keys($this->_initializers);
$call = array(&$this, '_getMetaKey');
- return array_combine($all, array_map($call, $all)) + $this->_meta;
+ return $all ? array_combine($all, array_map($call, $all)) + $this->_meta : $this->_meta;
}
if (isset($this->_meta[$key])) {
return $this->_meta[$key];
}
if (isset($this->_initializers[$key]) && $initializer = $this->_initializers[$key]) {
- return ($this->_meta[$key] = $initializer($this->_meta, $this->_schema));
+ unset($this->_initializers[$key]);
+ return ($this->_meta[$key] = $initializer(get_called_class()));
}
}
@@ -753,10 +761,10 @@ public static function bind($type, $name, array $config = array()) {
*/
public static function schema($field = null) {
$self = static::_object();
- $source = $self::meta('source');
if (!is_object($self->_schema)) {
- $self->_schema = static::connection()->describe($source, $self->_schema, $self->_meta);
+ $source = $self::meta('source');
+ $self->_schema = static::connection()->describe($source, $self->_schema, static::meta());
if (!is_object($self->_schema)) {
$class = get_called_class();
@@ -1138,16 +1146,6 @@ public static function &connection() {
}
/**
- * Gets just the class name portion of a fully-name-spaced class name, i.e.
- * `app\models\Posts::_name()` returns `'Posts'`.
- *
- * @return string
- */
- protected static function _name() {
- return basename(str_replace('\\', '/', get_called_class()));
- }
-
- /**
* Wraps `StaticObject::applyFilter()` to account for object instances.
*
* @see lithium\core\StaticObject::applyFilter()
@@ -9,6 +9,7 @@
namespace lithium\tests\cases\data;
use stdClass;
+use lithium\util\Inflector;
use lithium\data\Model;
use lithium\data\Entity;
use lithium\data\Schema;
@@ -801,6 +802,76 @@ public function testLazyLoad() {
$this->expectException($exception);
MockPost::relations('Unexisting');
}
+
+ public function testLazyMetadataInit() {
+ MockPost::config(array(
+ 'schema' => new Schema(array(
+ 'fields' => array(
+ 'id' => array('type' => 'integer'),
+ 'name' => array('type' => 'string'),
+ 'label' => array('type' => 'string')
+ )
+ ))
+ ));
+
+ $this->assertIdentical('mock_posts', MockPost::meta('source'));
+ $this->assertIdentical('name', MockPost::meta('title'));
+ $this->assertIdentical(null, MockPost::meta('unexisting'));
+
+ $config = array(
+ 'schema' => new Schema(array(
+ 'fields' => array(
+ 'id' => array('type' => 'integer'),
+ 'name' => array('type' => 'string'),
+ 'label' => array('type' => 'string')
+ )
+ )
+ ),
+ 'initializers' => array(
+ 'source' => function($self) {
+ return Inflector::tableize($self::meta('name'));
+ },
+ 'name' => function($self) {
+ return Inflector::singularize('CoolPosts');
+ },
+ 'title' => function($self) {
+ static $i = 1;
+ return 'label' . $i++;
+ }
+ )
+ );
+ MockPost::reset();
+ MockPost::config($config);
+ $this->assertIdentical('cool_posts', MockPost::meta('source'));
+ $this->assertIdentical('label1', MockPost::meta('title'));
+ $this->assertFalse('label2' == MockPost::meta('title'));
+ $this->assertIdentical('label1', MockPost::meta('title'));
+ $meta = MockPost::meta();
+ $this->assertIdentical('label1', $meta['title']);
+ $this->assertIdentical('CoolPost', MockPost::meta('name'));
+
+ MockPost::reset();
+ unset($config['initializers']['title']);
+ $config['initializers']['source'] = function($self) {
+ return Inflector::underscore($self::meta('name'));
+ };
+ MockPost::config($config);
+ $this->assertIdentical('cool_post', MockPost::meta('source'));
+ $this->assertIdentical('name', MockPost::meta('title'));
+ $this->assertIdentical('CoolPost', MockPost::meta('name'));
+
+ MockPost::reset();
+ MockPost::config($config);
+ $expected = array (
+ 'class' => 'lithium\\tests\\mocks\\data\\MockPost',
+ 'connection' => false,
+ 'key' => 'id',
+ 'name' => 'CoolPost',
+ 'title' => 'name',
+ 'source' => 'cool_post'
+ );
+ $this->assertEqual($expected, MockPost::meta());
+ }
}
?>

0 comments on commit 26d2307

Please sign in to comment.