Skip to content

Commit

Permalink
Add type system hooks for marshalling.
Browse files Browse the repository at this point in the history
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
markstory committed Mar 1, 2014
1 parent 3b42434 commit 6a278f4
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
13 changes: 13 additions & 0 deletions src/Database/Type.php
Expand Up @@ -238,4 +238,17 @@ public function newId() {
return null; 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;
}

} }
6 changes: 6 additions & 0 deletions src/ORM/Marshaller.php
Expand Up @@ -15,6 +15,7 @@
namespace Cake\ORM; namespace Cake\ORM;


use Cake\Database\Expression\TupleComparison; use Cake\Database\Expression\TupleComparison;
use Cake\Database\Type;
use Cake\ORM\Association; use Cake\ORM\Association;
use Cake\ORM\Table; use Cake\ORM\Table;


Expand Down Expand Up @@ -89,6 +90,7 @@ protected function _buildPropertyMap($include) {
public function one(array $data, $include = []) { public function one(array $data, $include = []) {
$propertyMap = $this->_buildPropertyMap($include); $propertyMap = $this->_buildPropertyMap($include);


$schema = $this->_table->schema();
$tableName = $this->_table->alias(); $tableName = $this->_table->alias();
$entityClass = $this->_table->entityClass(); $entityClass = $this->_table->entityClass();
$entity = new $entityClass(); $entity = new $entityClass();
Expand All @@ -99,10 +101,14 @@ public function one(array $data, $include = []) {


$properties = []; $properties = [];
foreach ($data as $key => $value) { foreach ($data as $key => $value) {
$columnType = $schema->columnType($key);
if (isset($propertyMap[$key])) { if (isset($propertyMap[$key])) {
$assoc = $propertyMap[$key]['association']; $assoc = $propertyMap[$key]['association'];
$nested = $propertyMap[$key]['nested']; $nested = $propertyMap[$key]['nested'];
$value = $this->_marshalAssociation($assoc, $value, $nested); $value = $this->_marshalAssociation($assoc, $value, $nested);
} elseif ($columnType) {
$converter = Type::build($columnType);
$value = $converter->marshall($value);
} }
$properties[$key] = $value; $properties[$key] = $value;
} }
Expand Down
51 changes: 50 additions & 1 deletion tests/TestCase/ORM/MarshallerTest.php
Expand Up @@ -48,7 +48,7 @@ class ProtectedArticle extends Entity {
*/ */
class MarshallerTest extends TestCase { 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 * setup
Expand Down Expand Up @@ -112,6 +112,55 @@ public function testOneSimple() {
$this->assertNull($result->isNew(), 'Should be detached'); $this->assertNull($result->isNew(), 'Should be detached');
} }


/**
* 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. * Test one() follows mass-assignment rules.
* *
Expand Down

0 comments on commit 6a278f4

Please sign in to comment.