Permalink
Browse files

Add type system hooks for marshalling.

In order to properly handle date/datetime fields we'll need a way to
convert from request data into PHP objects. This feels like it fits best
with the existing Type classes.

Add an empty hook into Type so that subclasses can specialize it.
  • Loading branch information...
1 parent 3b42434 commit 6a278f4cc42fef72396a59f6f76b4557407a94cf @markstory markstory committed Mar 1, 2014
Showing with 69 additions and 1 deletion.
  1. +13 −0 src/Database/Type.php
  2. +6 −0 src/ORM/Marshaller.php
  3. +50 −1 tests/TestCase/ORM/MarshallerTest.php
View
13 src/Database/Type.php
@@ -238,4 +238,17 @@ public function newId() {
return null;
}
+/**
+ * Marshalls flat data into PHP objects.
+ *
+ * Most useful for converting request data into PHP objects
+ * that make sense for the rest of the ORM/Database layers.
+ *
+ * @param mixed $value The value to convert.
+ * @return mixed Converted value.
+ */
+ public function marshall($value) {
+ return $value;
+ }
+
}
View
6 src/ORM/Marshaller.php
@@ -15,6 +15,7 @@
namespace Cake\ORM;
use Cake\Database\Expression\TupleComparison;
+use Cake\Database\Type;
use Cake\ORM\Association;
use Cake\ORM\Table;
@@ -89,6 +90,7 @@ protected function _buildPropertyMap($include) {
public function one(array $data, $include = []) {
$propertyMap = $this->_buildPropertyMap($include);
+ $schema = $this->_table->schema();
$tableName = $this->_table->alias();
$entityClass = $this->_table->entityClass();
$entity = new $entityClass();
@@ -99,10 +101,14 @@ public function one(array $data, $include = []) {
$properties = [];
foreach ($data as $key => $value) {
+ $columnType = $schema->columnType($key);
if (isset($propertyMap[$key])) {
$assoc = $propertyMap[$key]['association'];
$nested = $propertyMap[$key]['nested'];
$value = $this->_marshalAssociation($assoc, $value, $nested);
+ } elseif ($columnType) {
+ $converter = Type::build($columnType);
+ $value = $converter->marshall($value);
}
$properties[$key] = $value;
}
View
51 tests/TestCase/ORM/MarshallerTest.php
@@ -48,7 +48,7 @@ class ProtectedArticle extends Entity {
*/
class MarshallerTest extends TestCase {
- public $fixtures = ['core.tag', 'core.article', 'core.user', 'core.comment'];
+ public $fixtures = ['core.tag', 'core.articles_tag', 'core.article', 'core.user', 'core.comment'];
/**
* setup
@@ -113,6 +113,55 @@ public function testOneSimple() {
}
/**
+ * Test marshalling datetime/date field.
+ *
+ * @return void
+ */
+ public function testOneWithDatetimeField() {
+ $data = [
+ 'comment' => 'My Comment text',
+ 'created' => [
+ 'year' => '2014',
+ 'month' => '2',
+ 'day' => 14
+ ]
+ ];
+ $marshall = new Marshaller($this->comments);
+ $result = $marshall->one($data, []);
+
+ $this->assertEquals(new \DateTime('2014-02-14 00:00:00'), $result->created);
+
+ $data['created'] = [
+ 'year' => '2014',
+ 'month' => '2',
+ 'day' => 14,
+ 'hour' => 9,
+ 'minute' => 25,
+ 'meridian' => 'pm'
+ ];
+ $result = $marshall->one($data, []);
+ $this->assertEquals(new \DateTime('2014-02-14 21:25:00'), $result->created);
+
+ $data['created'] = [
+ 'year' => '2014',
+ 'month' => '2',
+ 'day' => 14,
+ 'hour' => 9,
+ 'minute' => 25,
+ ];
+ $result = $marshall->one($data, []);
+ $this->assertEquals(new \DateTime('2014-02-14 09:25:00'), $result->created);
+
+ $data['created'] = '2014-02-14 09:25:00';
+ $result = $marshall->one($data, []);
+ $this->assertEquals(new \DateTime('2014-02-14 09:25:00'), $result->created);
+
+ $data['created'] = 1392387900;
+ $result = $marshall->one($data, []);
+ $this->assertEquals($data['created'], $result->created->getTimestamp());
+ }
+
+/**
* Test one() follows mass-assignment rules.
*
* @return void

0 comments on commit 6a278f4

Please sign in to comment.