123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- <?php
- class DBObject implements ISavableObject, JsonSerializable {
- protected static $PREPARED_STATEMENTS=array();
- private static $_classFields=array();
- protected $_fields=array();
- protected $_changedFields=array();
- private $_table, $_keys, $_ids;
- public static function VariableToDBField($variableName) {
- $parts=preg_split('/(?=[A-Z])/', $variableName);
- for ($i=0; $i<count($parts); $i++)
- $parts[$i]=strtolower($parts[$i]);
- return trim(implode("_", $parts), "_"); // If the variable name start with upper case then we get an extra blank entry in the array causing an extra _
- }
- public static function DBFieldToVariable($fieldName) {
- $parts=explode("_", $fieldName);
- for ($i=0; $i<count($parts); $i++)
- $parts[$i]=ucfirst($parts[$i]);
- return implode("", $parts);
- }
- private function ReIndexKeyAndIdArrays() {
- $newKeyArray=array();
- foreach ($this->_keys as $index=> $key) {
- $newKeyArray[':'.$index]=$key;
- }
- $this->_keys=$newKeyArray;
- $newIdArray=array();
- foreach ($this->_ids as $index=> $id) {
- $newIdArray[':'.$index]=$id;
- }
- $this->_ids=$newIdArray;
- }
- private function GetWhereClause() {
- $qualifiers=array();
- foreach ($this->_keys as $index=> $key)
- $qualifiers[]=" `$key`=$index";
- return implode(" AND", $qualifiers);
- }
- function __construct($table, $key, $id) {
- $this->_table=$table;
- $this->_keys=array();
- $this->_ids=array();
- if (is_array($key)&&is_array($id)) {
- $this->_keys=$key;
- $this->_ids=$id;
- } elseif ($id!=null && ($id!="" || (int)$id!=0)) {
- $this->_keys=array($key);
- $this->_ids=array($id);
- }
- $this->ReIndexKeyAndIdArrays();
- $this->Load();
- }
- public function __get($name) {
- if (array_key_exists($name, $this->_fields))
- return $this->_fields[$name];
- return null;
- }
- public function __set($name, $value) {
- if (array_key_exists($name, $this->_fields)&&$this->_fields[$name]!==$value) {
- $this->_changedFields[$name]=$name;
- $this->_fields[$name]=$value;
- }
- }
- public function __isset($name) {
- return array_key_exists($name, $this->_fields);
- }
- public function Load() {
- $PDO=BaseRepository::GetPDO();
- $class=get_class($this);
- if (!isset(self::$_classFields[$class])) {
- self::$_classFields[$class]=$PDO->query("DESCRIBE `{$this->_table}`")->fetchAll(PDO::FETCH_COLUMN);
- }
- foreach (self::$_classFields[$class] as $field)
- $this->_fields[self::DBFieldToVariable($field)]=null;
- if (count($this->_keys)>0){
- $statementKey=$class.'_construct_'.$this->_table.implode('', $this->_keys);
- if (!isset(self::$PREPARED_STATEMENTS[$statementKey])) {
- $fields=implode("`, `", self::$_classFields[$class]);
- $sql="SELECT `$fields` FROM `{$this->_table}` WHERE".$this->GetWhereClause();
- self::$PREPARED_STATEMENTS[$statementKey]=$PDO->prepare($sql);
- }
- $prep=self::$PREPARED_STATEMENTS[$statementKey];
- $prep->execute($this->_ids);
- $errorInfo=$prep->errorInfo();
- if ($errorInfo[0]!='00000'){
- Utils::var_dump_email($prep);
- throw new Exception($errorInfo[2]);
- }
- $record=$prep->fetch();
- if ($record!==false)
- foreach ($record as $key=> $value)
- $this->_fields[self::DBFieldToVariable($key)]=$value;
- else {
- $this->_keys=array();
- $this->_ids=array();
- }
- }
- }
- protected function HasChangedFields() {
- return count($this->_changedFields)>0;
- }
- public function Save() {
- $PDO=BaseRepository::GetPDO();
- if (!$this->HasChangedFields())
- return;
- $fields=array();
- $execData=array();
- foreach ($this->_changedFields as $field) {
- $fields[]='`'.self::VariableToDBField($field).'`=:'.$field;
- $execData[':'.$field]=$this->_fields[$field];
- }
- if (count($this->_ids)!==0) {
- $sql="UPDATE `{$this->_table}` SET ".implode(", ", $fields)." WHERE".$this->GetWhereClause();
- $execData=array_merge($execData, $this->_ids);
- } else {
- $sql="INSERT INTO `{$this->_table}` SET ".implode(", ", $fields);
- }
- $prep=$PDO->prepare($sql);
- $prep->execute($execData);
- $errorInfo=$prep->errorInfo();
- if ($errorInfo[0]!='00000')
- throw new Exception($errorInfo[2]);
- if (count($this->_ids)===0) { // If this is a new object we want to reload fromt he DB to make sure all fields are correct.
- // In order to do so we need to find the value for the key we're using
- $id=$PDO->lastInsertId();
- if ($id!=0 && count($this->_keys)==0) {
- $this->_keys=$this->_ids=array();
- $key=$PDO->query("SHOW INDEX FROM `{$this->_table}` WHERE Key_name='PRIMARY'")->fetch()['Column_name'];
- $this->_keys[]=$key;
- $this->_ids[]=$PDO->query("SELECT `$key` FROM `{$this->_table}` WHERE `$key`=$id")->fetchColumn();
- $this->ReIndexKeyAndIdArrays();
- }
- $this->Load();
- }
- }
- public function jsonSerialize() {
- $obj=new stdClass();
- foreach ($this->_fields as $key=> $value) {
- $obj->$key=$value;
- }
- return $obj;
- }
- }
|