Created
April 24, 2015 09:51
-
-
Save NuckChorris/e74a747b426e6ab68a2e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once 'classes/db.class.php'; | |
/** | |
* This is an ORM. | |
* I may have gone a bit overboard on this final project. | |
* I just got tired of constantly dropping into raw SQL for mundane crap. | |
*/ | |
class Model { | |
private $_attributes = array(); | |
private $_associations_unloaded = array(); | |
protected $_new = false; | |
/** | |
* Dynamically save/retrieve properties, casting to the desired type | |
*/ | |
public function __set($key, $val) { | |
if (array_key_exists($key, $this->_fields)) { | |
// Property set | |
$type = $this->_fields[$key]; | |
if (ctype_lower($type)) { | |
// Primitive cast | |
$cast_value = $val; | |
settype($cast_value, $type); | |
$this->_attributes[$key] = $cast_value; | |
} else { | |
// Class cast | |
$this->_attributes[$key] = new $type($val); | |
} | |
} else if (substr($key, -3) === '_id') { | |
// Association set | |
$this->_associations_unloaded[substr($key, 0, -3)] = $val; | |
} | |
} | |
public function __get($key) { | |
if (array_key_exists($key, $this->_fields)) { | |
return $this->_attributes[$key]; | |
} else if (array_key_exists($key, $this->_associations)) { | |
$class = $this->_associations[$key][1]; | |
if ($this->_assocations[$key][0] === 'has_one') { | |
return $class::find($this->_associations_unloaded[$key])[0]; | |
} else if ($this->_associations[$key][0] === 'has_many') { | |
$foreign_key = substr(self::getTable(), 0, -1) . '_id'; | |
return $class::where(array($foreign_key => $this->_attributes['id'])); | |
} | |
} | |
} | |
/** | |
* Turn class name into a snake_case table name | |
*/ | |
public static function getTable() { | |
$class = get_called_class(); | |
return ltrim(strtolower(preg_replace('/[A-Z]/', '_$0', $class)), '_') . 's'; | |
} | |
/** | |
* Get instance or instances by their ID(s) | |
*/ | |
public static function find($id) { | |
$db = DB::conn(); | |
$table = self::getTable(); | |
$query = null; | |
if (is_array($id)) { | |
$ids = implode(',', $id); | |
$query = $db->prepare("SELECT * FROM $table WHERE id IN ($ids)"); | |
} else { | |
$query = $db->prepare("SELECT * FROM $table WHERE id = :id"); | |
$query->bindValue('id', $id, PDO::PARAM_INT); | |
} | |
$query->execute(); | |
$query->setFetchMode(PDO::FETCH_CLASS, get_called_class()); | |
$results = $query->fetchAll(); | |
return is_array($id) ? $results : $results[0]; | |
} | |
/** | |
* Get instances by a field or set of fields | |
*/ | |
public static function where($arr) { | |
$db = DB::conn(); | |
$table = self::getTable(); | |
$query = "SELECT * FROM $table WHERE "; | |
foreach (array_keys($arr) as $column) { | |
$query .= "$column = :$column AND"; | |
} | |
// Chop off the final AND | |
$query = substr($query, 0, -4); | |
$query = $db->prepare($query); | |
foreach ($arr as $col => $val) { | |
$query->bindValue($col, $val); | |
} | |
$query->execute(); | |
$query->setFetchMode(PDO::FETCH_CLASS, get_called_class()); | |
return $query->fetchAll(); | |
} | |
/** | |
* Save the instance | |
*/ | |
public function save() { | |
$db = DB::conn(); | |
$keys = array_keys($this->_attributes); | |
$table = self::getTable(); | |
if ($this->_new) { | |
$columns = implode(',', $keys); | |
$placeholders = ':' . implode(',:', $keys); | |
$query = $db->prepare("INSERT INTO $table ($columns) VALUES ($placeholders)"); | |
} else { | |
$query = "UPDATE $table SET "; | |
foreach ($keys as $column) { | |
if ($column !== 'id') { | |
$query .= "$column=:$column,"; | |
} | |
} | |
$query = substr($query, 0, -1); | |
$query .= " WHERE id = :id"; | |
} | |
$query = $db->prepare($query); | |
foreach($this->_attributes as $attr => $value) { | |
// Because DateTime doesn't implement __toString for some stupid reason | |
if (is_a($value, 'DateTime')) { | |
$value = $value->format('Y-m-d H:i:s'); | |
} | |
$query->bindValue($attr, $value); | |
} | |
return $query->execute(); | |
} | |
public function fields() { | |
return array_keys($this->_fields); | |
} | |
/** | |
* Create an unsaved instance | |
*/ | |
public static function create() { | |
$class = get_called_class(); | |
$new = new $class(); | |
$new->_new = true; | |
return $new; | |
} | |
/** | |
* Run validators | |
*/ | |
public function isValid() { | |
$errors = array(); | |
foreach($this->fields() as $field) { | |
$validator = 'validate_' . $field; | |
if (method_exists($this, $validator)) { | |
$err = call_user_func(array($this, $validator), $this->_attributes[$field]); | |
if ($err) { | |
$errors[$field] = $err; | |
} | |
} | |
} | |
if (count($errors) > 0) { | |
return $errors; | |
} else { | |
return true; | |
} | |
} | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once '_model.class.php'; | |
include_once 'status_report.class.php'; | |
class Incident extends Model { | |
protected $_fields = array( | |
'id' => 'integer', | |
'title' => 'string', | |
'created_at' => 'DateTime', | |
'updated_at' => 'DateTime', | |
'status' => 'string', | |
'command_post' => 'string' | |
); | |
protected $_associations = array( | |
'status_reports' => array('has_many', 'StatusReport') | |
); | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once '_model.class.php'; | |
include_once 'user.class.php'; | |
include_once 'incident.class.php'; | |
class Role extends Model { | |
protected $_fields = array( | |
'id' => 'integer', | |
'role' => 'string', | |
'other_role' => 'string', | |
'sign_on' => 'DateTime', | |
'sign_off' => 'DateTime' | |
); | |
protected $_associations = array( | |
'user' => array('has_one', 'User'), | |
'incident' => array('has_one', 'Incident') | |
); | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once '_model.class.php'; | |
include_once 'user.class.php'; | |
include_once 'incident.class.php'; | |
class StatusReport extends Model { | |
protected $_fields = array( | |
'id' => 'integer', | |
'created_at' => 'DateTime', | |
'title' => 'string', | |
'text' => 'string' | |
); | |
protected $_associations = array( | |
'user' => array('has_one', 'User'), | |
'incident' => array('has_one', 'Incident'), | |
); | |
} | |
?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
include_once '_model.class.php'; | |
class User extends Model { | |
protected $_fields = array( | |
'id' => 'integer', | |
'email' => 'string', | |
'password' => 'string', | |
'first_name' => 'string', | |
'last_name' => 'string', | |
'administrator' => 'boolean' | |
); | |
protected $_associations = array( | |
'role' => array('has_many', 'Role') | |
); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment