Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit 6a278f4cc42fef72396a59f6f76b4557407a94cf 1 parent 3b42434
Mark Story markstory authored
13 src/Database/Type.php
View
@@ -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;
+ }
+
}
6 src/ORM/Marshaller.php
View
@@ -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;
}
51 tests/TestCase/ORM/MarshallerTest.php
View
@@ -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
Please sign in to comment.
Something went wrong with that request. Please try again.