id = null; if ($id !== null && is_numeric($id)) $this->selectById($id); } public static function init($config = null) { if (self::$dbo !== null) return true; // @codeCoverageIgnoreStart // Load config from written file; this file is created from setup script if ($config === null && self::$config === null) { self::$config = @include("core/config.inc.php"); if (empty(self::$config)) return false; } // @codeCoverageIgnoreEnd else self::$config = $config; self::$dbo = new \PDO(self::$config[0], self::$config[1], self::$config[2]); return true; } public static function getDbPrefix() { return self::$config[3]; } public function getTableName() { $className = new \ReflectionClass($this); return $this->getDbPrefix().strtolower($className->getShortName()); } public static function setup() { $tables = array("Admin", "User", "Address", "Cart", "Category", "Product", "CartProduct", "Meta", "Cms", "Config", "Module", "ModuleHook"); self::init(); self::$dbo->beginTransaction(); try { foreach ($tables as $i) { $i = "Entity\\".$i; $table = new $i(); if ($table->install() != true) throw new \Exception("{$i}: Cannot table setup failure"); } } catch (\Exception $e) { self::$dbo->rollBack(); error_log($e->getMessage()); return false; } self::$dbo->commit(); return true; } public function getMeta($lang=null) { $fetcher = new \Entity\Meta(); return $fetcher->query(array("type" => get_class($this))); } public function __get($key) { if ($key == "meta") return $this->getMeta(); if ($key == "id") return $this->id === null ? null : (int) $this->id; if (!isset($this->fieldsValues[$key])) return null; return $this->fieldsValues[$key]; } public function __set($key, $value) { if ($value instanceof \DateTime) $value = $value->format("Y-m-d"); $this->fieldsValues[$key] = $value; if (is_bool($value)) $this->changed[$key] = $value ? 1 : 0; else $this->changed[$key] = self::$dbo->quote($value); return $value; } public function save() { \Tools\Hooks::trigger("onBeforeEntitySave"); \Tools\Hooks::trigger("onBeforeEntitySave".$this->getTableName()); if ($this->id === null) { if (empty ($this->changed)) { $query = "INSERT INTO `{$this->getTableName()}` () VALUES ()"; $result = self::$dbo->exec($query); if (!$result) throw new \Exception(self::$dbo->errorInfo()[2]); } else { $query = "INSERT INTO `{$this->getTableName()}` (`" .implode("`,`", array_keys($this->changed)) . "`) VALUES (" . implode(",", $this->changed) . ")"; $result = self::$dbo->exec($query); if (!$result) throw new \Exception(self::$dbo->errorInfo()[2]); $this->changed = array(); } $this->id = self::$dbo->lastInsertId(); } else { if (!empty($this->changed)) { if ($this->id === false) throw new \Exception("Cannot update private row"); $query = "UPDATE {$this->getTableName()} SET "; $newValues = array(); foreach ($this->changed as $i => $j) $newValues[] = "`{$i}`=" . $j; $query .= implode(",",$newValues)." WHERE id={$this->id}"; $result = self::$dbo->exec($query); if (!$result) throw new \Exception(self::$dbo->errorInfo()[2]); $this->changed = array(); } } \Tools\Hooks::trigger("onAfterEntitySave"); \Tools\Hooks::trigger("onAfterEntitySave".$this->getTableName()); } public function selects($criteria = null, $orderBy = null) { $query = "SELECT * FROM {$this->getTableName()}"; if (!empty($criteria)) { $subQuery = array(); foreach ($criteria as $i => $j) { if ($j == null) $subQuery[] = "`{$i}` IS NULL"; else if (is_array($j)) { $inArray = []; foreach ($j as $k) $inArray[] = self::$dbo->quote($k); $subQuery[] = "`{$i}` IN (".implode(",", $inArray).")"; } else $subQuery[] = "`{$i}`=".self::$dbo->quote($j); } $query .= " WHERE ".implode(" AND ", $subQuery); } if (!empty($orderBy)) { $_orderBy = array(); foreach ($orderBy as $i => $j) { if (is_numeric($i)) $_orderBy[] = "`{$j}` ASC"; else { $orderType = "ASC"; if (strtoupper($j == "DESC")) $orderType = "DESC"; $_orderBy[] = "`{$i}` {$orderType}"; } } $query .= " ORDER BY ".implode(",", $_orderBy); } $result = self::$dbo->query($query, \PDO::FETCH_ASSOC); if ($result === false) throw new \Exception(self::$dbo->errorInfo()[2]); $resultObj = array(); $className = get_class($this); foreach ($result as $i) { $iObj = new $className(); $iObj->populate($i); $resultObj[] = $iObj; } return $resultObj; } public function selectById($id) { $query = "SELECT * FROM {$this->getTableName()} WHERE id=".(int)$id." LIMIT 1"; $result = self::$dbo->query($query, \PDO::FETCH_ASSOC); if ($result === false || empty($result)) throw new \Exception("Cannot fetch data: ".self::$dbo->errorInfo()[2]); $this->populate($result->fetch()); } private function populate($data) { $this->id = FALSE; foreach ($data as $i => $j) $this->fieldsValues[$i] = $j; if (isset($this->fieldsValues["id"])) $this->id = (int) $this->fieldsValues["id"]; $this->changed = array(); } }