Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Beginning refactoring of... stuff.

  • Loading branch information...
commit b51972c0556cdc9d53551824b8adcd54ea8568e1 1 parent 6524ad6
@nateabele nateabele authored
View
8 libraries/lithium/data/Connections.php
@@ -140,16 +140,16 @@ public static function add($name, array $config = array()) {
* @return mixed A configured instance of the connection, or an array of the configuration used.
*/
public static function get($name = null, array $options = array()) {
- static $nullAdapter;
+ static $mockAdapter;
$defaults = array('config' => false, 'autoCreate' => true);
$options += $defaults;
if ($name === false) {
- if (!$nullAdapter) {
+ if (!$mockAdapter) {
$class = Libraries::locate('data.source', 'Mock');
- $nullAdapter = new $class();
+ $mockAdapter = new $class();
}
- return $nullAdapter;
+ return $mockAdapter;
}
if (!$name) {
View
8 libraries/lithium/data/Entity.php
@@ -156,7 +156,13 @@ public function &__get($name) {
* @param string $value Property value.
* @return mixed Result.
*/
- public function __set($name, $value) {
+ public function __set($name, $value = null) {
+ if (is_array($name) && !$value) {
+ foreach ($name as $key => $value) {
+ $this->__set($key, $value);
+ }
+ return;
+ }
$this->_modified[$name] = true;
$this->_data[$name] = $value;
}
View
60 libraries/lithium/data/Model.php
@@ -753,14 +753,14 @@ public function validates($entity, array $options = array()) {
*/
public function delete($entity, array $options = array()) {
$self = static::_object();
- $_class = $self->_classes['query'];
$params = compact('entity', 'options');
- return static::_filter(__FUNCTION__, $params, function($self, $params) use ($_class) {
- $type = 'delete';
- $entity = $params['entity'];
- $options = $params['options'] + array('model' => $self) + compact('type', 'entity');
- return $self::connection()->delete(new $_class($options), $options);
+ return static::_filter(__FUNCTION__, $params, function($self, $params) {
+ $options = $params + $params['options'] + array('model' => $self, 'type' => 'delete');
+ unset($options['options']);
+
+ $query = $self::invokeMethod('_instance', array('query', $options));
+ return $self::connection()->delete($query, $options);
});
}
@@ -780,13 +780,15 @@ public function delete($entity, array $options = array()) {
*/
public static function update($data, $conditions = array(), array $options = array()) {
$self = static::_object();
- $_class = $self->_classes['query'];
$params = compact('data', 'conditions', 'options');
- return static::_filter(__FUNCTION__, $params, function($self, $params) use ($_class) {
+ return static::_filter(__FUNCTION__, $params, function($self, $params) {
$options = $params + $params['options'] + array('model' => $self, 'type' => 'update');
unset($options['options']);
- return $self::connection()->update(new $_class($options), $options);
+ var_export($options);
+
+ $query = $self::invokeMethod('_instance', array('query', $options));
+ return $self::connection()->update($query, $options);
});
}
@@ -805,25 +807,15 @@ public static function update($data, $conditions = array(), array $options = arr
*/
public static function remove($conditions = array(), array $options = array()) {
$self = static::_object();
- $_class = $self->_classes['query'];
$params = compact('conditions', 'options');
- return static::_filter(__FUNCTION__, $params, function($self, $params) use ($_class) {
+ return static::_filter(__FUNCTION__, $params, function($self, $params) {
$options = $params['options'] + $params + array('model' => $self, 'type' => 'delete');
unset($options['options']);
- return $self::connection()->delete(new $_class($options), $options);
- });
- }
- /**
- * Gets just the class name portion of a fully-name-spaced class name, i.e.
- * `app\models\Post::_name()` returns `'Post'`.
- *
- * @return string
- */
- protected static function _name() {
- static $name;
- return $name ?: $name = join('', array_slice(explode("\\", get_called_class()), -1));
+ $query = $self::invokeMethod('_instance', array('query', $options));
+ return $self::connection()->delete($query, $options);
+ });
}
/**
@@ -848,10 +840,14 @@ public static function &connection() {
}
/**
- * @deprecated
+ * Gets just the class name portion of a fully-name-spaced class name, i.e.
+ * `app\models\Post::_name()` returns `'Post'`.
+ *
+ * @return string
*/
- protected static function &_connection() {
- return static::connection();
+ protected static function _name() {
+ static $name;
+ return $name ?: $name = join('', array_slice(explode("\\", get_called_class()), -1));
}
/**
@@ -979,12 +975,20 @@ protected static function _findFilters() {
} else {
$options = $params['options'];
}
- $options += compact('classes', 'model');
- $query = new $classes['query'](array('type' => 'read') + $options);
+ $options += array('type' => 'read') + compact('model');
+ $query = $self::invokeMethod('_instance', array('query', $options));
return $self::connection()->calculation('count', $query, $options);
}
);
}
+
+ /**
+ * @deprecated
+ * @see lithium\data\Model::connection()
+ */
+ protected static function &_connection() {
+ return static::connection();
+ }
}
?>
View
74 libraries/lithium/data/collection/DocumentSet.php
@@ -8,21 +8,11 @@
namespace lithium\data\collection;
-use \Iterator;
-use \lithium\data\Source;
-use \lithium\util\Collection;
+use lithium\data\Source;
class DocumentSet extends \lithium\data\Collection {
- /**
- * The class dependencies for `Document`.
- *
- * @var array
- */
- protected $_classes = array(
- 'entity' => 'lithium\data\entity\Document',
- 'set' => __CLASS__
- );
+ protected $_marked = array();
/**
* PHP magic method used when setting properties on the `Document` instance, i.e.
@@ -50,7 +40,7 @@ public function __set($name, $value = null) {
$key = $path[$i];
$next = $current->__get($key);
- if (!$next instanceof Document) {
+ if (!is_object($next)) {
$next = $current->_data[$key] = $this->_relation('set', $key, array());
}
$current = $next;
@@ -58,7 +48,7 @@ public function __set($name, $value = null) {
$current->__set(end($path), $value);
}
- if ($this->_isComplexType($value) && !$value instanceof Iterator) {
+ if (is_array($value)) {
$value = $this->_relation('set', $name, $value);
}
$this->_data[$name] = $value;
@@ -114,19 +104,18 @@ public function set($values) {
public function offsetGet($offset) {
$data = null;
$null = null;
+ $model = $this->_model;
if (!isset($this->_data[$offset]) && !$data = $this->_populate(null, $offset)) {
return $null;
}
- $data = $data ?: $this->_data[$offset];
-
- if (is_a($data, $this->_classes['entity'])) {
- return $data;
+ if (isset($this->_marked[$offset])) {
+ return $this->_data[$offset];
}
-
- if ($this->_isComplexType($data)) {
+ if (is_array($this->_data[$offset])) {
$this->_data[$offset] = $this->_relation('entity', $offset, $this->_data[$offset]);
}
+ $this->_marked[$offset] = true;
return $this->_data[$offset];
}
@@ -136,17 +125,16 @@ public function offsetGet($offset) {
* @return object Returns the first `Document` object instance in the collection.
*/
public function rewind() {
- $data = parent::rewind();
+ $data = parent::rewind() ?: $this->_populate();
$key = key($this->_data);
- if (is_a($data, $this->_classes['entity'])) {
+ if (is_object($data)) {
return $data;
}
- if ($this->_isComplexType($data)) {
- $this->_data[$key] = $this->_relation('entity', $key, $this->_data[$key]);
+ if (isset($this->_data[$key])) {
+ return $this->offsetGet($key);
}
- return isset($this->_data[$key]) ? $this->_data[$key] : null;
}
public function current() {
@@ -156,7 +144,7 @@ public function current() {
/**
* Returns the next document in the set, and advances the object's internal pointer. If the end
* of the set is reached, a new document will be fetched from the data source connection handle
- * (`$_handle`). If no more documents can be fetched, returns `null`.
+ * If no more documents can be fetched, returns `null`.
*
* @return object|null Returns the next document in the set, or `null`, if no more documents are
* available.
@@ -181,32 +169,6 @@ public function export(Source $dataSource, array $options = array()) {
}
/**
- * Used by getter and setter methods to determine whether the value of data is a complex type
- * that should be given its own sub-object withih the `Document`.
- *
- * @param mixed $data The data to be tested. This test is used to determine if `$data` should be
- * wrapped in an instance of `Document`.
- * @return boolean Returns `false` if the value of `$data` is a scalar type or a one-dimensional
- * array of scalar values, otherwise returns `true`.
- */
- protected function _isComplexType($data) {
- if (is_object($data) && (array) $data === array()) {
- return false;
- }
- if (is_scalar($data) || !$data) {
- return false;
- }
- if (is_array($data)) {
- if (array_keys($data) === range(0, count($data) - 1)) {
- if (array_filter($data, 'is_scalar') == array_filter($data)) {
- return false;
- }
- }
- }
- return true;
- }
-
- /**
* Lazy-loads a document from a query using a reference to a database adapter and a query
* result resource.
*
@@ -215,13 +177,15 @@ protected function _isComplexType($data) {
* @return array
*/
protected function _populate($data = null, $key = null) {
- if ($this->closed()) {
+ if ($this->closed() || !($model = $this->_model)) {
return;
}
- if (($data = $data ?: $this->_handle->result('next', $this->_result, $this)) === null) {
+ $conn = $model::connection();
+
+ if (($data = $data ?: $conn->result('next', $this->_result, $this)) === null) {
return $this->close();
}
- return $this->_data[] = $this->_relation('entity', $key, $data, array('exists' => true));
+ return $this->_data[] = $conn->cast($model, $key, $data, array('exists' => true));
}
/**
View
51 libraries/lithium/data/collection/RecordSet.php
@@ -38,18 +38,8 @@ class RecordSet extends \lithium\data\Collection {
protected $_columns = array();
/**
- * Dynamic dependancies
- *
- * @var array
- */
- protected $_classes = array(
- 'entity' => '\lithium\data\entity\Record',
- 'set' => __CLASS__
- );
-
- /**
- * Initializes the record set and uses the database handle to get the column list contained in
- * the query that created this object.
+ * Initializes the record set and uses the database connection to get the column list contained
+ * in the query that created this object.
*
* @see lithium\data\collection\RecordSet::$_columns
* @return void
@@ -59,7 +49,7 @@ class RecordSet extends \lithium\data\Collection {
protected function _init() {
parent::_init();
- if ($this->_handle && $this->_result) {
+ if ($this->_result) {
$this->_columns = $this->_columnMap();
}
if ($this->_data && !$this->_index) {
@@ -178,8 +168,8 @@ public function key($full = false) {
/**
* Returns the next record in the set, and advances the object's internal pointer. If the end of
- * the set is reached, a new record will be fetched from the data source connection handle
- * (`$_handle`). If no more records can be fetched, returns `null`.
+ * the set is reached, a new record will be fetched from the data source connection handle.
+ * If no more records can be fetched, returns `null`.
*
* @return object Returns the next record in the set, or `null`, if no more records are
* available.
@@ -265,28 +255,30 @@ public function map($filter, array $options = array()) {
* Lazy-loads records from a query using a reference to a database adapter and a query
* result resource.
*
- * @param array $record
+ * @param array $data
* @param mixed $key
* @return array
*/
- protected function _populate($record = null, $key = null) {
- if ($this->closed() && !$record) {
+ protected function _populate($data = null, $key = null) {
+ if ($this->closed() && !$record || !($model = $this->_model)) {
return;
}
- $modelClass = $this->_model;
- $class = $this->_classes['entity'];
+ $conn = $model::connection();
- if (!($record = $record ?: $this->_handle->result('next', $this->_result, $this))) {
+ if (!($data = $data ?: $conn->result('next', $this->_result, $this))) {
return $this->close();
}
+ $offset = 0;
+ $recordMap = array();
- if (is_array($record)) {
- foreach ($this->_columns as $model => $fields) {
- $data = array_combine($fields, array_slice($record, 0, count($fields)));
- $record = new $class(compact('model', 'data') + array('exists' => true));
- }
+ foreach ($this->_columns as $model => $fields) {
+ $record = array_combine($fields, array_slice($data, $offset, count($fields)));
+ $recordMap[$model] = $conn->item($model, $record, array('exists' => true));
}
- if (is_array($key = $modelClass::key($record))) {
+ $record = reset($recordMap);
+ unset($recordMap[key($recordMap)]);
+
+ if (is_array($key = $model::key($recordMap))) {
$key = count($key) === 1 ? reset($key) : $key;
}
if (in_array($key, $this->_index)) {
@@ -301,7 +293,10 @@ protected function _columnMap() {
if ($this->_query && $map = $this->_query->map()) {
return $map;
}
- return $this->_handle->schema($this->_query, $this->_result, $this);
+ if (!($model = $this->_model)) {
+ return array();
+ }
+ return $model::connection()->schema($this->_query, $this->_result, $this);
}
}
View
160 libraries/lithium/data/entity/Document.php
@@ -8,9 +8,9 @@
namespace lithium\data\entity;
-use \Iterator;
-use \lithium\data\Source;
-use \lithium\util\Collection;
+use Iterator;
+use lithium\data\Source;
+use lithium\util\Collection;
/**
* `Document` is an alternative to the `entity\Record` class, which is optimized for
@@ -59,7 +59,7 @@
* {{{$employees = $acme->employees;
* // returns a Document object with the data in 'employees'}}}
*/
-class Document extends \lithium\data\Entity {
+class Document extends \lithium\data\Entity implements \Iterator {
/**
* If this `Document` instance has a parent document (see `$_parent`), this value indicates
@@ -106,6 +106,14 @@ class Document extends \lithium\data\Entity {
protected $_stats = array();
/**
+ * Holds the current iteration state. Used by `Document::valid()` to terminate `foreach` loops
+ * when there are no more fields to iterate over.
+ *
+ * @var boolean
+ */
+ protected $_valid = false;
+
+ /**
* The class dependencies for `Document`.
*
* @var array
@@ -121,7 +129,7 @@ class Document extends \lithium\data\Entity {
* @var array
*/
protected $_autoConfig = array(
- 'data', 'classes' => 'merge', 'handle', 'model',
+ 'data', 'classes' => 'merge', 'model',
'result', 'parent', 'exists', 'stats', 'pathKey'
);
@@ -147,7 +155,7 @@ protected function _init() {
*/
public function &__get($name) {
$data = null;
- $null = null;
+ $null = null;
if (isset($this->_relationships[$name])) {
return $this->_relationships[$name];
@@ -168,42 +176,25 @@ public function &__get($name) {
}
}
}
- $data = isset($this->_data[$name]) ? $this->_data[$name] : null;
-
- if (!is_object($data) && $this->_isComplexType($data)) {
- $this->_data[$name] = $this->_relation('entity', $name, $this->_data[$name]);
+ if (!isset($this->_data[$name])) {
+ return $null;
}
- $this->_marked[$name] = true;
+ $data = $this->_data[$name];
- if (isset($this->_data[$name])) {
- return $this->_data[$name];
+ if ($model = $this->_model) {
+ $pathKey = $this->_pathKey ? "{$this->_pathKey}.{$name}" : $name;
+ $options = compact('pathKey');
+ $this->_data[$name] = $model::connection()->cast($model, $name, $data, $options);
}
- return $null;
+
+ $this->_marked[$name] = true;
+ return $this->_data[$name];
}
public function export(Source $dataSource, array $options = array()) {
$defaults = array('atomic' => true);
$options += $defaults;
- $data = array();
- $nested = array();
-
- foreach ($this->_data as $key => $val) {
- if (!is_object($val)) {
- $data[$key] = $val;
- continue;
- }
- $nestedOptions = $options;
-
- switch (true) {
- case (is_a($val, $this->_classes['set'])):
- $nestedOptions = array('atomic' => false) + $options;
- case (is_a($val, $this->_classes['entity'])):
- if ($data[$key] = $val->export($dataSource, $nestedOptions)) {
- $nested[$key] = true;
- }
- break;
- }
- }
+ list($data, $nested) = $this->_exportRecursive($dataSource, $options);
if ($options['atomic'] && $this->_exists) {
$data = array_intersect_key($data, $this->_modified + $nested);
@@ -224,6 +215,30 @@ public function export(Source $dataSource, array $options = array()) {
return $data;
}
+ protected function _exportRecursive(Source $dataSource, array $options = array()) {
+ $data = array();
+ $nested = array();
+
+ foreach ($this->_data as $key => $val) {
+ $isEntity = is_a($val, $this->_classes['entity']);
+ $isSet = is_a($val, $this->_classes['set']);
+
+ if (!$isEntity && !$isSet) {
+ $data[$key] = $val;
+ continue;
+ }
+ $nestedOptions = $options;
+
+ if ($isSet || isset($this->_modified[$key])) {
+ $nestedOptions = array('atomic' => false) + $nestedOptions;
+ }
+ if (($isEntity || $isSet) && $data[$key] = $val->export($dataSource, $nestedOptions)) {
+ $nested[$key] = true;
+ }
+ }
+ return array($data, $nested);
+ }
+
public function update($id = null, array $data = array()) {
foreach ($this->_data as $key => $val) {
if (is_a($val, $this->_classes['entity'])) {
@@ -288,19 +303,19 @@ protected function &_getNested($name) {
* @return void
*/
public function __set($name, $value = null) {
- if (is_array($name) && !$value) {
- foreach ($name as $key => $value) {
- $this->__set($key, $value);
+ if (is_array($name)) {
+ foreach ($name as $key => $val) {
+ $this->__set($key, $val);
}
return;
}
-
if (is_string($name) && strpos($name, '.')) {
return $this->_setNested($name, $value);
}
-
- if ($this->_isComplexType($value)) {
- $value = $this->_relation('entity', $name, $value);
+ if ($model = $this->_model) {
+ $pathKey = $this->_pathKey ? "{$this->_pathKey}.{$name}" : $name;
+ $options = compact('pathKey');
+ $value = $model::connection()->cast($model, $name, $value, $options);
}
$this->_data[$name] = $value;
$this->_marked[$name] = true;
@@ -374,6 +389,35 @@ public function offsetGet($offset) {
}
/**
+ * Rewinds to the first item.
+ *
+ * @return mixed The current item after rewinding.
+ */
+ public function rewind() {
+ reset($this->_data);
+ $this->_valid = (count($this->_data) > 0);
+ return current($this->_data);
+ }
+
+ /**
+ * Used by the `Iterator` interface to determine the current state of the iteration, and when
+ * to stop iterating.
+ *
+ * @return boolean
+ */
+ public function valid() {
+ return $this->_valid;
+ }
+
+ public function current() {
+ return current($this->_data);
+ }
+
+ public function key() {
+ return key($this->_data);
+ }
+
+ /**
* Returns the next `Document` in the set, and advances the object's internal pointer. If the
* end of the set is reached, a new document will be fetched from the data source connection
* handle (`$_handle`). If no more records can be fetched, returns `null`.
@@ -389,7 +433,6 @@ public function next() {
if (!$this->_valid && $cur !== $prev && $cur !== null) {
$this->_valid = true;
}
- $this->_valid = $this->_valid ?: !is_null($this->_populate());
return $this->_valid ? $this->__get(key($this->_data)) : null;
}
@@ -407,39 +450,6 @@ public function data($field = null) {
function($relationship) { return $relationship->data(); }, $this->_relationships
);
}
-
- /**
- * Used by getter and setter methods to determine whether the value of data is a complex type
- * that should be given its own sub-object withih the `Document`.
- *
- * @param mixed $data The data to be tested. This test is used to determine if `$data` should be
- * wrapped in an instance of `Document`.
- * @return boolean Returns `false` if the value of `$data` is a scalar type or a one-dimensional
- * array of scalar values, otherwise returns `true`.
- */
- protected function _isComplexType($data) {
- if (is_object($data)) {
- foreach ($this->_classes as $class) {
- if (is_a($data, $class)) {
- return false;
- }
- }
- if ((array) $data === array()) {
- return false;
- }
- }
- if (is_scalar($data) || !$data) {
- return false;
- }
- if (is_array($data)) {
- if (array_keys($data) === range(0, count($data) - 1)) {
- if (array_filter($data, 'is_scalar') == array_filter($data)) {
- return false;
- }
- }
- }
- return true;
- }
}
?>
View
2  libraries/lithium/data/source/Database.php
@@ -96,7 +96,7 @@
*
* @param string $type next|close The current step in the iteration.
* @param mixed $resource The result resource returned from the database.
- * @param \lithium\data\model\Query $context The given query.
+ * @param lithium\data\model\Query $context The given query.
* @return void
*/
abstract public function result($type, $resource, $context);
View
97 libraries/lithium/data/source/MongoDb.php
@@ -188,10 +188,10 @@ public static function enabled($feature = null) {
* their respective properties in `Model`.
*/
public function configureClass($class) {
- return array('meta' => array('key' => '_id'), 'classes' => array(
- 'entity' => $this->_classes['entity'],
- 'set' => $this->_classes['set'],
- ));
+ return array(
+ 'meta' => array('key' => '_id'),
+ 'schema' => array('_id' => array('type' => 'MongoId'))
+ );
}
/**
@@ -324,7 +324,7 @@ public function create($query, array $options = array()) {
$query = $params['query'];
$options = $params['options'];
- $data = $self->invokeMethod('_toMongoId', array($query->data()));
+ $data = $query->data();
$params = $query->export($self);
$gridCol = "{$_config['gridPrefix']}.files";
@@ -345,7 +345,7 @@ public function create($query, array $options = array()) {
protected function _saveFile($params) {
$uploadKeys = array('name', 'type', 'tmp_name', 'error', 'size');
- $data = $this->_toMongoId($params['data']);
+ $data = $params['data'];
$grid = $this->connection->getGridFS();
$file = null;
$method = null;
@@ -389,8 +389,9 @@ protected function _saveFile($params) {
*/
public function read($query, array $options = array()) {
$this->_checkConnection();
- $defaults = array('return' => 'resource', 'model' => null);
+ $defaults = array('return' => 'resource');
$options += $defaults;
+
$params = compact('query', 'options');
$_config = $this->_config;
@@ -404,7 +405,7 @@ public function read($query, array $options = array()) {
if ($group = $args['group']) {
$result = $self->invokeMethod('_group', array($group, $args, $options));
$config = array('class' => 'set') + compact('query') + $result;
- return $self->item($options['model'], $config['data'], $config);
+ return $self->item($query->model(), $config['data'], $config);
}
$collection = $self->connection->{$source};
@@ -418,7 +419,7 @@ public function read($query, array $options = array()) {
}
$result = $result->sort($args['order'])->limit($args['limit'])->skip($args['offset']);
$config = compact('result', 'query') + array('class' => 'set');
- return $self->item($options['model'], array(), $config);
+ return $self->item($query->model(), array(), $config);
});
}
@@ -457,9 +458,7 @@ public function update($query, array $options = array()) {
$args['data']['_id'] = $self->invokeMethod('_saveFile', array($args));
}
unset($args['data']['_id']);
-
- $update = $self->invokeMethod('_toMongoId', array($args['data']));
- $update = ($options['atomic']) ? array('$set' => $update) : $update;
+ $update = ($options['atomic']) ? array('$set' => $args['data']) : $args['data'];
if ($self->connection->{$args['source']}->update($args['conditions'], $update)) {
$query->entity() ? $query->entity()->update() : null;
@@ -484,7 +483,7 @@ public function delete($query, array $options = array()) {
$options = $params['options'];
$params = $query->export($self);
- $conditions = $self->invokeMethod('_toMongoId', array($params['conditions']));
+ $conditions = $params['conditions'];
return $self->connection->{$params['source']}->remove($conditions);
});
}
@@ -696,38 +695,26 @@ public function order($order, $context) {
return $order ?: array();
}
- /**
- * Returns a newly-created `Document` object, bound to a model and populated with default data
- * and options.
- *
- * @param string $model A fully-namespaced class name representing the model class to which the
- * `Document` object will be bound.
- * @param array $data The default data with which the new `Document` should be populated.
- * @param array $options Any additional options to pass to the `Record`'s constructor.
- * @return object Returns a new, un-saved `Document` object bound to the model class specified
- * in `$model`.
- */
- public function item($model, array $data = array(), array $options = array()) {
- return parent::item($model, $data, array('handle' => $this) + $options);
- }
+ public function cast($model, $key, $value, array $options = array()) {
+ $schema = $model::schema($key);
+ $schema = (array) $schema + array('type' => null, 'array' => false);
+ $type = $schema['type'];
- /**
- * Adds a proper MongoId to the passed `$data` if an appropriate `_id` field with a
- * 24-character alphanumeric identifier exists.
- *
- * @param array|object $data The passed data. If `$data` is an object, no MongoId will
- * be generated and the original object will be returned.
- * @return array|object The passed `$data` with the `_id` parameter transformed into a
- * `MongoId` object, or the original data if `_id` is not set, or if `_id` is already
- * an object.
- */
- protected function _toMongoId($data) {
- if (isset($data['_id']) && !is_object($data['_id'])) {
- if (preg_match('/^[0-9a-f]{24}$/', (string) $data['_id'])) {
- $data['_id'] = new MongoId($data['_id']);
- }
+ if (is_object($value)) {
+ return $value;
+ }
+ switch (true) {
+ case ($type == 'MongoId' || $type == 'id'):
+ return preg_match('/^[0-9a-f]{24}$/', (string) $value) ? MongoId($value) : $value;
+ case in_array($type, array('date', 'datetime', 'timestamp', 'MongoDate')):
+ return new MongoDate(intval($value));
+ case is_array($value):
+ if (array_keys($value) === range(0, count($value) - 1)) {
+ return $this->item($model, $value, array('class' => 'array') + $options);
+ }
+ return $this->item($model, $value, $options);
}
- return $data;
+ return $value;
}
protected function _checkConnection() {
@@ -735,6 +722,30 @@ protected function _checkConnection() {
throw new NetworkException("Could not connect to the database.");
}
}
+
+ /**
+ * Used by getter and setter methods to determine whether the value of data is a complex type
+ * that should be given its own sub-object withih a MongoDB `Document`.
+ *
+ * @param mixed $data The data to be tested. This test is used to determine if `$data` should be
+ * wrapped in a MongoDB `Document`.
+ * @return boolean Returns `false` if the value of `$data` is a scalar type or a one-dimensional
+ * array of scalar values, otherwise returns `true`.
+ */
+ protected function _detectType($data) {
+ if (is_object($data) || is_scalar($data) || !$data) {
+ return false;
+ }
+ if (!is_array($data)) {
+ return true;
+ }
+ if (array_keys($data) === range(0, count($data) - 1)) {
+ if (array_filter($data, 'is_scalar') == array_filter($data)) {
+ return false;
+ }
+ }
+ return is_array($data);
+ }
}
?>
View
7 libraries/lithium/data/source/http/adapter/CouchDb.php
@@ -320,6 +320,13 @@ public function item($model, array $data = array(), array $options = array()) {
return parent::item($model, $this->_format($data), $options);
}
+ public function cast($model, $key, $value, array $options = array()) {
+ $schema = $model::schema($key);
+ $schema = (array) $schema + array('type' => null, 'array' => false);
+ $type = $schema['type'];
+ return $value;
+ }
+
/**
* get result
*
Please sign in to comment.
Something went wrong with that request. Please try again.