<?php
 namespace App\EntityPreference; abstract class BaseAbstract { protected $id; protected $DBTEntityPreferences; protected $field_idEntityName=''; protected $field_var='var'; protected $field_value='value'; protected $field_lastUpdateUser='idUpdateUser'; protected $field_lastUpdateTime='lastUpdate'; protected $cacheType = 'preference'; protected $cacheTtl = 86400; static protected $instance = []; public function __set($var, $value) { if (!\DB::isInsideTransaction()) { throw new \Exception('Entity Preference entity must be inside a transaction.'); } $this->validate($var, $value); if ($value!==null){ $updatePreferenceSQL="REPLACE INTO `{$this->DBTEntityPreferences}` SET "; $updatePreferenceSQL.='`'.$this->field_idEntityName.'`=?, `'.$this->field_var.'`=?, `'.$this->field_value.'`=?'; $fields= [$this->id, $var, $value]; if ($this->field_lastUpdateUser) { $updatePreferenceSQL.=', `'.$this->field_lastUpdateUser.'`=?'; $fields[]=CURRENT_ID_USER; } if ($this->field_lastUpdateTime) { $updatePreferenceSQL.=', `'.$this->field_lastUpdateTime.'`=?'; $fields[]=TIMESTAMP; } $updatePreferenceEx=\DB::getInstance()->Execute($updatePreferenceSQL, $fields); if (!$updatePreferenceEx) { \Log::getInstance()->dbError("Could not set `".get_called_class()."` preference for entity `{$this->id}`"); throw new \DBException('Unable to set `'.get_called_class().'` preference for id `'.$this->id.'`.'); } \Engine\Cache\General::getInstance($this->cacheType)->delete('Preference-'.get_called_class().'['.$this->id.']:'.$var); } else{ $this->__unset($var); } } protected function validate($var, $value): void { } public function __get($var) { $cachedValue=\Engine\Cache\General::getInstance($this->cacheType)->get('Preference-'.get_called_class().'['.$this->id.']:'.$var); if ($cachedValue!==null) return $cachedValue; $getPreferenceSQL="SELECT `".$this->field_value."` FROM `{$this->DBTEntityPreferences}` WHERE `".$this->field_idEntityName."`= ? AND `".$this->field_var."`= ?"; $getPreferenceRes = \DB::getInstance()->Execute($getPreferenceSQL, [$this->id, $var]); if (!$getPreferenceRes) { \Log::getInstance()->dbError("Could not get `".get_called_class()."` preference for entity `{$this->id}`"); throw new \DBException('Unable to get `'.get_called_class().'` preference for id `'.$this->id.'`.'); } $getPreferenceArr = $getPreferenceRes->FetchRow(); if (!$getPreferenceArr) $return = null; else $return = $getPreferenceArr[$this->field_value]; if ($this->cacheTtl!=-1) { \Engine\Cache\General::getInstance($this->cacheType)->set('Preference-'.get_called_class().'['.$this->id.']:'.$var, $return, $this->cacheTtl); } return $return; } public function __unset($var) { $updatePreferenceSQL="DELETE FROM `{$this->DBTEntityPreferences}` WHERE `".$this->field_idEntityName."`= ? AND `".$this->field_var."`= ?"; $updatePreferenceEx=\DB::getInstance()->Execute( $updatePreferenceSQL, [$this->id, $var]); if (!$updatePreferenceEx) { \Log::getInstance()->dbError("Could not unset `".get_called_class()."` preference for entity `{$this->id}`"); throw new \DBException('Unable to unset `'.get_called_class().'` preference for id `'.$this->id.'`.'); } \Engine\Cache\General::getInstance($this->cacheType)->delete('Preference-'.get_called_class().'['.$this->id.']:'.$var); return true; } static public function getInstance($idEntity = null) { $className = get_called_class(); $cache = \Engine\Cache\General::getInstance('localMemory'); $cacheKey = sprintf("%s:%s:%s", __METHOD__, $className, $idEntity); $obj = $cache->get($cacheKey); if ($obj===null) { $obj = new static($idEntity); $cache->set($cacheKey, $obj, PHP_INT_MAX); } return $obj; } final protected function __construct($id) { $this->setDbTableName(); if (!$this->DBTEntityPreferences) { throw new \Exception('The class `'.get_called_class().'` does not have the `DBTEntityPreferences` attribute set.'); } $this->setEntityId($id); } abstract protected function setDbTableName() ; protected function setEntityId($id) { if (!is_numeric($id) or $id<0) { throw new \Exception('Preference entity id is not valid'); } $this->id = $id; } public function getId() { return $this->id; } } 