check_fields = $check_fields;
$this->db = new Database(Config::$database);
if($table){
$this->table = $table;
}
if($this->table && $this->check_fields){
$this->load_fields();
}
return $this;
}
/**
*
* This method automatically triggers whenever we try to get a property
* from this object.
*
* Instead of actually getting a property from this object, it instead pulls
* it from the data property, which is an array.
*
* @param string $var The property being requested
*
* @return mixed The value of the property being requested, or false if the property doesn't exist
*
*/
function __get($var){
if(method_exists($this, $var)){
return $this->$var();
}else if(isset($this->data[$var])){
return XSS::filter($this->data[$var]);
}else{
return false;
}
}
/**
*
* This method automatically triggers whenever we try to set a property
* from this object.
*
* Instead of actually setting a property on this object, it instead modifies
* or adds the value in the data property, which is an array.
*
* It only works if the key ($var) exists in the fields property, which is an
* array of all the possible fields in this database table. If that property
* didn't exist, it just returns false, thus, failing silently.
*
* @param string $var The name of the property being changed
* @param string $val The value of the property being changed
*
* @return boolean Whether the property existed or not.
*
*/
function __set($var, $val){
if($var == 'primary_key'){
$this->primary_key = $val;
}
if($this->check_fields){
if(in_array($var, $this->fields)){
$this->data[$var] = $val;
return true;
}else{
return false;
}
}else{
$this->data[$var] = $val;
return true;
}
}
/**
*
*
*/
public function load_fields(){
$this->fields = Field_Provider::table($this->table, $this->db);
return $this;
}
/**
*
*
*/
public function set_table($table){
$this->table = $table;
return $this;
}
/**
*
* Load information from the database table
*
* @param int $id The value of the id field in the table
*
* @return $this
*
*/
public function load($data){
$this->db->select('*')->from($this->table);
if (is_array($data)) {
$this->db->where($data);
} else {
$this->db->where($this->primary_key, $data);
}
$q = $this->db->build_query();
if (Model_Provider::has($q)) {
$this->db->reset();
$obj = Model_Provider::get($q);
// echo "
$q
";
$this->fill($obj->to_array());
return $obj;
} else {
$result = $this->db->get_one();
$this->data = $result;
Model_Provider::set($this->db->last_query, $this);
return $this;
}
}
/**
*
* Fill the data array of this model. Useful for adding data from $_POST quickly
*
* @param array $data An associative array containing one or more fields => value pairs
*
* @return $this
*
*/
public function fill($data){
$not_added = array();
if($this->check_fields){
foreach($data as $key => $value){
if(in_array($key, $this->fields)){
$this->data[$key] = $value;
}else{
$not_added[$key] = $value;
}
}
}else{
$this->data = $data;
}
return $this;
}
/**
*
* Insert or update this record in the table
*
* @return boolean Whether the insert/update was successful or not
*
*/
public function save(){
if(!isset($this->data[$this->primary_key])){
$success = $this->db
->set($this->data)
->insert($this->table);
$this->data[$this->primary_key] = $this->db->last_insert_id;
}else{
$success = $this->db
->set($this->data)
->where($this->primary_key, $this->data[$this->primary_key])
->update($this->table);
}
return $success;
}
/**
*
* Delete this record from the table. This is a soft delete
*
* @return boolean Whether the delete was successful
*
*/
public function delete(){
return $this->soft_delete();
}
/**
*
* Specifically perform a soft delete.
*
* This only sets the 'deleted' field of this record to 1
*
* @return boolean Whether the delete was successful
*
*/
public function soft_delete(){
if($this->data[$this->primary_key]){
$this->data['deleted'] = 1;
return $this->save();
}else{
return false;
}
}
/**
*
* Specifically perform a hard delete.
*
* This is different to a soft delete because the record will
* be permanently removed from the db.
*
* @return boolean Whether the delete was successful
*
*/
public function hard_delete(){
if($this->data[$this->primary_key]){
return $this->db
->where($this->primary_key, $this->data[$this->primary_key])
->delete($this->table);
}else{
return false;
}
}
public function hasOne($model, $foreign_key = null, $local_key = null){
$m = new $model();
# assume the local_key
if(is_null($foreign_key)){
$foreign_key = strtolower(get_class($this)).'_id';
}
if(is_null($local_key)){
$local_key = $m->primary_key;
}
$m->load([$foreign_key => $this->$local_key]);
return $m;
}
public function belongsTo($model, $local_key = null, $parent_key = null){
$m = new $model();
if(is_null($parent_key)){
$parent_key = strtolower($model).'_id';
}
if(is_null($local_key)){
$local_key = $m->primary_key;
}
$m->load([$local_key => $this->$parent_key]);
return $m;
}
public function hasMany($model, $foreign_key = null, $where = []){
$c = new Collection();
if(is_null($foreign_key)){
$foreign_key = strtolower($model)+'_id';
}
$id = $this->primary_key;
$c->where($foreign_key, $this->$id);
$c->where($where);
$c->order_by('id');
$c->get($model);
return $c->items;
}
public function belongsToMany($model, $join_table, $this_id = null, $that_id = null, $where = []){
$m = new $model();
if(is_null($this_id)){
$this_id = strtolower(get_class($this)).'_id';
}
if(is_null($that_id)){
$that_id = strtolower($model).'_id';
}
$id = $this->primary_key;
$fields = [];
foreach($m->fields as $field){
$fields[] = $m->table.'.'.$field;
}
$this->db
->select(implode(', ', $fields))
->from(implode(', ', [$join_table, $m->table, $this->table]))
->where($m->table.'.'.$m->primary_key, $join_table.'.'.$that_id, false)
->where($this->table.'.'.$this->primary_key, $join_table.'.'.$this_id, false)
->where($this->table.'.'.$this->primary_key, $this->$id)
->where($where);
$q = $this->db->build_query();
if(Model_Provider::has($q)){
// echo "$q
";
return Model_Provider::get($q);
} else {
$results = $this->db->get();
$items = [];
foreach($results as $result){
$m = new $model();
$m->fill($result);
$items[] = $m;
}
Model_Provider::set($q, $items);
return $items;
}
}
public function to_array(){
$data = $this->data;
if(!$data){
$data = [];
}
foreach($data as $key => $val){
$data[$key] = XSS::filter($val);
}
return $this->data;
}
public function __TOSTRING(){
return json_encode($this->to_array());
}
public function to_json(){
return $this->__TOSTRING();
}
}
class Field_Provider {
private static $tables = [];
public static function table($name, $db){
if(self::$tables[$name] === null){
self::$tables[$name] = $db->get_columns($name);
}
return self::$tables[$name];
}
}
class Model_Provider {
private static $queries = [];
public static function set($query, $data){
self::$queries[$query] = $data;
}
public static function has($query){
return isset(self::$queries[$query]);
}
public static function get($query){
return self::$queries[$query];
}
}