Skip to content

Instantly share code, notes, and snippets.

@cviebrock
Created March 7, 2012 22:31
Show Gist options
  • Select an option

  • Save cviebrock/1996758 to your computer and use it in GitHub Desktop.

Select an option

Save cviebrock/1996758 to your computer and use it in GitHub Desktop.
serializable abstract eloquent class :)
<?php
class Data extends Aware {
public static $timestamps = true;
public static $table = 'data';
private static $class = null;
public static $types = array();
public static $rules = array(
'user_id' => 'required|exists:users,id',
'class' => 'required',
'type' => 'required',
'string' => 'required',
);
// overload this in the extended class with all the fields we want to serialize
// added benefit: the Aware bundle won't try and save these attributes into the DB
public $temporary = array();
// this is where we'll temporarily store the unserialized data
protected $unserialized_data = array();
public function __construct($attributes = array())
{
// automagically build the "type" rules based on the "types" attribute
$rules['type'] = array(
'required',
'in:' . join(',', static::$types)
);
parent::__construct($attributes);
}
/**
* expand
* Converts the serialized data into regular attributes
*
* @param string $key
* @return mixed
*/
public function expand() {
$this->unserialized_data = json_decode($this->string);
}
/**
* compact
* Converts the regular attributes into serialized data
*
* @param string $key
* @return mixed
*/
public function compact() {
// update the dirty fields first
// because of Aware, these will be in "ignore"
foreach ($this->temporary as $key) {
if( isset($this->ignore[$key]) ) {
$this->unserialized_data[$key] = $this->ignore[$key];
}
}
$this->string = json_encode($this->unserialized_data);
}
/**
* __get
* Overrides the parent method to look for serialized data first
*
* @param string $key
* @return mixed
*/
public function __get($key) {
// expand if we haven't yet
if ( !is_array($this->unserialized_data) ) {
$this->expand();
}
// are we trying to get a key from one of the temporary attributes,
// and does it exist? if so, return it
if ( in_array($key, $this->temporary) && array_key_exists($key, $this->unserialized_data) ) {
return $this->unserialized_data[$key];
}
// else, default to parent method
return parent::__get($key);
}
/**
* Save.
* Should automatically serialize the attributes into data.string.
*
* @param int $count
* @return array
*/
public function save($rules=array(), $messages=array())
{
// serialize the data and then save
$this->compact();
// force the class
$this->class = static::$class;
parent::save($rules, $messages);
}
}
/* AN EXAMPLE */
class Data_Phone extends Data {
// this is what will get saved in data.class
protected static $class = 'phone';
// these are the options for data.type
public static $types = array(
'work/voice' => 'Work',
'home/voice' => 'Home',
'cell/voice' => 'Mobile',
'work/fax' => 'Work Fax',
'home/fax' => 'Home Fax',
'pager' => 'Pager',
'other/voice' => 'Other',
);
// this are attributes that we'd like (for ease of use), but that get
// serialized/unserialized when saving/loading
public $temporary = array(
'number',
'extension',
);
// we can make rules and messages for these attributes too:
public static $rules = array(
'number' => 'required|phone',
'extension' => 'integer',
);
public static $messages = array(
'number_phone' => 'Phone numbers can start with a "+", and only contain 0-9, "-", "." or " "',
'extension' => 'Extensions can only contain numbers',
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment