Skip to content

Instantly share code, notes, and snippets.

@johnsardine
Last active August 29, 2015 14:25
Show Gist options
  • Save johnsardine/3c935bbc73dd0cd85004 to your computer and use it in GitHub Desktop.
Save johnsardine/3c935bbc73dd0cd85004 to your computer and use it in GitHub Desktop.
<?php
class BaseModel implements ArrayAccess {
public $attributes = array();
public $attributes_cast_as = array(); // key => closure returning the value
public $attributes_cast_as_integer = array();
public $attributes_cast_as_float = array();
public $attributes_cast_as_string = array();
public function __isset($key)
{
return array_key_exists($key, $this->attributes);
}
public function __unset($key)
{
if ( array_key_exists($key, $this->attributes) ) {
unset( $this->attributes[$key] );
}
return true;
}
public function __set($key, $value)
{
$value = $this->__castValue($key, $value, 'set');
if ( is_array($value) )
$value = json_encode($value);
if ( array_key_exists($key, $this->attributes) ) {
$this->attributes[$key] = $value;
}
return true;
}
public function __get($key)
{
if ( array_key_exists($key, $this->attributes) ) {
$data = $this->attributes;
}
if ( !isset($data[$key]) )
return null;
$value = $data[$key];
if ( $value instanceof Closure )
$value = $value($this, $key, 'get');
if ( is_scalar($value) ) {
$json_value = json_decode($value, true);
if ( is_array($json_value) ) {
$json_value = $this->__castValue($key, $json_value, 'get');
return $json_value;
}
}
$value = $this->__castValue($key, $value, 'get');
return $value;
}
public function __castValue($key, $value, $action = 'get') {
if ( is_null($value) )
return $value;
if ( in_array($key, $this->attributes_cast_as_integer) )
return intval($value);
if ( in_array($key, $this->attributes_cast_as_float) )
return floatval($value);
if ( in_array($key, $this->attributes_cast_as_string) )
return strval($value);
if (
!array_key_exists($key, $this->attributes_cast_as)
||
( array_key_exists($key, $this->attributes_cast_as) && !$this->attributes_cast_as[$key] instanceof Closure )
)
return $value;
return $this->attributes_cast_as[$key]($value, $this, $action);
}
public function offsetSet($key, $value)
{
return $this->__set($key, $value);
}
public function offsetExists($key)
{
return $this->__isset($key);
}
public function offsetUnset($key)
{
$this->__unset($key);
}
public function offsetGet($key)
{
return $this->__get($key);
}
public function toArray() {
$output = array();
foreach ($this->attributes as $key => $value) {
$value = $this->__get($key);
$output[$key] = ( is_object($value) ) ? $value->toArray() : $value;
}
return $output;
}
public function toJson() {
return json_encode($this->toArray());
}
}
<?php
class ChildModel implements BaseModel {
public $attributes = array(
'id' => 0,
'title' => '',
'date' => '0000-00-00 00:00:00',
'sample_custom' = '',
);
public function __construct(array $data = array()) {
// Cast attribute "id" as integer
$this->attributes_cast_as_integer[] = 'id';
// Cast attribute "title" as string
$this->attributes_cast_as_string[] = 'title';
// Set "date" attribute value as current date
if ( !isset($attributes['item_date']) )
$this->__set('date', date('Y-m-d H:i:s'));
// Custom attribute processing with a closure
$this->attributes_cast_as['sample_custom'] = function($value, $object, $action) {
if ( empty($value) && $action === 'set' )
return 'Prepended string with id following:'.$object->id;
return $value;
};
// Process any input attributes cast them and add them to the attributes property
foreach ($data as $key => $value) {
$this->__set($key, $value);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment