<?php
namespace Tlf;
/**
* Minimal ORM implementation.
*
* @tagline (Alpha version) A minimalist ORM for mapping arrays of data to objects with magic getters & some convenience methods
*/
#[\AllowDynamicProperties]
class LilOrm {
public $_cache = [];
public function __construct($row){
foreach ($row??[] as $k=>$v){
$this->$k = $v;
}
}
protected function get_ldb(): \Tlf\LilDb {
return \ldb();
}
/**
* Get an object with the given id
*
* @tip you could just use $id & $id_column as `select * from $name where $id_column = $id, though this is not the intended use
*
* @param $name the table name
* @param $id the id of the row to retrieve
* @param $id_column the id_column of the target row
*
* @return a LilOrm object or null if no rows found
*/
public function one($name, $id, $id_column='id'){
if (isset($this->_cache[$name.'-'.$id]))return $this->_cache[$name.'-'.$id];
$row = $this->get_ldb()->select($name,[$id_column=>$id])[0]??null;
if ($row==null)return null;
$obj = $this->object($name, $row);
$this->_cache[$name.'-'.$id] = $obj;
return $obj;
}
/**
* Get an array of objects that point to this item
*
* @param $that the table name to select from
* @param $id_column the column to select against. Ex: `item_id` thus `this.id = that.item_id
*
* @return an array of rows
*/
public function many($that, $id_column=null, $this_table=null){
$id = $this->id;
if (isset($this->_cache[$that.'-'.$id]))return $this->_cache[$that.'-'.$id];
if ($id_column == null){
$fqn = strtolower(get_class($this));
$pos = strrpos($fqn, "\\");
$table = substr($fqn,$pos+1);
$id_column = $table.'_id';
}
if ($this_table == null) $this_table = strtolower(get_class($this));
$rows = $this->get_ldb()->select($that,[$id_column=>$id]);
$this->_cache[$that.'-'.$id] = $rows ?? [];
return $this->_cache[$that.'-'.$id];
// return;
// if ($rows==null)return [];
//
// $objects = [];
// foreach ($rows as $row){
// $objects[] = $this->object($that,$row);
// }
//
// $this->_cache[$that.'-'.$id] = $objects;
//
// return $objects;
// $obj = $this->object($that, $row);
// return $obj;
}
public function object($name, array $row){
$class = get_class($this);
$parts = explode("\\",$class);
array_pop($parts);
$namespace = implode("\\", $parts);
$class = $namespace.'\\'.ucfirst($name);
if (class_exists($class)){
return new $class($row);
}
return (object)$row;
}
/**
* Get an array of objects from rows
* @param $rows an array of rows
* @return array of objects
*/
static public function from_rows(array $rows){
$list = [];
foreach ($rows as $r){
$class = static::class;
$list[] = new $class($r);
}
return $list;
}
public function __get($prop){
if (substr($prop,0,1)=='_')return false;
if (method_exists($this,$mthd='get'.ucfirst($prop))){
return $this->$mthd();
}
return '';
// trigger_error("Property '$prop' does not exist on ".get_class($this));
throw new \Exception("Property '$prop' does not exist on ".get_class($this));
return null;
}
}