Skip to content

Instantly share code, notes, and snippets.

@mnpenner
Created May 4, 2014 18:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mnpenner/27671ee41f790c220726 to your computer and use it in GitHub Desktop.
Save mnpenner/27671ee41f790c220726 to your computer and use it in GitHub Desktop.
<?php
namespace Expressive;
class Model extends \Eloquent {
protected static $fields = [];
protected static $unguarded = true;
function __construct(array $attributes = []) {
if(static::$fields) {
if(!$this->fillable) {
$this->fillable = array_keys(static::$fields);
}
if(!$this->dates) {
$this->dates = array_keys(array_filter(static::$fields,function($fieldType) {
return $fieldType === Type::DATETIME;
}));
}
foreach(static::$fields as $fieldName => $fieldType) {
if($fieldType === Type::PRIMARY) {
$this->primaryKey = $fieldName;
break; // Laravel doesn't support composite keys :-(
}
}
}
parent::__construct($attributes);
}
public function save(array $options = array()) {
$tmpAttrs = $this->attributes;
$this->attributes = array_only($this->attributes,array_keys(static::$fields)); // filter out unfillable fields
parent::save($options);
$this->attributes = array_merge($tmpAttrs, $this->attributes); // put them back in, but keep any updated fields like ID
}
public function setAttribute($key, $value) {
if(isset(static::$fields[$key])) {
switch(static::$fields[$key]) {
case Type::PRIMARY:
case Type::FOREIGN:
$value = (int)$value ?: null;
break;
case Type::DATETIME:
$value = $this->fromDateTime($value);
break;
case Type::MUTATOR:
$method = 'set'.studly_case($key).'Attribute';
if(!method_exists($this,$method)) throw new \Exception(get_called_class().'::'.$method.' is undefined');
$value = $this->{$method}($value);
break;
default:
settype($value, static::$fields[$key]);
break;
}
$this->attributes[$key] = $value;
} else {
parent::setAttribute($key, $value);
}
}
}
<?php
namespace Expressive;
class Type {
// see http://ca1.php.net/manual/en/function.settype.php
const BOOL = 'boolean';
const INT = 'integer';
const FLOAT = 'float';
const STRING = 'string';
const ARRAY_ = 'array';
const OBJECT = 'object';
const NULL = 'null';
const PRIMARY = '__primary';
const FOREIGN = '__foreign';
const DATETIME = '__datetime';
/**
* @see http://laravel.com/docs/eloquent#accessors-and-mutators
*/
const MUTATOR = '__mutator';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment