diff --git a/core/Api/CreateApiKey.class.php b/core/Api/CreateApiKey.class.php
index ba6ec01..a0c3c3c 100644
--- a/core/Api/CreateApiKey.class.php
+++ b/core/Api/CreateApiKey.class.php
@@ -17,13 +17,20 @@ class CreateApiKey extends Request {
}
$apiKey = generateRandomString(64);
- $query = "INSERT INTO ApiKey (user_id, api_key, valid_until) VALUES (?,?,(SELECT DATE_ADD(now(), INTERVAL 30 DAY)))";
- $request = new ExecuteStatement($this->user);
- $this->success = $request->execute(array("query" => $query, $this->user->getId(), $apiKey));
- $this->lastError = $request->getLastError();
- $this->result["api_key"] = $apiKey;
- $this->result["valid_until"] = "TODO";
- $this->result["uid"] = $this->user->getSQL()->getLastInsertId();
+ $sql = $this->user->getSQL();
+ $validUntil = (new \DateTime())->modify("+30 DAY");
+
+ $this->success = $sql->insert("ApiKey", array("user_id", "api_key", "valid_until"))
+ ->addRow($this->user->getId(), $apiKey, $validUntil)
+ ->execute();
+
+ $this->lastError = $sql->getLastError();
+
+ if ($this->success) {
+ $this->result["api_key"] = $apiKey;
+ $this->result["valid_until"] = $validUntil->getTimestamp();
+ $this->result["uid"] = $sql->getLastInsertId();
+ }
return $this->success;
}
};
diff --git a/core/Api/ExecuteSelect.class.php b/core/Api/ExecuteSelect.class.php
deleted file mode 100644
index b54f4fc..0000000
--- a/core/Api/ExecuteSelect.class.php
+++ /dev/null
@@ -1,109 +0,0 @@
- new StringType('query')
- ));
-
- $this->isPublic = false;
- $this->variableParamCount = true;
- }
-
- public function execute($values = array()) {
- if(!parent::execute($values)) {
- return false;
- }
-
- $sql = $this->user->getSQL();
- $this->success = false;
- $this->result['rows'] = array();
-
- if(count($this->params) === 1) {
- $res = $sql->query($this->getParam('query'));
- if(!$res) {
- $this->lastError = 'Database Error: query() failed with ' . $sql->getLastError();
- return false;
- }
-
- while($row = $res->fetch_assoc()) {
- array_push($this->result['rows'], $row);
- }
-
- $this->success = true;
- $res->close();
- } else {
- $aSqlParams = array('');
- foreach($this->params as $param) {
- if($param->name === 'query') continue;
-
- $value = $param->value;
- switch($param->type) {
- case Parameter::TYPE_BOOLEAN:
- $value = $param->value ? 1 : 0;
- case Parameter::TYPE_INT:
- $aSqlParams[0] .= 'i';
- break;
- case Parameter::TYPE_FLOAT:
- $aSqlParams[0] .= 'd';
- break;
- case Parameter::TYPE_DATE:
- $value = $value->format('Y-m-d');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_TIME:
- $value = $value->format('H:i:s');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_DATE_TIME:
- $value = $value->format('Y-m-d H:i:s');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_EMAIL:
- default:
- $aSqlParams[0] .= 's';
- }
-
- $aSqlParams[] = $value;
- }
-
- $tmp = array();
- foreach($aSqlParams as $key => $value) $tmp[$key] = &$aSqlParams[$key];
- if($stmt = $sql->connection->prepare($this->getParam('query'))) {
- if(call_user_func_array(array($stmt, "bind_param"), $tmp))
- {
- if($stmt->execute()) {
- $res = $stmt->get_result();
- if($res) {
- while($row = $res->fetch_assoc()) {
- array_push($this->result['rows'], $row);
- }
- $res->close();
- $this->success = true;
- } else {
- $this->lastError = 'Database Error: execute() failed with ' . $sql->getLastError();
- }
- } else {
- $this->lastError = 'Database Error: get_result() failed with ' . $sql->getLastError();
- }
- } else {
- $this->lastError = 'Database Error: bind_param() failed with ' . $sql->getLastError();
- }
-
- $stmt->close();
- } else {
- $this->lastError = 'Database Error: prepare failed with() ' . $sql->getLastError();
- }
- }
-
- return $this->success;
- }
-};
-
-?>
diff --git a/core/Api/ExecuteStatement.class.php b/core/Api/ExecuteStatement.class.php
deleted file mode 100644
index 7162fbc..0000000
--- a/core/Api/ExecuteStatement.class.php
+++ /dev/null
@@ -1,97 +0,0 @@
- new StringType('query')
- ));
-
- $this->isPublic = false;
- $this->variableParamCount = true;
- }
-
- public function execute($values = array()) {
- if(!parent::execute($values)) {
- return false;
- }
-
- $this->success = false;
- $this->result['rows'] = array();
-
- if(count($this->params) == 1) {
- $this->success = $this->user->getSQL()->execute($this->getParam('query'));
- if(!$this->success) {
- $this->lastError = $this->user->getSQL()->getLastError();
- }
- } else {
- $aSqlParams = array('');
- foreach($this->params as $param) {
- if($param->name === 'query') continue;
-
- $value = $param->value;
- if(is_null($value)) {
- $aSqlParams[0] .= 's';
- } else {
- switch($param->type) {
- case Parameter::TYPE_BOOLEAN:
- $value = $param->value ? 1 : 0;
- $aSqlParams[0] .= 'i';
- break;
- case Parameter::TYPE_INT:
- $aSqlParams[0] .= 'i';
- break;
- case Parameter::TYPE_FLOAT:
- $aSqlParams[0] .= 'd';
- break;
- case Parameter::TYPE_DATE:
- $value = $value->format('Y-m-d');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_TIME:
- $value = $value->format('H:i:s');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_DATE_TIME:
- $value = $value->format('Y-m-d H:i:s');
- $aSqlParams[0] .= 's';
- break;
- case Parameter::TYPE_EMAIL:
- default:
- $aSqlParams[0] .= 's';
- }
- }
-
- $aSqlParams[] = $value;
- }
-
- $tmp = array();
- foreach($aSqlParams as $key => $value) $tmp[$key] = &$aSqlParams[$key];
- if($stmt = $this->user->getSQL()->connection->prepare($this->getParam('query'))) {
- if(call_user_func_array(array($stmt, "bind_param"), $tmp)) {
- if($stmt->execute()) {
- $this->result['rows'] = $stmt->affected_rows;
- $this->success = true;
- } else {
- $this->lastError = 'Database Error: execute() failed with ' . $this->user->getSQL()->getLastError();
- }
- } else {
- $this->lastError = 'Database Error: bind_param() failed with ' . $this->user->getSQL()->getLastError();
- }
-
- $stmt->close();
- } else {
- $this->lastError = 'Database Error: prepare() failed with ' . $this->user->getSQL()->getLastError();
- }
- }
-
- return $this->success;
- }
-};
-
-?>
diff --git a/core/Api/External/RequestData.class.php b/core/Api/External/RequestData.class.php
deleted file mode 100644
index 468883b..0000000
--- a/core/Api/External/RequestData.class.php
+++ /dev/null
@@ -1,82 +0,0 @@
- new StringType("url", 256)
- ));
- $this->isPublic = false;
- }
-
- private function requestURL() {
- $url = $this->getParam("url");
-
- $ckfile = tempnam("/tmp", 'cookiename');
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
- // curl_setopt($ch, CURLOPT_HEADER, 1);
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
- curl_setopt($ch, CURLOPT_COOKIESESSION, true);
- curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
- curl_setopt($ch, CURLOPT_COOKIEFILE, $ckfile);
- $data = curl_exec($ch);
- $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
-
- $success = false;
- if(curl_errno($ch)) {
- $this->lastError = curl_error($ch);
- } else if($statusCode != 200) {
- $this->lastError = "External Site returned status code: " . $statusCode;
- } else {
- $this->result["data"] = $data;
- $this->result["cached"] = false;
- $success = true;
- }
-
- unlink($ckfile);
- curl_close ($ch);
- return $success;
- }
-
- public function execute($values = array()) {
- if(!parent::execute($values)) {
- return false;
- }
-
- $url = $this->getParam("url");
- $expires = $this->getParam("expires");
-
- $query = "SELECT data, expires FROM ExternalSiteCache WHERE url=?";
- $req = new \Api\ExecuteSelect($this->user);
- $this->success = $req->execute(array("query" => $query, $url));
- $this->lastError = $req->getLastError();
-
- if($this->success) {
- $mustRevalidate = true;
-
- if(!empty($req->getResult()['rows'])) {
- $row = $req->getResult()['rows'][0];
- if($row["expires"] == null || !isinPast($row["expires"])) {
- $mustRevalidate = false;
- $this->result["data"] = $row["data"];
- $this->result["expires"] = $row["expires"];
- $this->result["cached"] = true;
- }
- }
-
- if($mustRevalidate) {
- $this->success = $this->requestURL();
- }
- }
-
- return $this->success;
- }
-};
-
-?>
diff --git a/core/Api/External/WriteData.class.php b/core/Api/External/WriteData.class.php
deleted file mode 100644
index d982a13..0000000
--- a/core/Api/External/WriteData.class.php
+++ /dev/null
@@ -1,44 +0,0 @@
- new StringType("url", 256),
- "data" => new StringType("data", -1),
- "expires" => new Parameter("expires", Parameter::TYPE_INT, false, 0),
- ));
- $this->isPublic = false;
- }
-
- public function execute($values = array()) {
- if(!parent::execute($values)) {
- return false;
- }
-
- $url = $this->getParam("url");
- $data = $this->getParam("data");
- $expires = $this->getParam("expires");
-
- if($expires > 0) {
- $expires = getDateTime(new \DateTime("+${expires} seconds"));
- } else {
- $expires = null;
- }
-
- $query = "INSERT INTO ExternalSiteCache (url, data, expires) VALUES(?,?,?)
- ON DUPLICATE KEY UPDATE data=?, expires=?";
-
- $request = new \Api\ExecuteStatement($this->user);
- $this->success = $request->execute(array("query" => $query, $url, $data, $expires, $data, $expires));
- $this->lastError = $request->getLastError();
-
- return $this->lastError;
- }
-}
-
-?>
diff --git a/core/Api/GetApiKeys.class.php b/core/Api/GetApiKeys.class.php
index 79469ad..8d53594 100644
--- a/core/Api/GetApiKeys.class.php
+++ b/core/Api/GetApiKeys.class.php
@@ -2,6 +2,9 @@
namespace Api;
+use \Driver\SQL\Keyword;
+use \Driver\SQL\Condition\Compare;
+
class GetApiKeys extends Request {
public function __construct($user, $externCall = false) {
@@ -14,16 +17,19 @@ class GetApiKeys extends Request {
return false;
}
- $query = "SELECT ApiKey.uid, ApiKey.api_key, ApiKey.valid_until
- FROM ApiKey
- WHERE ApiKey.user_id = ?
- AND ApiKey.valid_until > now()";
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array("query" => $query, $this->user->getId()));
- $this->lastError = $request->getLastError();
+ $sql = $this->user->getSQL();
+ $res = $sql->select("uid", "api_key", "valid_until")
+ ->from("ApiKey")
+ ->where(new Compare("user_id", $this->user->getId()))
+ ->where(new Compare("valid_until", new Keyword($sql->currentTimestamp()), ">"))
+ ->where(new Compare("active", true))
+ ->execute();
+
+ $this->success = ($res !== FALSE);
+ $this->lastError = $sql->getLastError();
if($this->success) {
- $this->result["api_keys"] = $request->getResult()['rows'];
+ $this->result["api_keys"] = $res;
}
return $this->success;
diff --git a/core/Api/GetLanguages.class.php b/core/Api/GetLanguages.class.php
index aec1f86..d10be01 100644
--- a/core/Api/GetLanguages.class.php
+++ b/core/Api/GetLanguages.class.php
@@ -13,17 +13,20 @@ class GetLanguages extends Request {
return false;
}
- $query = 'SELECT uid, code, name FROM Language';
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array('query' => $query));
- $this->lastError = $request->getLastError();
+ $sql = $this->user->getSQL();
+ $res = $sql->select("uid", "code", "name")
+ ->from("Language")
+ ->execute();
+
+ $this->success = ($res !== FALSE);
+ $this->lastError = $sql->getLastError();
if($this->success) {
$this->result['languages'] = array();
- if(count($request->getResult()['rows']) === 0) {
+ if(empty($res) === 0) {
$this->lastError = L("No languages found");
} else {
- foreach($request->getResult()['rows'] as $row) {
+ foreach($res as $row) {
$this->result['languages'][$row['uid']] = $row;
}
}
diff --git a/core/Api/Login.class.php b/core/Api/Login.class.php
index e6b2cf9..ea4b412 100644
--- a/core/Api/Login.class.php
+++ b/core/Api/Login.class.php
@@ -4,6 +4,7 @@ namespace Api;
use Api\Parameter\Parameter;
use Api\Parameter\StringType;
+use Driver\SQL\Condition\Compare;
class Login extends Request {
@@ -42,27 +43,30 @@ class Login extends Request {
$password = $this->getParam('password');
$stayLoggedIn = $this->getParam('stayLoggedIn');
- $query = 'SELECT User.uid, User.password, User.salt FROM User WHERE User.name=?';
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array('query' => $query, $username));
- $this->lastError = $request->getLastError();
+ $sql = $this->user->getSQL();
+ $res = $sql->select("User.uid", "User.password", "User.salt")
+ ->from("User")
+ ->where(new Compare("User.name", $username))
+ ->execute();
+
+ $this->success = ($res !== FALSE);
+ $this->lastError = $sql->getLastError();
if($this->success) {
- $this->success = false;
- if(count($request->getResult()['rows']) === 0) {
+ if(count($res) === 0) {
return $this->wrongCredentials();
- $this->lastError = L('Wrong username or password');
} else {
- $row = $request->getResult()['rows'][0];
+ $row = $res[0];
$salt = $row['salt'];
$uid = $row['uid'];
$hash = hash('sha256', $password . $salt);
if($hash === $row['password']) {
- if(!($this->success = $this->user->createSession($uid, $stayLoggedIn))) {
- return $this->createError("Error creating Session");
- } else {
- $this->result['logoutIn'] = $this->user->getSession()->getExpiresSeconds();
- }
+ if(!($this->success = $this->user->createSession($uid, $stayLoggedIn))) {
+ return $this->createError("Error creating Session: " . $sql->getLastError());
+ } else {
+ $this->result['logoutIn'] = $this->user->getSession()->getExpiresSeconds();
+ $this->success = true;
+ }
}
else {
return $this->wrongCredentials();
diff --git a/core/Api/Logout.class.php b/core/Api/Logout.class.php
index 4fb6149..c126bc0 100644
--- a/core/Api/Logout.class.php
+++ b/core/Api/Logout.class.php
@@ -15,9 +15,9 @@ class Logout extends Request {
return false;
}
- $this->success = true;
- $this->user->logout();
- return true;
+ $this->success = $this->user->logout();
+ $this->lastError = $this->user->getSQL()->getLastError();
+ return $this->success;
}
};
diff --git a/core/Api/RefreshApiKey.class.php b/core/Api/RefreshApiKey.class.php
index 9f83af8..3a24a30 100644
--- a/core/Api/RefreshApiKey.class.php
+++ b/core/Api/RefreshApiKey.class.php
@@ -1,7 +1,10 @@
getParam("id");
- $query = "SELECT * FROM ApiKey WHERE uid = ? AND user_id = ? AND valid_until > now()";
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array("query" => $query, $id, $this->user->getId()));
- $this->lastError = $request->getLastError();
- if($this->success && count($request->getResult()['rows']) == 0) {
+ $sql = $this->user->getSQL();
+ $res = $sql->select("COUNT(*)")
+ ->from("ApiKey")
+ ->where(new Compare("uid", $id))
+ ->where(new Compare("user_id", $this->user->getId()))
+ ->where(new Compare("valid_until", new Keyword($sql->currentTimestamp()), ">"))
+ ->where(new Compare("active", 1))
+ ->execute();
+
+ $this->success = ($res !== FALSE);
+ $this->lastError = $sql->getLastError();
+
+ if($this->success && $res[0]["COUNT(*)"] === 0) {
$this->success = false;
$this->lastError = "This API-Key does not exist.";
}
@@ -36,10 +47,18 @@ class RefreshApiKey extends Request {
if(!$this->apiKeyExists())
return false;
- $query = "UPDATE ApiKey SET valid_until = (SELECT DATE_ADD(now(), INTERVAL 30 DAY)) WHERE uid = ? AND user_id = ? AND valid_until > now()";
- $request = new ExecuteStatement($this->user);
- $this->success = $request->execute(array("query" => $query, $id, $this->user->getId()));
- $this->lastError = $request->getLastError();
+ $validUntil = (new \DateTime)->modify("+30 DAY");
+ $sql = $this->user->getSQL();
+ $this->success = $sql->update("ApiKey")
+ ->set("valid_until", $validUntil)
+ ->where(new Compare("uid", $id))
+ ->where(new Compare("user_id", $this->user->getId()))
+ ->execute();
+ $this->lastError = $sql->getLastError();
+
+ if ($this->success) {
+ $this->result["valid_until"] = $validUntil->getTimestamp();
+ }
return $this->success;
}
diff --git a/core/Api/RevokeApiKey.class.php b/core/Api/RevokeApiKey.class.php
index 314ebd9..f2b8448 100644
--- a/core/Api/RevokeApiKey.class.php
+++ b/core/Api/RevokeApiKey.class.php
@@ -1,7 +1,10 @@
getParam("id");
- $query = "SELECT * FROM ApiKey WHERE uid = ? AND user_id = ? AND valid_until > now()";
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array("query" => $query, $id, $this->user->getId()));
- $this->lastError = $request->getLastError();
- if($this->success && count($request->getResult()['rows']) == 0) {
+ $sql = $this->user->getSQL();
+ $res = $sql->select("COUNT(*)")
+ ->from("ApiKey")
+ ->where(new Compare("uid", $id))
+ ->where(new Compare("user_id", $this->user->getId()))
+ ->where(new Compare("valid_until", new Keyword($sql->currentTimestamp()), ">"))
+ ->where(new Compare("active", 1))
+ ->execute();
+
+ $this->success = ($res !== FALSE);
+ $this->lastError = $sql->getLastError();
+
+ if($this->success && $res[0]["COUNT(*)"] === 0) {
$this->success = false;
$this->lastError = "This API-Key does not exist.";
}
@@ -36,10 +47,13 @@ class RevokeApiKey extends Request {
if(!$this->apiKeyExists())
return false;
- $query = "DELETE FROM ApiKey WHERE valid_until < now() OR (uid = ? AND user_id = ?)";
- $request = new ExecuteStatement($this->user);
- $this->success = $request->execute(array("query" => $query, $id, $this->user->getId()));
- $this->lastError = $request->getLastError();
+ $sql = $this->user->getSQL();
+ $this->success = $sql->update("ApiKey")
+ ->set("active", false)
+ ->where(new Compare("uid", $id))
+ ->where(new Compare("user_id", $this->user->getId()))
+ ->execute();
+ $this->lastError = $sql->getLastError();
return $this->success;
}
diff --git a/core/Api/SetLanguage.class.php b/core/Api/SetLanguage.class.php
index 881cfbf..c12d69a 100644
--- a/core/Api/SetLanguage.class.php
+++ b/core/Api/SetLanguage.class.php
@@ -4,6 +4,8 @@ namespace Api;
use Api\Parameter\Parameter;
use Api\Parameter\StringType;
+use Driver\SQL\Condition\CondOr;
+use Driver\SQL\Condition\Compare;
class SetLanguage extends Request {
@@ -24,16 +26,20 @@ class SetLanguage extends Request {
return $this->createError(L("Either langId or langCode must be given"));
}
- $query = "SELECT uid, code, name FROM Language WHERE uid=? OR code=?";
- $request = new ExecuteSelect($this->user);
- $this->success = $request->execute(array("query" => $query, $langId, $langCode));
- $this->lastError = $request->getLastError();
+ $res = $this->user->getSQL()
+ ->select("uid", "code", "name")
+ ->from("Language")
+ ->where(new CondOr(new Compare("uid", $langId), new Compare("code", $langCode)))
+ ->execute();
- if($this->success) {
- if(count($request->getResult()['rows']) == 0) {
+ $this->success = ($res !== FALSE);
+ $this->lastError = $this->user->getSQL()->getLastError();
+
+ if ($this->success) {
+ if(count($res) == 0) {
return $this->createError(L("This Language does not exist"));
} else {
- $row = $request->getResult()['rows'][0];
+ $row = $res[0];
$this->language = \Objects\Language::newInstance($row['uid'], $row['code'], $row['name']);
if(!$this->language) {
return $this->createError(L("Error while loading language"));
@@ -47,11 +53,13 @@ class SetLanguage extends Request {
private function updateLanguage() {
$languageId = $this->language->getId();
$userId = $this->user->getId();
+ $sql = $this->user->getSQL();
- $query = "UPDATE User SET language_id = ? WHERE uid = ?";
- $request = new ExecuteStatement($this->user);
- $this->success = $request->execute(array("query" => $query, $languageId, $userId));
- $this->lastError = $request->getLastError();
+ $this->success = $sql->update("User")
+ ->set("language_id", $languageId)
+ ->where(new Compare("uid", $userId))
+ ->execute();
+ $this->lastError = $sql->getLastError();
return $this->success;
}
diff --git a/core/Configuration/CreateDatabase.class.php b/core/Configuration/CreateDatabase.class.php
new file mode 100644
index 0000000..8d18a6a
--- /dev/null
+++ b/core/Configuration/CreateDatabase.class.php
@@ -0,0 +1,94 @@
+createTable("Language")
+ ->addSerial("uid")
+ ->addString("code", 5)
+ ->addString("name", 32)
+ ->primaryKey("uid")
+ ->unique("code")
+ ->unique("name");
+
+ $queries[] = $sql->insert("Language", array("uid", "code", "name"))
+ ->addRow(1, "en_US", 'American English')
+ ->addRow(2, "de_DE", 'Deutsch Standard')
+ ->onDuplicateKeyStrategy(new UpdateStrategy(array("name" => new Column("name"))));
+
+ $queries[] = $sql->createTable("User")
+ ->addSerial("uid")
+ ->addString("email", 64, true)
+ ->addString("name", 32)
+ ->addString("salt", 16)
+ ->addString("password", 64)
+ ->addInt("language_id", true, 1)
+ ->primaryKey("uid")
+ ->unique("email")
+ ->unique("name")
+ ->foreignKey("language_id", "Language", "uid", new SetNullStrategy());
+
+ $queries[] = $sql->createTable("Session")
+ ->addSerial("uid")
+ ->addBool("active", true)
+ ->addDateTime("expires")
+ ->addInt("user_id")
+ ->addString("ipAddress", 45)
+ ->addString("os", 64)
+ ->addString("browser", 64)
+ ->addJson("data", false, '{}')
+ ->addBool("stay_logged_in", true)
+ ->primaryKey("uid", "user_id")
+ ->foreignKey("user_id", "User", "uid", new CascadeStrategy());
+
+ $queries[] = $sql->createTable("UserToken")
+ ->addInt("user_id")
+ ->addString("token", 36)
+ ->addEnum("type", array("password_reset", "confirmation"))
+ ->addDateTime("valid_until")
+ ->foreignKey("user_id", "User", "uid", new CascadeStrategy());
+
+ $queries[] = $sql->createTable("Group")
+ ->addSerial("uid")
+ ->addString("name", 32)
+ ->primaryKey("uid")
+ ->unique("name");
+
+ $queries[] = $sql->insert("Group", array("uid", "name"))
+ ->addRow(1, "Default")
+ ->addRow(2, "Administrator")
+ ->onDuplicateKeyStrategy(new UpdateStrategy(array("name" => new Column("name"))));
+
+ $queries[] = $sql->createTable("UserGroup")
+ ->addInt("user_id")
+ ->addInt("group_id")
+ ->unique("user_id", "group_id")
+ ->foreignKey("user_id", "User", "uid")
+ ->foreignKey("group_id", "Group", "uid");
+
+ $queries[] = $sql->createTable("ApiKey")
+ ->addSerial("uid")
+ ->addInt("user_id")
+ ->addBool("active", true)
+ ->addString("api_key", 64)
+ ->addDateTime("valid_until")
+ ->primaryKey("uid")
+ ->foreignKey("user_id", "User", "uid");
+
+ return $queries;
+ }
+}
+
+?>
diff --git a/core/Configuration/database.sql b/core/Configuration/database.sql
index 7fda489..b4ce6d4 100644
--- a/core/Configuration/database.sql
+++ b/core/Configuration/database.sql
@@ -20,11 +20,11 @@ CREATE TABLE IF NOT EXISTS User (
`password` varchar(64) NOT NULL,
`language_id` int(11) DEFAULT 1,
PRIMARY KEY (`uid`),
- FOREIGN KEY (`language_id`) REFERENCES `Language` (`uid`) ON DELETE SET DEFAULT
+ FOREIGN KEY (`language_id`) REFERENCES `Language` (`uid`) ON DELETE SET NULL
);
CREATE TABLE IF NOT EXISTS UserInvitation (
- `email` VARCHAR(256) NOT NULL,
+ `email` VARCHAR(64) NOT NULL,
`token` VARCHAR(36) UNIQUE NOT NULL,
`valid_until` DATETIME NOT NULL
);
diff --git a/core/Documents/Install.class.php b/core/Documents/Install.class.php
index f917714..c0b429f 100644
--- a/core/Documents/Install.class.php
+++ b/core/Documents/Install.class.php
@@ -97,18 +97,15 @@ namespace Documents\Install {
return self::DATABASE_CONFIGURATION;
}
- $request = new \Api\ExecuteSelect($user);
- $success = $request->execute(array("query" => "SELECT COUNT(*) AS count FROM User"));
- $this->errorString = $request->getLastError();
-
- if($success) {
- if($request->getResult()['rows'][0]["count"] > 0) {
+ $res = $user->getSQL()->select("COUNT(*) as count")->from("User")->execute();
+ if ($res === FALSE) {
+ return self::DATABASE_CONFIGURATION;
+ } else {
+ if ($res[0]["count"] > 0) {
$step = self::ADD_MAIL_SERVICE;
} else {
return self::CREATE_USER;
}
- } else {
- return self::DATABASE_CONFIGURATION;
}
if($step === self::ADD_MAIL_SERVICE && $config->isFilePresent("Mail")) {
@@ -163,6 +160,9 @@ namespace Documents\Install {
$username = $this->getParameter("username");
$password = $this->getParameter("password");
$database = $this->getParameter("database");
+ $type = $this->getParameter("type");
+ $encoding = $this->getParameter("encoding");
+ $encoding = ($encoding ? $encoding : "UTF-8");
$success = true;
$missingInputs = array();
@@ -191,43 +191,54 @@ namespace Documents\Install {
$missingInputs[] = "Database";
}
+ if(is_null($type) || empty($type)) {
+ $success = false;
+ $missingInputs[] = "Type";
+ }
+
+ $supportedTypes = array("mysql"); # , "oracle", "postgres");
if(!$success) {
$msg = "Please fill out the following inputs:
" .
$this->createUnorderedList($missingInputs);
} else if(!is_numeric($port) || ($port = intval($port)) < 1 || $port > 65535) {
$msg = "Port must be in range of 1-65535.";
$success = false;
+ } else if(!in_array($type, $supportedTypes)) {
+ $msg = "Unsupported database type. Must be one of: " . implode(", ", $supportedTypes);
+ $success = false;
} else {
$connectionData = new \Objects\ConnectionData($host, $port, $username, $password);
$connectionData->setProperty('database', $database);
- $connectionData->setProperty('encoding', 'utf8');
- $sql = new \Driver\SQL($connectionData);
- $success = $sql->connect();
-
- if(!$success) {
+ $connectionData->setProperty('encoding', $encoding);
+ $connectionData->setProperty('type', $type);
+ $sql = \Driver\SQL\SQL::createConnection($connectionData);
+ $success = false;
+ if(!($sql instanceof \Driver\SQL\SQL)) {
+ $msg = "Error connecting to database: " . str($sql);
+ } else if(!$sql->isConnected()) {
$msg = "Error connecting to database:
" . $sql->getLastError();
} else {
- try {
- $msg = "Error loading database script $this->databaseScript";
- $commands = file_get_contents($this->databaseScript);
- $success = $sql->executeMulti($commands);
- if(!$success) {
- $msg = $sql->getLastError();
- } else if(!$this->getDocument()->getUser()->getConfiguration()->create("Database", $connectionData)) {
+
+ $msg = "";
+ $success = true;
+ $queries = \Configuration\CreateDatabase::createQueries($sql);
+ foreach($queries as $query) {
+ if (!$query->execute()) {
+ $msg = "Error creating tables: " . $sql->getLastError();
$success = false;
- $msg = "Unable to write file";
- } else {
- $msg = "";
+ break;
}
- } catch(Exception $e) {
- $success = false;
- $msg .= ": " . $e->getMessage();
}
- if($sql) {
- $sql->close();
+ if($success && !$this->getDocument()->getUser()->getConfiguration()->create("Database", $connectionData)) {
+ $success = false;
+ $msg = "Unable to write file";
}
}
+
+ if($sql) {
+ $sql->close();
+ }
}
return array("success" => $success, "msg" => $msg);
@@ -280,10 +291,13 @@ namespace Documents\Install {
} else {
$salt = generateRandomString(16);
$hash = hash('sha256', $password . $salt);
- $query = "INSERT INTO User (name, salt, password) VALUES (?,?,?)";
- $req = new \Api\ExecuteStatement($user);
- $success = $req->execute(array("query" => $query, $username, $salt, $hash));
- $nsg = $req->getLastError();
+ $sql = $user->getSQL();
+
+ $success = $sql->insert("User", array("name", "salt", "password"))
+ ->addRow($username, $salt, $hash)
+ ->execute();
+
+ $msg = $sql->getLastError();
}
return array("msg" => $msg, "success" => $success);
@@ -293,9 +307,9 @@ namespace Documents\Install {
$user = $this->getDocument()->getUser();
if($this->getParameter("prev") === "true") {
- $req = new \Api\ExecuteStatement($user);
- $success = $req->execute(array("query" => "TRUNCATE User"));
- $msg = $req->getLastError();
+ $sql = $user->getSQL();
+ $success = $sql->delete("User")->execute();
+ $msg = $sql->getLastError();
return array("success" => $success, "msg" => $msg);
}
@@ -462,40 +476,58 @@ namespace Documents\Install {
$attributes = array(
"name" => $name,
"id" => $name,
- "class" => "form-control",
- "type" => $type,
+ "class" => "form-control"
);
if(isset($formItem["required"]) && $formItem["required"]) {
$attributes["required"] = "";
}
- if(isset($formItem["value"]) && $formItem["value"]) {
- $attributes["value"] = $formItem["value"];
+ if ($type !== "select") {
+ $attributes["type"] = $type;
+
+ if(isset($formItem["value"]) && $formItem["value"]) {
+ $attributes["value"] = $formItem["value"];
+ }
+
+ if($type === "number") {
+ if(isset($formItem["min"]) && is_numeric($formItem["min"]))
+ $attributes["min"] = $formItem["min"];
+ if(isset($formItem["max"]) && is_numeric($formItem["max"]))
+ $attributes["max"] = $formItem["max"];
+ if(isset($formItem["step"]) && is_numeric($formItem["step"]))
+ $attributes["step"] = $formItem["step"];
+ }
}
- if($type === "number") {
- if(isset($formItem["min"]) && is_numeric($formItem["min"]))
- $attributes["min"] = $formItem["min"];
- if(isset($formItem["max"]) && is_numeric($formItem["max"]))
- $attributes["max"] = $formItem["max"];
- if(isset($formItem["step"]) && is_numeric($formItem["step"]))
- $attributes["step"] = $formItem["step"];
+ $replacements = array("+" => " ", "&" => "\" ", "=" => "=\"");
+ $attributes = http_build_query($attributes) . "\"";
+ foreach($replacements as $key => $val) {
+ $attributes = str_replace($key, $val, $attributes);
}
- $attributes = str_replace("+", " ", str_replace("&", "\" ", str_replace("=", "=\"", http_build_query($attributes)))) . "\"";
+ if ($type === "select") {
+ $items = $formItem["items"] ?? array();
+ $element = "";
+ } else {
+ $element = "";
+ }
if(!$inline) {
return
"
-
+ $element
";
} else {
return
"
-
+ $element
";
}
}
@@ -510,6 +542,9 @@ namespace Documents\Install {
self::DATABASE_CONFIGURATION => array(
"title" => "Database configuration",
"form" => array(
+ array("title" => "Database Type", "name" => "type", "type" => "select", "required" => true, "items" => array(
+ "mysql" => "MySQL", "oracle" => "Oracle", "postgres" => "PostgreSQL"
+ )),
array("title" => "Username", "name" => "username", "type" => "text", "required" => true),
array("title" => "Password", "name" => "password", "type" => "password"),
array("title" => "Database", "name" => "database", "type" => "text", "required" => true),
@@ -523,6 +558,10 @@ namespace Documents\Install {
"value" => "3306", "min" => "1", "max" => "65535", "row" => true
)
)),
+ array(
+ "title" => "Encoding", "name" => "encoding", "type" => "text", "required" => false,
+ "value" => "UTF-8"
+ ),
)
),
self::CREATE_USER => array(
diff --git a/core/Driver/SQL.class.php b/core/Driver/SQL.class.php
deleted file mode 100644
index 80a1bf1..0000000
--- a/core/Driver/SQL.class.php
+++ /dev/null
@@ -1,133 +0,0 @@
-connection = NULL;
- $this->lastError = 'Not connected';
- $this->connectionData = $connectionData;
- }
-
- public function connect() {
- if(!is_null($this->connection))
- return true;
-
- @$this->connection = mysqli_connect(
- $this->connectionData->getHost(),
- $this->connectionData->getLogin(),
- $this->connectionData->getPassword(),
- $this->connectionData->getProperty('database'),
- $this->connectionData->getPort()
- );
-
- if (mysqli_connect_errno($this->connection)) {
- $this->lastError = "Failed to connect to MySQL: " . mysqli_connect_error();
- $this->connection = NULL;
- return false;
- }
-
- mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding'));
- return true;
- }
-
- public function disconnect() {
- if(is_null($this->connection))
- return;
-
- mysqli_close($this->connection);
- $this->connection = NULL;
- }
-
- public function isConnected() {
- return !is_null($this->connection);
- }
-
- public function getLastError() {
- return empty(trim($this->lastError)) ? mysqli_error($this->connection) . " " . $this->getLastErrorNumber() : trim($this->lastError);
- }
-
- public function setLastError($str) {
- $this->lastError = $str;
- }
-
- public function getLastErrorNumber() {
- return mysqli_errno($this->connection);
- }
-
- public function getLastInsertId() {
- return $this->connection->insert_id;
- }
-
- public function close() {
- if(!is_null($this->connection)) {
- $this->connection->close();
- }
- }
-
- public function getAffectedRows() {
- return $this->connection->affected_rows;
- }
-
- public function execute($query) {
- if(!$this->isConnected()) {
- return false;
- }
-
- if(!mysqli_query($this->connection, $query)) {
- $this->lastError = mysqli_error($this->connection);
- return false;
- }
-
- return true;
- }
-
- public function executeMulti($queries) {
- if(!$this->isConnected()) {
- return false;
- }
-
- if(!$this->connection->multi_query($queries)) {
- $this->lastError = mysqli_error($this->connection);
- return false;
- }
-
- while (($success = $this->connection->next_result())) {
- if (!$this->connection->more_results()) break;
- }
-
- if(!$success) {
- $this->lastError = mysqli_error($this->connection);
- return false;
- }
-
- return true;
- }
-
- public function query($query) {
- if(!$this->isConnected()) {
- return false;
- }
-
- $res = mysqli_query($this->connection, $query);
- if(!$res) {
- $this->lastError = mysqli_error($this->connection);
- return false;
- }
-
- return $res;
- }
-
- public static function createConnection($connectionData) {
- $sql = new SQL($connectionData);
- $sql->connect();
- return $sql;
- }
-}
-
-?>
diff --git a/core/Driver/SQL/Column/BoolColumn.class.php b/core/Driver/SQL/Column/BoolColumn.class.php
new file mode 100644
index 0000000..8c91230
--- /dev/null
+++ b/core/Driver/SQL/Column/BoolColumn.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Column/Column.class.php b/core/Driver/SQL/Column/Column.class.php
new file mode 100644
index 0000000..658a011
--- /dev/null
+++ b/core/Driver/SQL/Column/Column.class.php
@@ -0,0 +1,23 @@
+name = $name;
+ $this->nullable = $nullable;
+ $this->defaultValue = $defaultValue;
+ }
+
+ public function getName() { return $this->name; }
+ public function notNull() { return !$this->nullable; }
+ public function getDefaultValue() { return $this->defaultValue; }
+
+}
+
+?>
diff --git a/core/Driver/SQL/Column/DateTimeColumn.class.php b/core/Driver/SQL/Column/DateTimeColumn.class.php
new file mode 100644
index 0000000..7c41ab9
--- /dev/null
+++ b/core/Driver/SQL/Column/DateTimeColumn.class.php
@@ -0,0 +1,12 @@
+
diff --git a/core/Driver/SQL/Column/EnumColumn.class.php b/core/Driver/SQL/Column/EnumColumn.class.php
new file mode 100644
index 0000000..e5744a4
--- /dev/null
+++ b/core/Driver/SQL/Column/EnumColumn.class.php
@@ -0,0 +1,17 @@
+values = $values;
+ }
+
+ public function getValues() { return $this->values; }
+}
+
+?>
diff --git a/core/Driver/SQL/Column/IntColumn.class.php b/core/Driver/SQL/Column/IntColumn.class.php
new file mode 100644
index 0000000..8c904a2
--- /dev/null
+++ b/core/Driver/SQL/Column/IntColumn.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Column/JsonColumn.class.php b/core/Driver/SQL/Column/JsonColumn.class.php
new file mode 100644
index 0000000..748237c
--- /dev/null
+++ b/core/Driver/SQL/Column/JsonColumn.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Column/SerialColumn.class.php b/core/Driver/SQL/Column/SerialColumn.class.php
new file mode 100644
index 0000000..2e25825
--- /dev/null
+++ b/core/Driver/SQL/Column/SerialColumn.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Column/StringColumn.class.php b/core/Driver/SQL/Column/StringColumn.class.php
new file mode 100644
index 0000000..381580f
--- /dev/null
+++ b/core/Driver/SQL/Column/StringColumn.class.php
@@ -0,0 +1,17 @@
+maxSize = $maxSize;
+ }
+
+ public function getMaxSize() { return $this->maxSize; }
+}
+
+?>
diff --git a/core/Driver/SQL/Condition/Compare.class.php b/core/Driver/SQL/Condition/Compare.class.php
new file mode 100644
index 0000000..93a32eb
--- /dev/null
+++ b/core/Driver/SQL/Condition/Compare.class.php
@@ -0,0 +1,19 @@
+operator = $operator;
+ $this->column = $col;
+ $this->value = $val;
+ }
+
+ public function getColumn() { return $this->column; }
+ public function getValue() { return $this->value; }
+ public function getOperator() { return $this->operator; }
+
+}
+
+?>
diff --git a/core/Driver/SQL/Condition/CondAnd.class.php b/core/Driver/SQL/Condition/CondAnd.class.php
new file mode 100644
index 0000000..7616c90
--- /dev/null
+++ b/core/Driver/SQL/Condition/CondAnd.class.php
@@ -0,0 +1,16 @@
+conditions = $conditions;
+ }
+
+ public function getConditions() { return $this->conditions; }
+}
+
+?>
diff --git a/core/Driver/SQL/Condition/CondBool.class.php b/core/Driver/SQL/Condition/CondBool.class.php
new file mode 100644
index 0000000..d374ea8
--- /dev/null
+++ b/core/Driver/SQL/Condition/CondBool.class.php
@@ -0,0 +1,15 @@
+value = $val;
+ }
+
+ public function getValue() { return $this->value; }
+
+}
+
+?>
diff --git a/core/Driver/SQL/Condition/CondOr.class.php b/core/Driver/SQL/Condition/CondOr.class.php
new file mode 100644
index 0000000..c145632
--- /dev/null
+++ b/core/Driver/SQL/Condition/CondOr.class.php
@@ -0,0 +1,16 @@
+conditions = $conditions;
+ }
+
+ public function getConditions() { return $this->conditions; }
+}
+
+?>
diff --git a/core/Driver/SQL/Condition/Condition.class.php b/core/Driver/SQL/Condition/Condition.class.php
new file mode 100644
index 0000000..b8e6853
--- /dev/null
+++ b/core/Driver/SQL/Condition/Condition.class.php
@@ -0,0 +1,9 @@
+
diff --git a/core/Driver/SQL/Constraint/Constraint.class.php b/core/Driver/SQL/Constraint/Constraint.class.php
new file mode 100644
index 0000000..83afe69
--- /dev/null
+++ b/core/Driver/SQL/Constraint/Constraint.class.php
@@ -0,0 +1,16 @@
+columnName = $columnName;
+ }
+
+ public function getColumnName() { return $this->columnName; }
+};
+
+?>
diff --git a/core/Driver/SQL/Constraint/ForeignKey.class.php b/core/Driver/SQL/Constraint/ForeignKey.class.php
new file mode 100644
index 0000000..9b88782
--- /dev/null
+++ b/core/Driver/SQL/Constraint/ForeignKey.class.php
@@ -0,0 +1,23 @@
+referencedTable = $refTable;
+ $this->referencedColumn = $refColumn;
+ $this->strategy = $strategy;
+ }
+
+ public function getReferencedTable() { return $this->referencedTable; }
+ public function getReferencedColumn() { return $this->referencedColumn; }
+ public function onDelete() { return $this->strategy; }
+};
+
+?>
diff --git a/core/Driver/SQL/Constraint/PrimaryKey.class.php b/core/Driver/SQL/Constraint/PrimaryKey.class.php
new file mode 100644
index 0000000..1bb7683
--- /dev/null
+++ b/core/Driver/SQL/Constraint/PrimaryKey.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Constraint/Unique.class.php b/core/Driver/SQL/Constraint/Unique.class.php
new file mode 100644
index 0000000..022062d
--- /dev/null
+++ b/core/Driver/SQL/Constraint/Unique.class.php
@@ -0,0 +1,13 @@
+
diff --git a/core/Driver/SQL/Join.class.php b/core/Driver/SQL/Join.class.php
new file mode 100644
index 0000000..270c289
--- /dev/null
+++ b/core/Driver/SQL/Join.class.php
@@ -0,0 +1,26 @@
+tpye = $type;
+ $this->table = $table;
+ $this->columnA = $columnA;
+ $this->columnB = $columnB;
+ }
+
+ public function getType() { return $this->type; }
+ public function getTable() { return $this->table; }
+ public function getColumnA() { return $this->columnA; }
+ public function getColumnB() { return $this->columnB; }
+
+}
+
+?>
diff --git a/core/Driver/SQL/Keyword.class.php b/core/Driver/SQL/Keyword.class.php
new file mode 100644
index 0000000..16bb6c1
--- /dev/null
+++ b/core/Driver/SQL/Keyword.class.php
@@ -0,0 +1,17 @@
+value = $value;
+ }
+
+ public function getValue() { return $this->value; }
+
+}
+
+?>
diff --git a/core/Driver/SQL/MySQL.class.php b/core/Driver/SQL/MySQL.class.php
new file mode 100644
index 0000000..55f675c
--- /dev/null
+++ b/core/Driver/SQL/MySQL.class.php
@@ -0,0 +1,430 @@
+connection)) {
+ return true;
+ }
+
+ @$this->connection = mysqli_connect(
+ $this->connectionData->getHost(),
+ $this->connectionData->getLogin(),
+ $this->connectionData->getPassword(),
+ $this->connectionData->getProperty('database'),
+ $this->connectionData->getPort()
+ );
+
+ if (mysqli_connect_errno($this->connection)) {
+ $this->lastError = "Failed to connect to MySQL: " . mysqli_connect_error();
+ $this->connection = NULL;
+ return false;
+ }
+
+ mysqli_set_charset($this->connection, $this->connectionData->getProperty('encoding'));
+ return true;
+ }
+
+ public function disconnect() {
+ if(is_null($this->connection)) {
+ return true;
+ }
+
+ mysqli_close($this->connection);
+ $this->connection = NULL;
+ }
+
+ public function getLastError() {
+ $lastError = parent::getLastError();
+ if (empty($lastError)) {
+ $lastError = mysqli_error($this->connection);
+ }
+
+ return $lastError;
+ }
+
+ private function getPreparedParams($values) {
+ $sqlParams = array('');
+ foreach($values as $value) {
+ $paramType = Parameter::parseType($value);
+ switch($paramType) {
+ case Parameter::TYPE_BOOLEAN:
+ $value = $value ? 1 : 0;
+ case Parameter::TYPE_INT:
+ $sqlParams[0] .= 'i';
+ break;
+ case Parameter::TYPE_FLOAT:
+ $sqlParams[0] .= 'd';
+ break;
+ case Parameter::TYPE_DATE:
+ $value = $value->format('Y-m-d');
+ $sqlParams[0] .= 's';
+ break;
+ case Parameter::TYPE_TIME:
+ $value = $value->format('H:i:s');
+ $sqlParams[0] .= 's';
+ break;
+ case Parameter::TYPE_DATE_TIME:
+ $value = $value->format('Y-m-d H:i:s');
+ $sqlParams[0] .= 's';
+ break;
+ case Parameter::TYPE_EMAIL:
+ default:
+ $sqlParams[0] .= 's';
+ }
+
+ $sqlParams[] = $value;
+ }
+
+ return $sqlParams;
+ }
+
+ protected function execute($query, $values = NULL, $returnValues = false) {
+
+ $resultRows = array();
+ $this->lastError = "";
+
+ if (is_null($values) || empty($values)) {
+ $res = mysqli_query($this->connection, $query);
+ $success = $res !== FALSE;
+ if ($success && $returnValues) {
+ while($row = $res->fetch_assoc()) {
+ $resultRows[] = $row;
+ }
+ $res->close();
+ }
+ } else if($stmt = $this->connection->prepare($query)) {
+
+ $success = false;
+ $sqlParams = $this->getPreparedParams($values);
+ $tmp = array();
+ foreach($sqlParams as $key => $value) $tmp[$key] = &$sqlParams[$key];
+ if(call_user_func_array(array($stmt, "bind_param"), $tmp)) {
+ if($stmt->execute()) {
+ if ($returnValues) {
+ $res = $stmt->get_result();
+ if($res) {
+ while($row = $res->fetch_assoc()) {
+ $resultRows[] = $row;
+ }
+ $res->close();
+ $success = true;
+ } else {
+ $this->lastError = "PreparedStatement::get_result failed: $stmt->error ($stmt->errno)";
+ }
+ } else {
+ $success = true;
+ }
+ } else {
+ $this->lastError = "PreparedStatement::execute failed: $stmt->error ($stmt->errno)";
+ }
+ } else {
+ $this->lastError = "PreparedStatement::prepare failed: $stmt->error ($stmt->errno)";
+ }
+
+ $stmt->close();
+ } else {
+ $success = false;
+ }
+
+ return ($success && $returnValues) ? $resultRows : $success;
+ }
+
+ public function executeCreateTable($createTable) {
+ $tableName = $createTable->getTableName();
+ $ifNotExists = $createTable->ifNotExists() ? " IF NOT EXISTS": "";
+
+ $entries = array();
+ foreach($createTable->getColumns() as $column) {
+ $entries[] = ($tmp = $this->getColumnDefinition($column));
+ if (is_null($tmp)) {
+ return false;
+ }
+ }
+
+ foreach($createTable->getConstraints() as $constraint) {
+ $entries[] = ($tmp = $this->getConstraintDefinition($constraint));
+ if (is_null($tmp)) {
+ return false;
+ }
+ }
+
+ $entries = implode(",", $entries);
+ $query = "CREATE TABLE$ifNotExists `$tableName` ($entries)";
+ return $this->execute($query);
+ }
+
+ public function executeInsert($insert) {
+ $tableName = $insert->getTableName();
+ $columns = $insert->getColumns();
+ $rows = $insert->getRows();
+ $onDuplicateKey = $insert->onDuplicateKey() ?? "";
+
+ if (empty($rows)) {
+ $this->lastError = "No rows to insert given.";
+ return false;
+ }
+
+ if (is_null($columns) || empty($columns)) {
+ $columns = "";
+ $numColumns = count($rows[0]);
+ } else {
+ $numColumns = count($columns);
+ $columns = " (`" . implode("`, `", $columns) . "`)";
+ }
+
+ $numRows = count($rows);
+ $parameters = array();
+ $values = implode(",", array_fill(0, $numRows, "(" . implode(",", array_fill(0, $numColumns, "?")) . ")"));
+
+ foreach($rows as $row) {
+ $parameters = array_merge($parameters, $row);
+ }
+
+ if ($onDuplicateKey) {
+ if ($onDuplicateKey instanceof UpdateStrategy) {
+ $updateValues = array();
+ foreach($onDuplicateKey->getValues() as $key => $value) {
+ if ($value instanceof Column) {
+ $columnName = $value->getName();
+ $updateValues[] = "`$key`=`$columnName`";
+ } else {
+ $updateValues[] = "`$key`=?";
+ $parameters[] = $value;
+ }
+ }
+
+ $onDuplicateKey = " ON DUPLICATE KEY UPDATE " . implode(",", $updateValues);
+ } else {
+ $strategy = get_class($onDuplicateKey);
+ $this->lastError = "ON DUPLICATE Strategy $strategy is not supported yet.";
+ return false;
+ }
+ }
+
+ $query = "INSERT INTO `$tableName`$columns VALUES$values$onDuplicateKey";
+ $success = $this->execute($query, $parameters);
+
+ if($success) {
+ $this->lastInsertId = mysqli_insert_id($this->connection);
+ }
+
+ return $success;
+ }
+
+ public function executeSelect($select) {
+
+ $columns = implode(",", $select->getColumns());
+ $tables = $select->getTables();
+ $params = array();
+
+ if (is_null($tables) || empty($tables)) {
+ return "SELECT $columns";
+ } else {
+ $tables = implode(",", $tables);
+ }
+
+ $conditions = $select->getConditions();
+ if (!empty($conditions)) {
+ $condition = " WHERE " . $this->buildCondition($conditions, $params);
+ } else {
+ $condition = "";
+ }
+
+ $joinStr = "";
+ $joins = $select->getJoins();
+ if (!empty($joins)) {
+ $joinStr = "";
+ foreach($joins as $join) {
+ $type = $join->getType();
+ $joinTable = $join->getTable();
+ $columnA = $join->getColumnA();
+ $columnB = $join->getColumnB();
+ $joinStr .= " $type JOIN $joinTable ON $columnA=$columnB";
+ }
+ }
+
+ $orderBy = "";
+ $limit = "";
+ $offset = "";
+
+ $query = "SELECT $columns FROM $tables$joinStr$condition$orderBy$limit$offset";
+ return $this->execute($query, $params, true);
+ }
+
+ public function executeDelete($delete) {
+
+ $table = $delete->getTable();
+ $conditions = $delete->getConditions();
+ if (!empty($conditions)) {
+ $condition = " WHERE " . $this->buildCondition($conditions, $params);
+ } else {
+ $condition = "";
+ }
+
+ $query = "DELETE FROM $table$condition";
+ return $this->execute($query);
+ }
+
+ public function executeTruncate($truncate) {
+ return $this->execute("TRUNCATE " . $truncate->getTable());
+ }
+
+ public function executeUpdate($update) {
+
+ $params = array();
+ $table = $update->getTable();
+
+ $valueStr = array();
+ foreach($update->getValues() as $key => $val) {
+ $valueStr[] = "$key=" . $this->addValue($val, $params);
+ }
+ $valueStr = implode(",", $valueStr);
+
+ $conditions = $update->getConditions();
+ if (!empty($conditions)) {
+ $condition = " WHERE " . $this->buildCondition($conditions, $params);
+ } else {
+ $condition = "";
+ }
+
+ $query = "UPDATE $table SET $valueStr$condition";
+ return $this->execute($query, $params);
+ }
+
+ protected function buildCondition($condition, &$params) {
+ if ($condition instanceof \Driver\SQL\Condition\CondOr) {
+ $conditions = array();
+ foreach($condition->getConditions() as $cond) {
+ $conditions[] = $this->buildCondition($cond, $params);
+ }
+ return "(" . implode(" OR ", $conditions) . ")";
+ } else if ($condition instanceof \Driver\SQL\Condition\Compare) {
+ $column = $condition->getColumn();
+ $value = $condition->getValue();
+ $operator = $condition->getOperator();
+ return $column . $operator . $this->addValue($value, $params);
+ } else if ($condition instanceof \Driver\SQL\Condition\CondBool) {
+ return $condition->getValue();
+ } else if (is_array($condition)) {
+ if (count($condition) == 1) {
+ return $this->buildCondition($condition[0], $params);
+ } else {
+ $conditions = array();
+ foreach($condition as $cond) {
+ $conditions[] = $this->buildCondition($cond, $params);
+ }
+ return implode(" AND ", $conditions);
+ }
+ }
+ }
+
+ public function getColumnDefinition($column) {
+ $columnName = $column->getName();
+
+ if ($column instanceof StringColumn) {
+ $maxSize = $column->getMaxSize();
+ if ($maxSize) {
+ $type = "VARCHAR($maxSize)";
+ } else {
+ $type = "TEXT";
+ }
+ } else if($column instanceof SerialColumn) {
+ $type = "INTEGER AUTO_INCREMENT";
+ } else if($column instanceof IntColumn) {
+ $type = "INTEGER";
+ } else if($column instanceof DateTimeColumn) {
+ $type = "DATETIME";
+ } else if($column instanceof EnumColumn) {
+ $values = array();
+ foreach($column->getValues() as $value) {
+ $values[] = $this->getValueDefinition($value);
+ }
+
+ $values = implode(",", $values);
+ $type = "ENUM($values)";
+ } else if($column instanceof BoolColumn) {
+ $type = "BOOLEAN";
+ } else if($column instanceof JsonColumn) {
+ $type = "JSON";
+ } else {
+ $this->lastError = "Unsupported Column Type: " . get_class($column);
+ return NULL;
+ }
+
+ $notNull = $column->notNull() ? " NOT NULL" : "";
+ $defaultValue = (!is_null($column->getDefaultValue()) || !$column->notNull()) ? " DEFAULT " . $this->getValueDefinition($column->getDefaultValue()) : "";
+ return "`$columnName` $type$notNull$defaultValue";
+ }
+
+ public function getConstraintDefinition($constraint) {
+ $columnName = $constraint->getColumnName();
+ if ($constraint instanceof PrimaryKey) {
+ if (is_array($columnName)) $columnName = implode('`,`', $columnName);
+ return "PRIMARY KEY (`$columnName`)";
+ } else if ($constraint instanceof Unique) {
+ if (is_array($columnName)) $columnName = implode('`,`', $columnName);
+ return "UNIQUE (`$columnName`)";
+ } else if ($constraint instanceof ForeignKey) {
+ $refTable = $constraint->getReferencedTable();
+ $refColumn = $constraint->getReferencedColumn();
+ $strategy = $constraint->onDelete();
+ $code = "FOREIGN KEY (`$columnName`) REFERENCES `$refTable` (`$refColumn`)";
+ if ($strategy instanceof SetDefaultStrategy) {
+ $code .= " ON DELETE SET DEFAULT";
+ } else if($strategy instanceof SetNullStrategy) {
+ $code .= " ON DELETE SET NULL";
+ } else if($strategy instanceof CascadeStrategy) {
+ $code .= " ON DELETE CASCADE";
+ }
+
+ return $code;
+ }
+ }
+
+ // TODO: check this please..
+ // TODO: Constants??
+ public function getValueDefinition($value) {
+ if (is_numeric($value) || is_bool($value)) {
+ return $value;
+ } else if(is_null($value)) {
+ return "NULL";
+ } else if($value instanceof Keyword) {
+ return $value->getValue();
+ } else {
+ $str = addslashes($value);
+ return "'$str'";
+ }
+ }
+
+ public function currentTimestamp() {
+ return "NOW()";
+ }
+};
diff --git a/core/Driver/SQL/Query/CreateTable.class.php b/core/Driver/SQL/Query/CreateTable.class.php
new file mode 100644
index 0000000..77116de
--- /dev/null
+++ b/core/Driver/SQL/Query/CreateTable.class.php
@@ -0,0 +1,97 @@
+tableName = $name;
+ $this->columns = array();
+ $this->constraints = array();
+ $this->ifNotExists = false;
+ }
+
+ public function addSerial($name) {
+ $this->columns[$name] = new SerialColumn($name);
+ return $this;
+ }
+
+ public function addString($name, $maxSize=NULL, $nullable=false, $defaultValue=NULL) {
+ $this->columns[$name] = new StringColumn($name, $maxSize, $nullable, $defaultValue);
+ return $this;
+ }
+
+ public function addDateTime($name, $nullable=false, $defaultNow=false) {
+ $this->columns[$name] = new DateTimeColumn($name, $nullable, $defaultNow);
+ return $this;
+ }
+
+ public function addInt($name, $nullable=false, $defaultValue=NULL) {
+ $this->columns[$name] = new IntColumn($name, $nullable, $defaultValue);
+ return $this;
+ }
+
+ public function addBool($name, $defaultValue=false) {
+ $this->columns[$name] = new BoolColumn($name, $defaultValue);
+ return $this;
+ }
+
+ public function addJson($name, $nullable=false, $defaultValue=NULL) {
+ $this->columns[$name] = new JsonColumn($name, $nullable, $defaultValue);
+ return $this;
+ }
+
+ public function addEnum($name, $values, $nullable=false, $defaultValue=NULL) {
+ $this->columns[$name] = new EnumColumn($name, $values, $nullable, $defaultValue);
+ return $this;
+ }
+
+ public function primaryKey(...$names) {
+ $this->constraints[] = new PrimaryKey($names);
+ return $this;
+ }
+
+ public function unique(...$names) {
+ $this->constraints[] = new Unique($names);
+ return $this;
+ }
+
+ public function foreignKey($name, $refTable, $refColumn, $strategy = NULL) {
+ $this->constraints[] = new ForeignKey($name, $refTable, $refColumn, $strategy);
+ return $this;
+ }
+
+ public function onlyIfNotExists() {
+ $this->ifNotExists = true;
+ return $this;
+ }
+
+ public function execute() {
+ return $this->sql->executeCreateTable($this);
+ }
+
+ public function ifNotExists() { return $this->ifNotExists; }
+ public function getTableName() { return $this->tableName; }
+ public function getColumns() { return $this->columns; }
+ public function getConstraints() { return $this->constraints; }
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Delete.class.php b/core/Driver/SQL/Query/Delete.class.php
new file mode 100644
index 0000000..1b4f507
--- /dev/null
+++ b/core/Driver/SQL/Query/Delete.class.php
@@ -0,0 +1,29 @@
+table = $table;
+ $this->conditions = array();
+ }
+
+ public function where(...$conditions) {
+ $this->conditions = array_merge($this->conditions, $conditions);
+ return $this;
+ }
+
+ public function execute() {
+ return $this->sql->executeDelete($this);
+ }
+
+ public function getTable() { return $this->table; }
+ public function getConditions() { return $this->conditions; }
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Insert.class.php b/core/Driver/SQL/Query/Insert.class.php
new file mode 100644
index 0000000..b6145dd
--- /dev/null
+++ b/core/Driver/SQL/Query/Insert.class.php
@@ -0,0 +1,40 @@
+tableName = $name;
+ $this->columns = $columns;
+ $this->rows = array();
+ $this->onDuplicateKey = NULL;
+ }
+
+ public function addRow(...$values) {
+ $this->rows[] = $values;
+ return $this;
+ }
+
+ public function onDuplicateKeyStrategy($strategy) {
+ $this->onDuplicateKey = $strategy;
+ return $this;
+ }
+
+ public function execute() {
+ return $this->sql->executeInsert($this);
+ }
+
+ public function getTableName() { return $this->tableName; }
+ public function getColumns() { return $this->columns; }
+ public function getRows() { return $this->rows; }
+ public function onDuplicateKey() { return $this->onDuplicateKey; }
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Query.class.php b/core/Driver/SQL/Query/Query.class.php
new file mode 100644
index 0000000..dce4510
--- /dev/null
+++ b/core/Driver/SQL/Query/Query.class.php
@@ -0,0 +1,17 @@
+sql = $sql;
+ }
+
+ public abstract function execute();
+
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Select.class.php b/core/Driver/SQL/Query/Select.class.php
new file mode 100644
index 0000000..4616393
--- /dev/null
+++ b/core/Driver/SQL/Query/Select.class.php
@@ -0,0 +1,50 @@
+columns = (!empty($columns) && is_array($columns[0])) ? $columns[0] : $columns;
+ $this->tables = array();
+ $this->conditions = array();
+ $this->joins = array();
+ }
+
+ public function from(...$tables) {
+ $this->tables = array_merge($this->tables, $tables);
+ return $this;
+ }
+
+ public function where(...$conditions) {
+ $this->conditions = array_merge($this->conditions, $conditions);
+ return $this;
+ }
+
+ public function innerJoin($table, $columnA, $columnB) {
+ $this->joins[] = new \Driver\SQL\Join("INNER", $table, $columnA, $columnB);
+ return $this;
+ }
+
+ public function leftJoin($table, $columnA, $columnB) {
+ $this->joins[] = new \Driver\SQL\Join("LEFT", $table, $columnA, $columnB);
+ return $this;
+ }
+
+ public function execute() {
+ return $this->sql->executeSelect($this);
+ }
+
+ public function getColumns() { return $this->columns; }
+ public function getTables() { return $this->tables; }
+ public function getConditions() { return $this->conditions; }
+ public function getJoins() { return $this->joins; }
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Truncate.class.php b/core/Driver/SQL/Query/Truncate.class.php
new file mode 100644
index 0000000..d5b39af
--- /dev/null
+++ b/core/Driver/SQL/Query/Truncate.class.php
@@ -0,0 +1,21 @@
+tableName = $name;
+ }
+
+ public function execute() {
+ return $this->sql->executeTruncate($this);
+ }
+
+ public function getTableName() { return $this->tableName; }
+};
+
+?>
diff --git a/core/Driver/SQL/Query/Update.class.php b/core/Driver/SQL/Query/Update.class.php
new file mode 100644
index 0000000..9c29edf
--- /dev/null
+++ b/core/Driver/SQL/Query/Update.class.php
@@ -0,0 +1,37 @@
+values = array();
+ $this->table = $table;
+ $this->conditions = array();
+ }
+
+ public function where(...$conditions) {
+ $this->conditions = array_merge($this->conditions, $conditions);
+ return $this;
+ }
+
+ public function set($key, $val) {
+ $this->values[$key] = $val;
+ return $this;
+ }
+
+ public function execute() {
+ return $this->sql->executeUpdate($this);
+ }
+
+ public function getTable() { return $this->table; }
+ public function getConditions() { return $this->conditions; }
+ public function getValues() { return $this->values; }
+};
+
+?>
diff --git a/core/Driver/SQL/SQL.class.php b/core/Driver/SQL/SQL.class.php
new file mode 100644
index 0000000..ff4b47a
--- /dev/null
+++ b/core/Driver/SQL/SQL.class.php
@@ -0,0 +1,186 @@
+type = $type;
+ $this->connection = NULL;
+ $this->lastError = 'Not connected';
+ $this->connectionData = $connectionData;
+ $this->lastInsertId = 0;
+ }
+
+ public abstract function connect();
+ public abstract function disconnect();
+
+ public function isConnected() {
+ return !is_null($this->connection);
+ }
+
+ public function getLastError() {
+ return trim($this->lastError);
+ }
+
+ // public function executeQuery($query) {
+ // if(!$this->isConnected()) {
+ // $this->lastError = "Database is not connected yet.";
+ // return false;
+ // }
+ //
+ // return $query->execute($this);
+ // // var_dump($generatedQuery);
+ // // return $this->execute($generatedQuery);
+ // }
+
+ public function createTable($tableName) {
+ return new Query\CreateTable($this, $tableName);
+ }
+
+ public function insert($tableName, $columns=array()) {
+ return new Query\Insert($this, $tableName, $columns);
+ }
+
+ public function select(...$columNames) {
+ return new Query\Select($this, $columNames);
+ }
+
+ public function truncate($table) {
+ return new Query\Truncate($this, $table);
+ }
+
+ public function delete($table) {
+ return new Query\Delete($this, $table);
+ }
+
+ public function update($table) {
+ return new Query\Update($this, $table);
+ }
+
+ // Querybuilder
+ public abstract function executeCreateTable($query);
+ public abstract function executeInsert($query);
+ public abstract function executeSelect($query);
+ public abstract function executeDelete($query);
+ public abstract function executeTruncate($query);
+ public abstract function executeUpdate($query);
+
+ //
+ public abstract function currentTimestamp();
+
+ protected abstract function getColumnDefinition($column);
+ protected abstract function getConstraintDefinition($constraint);
+ protected abstract function getValueDefinition($val);
+ protected abstract function buildCondition($conditions, &$params);
+
+ // Execute
+ protected abstract function execute($query, $values=NULL, $returnValues=false);
+
+ public function setLastError($str) {
+ $this->lastError = $str;
+ }
+
+ protected function addValue($val, &$params) {
+ if ($val instanceof Keyword) {
+ return $val->getValue();
+ } else {
+ $params[] = $val;
+ return "?";
+ }
+ }
+
+ /*public function getLastErrorNumber() {
+ return mysqli_errno($this->connection);
+ }*/
+
+ public function getLastInsertId() {
+ return $this->lastInsertId;
+ }
+
+ public function close() {
+ if(!is_null($this->connection)) {
+ $this->connection->close();
+ }
+ }
+
+ /*public function getAffectedRows() {
+ return $this->connection->affected_rows;
+ }*/
+
+ /*
+ public function execute($query) {
+ if(!$this->isConnected()) {
+ return false;
+ }
+
+ if(!mysqli_query($this->connection, $query)) {
+ $this->lastError = mysqli_error($this->connection);
+ return false;
+ }
+
+ return true;
+ }
+
+ public function executeMulti($queries) {
+ if(!$this->isConnected()) {
+ return false;
+ }
+
+ if(!$this->connection->multi_query($queries)) {
+ $this->lastError = mysqli_error($this->connection);
+ return false;
+ }
+
+ while (($success = $this->connection->next_result())) {
+ if (!$this->connection->more_results()) break;
+ }
+
+ if(!$success) {
+ $this->lastError = mysqli_error($this->connection);
+ return false;
+ }
+
+ return true;
+ }
+
+ public function query($query) {
+ if(!$this->isConnected()) {
+ return false;
+ }
+
+ $res = mysqli_query($this->connection, $query);
+ if(!$res) {
+ $this->lastError = mysqli_error($this->connection);
+ return false;
+ }
+
+ return $res;
+ }
+ */
+
+ public static function createConnection($connectionData) {
+ $type = $connectionData->getProperty("type");
+ if ($type === "mysql") {
+ $sql = new MySQL($connectionData);
+ /*} else if ($type === "postgres") {
+ // $sql = new PostgreSQL($connectionData);
+ } else if ($type === "oracle") {
+ // $sql = new OracleSQL($connectionData);
+ */
+ } else {
+ return "Unknown database type";
+ }
+
+ $sql->connect();
+ return $sql;
+ }
+}
+
+?>
diff --git a/core/Driver/SQL/Strategy/CascadeStrategy.class.php b/core/Driver/SQL/Strategy/CascadeStrategy.class.php
new file mode 100644
index 0000000..103f8bd
--- /dev/null
+++ b/core/Driver/SQL/Strategy/CascadeStrategy.class.php
@@ -0,0 +1,12 @@
+
diff --git a/core/Driver/SQL/Strategy/SetDefaultStrategy.class.php b/core/Driver/SQL/Strategy/SetDefaultStrategy.class.php
new file mode 100644
index 0000000..b896080
--- /dev/null
+++ b/core/Driver/SQL/Strategy/SetDefaultStrategy.class.php
@@ -0,0 +1,12 @@
+
diff --git a/core/Driver/SQL/Strategy/SetNullStrategy.class.php b/core/Driver/SQL/Strategy/SetNullStrategy.class.php
new file mode 100644
index 0000000..7b6fd05
--- /dev/null
+++ b/core/Driver/SQL/Strategy/SetNullStrategy.class.php
@@ -0,0 +1,12 @@
+
diff --git a/core/Driver/SQL/Strategy/Strategy.class.php b/core/Driver/SQL/Strategy/Strategy.class.php
new file mode 100644
index 0000000..83b662d
--- /dev/null
+++ b/core/Driver/SQL/Strategy/Strategy.class.php
@@ -0,0 +1,9 @@
+
diff --git a/core/Driver/SQL/Strategy/UpdateStrategy.class.php b/core/Driver/SQL/Strategy/UpdateStrategy.class.php
new file mode 100644
index 0000000..3fce860
--- /dev/null
+++ b/core/Driver/SQL/Strategy/UpdateStrategy.class.php
@@ -0,0 +1,16 @@
+values = $values;
+ }
+
+ public function getValues() { return $this->values; }
+};
+
+?>
diff --git a/core/Objects/Session.class.php b/core/Objects/Session.class.php
index acc025f..5a54ede 100644
--- a/core/Objects/Session.class.php
+++ b/core/Objects/Session.class.php
@@ -2,6 +2,8 @@
namespace Objects;
+use \Driver\SQL\Condition\Compare;
+
class Session extends ApiObject {
const DURATION = 120;
@@ -84,20 +86,22 @@ class Session extends ApiObject {
public function insert($stayLoggedIn) {
$this->updateMetaData();
- $query = "INSERT INTO Session (expires, user_id, ipAddress, os, browser, data, stay_logged_in)
- VALUES (DATE_ADD(NOW(), INTERVAL ? MINUTE),?,?,?,?,?,?)";
- $request = new \Api\ExecuteStatement($this->user);
+ $sql = $this->user->getSQL();
- $success = $request->execute(array(
- 'query' => $query,
- Session::DURATION,
- $this->user->getId(),
- $this->ipAddress,
- $this->os,
- $this->browser,
- json_encode($_SESSION),
- $stayLoggedIn
- ));
+ $hours = Session::DURATION;
+ $columns = array("expires", "user_id", "ipAddress", "os", "browser", "data", "stay_logged_in");
+
+ $success = $sql
+ ->insert("Session", $columns)
+ ->addRow(
+ (new \DateTime)->modify("+$hours hour"),
+ $this->user->getId(),
+ $this->ipAddress,
+ $this->os,
+ $this->browser,
+ json_encode($_SESSION),
+ $stayLoggedIn)
+ ->execute();
if($success) {
$this->sessionId = $this->user->getSQL()->getLastInsertId();
@@ -108,30 +112,30 @@ class Session extends ApiObject {
}
public function destroy() {
- $query = 'DELETE FROM Session WHERE Session.uid=? OR (Session.stay_logged_in = 0 AND Session.expires<=NOW())';
- $request = new \Api\ExecuteStatement($this->user);
- $success = $request->execute(array('query' => $query, $this->sessionId));
+ $success = $this->user->getSQL()->update("Session")
+ ->set("active", false)
+ ->where(new Compare("Session.uid", $this->sessionId))
+ ->where(new Compare("Session.user_id", $this->user->getId()))
+ ->execute();
+
return $success;
}
public function update() {
$this->updateMetaData();
+ $hours = Session::DURATION;
- $query = 'UPDATE Session
- SET Session.expires=DATE_ADD(NOW(), INTERVAL ? MINUTE),
- Session.ipAddress=?, Session.os=?, Session.browser=?, Session.data=?
- WHERE Session.uid=?';
+ $sql = $this->user->getSQL();
+ $success = $sql->update("Session")
+ ->set("Session.expires", (new \DateTime)->modify("+$hours hour"))
+ ->set("Session.ipAddress", $this->ipAddress)
+ ->set("Session.os", $this->os)
+ ->set("Session.browser", $this->browser)
+ ->set("Session.data", json_encode($_SESSION))
+ ->where(new Compare("Session.uid", $this->sessionId))
+ ->where(new Compare("Session.user_id", $this->user->getId()))
+ ->execute();
- $request = new \Api\ExecuteStatement($this->user);
- $success = $request->execute(array(
- 'query' => $query,
- Session::DURATION,
- $this->ipAddress,
- $this->os,
- $this->browser,
- json_encode($_SESSION),
- $this->sessionId,
- ));
return $success;
}
}
diff --git a/core/Objects/User.class.php b/core/Objects/User.class.php
index 6d6c701..f1e9d21 100644
--- a/core/Objects/User.class.php
+++ b/core/Objects/User.class.php
@@ -2,6 +2,11 @@
namespace Objects;
+use Driver\SQL\Keyword;
+use Driver\SQL\Column\Column;
+use Driver\SQL\Condition\Compare;
+use Driver\SQL\Condition\CondBool;
+
class User extends ApiObject {
private $sql;
@@ -30,7 +35,7 @@ class User extends ApiObject {
private function connectDb() {
$databaseConf = $this->configuration->getDatabase();
if($databaseConf) {
- $this->sql = \Driver\SQL::createConnection($databaseConf);
+ $this->sql = \Driver\SQL\SQL::createConnection($databaseConf);
}
}
@@ -74,10 +79,13 @@ class User extends ApiObject {
}
public function logout() {
+ $success = true;
if($this->loggedIn) {
- $this->session->destroy();
+ $success = $this->session->destroy();
$this->reset();
}
+
+ return $success;
}
public function updateLanguage($lang) {
@@ -96,30 +104,29 @@ class User extends ApiObject {
}
public function readData($userId, $sessionId, $sessionUpdate = true) {
- $query = 'SELECT User.name as userName, Language.uid as langId, Language.code as langCode,
- Language.name as langName, Session.data as sessionData, Session.stay_logged_in as stayLoggedIn
- FROM User
- INNER JOIN Session ON User.uid=Session.user_id
- LEFT JOIN Language ON User.language_id=Language.uid
- WHERE User.uid=? AND Session.uid=?
- AND (Session.stay_logged_in OR Session.expires>now())';
- $request = new \Api\ExecuteSelect($this);
- $success = $request->execute(array('query' => $query, $userId, $sessionId));
- // var_dump($userId);
- // var_dump($sessionId);
- // var_dump($request->getResult());
+ $res = $this->sql->select("User.name", "Language.uid as langId", "Language.code as langCode", "Language.name as langName",
+ "Session.data", "Session.stay_logged_in")
+ ->from("User")
+ ->innerJoin("Session", "Session.user_id", "User.uid")
+ ->leftJoin("Language", "User.language_id", "Language.uid")
+ ->where(new Compare("User.uid", $userId))
+ ->where(new Compare("Session.uid", $sessionId))
+ ->where(new Compare("Session.active", true))
+ ->where(new CondBool("Session.stay_logged_in"), new Compare("Session.expires", new Keyword($this->sql->currentTimestamp()), '>'))
+ ->execute();
+ $success = ($res !== FALSE);
if($success) {
- if(count($request->getResult()['rows']) === 0) {
+ if(empty($res)) {
$success = false;
} else {
- $row = $request->getResult()['rows'][0];
- $this->username = $row['userName'];
+ $row = $res[0];
+ $this->username = $row['name'];
$this->uid = $userId;
$this->session = new Session($this, $sessionId);
- $this->session->setData(json_decode($row["sessionData"]));
- $this->session->stayLoggedIn($row["stayLoggedIn"]);
+ $this->session->setData(json_decode($row["data"]));
+ $this->session->stayLoggedIn($row["stay_logged_in"]);
if($sessionUpdate) $this->session->update();
$this->loggedIn = true;
@@ -127,6 +134,8 @@ class User extends ApiObject {
$this->setLangauge(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
}
}
+ } else {
+ var_dump($this->sql->getLastError());
}
return $success;
@@ -171,29 +180,34 @@ class User extends ApiObject {
}
public function authorize($apiKey) {
+
if($this->loggedIn)
return true;
- $query = 'SELECT ApiKey.user_id as uid, User.name as username, Language.uid as langId, Language.code as langCode
- FROM ApiKey, User
- LEFT JOIN Language ON User.language_id=Language.uid
- WHERE api_key=? AND valid_until > now() AND User.uid = ApiKey.user_id';
-
- $request = new \Api\ExecuteSelect($this);
- $success = $request->execute(array('query' => $query, $apiKey));
+ $res = $this->sql->select("ApiKey.user_id as uid", "User.name as username", "Language.uid as langId", "Language.code as langCode", "Language.name as langName")
+ ->from("ApiKey")
+ ->innerJoin("User", "ApiKey.user_id", "User.uid")
+ ->leftJoin("Language", "User.language_id", "Language.uid")
+ ->where(new Compare("ApiKey.api_key", $apiKey))
+ ->where(new Compare("valid_until", new Keyword($this->sql->currentTimestamp()), ">"))
+ ->where(new COmpare("ApiKey.active", 1))
+ ->execute();
+ $success = ($res !== FALSE);
if($success) {
- if(count($request->getResult()['rows']) === 0) {
+ if(empty($res)) {
$success = false;
} else {
- $row = $request->getResult()['rows'][0];
+ $row = $res[0];
$this->uid = $row['uid'];
$this->username = $row['username'];
if(!is_null($row['langId'])) {
- $this->setLangauge(Language::newInstance($row['langId'], $row['langCode']));
+ $this->setLangauge(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
}
}
+ } else {
+ var_dump($this->sql->getLastError());
}
return $success;