Documented casting Entity properties and Ensured array casts are reserialized when set.

This commit is contained in:
Lonnie Ezell 2017-08-16 22:31:07 -05:00
parent 10ccce0115
commit abee717a2c
No known key found for this signature in database
GPG Key ID: 8EB408F8D82F5002
3 changed files with 79 additions and 2 deletions

View File

@ -178,6 +178,14 @@ class Entity
$value = $this->mutateDate($value);
}
// Array casting requires that we serialize the value
// when setting it so that it can easily be stored
// back to the database.
if (array_key_exists($key, $this->_options['casts']) && $this->_options['casts'][$key] === 'array')
{
$value = serialize($value);
}
// if a set* method exists for this key,
// use that method to insert this value.
$method = 'set' . str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $key)));
@ -331,10 +339,14 @@ class Entity
$value = (object)$value;
break;
case 'array':
if (is_string($value) && substr($value, 0, 2) === 'a:')
if (is_string($value) && (substr($value, 0, 2) === 'a:' || substr($value, 0, 2) === 's:'))
{
$value = unserialize($value);
}
else
{
$value = (object)$value;
}
break;
case 'datetime':
return new \DateTime($value);

View File

@ -319,7 +319,11 @@ class EntityTest extends \CIUnitTestCase
{
$entity = $this->getCastEntity();
$entity->seventh = serialize(['foo' => 'bar']);
$entity->seventh = ['foo' => 'bar'];
// Should be a serialized string now...
$check = $this->getPrivateProperty($entity, 'seventh');
$this->assertEquals(serialize(['foo' => 'bar']), $check);
$this->assertEquals(['foo' => 'bar'], $entity->seventh);
}

View File

@ -263,6 +263,10 @@ through the original ``$user->full_name``, also, as this is needed for the model
to the database. However, ``unset`` and ``isset`` only work on the mapped property, ``$name``, not on the original name,
``full_name``.
Mutators
========
Date Mutators
-------------
@ -301,3 +305,60 @@ current timezone, as set in **application/Config/App.php**::
// Can now use any Time methods:
echo $user->created_at->humanize();
echo $user->created_at->setTimezone('Europe/London')->toDateString();
Property Casting
----------------
You can specify that properties in your Entity should be converted to common data types with the **casts** entry in
the **$_options** property. The **casts** option should be an array where the key is the name of the class property,
and the value is the data type it should be cast to. Casting only affects when values are read. No conversions happen
that affect the permanent value in either the entity or the database. Properties can be cast to any of the following
data types: **integer**, **float**, **double**, **string**, **boolean**, **object**, **array**, **datetime**, and
**timestamp**.
For example, if you had a User entity with an **is_banned** property, you can cast it as a boolean::
<?php namespace App\Entities;
use CodeIgniter\Entity;
class User extends Entity
{
protected $is_banned;
protected _$options = [
'casts' => [
'is_banned' => 'boolean'
]
];
}
Array Casting
-------------
Array casting is especially useful with fields that store serialized arrays or json in them. When cast as an array,
they will automatically be unserialized when you read the property's value. Unlike the rest of the data types that
you can cast properties into, the **array** cast type will serialize the value whenever the property is set::
<?php namespace App\Entities;
use CodeIgniter\Entity;
class User extends Entity
{
protected $options;
protected _$options = [
'casts' => [
'options' => 'array'
]
];
}
$user = $userModel->find(15);
$options = $user->options;
$options['foo'] = 'bar';
$user->options = $options;
$userModel->save($user);