Cast SilverStripe types to appropriate JSON types (#60)

This commit is contained in:
andreaspiening 2018-04-19 15:54:43 +12:00 committed by Robbie Averill
parent 9243546b75
commit 73c61e7d4c
4 changed files with 116 additions and 2 deletions

View File

@ -9,6 +9,7 @@ use SilverStripe\RestfulServer\DataFormatter;
use SilverStripe\ORM\DataObjectInterface;
use SilverStripe\Control\Director;
use SilverStripe\ORM\SS_List;
use SilverStripe\ORM\FieldType;
/**
* Formats a DataObject's member fields into a JSON string
@ -89,7 +90,7 @@ class JSONDataFormatter extends DataFormatter
continue;
}
$fieldValue = $obj->obj($fieldName)->RAW();
$fieldValue = self::cast($obj->obj($fieldName));
$mappedFieldName = $this->getFieldAlias($className, $fieldName);
$serobj->$mappedFieldName = $fieldValue;
}
@ -117,7 +118,7 @@ class JSONDataFormatter extends DataFormatter
$serobj->$relName = ArrayData::array_to_object(array(
"className" => $relClass,
"href" => "$href.json",
"id" => $obj->$fieldName
"id" => self::cast($obj->obj($fieldName))
));
}
@ -190,4 +191,19 @@ class JSONDataFormatter extends DataFormatter
{
return Convert::json2array($strData);
}
public static function cast(FieldType\DBField $dbfield)
{
switch (true) {
case $dbfield instanceof FieldType\DBInt:
return (int)$dbfield->RAW();
case $dbfield instanceof FieldType\DBFloat:
return (float)$dbfield->RAW();
case $dbfield instanceof FieldType\DBBoolean:
return (bool)$dbfield->RAW();
case is_null($dbfield->RAW()):
return null;
}
return $dbfield->RAW();
}
}

View File

@ -0,0 +1,46 @@
<?php
namespace SilverStripe\RestfulServer\Tests;
use SilverStripe\RestfulServer\RestfulServer;
use SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject;
use SilverStripe\Dev\SapphireTest;
use SilverStripe\RestfulServer\DataFormatter\JSONDataFormatter;
/**
*
* @todo Test Relation getters
* @todo Test filter and limit through GET params
* @todo Test DELETE verb
*
*/
class JSONDataFormatterTest extends SapphireTest
{
protected static $fixture_file = 'JSONDataFormatterTest.yml';
protected static $extra_dataobjects = [
JSONDataFormatterTypeTestObject::class,
];
public function testJSONTypes()
{
$formatter = new JSONDataFormatter();
$parent = $this->objFromFixture(JSONDataFormatterTypeTestObject::class, 'parent');
$json = $formatter->convertDataObject($parent);
$this->assertRegexp('/"ID":\d+/', $json, 'PK casted to integer');
$this->assertRegexp('/"Created":"\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}"/', $json, 'Datetime casted to string');
$this->assertContains('"Name":"Parent"', $json, 'String casted to string');
$this->assertContains('"Active":true', $json, 'Boolean casted to boolean');
$this->assertContains('"Sort":17', $json, 'Integer casted to integer');
$this->assertContains('"Average":1.2345', $json, 'Float casted to float');
$this->assertContains('"ParentID":0', $json, 'Empty FK is 0');
$child3 = $this->objFromFixture(JSONDataFormatterTypeTestObject::class, 'child3');
$json = $formatter->convertDataObject($child3);
$this->assertContains('"Name":null', $json, 'Empty string is null');
$this->assertContains('"Active":false', $json, 'Empty boolean is false');
$this->assertContains('"Sort":0', $json, 'Empty integer is 0');
$this->assertContains('"Average":0', $json, 'Empty float is 0');
$this->assertRegexp('/"ParentID":\d+/', $json, 'FK casted to integer');
}
}

View File

@ -0,0 +1,20 @@
SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject:
parent:
Name: Parent
Active: true
Sort: 17
Average: 1.2345
child1:
Name: Child 1
Active: 1
Sort: 4
Average: 6.78
Parent: =>SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject.parent
child2:
Name: Child 2
Active: false
Sort: 9
Average: 1
Parent: =>SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject.parent
child3:
Parent: =>SilverStripe\RestfulServer\Tests\Stubs\JSONDataFormatterTypeTestObject.parent

View File

@ -0,0 +1,32 @@
<?php
namespace SilverStripe\RestfulServer\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
class JSONDataFormatterTypeTestObject extends DataObject implements TestOnly
{
/**
* @var string
*/
private static $table_name = 'JSONDataFormatterTypeTestObject';
/**
* @var array
*/
private static $db = [
'Name' => 'Varchar',
'Active' => 'Boolean',
'Sort' => 'Int',
'Average' => 'Float',
];
private static $has_one = [
'Parent' => JSONDataFormatterTypeTestObject::class,
];
private static $has_many = [
'Children' => JSONDataFormatterTypeTestObject::class,
];
}