php 7.4 dev branch
This commit is contained in:
parent
2636719583
commit
a8fc52b42a
2
.idea/.gitignore
vendored
Normal file
2
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/web-base.iml" filepath="$PROJECT_DIR$/.idea/web-base.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
4
.idea/php.xml
Normal file
4
.idea/php.xml
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="7.4" />
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
8
.idea/web-base.iml
Normal file
8
.idea/web-base.iml
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -2,6 +2,10 @@
|
||||
|
||||
Web-Base is a php framework which provides basic web functionalities.
|
||||
|
||||
### Requirements
|
||||
- PHP >= 7.4
|
||||
- One of these php extensions: mysqli, postgres
|
||||
|
||||
### Current Functionalities:
|
||||
- Installation Guide with automatic database setup
|
||||
- REST API
|
||||
|
@ -3,10 +3,11 @@
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
|
||||
class Create extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array());
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->apiKeyAllowed = false;
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
@ -39,6 +40,4 @@ class Create extends Request {
|
||||
}
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -3,12 +3,13 @@
|
||||
namespace Api\ApiKey;
|
||||
|
||||
use \Api\Request;
|
||||
use DateTime;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array());
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
@ -31,16 +32,20 @@ class Fetch extends Request {
|
||||
if($this->success) {
|
||||
$this->result["api_keys"] = array();
|
||||
foreach($res as $row) {
|
||||
try {
|
||||
$validUntil = (new DateTime($row["valid_until"]))->getTimestamp();
|
||||
} catch (\Exception $e) {
|
||||
$validUntil = $row["valid_until"];
|
||||
}
|
||||
|
||||
$this->result["api_keys"][] = array(
|
||||
"uid" => $row["uid"],
|
||||
"api_key" => $row["api_key"],
|
||||
"valid_until" => (new \DateTime($row["valid_until"]))->getTimestamp(),
|
||||
);
|
||||
"uid" => $row["uid"],
|
||||
"api_key" => $row["api_key"],
|
||||
"valid_until" => $validUntil,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -8,8 +8,8 @@ use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Refresh extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
@ -62,6 +62,4 @@ class Refresh extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -8,8 +8,8 @@ use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Revoke extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
"id" => new Parameter("id", Parameter::TYPE_INT),
|
||||
));
|
||||
$this->loginRequired = true;
|
||||
@ -57,6 +57,4 @@ class Revoke extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
||||
|
@ -4,8 +4,8 @@ namespace Api;
|
||||
|
||||
class GetLanguages extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array());
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
}
|
||||
|
||||
public function execute($values = array()) {
|
||||
@ -34,6 +34,4 @@ class GetLanguages extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -9,8 +9,8 @@ use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Create extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'groupId' => new Parameter('groupId', Parameter::TYPE_INT, true),
|
||||
'userId' => new Parameter('userId', Parameter::TYPE_INT, true),
|
||||
'title' => new StringType('title', 32),
|
||||
@ -130,6 +130,4 @@ class Create extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -7,10 +7,10 @@ use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Fetch extends Request {
|
||||
|
||||
private $notifications;
|
||||
private array $notifications;
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array());
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array());
|
||||
$this->loginRequired = true;
|
||||
}
|
||||
|
||||
@ -89,6 +89,4 @@ class Fetch extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -2,6 +2,8 @@
|
||||
|
||||
namespace Api\Parameter;
|
||||
|
||||
use DateTime;
|
||||
|
||||
class Parameter {
|
||||
const TYPE_INT = 0;
|
||||
const TYPE_FLOAT = 1;
|
||||
@ -18,11 +20,11 @@ class Parameter {
|
||||
|
||||
const names = array('Integer', 'Float', 'Boolean', 'String', 'Date', 'Time', 'DateTime', 'E-Mail', 'Raw', 'Array');
|
||||
|
||||
public $name;
|
||||
public string $name;
|
||||
public $value;
|
||||
public $optional;
|
||||
public $type;
|
||||
public $typeName;
|
||||
public int $type;
|
||||
public string $typeName;
|
||||
|
||||
public function __construct($name, $type, $optional = FALSE, $defaultValue = NULL) {
|
||||
$this->name = $name;
|
||||
@ -59,11 +61,11 @@ class Parameter {
|
||||
return Parameter::TYPE_BOOLEAN;
|
||||
else if(is_a($value, 'DateTime'))
|
||||
return Parameter::TYPE_DATE_TIME;
|
||||
else if(($d = \DateTime::createFromFormat('Y-m-d', $value)) && $d->format('Y-m-d') === $value)
|
||||
else if(($d = DateTime::createFromFormat('Y-m-d', $value)) && $d->format('Y-m-d') === $value)
|
||||
return Parameter::TYPE_DATE;
|
||||
else if(($d = \DateTime::createFromFormat('H:i:s', $value)) && $d->format('H:i:s') === $value)
|
||||
else if(($d = DateTime::createFromFormat('H:i:s', $value)) && $d->format('H:i:s') === $value)
|
||||
return Parameter::TYPE_TIME;
|
||||
else if(($d = \DateTime::createFromFormat('Y-m-d H:i:s', $value)) && $d->format('Y-m-d H:i:s') === $value)
|
||||
else if(($d = DateTime::createFromFormat('Y-m-d H:i:s', $value)) && $d->format('Y-m-d H:i:s') === $value)
|
||||
return Parameter::TYPE_DATE_TIME;
|
||||
else if (filter_var($value, FILTER_VALIDATE_EMAIL))
|
||||
return Parameter::TYPE_EMAIL;
|
||||
@ -157,5 +159,3 @@ class Parameter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -4,10 +4,10 @@ namespace Api\Parameter;
|
||||
|
||||
class StringType extends Parameter {
|
||||
|
||||
public $maxLength;
|
||||
public int $maxLength;
|
||||
public function __construct($name, $maxLength = -1, $optional = FALSE, $defaultValue = NULL) {
|
||||
parent::__construct($name, Parameter::TYPE_STRING, $optional, $defaultValue);
|
||||
$this->maxLength = $maxLength;
|
||||
parent::__construct($name, Parameter::TYPE_STRING, $optional, $defaultValue);
|
||||
}
|
||||
|
||||
public function parseParam($value) {
|
||||
@ -39,5 +39,3 @@ class StringType extends Parameter {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,30 +2,32 @@
|
||||
|
||||
namespace Api;
|
||||
|
||||
use Objects\User;
|
||||
|
||||
class Request {
|
||||
|
||||
protected $user;
|
||||
protected $params;
|
||||
protected $lastError;
|
||||
protected $result;
|
||||
protected $success;
|
||||
protected $isPublic;
|
||||
protected $loginRequired;
|
||||
protected $variableParamCount;
|
||||
protected $isDisabled;
|
||||
protected $apiKeyAllowed;
|
||||
protected User $user;
|
||||
protected array $params;
|
||||
protected string $lastError;
|
||||
protected array $result;
|
||||
protected bool $success;
|
||||
protected bool $isPublic;
|
||||
protected bool $loginRequired;
|
||||
protected bool $variableParamCount;
|
||||
protected bool $isDisabled;
|
||||
protected bool $apiKeyAllowed;
|
||||
|
||||
private $aDefaultParams;
|
||||
private $allowedMethods;
|
||||
private $externCall;
|
||||
private array $aDefaultParams;
|
||||
private array $allowedMethods;
|
||||
private bool $externCall;
|
||||
|
||||
public function __construct($user, $externCall = false, $params = array()) {
|
||||
public function __construct(User $user, bool $externalCall = false, array $params = array()) {
|
||||
$this->user = $user;
|
||||
$this->aDefaultParams = $params;
|
||||
$this->lastError = '';
|
||||
$this->success = false;
|
||||
$this->result = array();
|
||||
$this->externCall = $externCall;
|
||||
$this->externCall = $externalCall;
|
||||
$this->isPublic = true;
|
||||
$this->isDisabled = false;
|
||||
$this->loginRequired = false;
|
||||
@ -40,19 +42,6 @@ class Request {
|
||||
}
|
||||
}
|
||||
|
||||
public function getParamsString() {
|
||||
$str = "";
|
||||
$count = count($this->params);
|
||||
$i = 0;
|
||||
foreach($this->params as $param) {
|
||||
$str .= $param->toString();
|
||||
if($i < $count - 1) $str .= ", ";
|
||||
$i++;
|
||||
}
|
||||
|
||||
return "($str)";
|
||||
}
|
||||
|
||||
public function parseParams($values) {
|
||||
foreach($this->params as $name => $param) {
|
||||
$value = (isset($values[$name]) ? $values[$name] : NULL);
|
||||
@ -149,47 +138,24 @@ class Request {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function isValidString($str, $regex) {
|
||||
return preg_replace($regex, "", $str) === $str;
|
||||
}
|
||||
|
||||
protected function createError($err) {
|
||||
$this->success = false;
|
||||
$this->lastError = $err;
|
||||
return false;
|
||||
}
|
||||
//
|
||||
// public static function callDirectly($class, $db) {
|
||||
// header('Content-Type: application/json');
|
||||
// require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/api/objects/User.php';
|
||||
// require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/sql.php';
|
||||
// require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/conf/sql.php';
|
||||
//
|
||||
// $sql = connectSQL(getSqlData($db));
|
||||
// $user = new CUser($sql);
|
||||
// $request = new $class($user, true);
|
||||
// $request->execute();
|
||||
// $sql->close();
|
||||
// $user->sendCookies();
|
||||
// return $request->getJsonResult();
|
||||
// }
|
||||
|
||||
protected function getParam($name) { return isset($this->params[$name]) ? $this->params[$name]->value : NULL; }
|
||||
|
||||
public function isPublic() { return $this->isPublic; }
|
||||
public function getDescription() { return ''; }
|
||||
public function getSection() { return 'Default'; }
|
||||
public function getLastError() { return $this->lastError; }
|
||||
public function getResult() { return $this->result; }
|
||||
public function success() { return $this->success; }
|
||||
public function loginRequired() { return $this->loginRequired; }
|
||||
public function isExternCall() { return $this->externCall; }
|
||||
public function isExternalCall() { return $this->externCall; }
|
||||
|
||||
public function getJsonResult() {
|
||||
$this->result['success'] = $this->success;
|
||||
$this->result['msg'] = $this->lastError;
|
||||
return json_encode($this->result);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
?>
|
||||
}
|
@ -3,11 +3,13 @@
|
||||
namespace Api;
|
||||
use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use External\PHPMailer\Exception;
|
||||
use External\PHPMailer\PHPMailer;
|
||||
|
||||
class SendMail extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'from' => new Parameter('from', Parameter::TYPE_EMAIL),
|
||||
'to' => new Parameter('to', Parameter::TYPE_EMAIL),
|
||||
'subject' => new StringType('subject', -1),
|
||||
@ -23,36 +25,39 @@ class SendMail extends Request {
|
||||
return false;
|
||||
}
|
||||
|
||||
$mailConfig = $this->user->getConfiguration()->getMail();
|
||||
$mail = new \External\PHPMailer\PHPMailer;
|
||||
$mail->IsSMTP();
|
||||
$mail->setFrom($this->getParam('from'), $this->getParam('fromName'));
|
||||
$mail->addAddress($this->getParam('to'));
|
||||
$mail->Subject = $this->getParam('subject');
|
||||
$mail->SMTPDebug = 0;
|
||||
$mail->Host = $mailConfig->getHost();
|
||||
$mail->Port = $mailConfig->getPort();
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $mailConfig->getLogin();
|
||||
$mail->Password = $mailConfig->getPassword();
|
||||
$mail->SMTPSecure = 'tls';
|
||||
$mail->IsHTML(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Body = $this->getParam('body');
|
||||
try {
|
||||
$mailConfig = $this->user->getConfiguration()->getMail();
|
||||
$mail = new PHPMailer;
|
||||
$mail->IsSMTP();
|
||||
$mail->setFrom($this->getParam('from'), $this->getParam('fromName'));
|
||||
$mail->addAddress($this->getParam('to'));
|
||||
$mail->Subject = $this->getParam('subject');
|
||||
$mail->SMTPDebug = 0;
|
||||
$mail->Host = $mailConfig->getHost();
|
||||
$mail->Port = $mailConfig->getPort();
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $mailConfig->getLogin();
|
||||
$mail->Password = $mailConfig->getPassword();
|
||||
$mail->SMTPSecure = 'tls';
|
||||
$mail->IsHTML(true);
|
||||
$mail->CharSet = 'UTF-8';
|
||||
$mail->Body = $this->getParam('body');
|
||||
|
||||
$replyTo = $this->getParam('replyTo');
|
||||
if(!is_null($replyTo) && !empty($replyTo)) {
|
||||
$mail->AddReplyTo($replyTo, $this->getParam('fromName'));
|
||||
}
|
||||
$replyTo = $this->getParam('replyTo');
|
||||
if(!is_null($replyTo) && !empty($replyTo)) {
|
||||
$mail->AddReplyTo($replyTo, $this->getParam('fromName'));
|
||||
}
|
||||
|
||||
$this->success = @$mail->Send();
|
||||
if (!$this->success) {
|
||||
$this->lastError = 'Error sending Mail: ' . $mail->ErrorInfo;
|
||||
error_log("sendMail() failed: " . $mail->ErrorInfo);
|
||||
$this->success = @$mail->Send();
|
||||
if (!$this->success) {
|
||||
$this->lastError = "Error sending Mail: $mail->ErrorInfo";
|
||||
error_log("sendMail() failed: $mail->ErrorInfo");
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
$this->success = false;
|
||||
$this->lastError = "Error sending Mail: $e";
|
||||
}
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -6,13 +6,14 @@ use Api\Parameter\Parameter;
|
||||
use Api\Parameter\StringType;
|
||||
use Driver\SQL\Condition\CondOr;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
use Objects\Language;
|
||||
|
||||
class SetLanguage extends Request {
|
||||
|
||||
private $language;
|
||||
private Language $language;
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'langId' => new Parameter('langId', Parameter::TYPE_INT, true, NULL),
|
||||
'langCode' => new StringType('langCode', 5, true, NULL),
|
||||
));
|
||||
@ -40,7 +41,7 @@ class SetLanguage extends Request {
|
||||
return $this->createError(L("This Language does not exist"));
|
||||
} else {
|
||||
$row = $res[0];
|
||||
$this->language = \Objects\Language::newInstance($row['uid'], $row['code'], $row['name']);
|
||||
$this->language = Language::newInstance($row['uid'], $row['code'], $row['name']);
|
||||
if(!$this->language) {
|
||||
return $this->createError(L("Error while loading language"));
|
||||
}
|
||||
@ -75,9 +76,7 @@ class SetLanguage extends Request {
|
||||
$this->updateLanguage();
|
||||
}
|
||||
|
||||
$this->user->setLangauge($this->language);
|
||||
$this->user->setLanguage($this->language);
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -9,10 +9,10 @@ use \Driver\SQL\Condition\Compare;
|
||||
|
||||
class Login extends Request {
|
||||
|
||||
private $startedAt;
|
||||
private int $startedAt;
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall, array(
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall, array(
|
||||
'username' => new StringType('username', 32),
|
||||
'password' => new StringType('password'),
|
||||
'stayLoggedIn' => new Parameter('stayLoggedIn', Parameter::TYPE_BOOLEAN, true, true)
|
||||
@ -77,6 +77,4 @@ class Login extends Request {
|
||||
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -6,8 +6,8 @@ use \Api\Request;
|
||||
|
||||
class Logout extends Request {
|
||||
|
||||
public function __construct($user, $externCall = false) {
|
||||
parent::__construct($user, $externCall);
|
||||
public function __construct($user, $externalCall = false) {
|
||||
parent::__construct($user, $externalCall);
|
||||
$this->loginRequired = true;
|
||||
$this->apiKeyAllowed = false;
|
||||
}
|
||||
@ -21,6 +21,4 @@ class Logout extends Request {
|
||||
$this->lastError = $this->user->getSQL()->getLastError();
|
||||
return $this->success;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -2,11 +2,14 @@
|
||||
|
||||
namespace Configuration;
|
||||
|
||||
use Error;
|
||||
use Objects\ConnectionData;
|
||||
|
||||
class Configuration {
|
||||
|
||||
private $database;
|
||||
private $mail;
|
||||
private $jwt;
|
||||
private ?ConnectionData $database;
|
||||
private ?ConnectionData $mail;
|
||||
private ?KeyData $jwt;
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
@ -34,7 +37,7 @@ class Configuration {
|
||||
}
|
||||
|
||||
return $success;
|
||||
} catch(\Error $e) {
|
||||
} catch(Error $e) {
|
||||
die($e);
|
||||
}
|
||||
}
|
||||
@ -48,7 +51,7 @@ class Configuration {
|
||||
return file_exists($path);
|
||||
}
|
||||
|
||||
public function create($className, $data) {
|
||||
public function create(string $className, $data) {
|
||||
$path = getClassPath("\\Configuration\\$className");
|
||||
|
||||
if($data) {
|
||||
@ -59,22 +62,15 @@ class Configuration {
|
||||
|
||||
namespace Configuration;
|
||||
|
||||
class $className {
|
||||
|
||||
private \$key;
|
||||
class $className extends KeyData {
|
||||
|
||||
public function __construct() {
|
||||
\$this->key = '$key';
|
||||
parent::__construct('$key');
|
||||
}
|
||||
|
||||
public function getKey() {
|
||||
return \$this->key;
|
||||
}
|
||||
}
|
||||
|
||||
?>", false
|
||||
}", false
|
||||
);
|
||||
} else {
|
||||
} else if($data instanceof ConnectionData) {
|
||||
$superClass = get_class($data);
|
||||
$host = addslashes($data->getHost());
|
||||
$port = intval($data->getPort());
|
||||
@ -102,18 +98,17 @@ class Configuration {
|
||||
|
||||
?>", false
|
||||
);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$code = intendCode(
|
||||
"<?php
|
||||
|
||||
?>", false);
|
||||
$code = "<?php";
|
||||
}
|
||||
|
||||
return @file_put_contents($path, $code);
|
||||
}
|
||||
|
||||
public function delete($className) {
|
||||
public function delete(string $className) {
|
||||
$path = getClassPath("\\Configuration\\$className");
|
||||
if(file_exists($path)) {
|
||||
return unlink($path);
|
||||
@ -121,6 +116,4 @@ class Configuration {
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -2,16 +2,13 @@
|
||||
|
||||
namespace Configuration;
|
||||
|
||||
use \Driver\SQL\Query\CreateTable;
|
||||
use \Driver\SQL\Query\Insert;
|
||||
use \Driver\SQL\Column\Column;
|
||||
use \Driver\SQL\Strategy\UpdateStrategy;
|
||||
use Driver\SQL\SQL;
|
||||
use \Driver\SQL\Strategy\SetNullStrategy;
|
||||
use \Driver\SQL\Strategy\CascadeStrategy;
|
||||
|
||||
class CreateDatabase {
|
||||
|
||||
public static function createQueries($sql) {
|
||||
public static function createQueries(SQL $sql) {
|
||||
$queries = array();
|
||||
|
||||
// Language
|
||||
@ -111,5 +108,3 @@ class CreateDatabase {
|
||||
return $queries;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
17
core/Configuration/KeyData.class.php
Normal file
17
core/Configuration/KeyData.class.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Configuration;
|
||||
|
||||
class KeyData {
|
||||
|
||||
protected string $key;
|
||||
|
||||
public function __construct(string $key) {
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
public function getKey() {
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
}
|
@ -1,16 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Documents {
|
||||
class Admin extends \Elements\Document {
|
||||
|
||||
use Documents\Admin\AdminBody;
|
||||
use Documents\Admin\AdminHead;
|
||||
use Elements\Document;
|
||||
|
||||
class Admin extends Document {
|
||||
public function __construct($user) {
|
||||
parent::__construct($user, Admin\Head::class, Admin\Body::class);
|
||||
parent::__construct($user, AdminHead::class, AdminBody::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Documents\Admin {
|
||||
|
||||
class Head extends \Elements\Head {
|
||||
use Elements\Body;
|
||||
use Elements\Head;
|
||||
use Elements\Link;
|
||||
use Elements\Script;
|
||||
use Views\Admin;
|
||||
use Views\Login;
|
||||
|
||||
class AdminHead extends Head {
|
||||
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -20,10 +32,10 @@ namespace Documents\Admin {
|
||||
$this->loadJQuery();
|
||||
$this->loadBootstrap();
|
||||
$this->loadFontawesome();
|
||||
$this->addJS(\Elements\Script::CORE);
|
||||
$this->addCSS(\Elements\Link::CORE);
|
||||
$this->addJS(\Elements\Script::ADMIN);
|
||||
$this->addCSS(\Elements\Link::ADMIN);
|
||||
$this->addJS(Script::CORE);
|
||||
$this->addCSS(Link::CORE);
|
||||
$this->addJS(Script::ADMIN);
|
||||
$this->addCSS(Link::ADMIN);
|
||||
}
|
||||
|
||||
protected function initMetas() {
|
||||
@ -45,7 +57,7 @@ namespace Documents\Admin {
|
||||
}
|
||||
}
|
||||
|
||||
class Body extends \Elements\Body {
|
||||
class AdminBody extends Body {
|
||||
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -56,14 +68,12 @@ namespace Documents\Admin {
|
||||
|
||||
$document = $this->getDocument();
|
||||
if(!$document->getUser()->isLoggedIn()) {
|
||||
$html .= new \Views\Login($document);
|
||||
$html .= new Login($document);
|
||||
} else {
|
||||
$html .= new \Views\Admin($document);
|
||||
$html .= new Admin($document);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,16 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace Documents {
|
||||
class Document404 extends \Elements\Document {
|
||||
|
||||
use Documents\Document404\Body404;
|
||||
use Documents\Document404\Head404;
|
||||
use Elements\Document;
|
||||
|
||||
class Document404 extends Document {
|
||||
public function __construct($user) {
|
||||
parent::__construct($user, Document404\Head404::class, Document404\Body404::class);
|
||||
parent::__construct($user, Head404::class, Body404::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Documents\Document404 {
|
||||
|
||||
class Head404 extends \Elements\Head {
|
||||
use Elements\Body;
|
||||
use Elements\Head;
|
||||
|
||||
class Head404 extends Head {
|
||||
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -43,7 +51,7 @@ namespace Documents\Document404 {
|
||||
}
|
||||
}
|
||||
|
||||
class Body404 extends \Elements\Body {
|
||||
class Body404 extends Body {
|
||||
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -56,5 +64,3 @@ namespace Documents\Document404 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,9 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Documents {
|
||||
class Install extends \Elements\Document {
|
||||
|
||||
use Documents\Install\InstallBody;
|
||||
use Documents\Install\InstallHead;
|
||||
use Elements\Document;
|
||||
|
||||
class Install extends Document {
|
||||
public function __construct($user) {
|
||||
parent::__construct($user, Install\Head::class, Install\Body::class);
|
||||
parent::__construct($user, InstallHead::class, InstallBody::class);
|
||||
$this->databaseRequired = false;
|
||||
}
|
||||
}
|
||||
@ -11,7 +16,18 @@ namespace Documents {
|
||||
|
||||
namespace Documents\Install {
|
||||
|
||||
class Head extends \Elements\Head {
|
||||
use Api\Notifications\Create;
|
||||
use Configuration\CreateDatabase;
|
||||
use Driver\SQL\SQL;
|
||||
use Elements\Body;
|
||||
use Elements\Head;
|
||||
use Elements\Link;
|
||||
use Elements\Script;
|
||||
use External\PHPMailer\Exception;
|
||||
use External\PHPMailer\PHPMailer;
|
||||
use Objects\ConnectionData;
|
||||
|
||||
class InstallHead extends Head {
|
||||
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -21,9 +37,9 @@ namespace Documents\Install {
|
||||
$this->loadJQuery();
|
||||
$this->loadBootstrap();
|
||||
$this->loadFontawesome();
|
||||
$this->addJS(\Elements\Script::CORE);
|
||||
$this->addCSS(\Elements\Link::CORE);
|
||||
$this->addJS(\Elements\Script::INSTALL);
|
||||
$this->addJS(Script::CORE);
|
||||
$this->addCSS(Link::CORE);
|
||||
$this->addJS(Script::INSTALL);
|
||||
}
|
||||
|
||||
protected function initMetas() {
|
||||
@ -46,27 +62,31 @@ namespace Documents\Install {
|
||||
|
||||
}
|
||||
|
||||
class Body extends \Elements\Body {
|
||||
class InstallBody extends Body {
|
||||
|
||||
// Status enum
|
||||
const NOT_STARTED = 0;
|
||||
const PENDING = 1;
|
||||
const SUCCESFULL = 2;
|
||||
const SUCCESSFUL = 2;
|
||||
const ERROR = 3;
|
||||
|
||||
// Step enum
|
||||
const CHECKING_REQUIRMENTS = 1;
|
||||
const CHECKING_REQUIREMENTS = 1;
|
||||
const DATABASE_CONFIGURATION = 2;
|
||||
const CREATE_USER = 3;
|
||||
const ADD_MAIL_SERVICE = 4;
|
||||
const FINISH_INSTALLATION = 5;
|
||||
|
||||
//
|
||||
private $errorString;
|
||||
private string $errorString;
|
||||
private int $currentStep;
|
||||
private array $steps;
|
||||
|
||||
function __construct($document) {
|
||||
parent::__construct($document);
|
||||
$this->errorString = "";
|
||||
$this->currentStep = InstallBody::CHECKING_REQUIREMENTS;
|
||||
$this->steps = array();
|
||||
}
|
||||
|
||||
private function getParameter($name) {
|
||||
@ -80,7 +100,7 @@ namespace Documents\Install {
|
||||
private function getCurrentStep() {
|
||||
|
||||
if(!$this->checkRequirements()["success"]) {
|
||||
return self::CHECKING_REQUIRMENTS;
|
||||
return self::CHECKING_REQUIREMENTS;
|
||||
}
|
||||
|
||||
$user = $this->getDocument()->getUser();
|
||||
@ -109,7 +129,7 @@ namespace Documents\Install {
|
||||
if(!$config->isFilePresent("JWT") && !$config->create("JWT", generateRandomString(32))) {
|
||||
$this->errorString = "Unable to create jwt file";
|
||||
} else {
|
||||
$req = new \Api\Notifications\Create($user);
|
||||
$req = new Create($user);
|
||||
$success = $req->execute(array(
|
||||
"title" => "Welcome",
|
||||
"message" => "Your Web-base was successfully installed. Check out the admin dashboard. Have fun!",
|
||||
@ -145,8 +165,8 @@ namespace Documents\Install {
|
||||
}
|
||||
}
|
||||
|
||||
if(version_compare(PHP_VERSION, '7.1', '<')) {
|
||||
$failedRequirements[] = "PHP Version <b>>= 7.1</b> is required. Got: <b>" . PHP_VERSION . "</b>";
|
||||
if(version_compare(PHP_VERSION, '7.4', '<')) {
|
||||
$failedRequirements[] = "PHP Version <b>>= 7.4</b> is required. Got: <b>" . PHP_VERSION . "</b>";
|
||||
$success = false;
|
||||
}
|
||||
|
||||
@ -213,14 +233,14 @@ namespace Documents\Install {
|
||||
$msg = "Unsupported database type. Must be one of: " . implode(", ", $supportedTypes);
|
||||
$success = false;
|
||||
} else {
|
||||
$connectionData = new \Objects\ConnectionData($host, $port, $username, $password);
|
||||
$connectionData = new ConnectionData($host, $port, $username, $password);
|
||||
$connectionData->setProperty('database', $database);
|
||||
$connectionData->setProperty('encoding', $encoding);
|
||||
$connectionData->setProperty('type', $type);
|
||||
$sql = \Driver\SQL\SQL::createConnection($connectionData);
|
||||
$sql = SQL::createConnection($connectionData);
|
||||
$success = false;
|
||||
if(!($sql instanceof \Driver\SQL\SQL)) {
|
||||
$msg = "Error connecting to database: " . str($sql);
|
||||
if(is_string($sql)) {
|
||||
$msg = "Error connecting to database: $sql";
|
||||
} else if(!$sql->isConnected()) {
|
||||
if (!$sql->checkRequirements()["success"]) {
|
||||
$driverName = $sql->getDriverName();
|
||||
@ -234,7 +254,7 @@ namespace Documents\Install {
|
||||
|
||||
$msg = "";
|
||||
$success = true;
|
||||
$queries = \Configuration\CreateDatabase::createQueries($sql);
|
||||
$queries = CreateDatabase::createQueries($sql);
|
||||
foreach($queries as $query) {
|
||||
if (!($res = $query->execute())) {
|
||||
$msg = "Error creating tables: " . $sql->getLastError();
|
||||
@ -375,7 +395,7 @@ namespace Documents\Install {
|
||||
} else {
|
||||
$success = false;
|
||||
|
||||
$mail = new \External\PHPMailer\PHPMailer(true);
|
||||
$mail = new PHPMailer(true);
|
||||
$mail->IsSMTP();
|
||||
$mail->SMTPAuth = true;
|
||||
$mail->Username = $username;
|
||||
@ -395,12 +415,12 @@ namespace Documents\Install {
|
||||
$msg = "";
|
||||
$mail->smtpClose();
|
||||
}
|
||||
} catch(\External\PHPMailer\Exception $error) {
|
||||
} catch(Exception $error) {
|
||||
$msg = "Could not connect to SMTP Server: " . $error->errorMessage();
|
||||
}
|
||||
|
||||
if($success) {
|
||||
$connectionData = new \Objects\ConnectionData($address, $port, $username, $password);
|
||||
$connectionData = new ConnectionData($address, $port, $username, $password);
|
||||
if(!$user->getConfiguration()->create("Mail", $connectionData)) {
|
||||
$success = false;
|
||||
$msg = "Unable to create file";
|
||||
@ -416,7 +436,7 @@ namespace Documents\Install {
|
||||
|
||||
switch($this->currentStep) {
|
||||
|
||||
case self::CHECKING_REQUIRMENTS:
|
||||
case self::CHECKING_REQUIREMENTS:
|
||||
return $this->checkRequirements();
|
||||
|
||||
case self::DATABASE_CONFIGURATION:
|
||||
@ -451,7 +471,7 @@ namespace Documents\Install {
|
||||
$statusColor = "muted";
|
||||
break;
|
||||
|
||||
case self::SUCCESFULL:
|
||||
case self::SUCCESSFUL:
|
||||
$statusIcon = '<i class="fas fa-check-circle"></i>';
|
||||
$statusText = "Successfull";
|
||||
$statusColor = "success";
|
||||
@ -552,7 +572,7 @@ namespace Documents\Install {
|
||||
private function createProgessMainview() {
|
||||
|
||||
$views = array(
|
||||
self::CHECKING_REQUIRMENTS => array(
|
||||
self::CHECKING_REQUIREMENTS => array(
|
||||
"title" => "Application Requirements",
|
||||
"progressText" => "Checking requirements, please wait a moment…"
|
||||
),
|
||||
@ -661,7 +681,7 @@ namespace Documents\Install {
|
||||
);
|
||||
|
||||
if($this->currentStep != self::FINISH_INSTALLATION) {
|
||||
if ($this->currentStep == self::CHECKING_REQUIRMENTS) {
|
||||
if ($this->currentStep == self::CHECKING_REQUIREMENTS) {
|
||||
$buttons[] = array("title" => "Retry", "type" => "success", "id" => "btnRetry", "float" => "right");
|
||||
} else {
|
||||
$buttons[] = array("title" => "Submit", "type" => "success", "id" => "btnSubmit", "float" => "right");
|
||||
@ -706,7 +726,7 @@ namespace Documents\Install {
|
||||
$html = parent::getCode();
|
||||
|
||||
$this->steps = array(
|
||||
self::CHECKING_REQUIRMENTS => array(
|
||||
self::CHECKING_REQUIREMENTS => array(
|
||||
"title" => "Checking requirements",
|
||||
"status" => self::ERROR
|
||||
),
|
||||
@ -731,12 +751,12 @@ namespace Documents\Install {
|
||||
$this->currentStep = $this->getCurrentStep();
|
||||
|
||||
// set status
|
||||
for($step = self::CHECKING_REQUIRMENTS; $step < $this->currentStep; $step++) {
|
||||
$this->steps[$step]["status"] = self::SUCCESFULL;
|
||||
for($step = self::CHECKING_REQUIREMENTS; $step < $this->currentStep; $step++) {
|
||||
$this->steps[$step]["status"] = self::SUCCESSFUL;
|
||||
}
|
||||
|
||||
if($this->currentStep == self::FINISH_INSTALLATION) {
|
||||
$this->steps[$this->currentStep]["status"] = self::SUCCESFULL;
|
||||
$this->steps[$this->currentStep]["status"] = self::SUCCESSFUL;
|
||||
}
|
||||
|
||||
// POST
|
||||
@ -783,7 +803,4 @@ namespace Documents\Install {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,9 +2,10 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
abstract class Body extends \View {
|
||||
use View;
|
||||
|
||||
abstract class Body extends View {
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
}
|
||||
};
|
||||
?>
|
||||
}
|
@ -2,14 +2,16 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
use Objects\User;
|
||||
|
||||
abstract class Document {
|
||||
|
||||
protected $head;
|
||||
protected $body;
|
||||
protected $user;
|
||||
protected $databaseRequired;
|
||||
protected Head $head;
|
||||
protected Body $body;
|
||||
protected User $user;
|
||||
protected bool $databaseRequired;
|
||||
|
||||
public function __construct($user, $headClass, $bodyClass) {
|
||||
public function __construct(User $user, $headClass, $bodyClass) {
|
||||
$this->head = new $headClass($this);
|
||||
$this->body = new $bodyClass($this);
|
||||
$this->user = $user;
|
||||
@ -29,30 +31,6 @@ abstract class Document {
|
||||
return new $documentClass($user);
|
||||
}
|
||||
|
||||
public static function createDocument($class) {
|
||||
// TODO: check instance, configuration, ..
|
||||
|
||||
require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/sql.php';
|
||||
// require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/conf/config.php';
|
||||
// require_once realpath($_SERVER['DOCUMENT_ROOT']) . "/php/pages/$file.php";
|
||||
require_once realpath($_SERVER['DOCUMENT_ROOT']) . '/php/api/objects/User.php';
|
||||
|
||||
$connectionData = getSqlData($database);
|
||||
$sql = connectSQL($connectionData);
|
||||
if(!$sql->isConnected()) {
|
||||
http_response_code(500);
|
||||
die('Internal Database error');
|
||||
}
|
||||
|
||||
$user = new CUser($sql);
|
||||
$document = new $class($user);
|
||||
$code = $document->getCode();
|
||||
|
||||
$document->sendHeaders();
|
||||
$user->sendCookies();
|
||||
die($code);
|
||||
}
|
||||
|
||||
function getCode() {
|
||||
|
||||
if ($this->databaseRequired) {
|
||||
@ -75,6 +53,4 @@ abstract class Document {
|
||||
return $html;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
?>
|
||||
}
|
@ -2,15 +2,17 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
abstract class Head extends \View {
|
||||
use View;
|
||||
|
||||
protected $sources;
|
||||
protected $title;
|
||||
protected $metas;
|
||||
protected $rawFields;
|
||||
protected $keywords;
|
||||
protected $description;
|
||||
protected $baseUrl;
|
||||
abstract class Head extends View {
|
||||
|
||||
protected array $sources;
|
||||
protected string $title;
|
||||
protected array $metas;
|
||||
protected array $rawFields;
|
||||
protected array $keywords;
|
||||
protected string $description;
|
||||
protected string $baseUrl;
|
||||
|
||||
function __construct($document) {
|
||||
parent::__construct($document);
|
||||
@ -54,19 +56,6 @@ abstract class Head extends \View {
|
||||
$this->addCSS(Link::FONTAWESOME);
|
||||
}
|
||||
|
||||
public function loadSyntaxHighlighting() {
|
||||
$this->addJS(Script::HIGHLIGHT);
|
||||
$this->addJSCode(Script::HIGHLIGHT_JS_LOADER);
|
||||
$this->addCSS(Link::HIGHLIGHT);
|
||||
$this->addCSS(Link::HIGHLIGHT_THEME);
|
||||
}
|
||||
|
||||
public function loadJQueryTerminal($unixFormatting = true) {
|
||||
$this->addJS(Script::JQUERY_TERMINAL);
|
||||
if($unixFormatting) $this->addJS(Script::JQUERY_TERMINAL_UNIX);
|
||||
$this->addCSS(Link::JQUERY_TERMINAL);
|
||||
}
|
||||
|
||||
public function loadGoogleRecaptcha($siteKey) {
|
||||
$this->addJS("https://www.google.com/recaptcha/api.js?render=$siteKey");
|
||||
}
|
||||
@ -80,11 +69,6 @@ abstract class Head extends \View {
|
||||
$this->addJS(Script::BOOTSTRAP);
|
||||
}
|
||||
|
||||
public function loadChartJS() {
|
||||
$this->addJS(Script::MOMENT);
|
||||
$this->addJS(Script::CHART);
|
||||
}
|
||||
|
||||
public function getCode() {
|
||||
$header = "<head>";
|
||||
|
||||
@ -123,4 +107,3 @@ abstract class Head extends \View {
|
||||
return $header;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
class Link extends Source {
|
||||
use View;
|
||||
|
||||
class Link extends View {
|
||||
|
||||
const STYLESHEET = "stylesheet";
|
||||
const MIME_TEXT_CSS = "text/css";
|
||||
@ -23,20 +25,18 @@ class Link extends Source {
|
||||
// const REVEALJS_THEME_MOON = "/css/reveal_moon.css";
|
||||
// const REVEALJS_THEME_BLACK = "/css/reveal_black.css";
|
||||
|
||||
private $type;
|
||||
private $rel;
|
||||
private string $type;
|
||||
private string $rel;
|
||||
private string $href;
|
||||
|
||||
function __construct($rel, $href, $type = "") {
|
||||
parent::__construct('link', $href);
|
||||
$this->href = $href;
|
||||
$this->type = $type;
|
||||
$this->rel = $rel;
|
||||
}
|
||||
|
||||
function getCode() {
|
||||
$type = (empty($this->type) ? "" : " type=\"$this->type\"");
|
||||
$link = "<link rel=\"$this->rel\" href=\"$this->url\" $type/>";
|
||||
return $link;
|
||||
return "<link rel=\"$this->rel\" href=\"$this->href\"$type/>";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
class Script extends Source {
|
||||
class Script extends \View {
|
||||
|
||||
const MIME_TEXT_JAVASCRIPT = "text/javascript";
|
||||
|
||||
@ -32,11 +32,11 @@ class Script extends Source {
|
||||
|
||||
const HIGHLIGHT_JS_LOADER = "\$(document).ready(function(){\$('code').each(function(i, block) { hljs.highlightBlock(block); }); })";
|
||||
|
||||
private $type;
|
||||
private $content;
|
||||
private string $type;
|
||||
private string $content;
|
||||
private string $url;
|
||||
|
||||
function __construct($type, $src, $content = "") {
|
||||
parent::__construct('script', $src);
|
||||
$this->type = $type;
|
||||
$this->content = $content;
|
||||
}
|
||||
@ -49,5 +49,3 @@ class Script extends Source {
|
||||
return $script;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,22 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Elements;
|
||||
|
||||
class Source extends \View {
|
||||
|
||||
protected $sourceType;
|
||||
protected $url;
|
||||
|
||||
public function __construct($sourceType, $url) {
|
||||
$this->sourceType = $sourceType;
|
||||
$this->url = $url;
|
||||
}
|
||||
|
||||
public function getCode() {
|
||||
return "<$sourceType />";
|
||||
}
|
||||
|
||||
public function getUrl() { return $this->url; }
|
||||
}
|
||||
|
||||
?>
|
@ -2,12 +2,11 @@
|
||||
|
||||
namespace Elements;
|
||||
|
||||
class Style extends Source {
|
||||
class Style extends View {
|
||||
|
||||
private $style;
|
||||
private string $style;
|
||||
|
||||
function __construct($style) {
|
||||
parent::__construct('style', '');
|
||||
$this->style = $style;
|
||||
}
|
||||
|
||||
@ -15,5 +14,3 @@ class Style extends Source {
|
||||
return "<style>$this->style</style>";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -6,9 +6,6 @@ abstract class ApiObject implements \JsonSerializable {
|
||||
|
||||
public abstract function jsonSerialize();
|
||||
|
||||
public function __construct() { }
|
||||
public function __toString() { return json_encode($this); }
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -4,11 +4,11 @@ namespace Objects;
|
||||
|
||||
class ConnectionData {
|
||||
|
||||
private $host;
|
||||
private $port;
|
||||
private $login;
|
||||
private $password;
|
||||
private $properties;
|
||||
private string $host;
|
||||
private int $port;
|
||||
private string $login;
|
||||
private string $password;
|
||||
private array $properties;
|
||||
|
||||
public function __construct($host, $port, $login, $password) {
|
||||
$this->host = $host;
|
||||
@ -32,6 +32,7 @@ class ConnectionData {
|
||||
}
|
||||
|
||||
$this->properties[$key] = $val;
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getHost() { return $this->host; }
|
||||
@ -39,5 +40,3 @@ class ConnectionData {
|
||||
public function getLogin() { return $this->login; }
|
||||
public function getPassword() { return $this->password; }
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,16 +2,18 @@
|
||||
|
||||
namespace Objects {
|
||||
|
||||
class Language extends ApiObject {
|
||||
use LanguageModule;
|
||||
|
||||
class Language extends ApiObject {
|
||||
|
||||
const LANG_CODE_PATTERN = "/^[a-zA-Z]+_[a-zA-Z]+$/";
|
||||
|
||||
private $languageId;
|
||||
private $langCode;
|
||||
private $langName;
|
||||
private $modules;
|
||||
private int $languageId;
|
||||
private string $langCode;
|
||||
private string $langName;
|
||||
private array $modules;
|
||||
|
||||
protected $entries;
|
||||
protected array $entries;
|
||||
|
||||
public function __construct($languageId, $langCode, $langName) {
|
||||
$this->languageId = $languageId;
|
||||
@ -29,7 +31,7 @@ namespace Objects {
|
||||
public function getEntries() { return $this->entries; }
|
||||
public function getModules() { return $this->modules; }
|
||||
|
||||
public function loadModule($module) {
|
||||
public function loadModule(LanguageModule $module) {
|
||||
if(!is_object($module))
|
||||
$module = new $module;
|
||||
|
||||
@ -100,7 +102,8 @@ namespace Objects {
|
||||
}
|
||||
|
||||
namespace {
|
||||
function L($key) {
|
||||
|
||||
function L($key) {
|
||||
if(!array_key_exists('LANGUAGE', $GLOBALS))
|
||||
return $key;
|
||||
|
||||
@ -132,4 +135,3 @@ namespace {
|
||||
return $LANGUAGE->getShortCode();
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
@ -2,21 +2,24 @@
|
||||
|
||||
namespace Objects;
|
||||
|
||||
use DateTime;
|
||||
use \Driver\SQL\Condition\Compare;
|
||||
use Exception;
|
||||
use External\JWT;
|
||||
|
||||
class Session extends ApiObject {
|
||||
|
||||
const DURATION = 120;
|
||||
|
||||
private $sessionId;
|
||||
private $user;
|
||||
private $expires;
|
||||
private $ipAddress;
|
||||
private $os;
|
||||
private $browser;
|
||||
private $stayLoggedIn;
|
||||
private ?int $sessionId;
|
||||
private User $user;
|
||||
private int $expires;
|
||||
private string $ipAddress;
|
||||
private ?string $os;
|
||||
private ?string $browser;
|
||||
private bool $stayLoggedIn;
|
||||
|
||||
public function __construct($user, $sessionId) {
|
||||
public function __construct(User $user, ?int $sessionId) {
|
||||
$this->user = $user;
|
||||
$this->sessionId = $sessionId;
|
||||
$this->stayLoggedIn = true;
|
||||
@ -38,7 +41,7 @@ class Session extends ApiObject {
|
||||
$userAgent = @get_browser($_SERVER['HTTP_USER_AGENT'], true);
|
||||
$this->os = $userAgent['platform'] ?? "Unknown";
|
||||
$this->browser = $userAgent['parent'] ?? "Unknown";
|
||||
} catch(\Exception $ex) {
|
||||
} catch(Exception $ex) {
|
||||
$this->os = "Unknown";
|
||||
$this->browser = "Unknown";
|
||||
}
|
||||
@ -59,7 +62,7 @@ class Session extends ApiObject {
|
||||
$jwt = $this->user->getConfiguration()->getJwt();
|
||||
if($jwt) {
|
||||
$token = array('userId' => $this->user->getId(), 'sessionId' => $this->sessionId);
|
||||
$sessionCookie = \External\JWT::encode($token, $jwt->getKey());
|
||||
$sessionCookie = JWT::encode($token, $jwt->getKey());
|
||||
$secure = strcmp(getProtocol(), "https") === 0;
|
||||
setcookie('session', $sessionCookie, $this->getExpiresTime(), "/", "", $secure);
|
||||
}
|
||||
@ -94,7 +97,7 @@ class Session extends ApiObject {
|
||||
$success = $sql
|
||||
->insert("Session", $columns)
|
||||
->addRow(
|
||||
(new \DateTime)->modify("+$hours hour"),
|
||||
(new DateTime())->modify("+$hours hour"),
|
||||
$this->user->getId(),
|
||||
$this->ipAddress,
|
||||
$this->os,
|
||||
@ -113,13 +116,11 @@ class Session extends ApiObject {
|
||||
}
|
||||
|
||||
public function destroy() {
|
||||
$success = $this->user->getSQL()->update("Session")
|
||||
return $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() {
|
||||
@ -127,8 +128,8 @@ class Session extends ApiObject {
|
||||
$hours = Session::DURATION;
|
||||
|
||||
$sql = $this->user->getSQL();
|
||||
$success = $sql->update("Session")
|
||||
->set("Session.expires", (new \DateTime)->modify("+$hours hour"))
|
||||
return $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)
|
||||
@ -136,9 +137,5 @@ class Session extends ApiObject {
|
||||
->where(new Compare("Session.uid", $this->sessionId))
|
||||
->where(new Compare("Session.user_id", $this->user->getId()))
|
||||
->execute();
|
||||
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,25 +2,28 @@
|
||||
|
||||
namespace Objects;
|
||||
|
||||
use \External\JWT;
|
||||
use Driver\SQL\Column\Column;
|
||||
use Api\SetLanguage;
|
||||
use Configuration\Configuration;
|
||||
use Exception;
|
||||
use External\JWT;
|
||||
use Driver\SQL\SQL;
|
||||
use Driver\SQL\Condition\Compare;
|
||||
use Driver\SQL\Condition\CondBool;
|
||||
|
||||
class User extends ApiObject {
|
||||
|
||||
private $sql;
|
||||
private $configuration;
|
||||
private $loggedIn;
|
||||
private $session;
|
||||
private $uid;
|
||||
private $username;
|
||||
private $language;
|
||||
private ?SQL $sql;
|
||||
private Configuration $configuration;
|
||||
private bool $loggedIn;
|
||||
private ?Session $session;
|
||||
private int $uid;
|
||||
private string $username;
|
||||
private Language $language;
|
||||
|
||||
public function __construct($configuration) {
|
||||
session_start();
|
||||
$this->configuration = $configuration;
|
||||
$this->setLangauge(Language::DEFAULT_LANGUAGE());
|
||||
$this->setLanguage(Language::DEFAULT_LANGUAGE());
|
||||
$this->reset();
|
||||
$this->connectDb();
|
||||
$this->parseCookies();
|
||||
@ -35,7 +38,9 @@ class User extends ApiObject {
|
||||
private function connectDb() {
|
||||
$databaseConf = $this->configuration->getDatabase();
|
||||
if($databaseConf) {
|
||||
$this->sql = \Driver\SQL\SQL::createConnection($databaseConf);
|
||||
$this->sql = SQL::createConnection($databaseConf);
|
||||
} else {
|
||||
$this->sql = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +49,7 @@ class User extends ApiObject {
|
||||
public function getUsername() { return $this->username; }
|
||||
public function getSQL() { return $this->sql; }
|
||||
public function getLanguage() { return $this->language; }
|
||||
public function setLangauge($language) { $this->language = $language; $language->load(); }
|
||||
public function setLanguage(Language $language) { $this->language = $language; $language->load(); }
|
||||
public function getSession() { return $this->session; }
|
||||
public function getConfiguration() { return $this->configuration; }
|
||||
|
||||
@ -75,7 +80,7 @@ class User extends ApiObject {
|
||||
$this->uid = 0;
|
||||
$this->username = '';
|
||||
$this->loggedIn = false;
|
||||
$this->session = false;
|
||||
$this->session = null;
|
||||
}
|
||||
|
||||
public function logout() {
|
||||
@ -90,8 +95,10 @@ class User extends ApiObject {
|
||||
|
||||
public function updateLanguage($lang) {
|
||||
if($this->sql) {
|
||||
$request = new \Api\SetLanguage($this);
|
||||
$request = new SetLanguage($this);
|
||||
return $request->execute(array("langCode" => $lang));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,7 +137,7 @@ class User extends ApiObject {
|
||||
if($sessionUpdate) $this->session->update();
|
||||
$this->loggedIn = true;
|
||||
if(!is_null($row['langId'])) {
|
||||
$this->setLangauge(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
|
||||
$this->setLanguage(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -153,7 +160,7 @@ class User extends ApiObject {
|
||||
$this->readData($userId, $sessionId);
|
||||
}
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
} catch(Exception $e) {
|
||||
// ignored
|
||||
}
|
||||
}
|
||||
@ -187,7 +194,7 @@ class User extends ApiObject {
|
||||
->leftJoin("Language", "User.language_id", "Language.uid")
|
||||
->where(new Compare("ApiKey.api_key", $apiKey))
|
||||
->where(new Compare("valid_until", $this->sql->currentTimestamp(), ">"))
|
||||
->where(new COmpare("ApiKey.active", 1))
|
||||
->where(new Compare("ApiKey.active", 1))
|
||||
->execute();
|
||||
|
||||
$success = ($res !== FALSE);
|
||||
@ -200,7 +207,7 @@ class User extends ApiObject {
|
||||
$this->username = $row['username'];
|
||||
|
||||
if(!is_null($row['langId'])) {
|
||||
$this->setLangauge(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
|
||||
$this->setLanguage(Language::newInstance($row['langId'], $row['langCode'], $row['langName']));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -208,5 +215,3 @@ class User extends ApiObject {
|
||||
return $success;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
require_once './LanguageModule.php';
|
||||
|
||||
abstract class CLanguageModuleGeneral {
|
||||
|
||||
public static function getEntries($langCode) {
|
||||
switch($langCode) {
|
||||
case "de_DE":
|
||||
$this->entries[""] = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
@ -1,9 +1,6 @@
|
||||
<?php
|
||||
|
||||
abstract class CLanguageModule {
|
||||
|
||||
public abstract static function getEntries($langCode);
|
||||
abstract class LanguageModule {
|
||||
|
||||
public abstract function getEntries(string $langCode);
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -1,18 +1,19 @@
|
||||
<?php
|
||||
|
||||
use Elements\Document;
|
||||
|
||||
abstract class View {
|
||||
|
||||
private $document;
|
||||
private $loadView;
|
||||
protected $searchable;
|
||||
protected $reference;
|
||||
protected $title;
|
||||
protected $langModules;
|
||||
private Document $document;
|
||||
private bool $loadView;
|
||||
protected bool $searchable;
|
||||
protected string $reference;
|
||||
protected string $title;
|
||||
protected array $langModules;
|
||||
|
||||
public function __construct($document, $loadView = true) {
|
||||
public function __construct(Document $document, $loadView = true) {
|
||||
$this->document = $document;
|
||||
$this->searchable = false;
|
||||
$this->printable = false;
|
||||
$this->reference = "";
|
||||
$this->title = "Untitled View";
|
||||
$this->langModules = array();
|
||||
@ -224,7 +225,4 @@ abstract class View {
|
||||
$hidden = ($hidden?" hidden" : "");
|
||||
return "<div class=\"alert alert-$type$hidden\" role=\"alert\"$id>$text</div>";
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
?>
|
||||
}
|
@ -50,5 +50,3 @@ class LanguageFlags extends \View {
|
||||
return implode('', $flags);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,7 +2,9 @@
|
||||
|
||||
namespace Views;
|
||||
|
||||
class Login extends \View {
|
||||
use View;
|
||||
|
||||
class Login extends View {
|
||||
public function __construct($document) {
|
||||
parent::__construct($document);
|
||||
}
|
||||
@ -28,7 +30,7 @@ class Login extends \View {
|
||||
</div>';
|
||||
}
|
||||
|
||||
$html = "
|
||||
$html .= "
|
||||
<div class=\"container margin-top-xxl\">
|
||||
<div class=\"title text-center\">
|
||||
<h2>Admin Control Panel</h2>
|
||||
@ -51,5 +53,3 @@ class Login extends \View {
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -2,5 +2,3 @@
|
||||
|
||||
const USER_GROUP_DEFAULT = 1;
|
||||
const USER_GROUP_ADMIN = 2;
|
||||
|
||||
?>
|
||||
|
@ -1,20 +1,5 @@
|
||||
<?php
|
||||
|
||||
function clamp($val, $min, $max) {
|
||||
if($val < $min) return $min;
|
||||
if($val > $max) return $max;
|
||||
return $val;
|
||||
}
|
||||
|
||||
function downloadFile($url) {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
$data = curl_exec($ch);
|
||||
curl_close($ch);
|
||||
return $data;
|
||||
}
|
||||
|
||||
function getSubclassesOf($parent) {
|
||||
$result = array();
|
||||
foreach (get_declared_classes() as $class) {
|
||||
@ -28,30 +13,18 @@
|
||||
return stripos($_SERVER['SERVER_PROTOCOL'],'https') === 0 ? 'https' : 'http';
|
||||
}
|
||||
|
||||
function includeDir($dir, $aIgnore = array(), $recursive = false) {
|
||||
$aIgnore[] = '.';
|
||||
$aIgnore[] = '..';
|
||||
$aFiles = array_diff(scandir($dir), $aIgnore);
|
||||
|
||||
foreach($aFiles as $file) {
|
||||
$file = $dir . '/' . $file;
|
||||
if(is_dir($file)) {
|
||||
if($recursive) {
|
||||
includeDir($file, $aIgnore, true);
|
||||
}
|
||||
} else {
|
||||
require_once $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function generateRandomString($length) {
|
||||
function generateRandomString($length) : string {
|
||||
$randomString = '';
|
||||
if($length > 0) {
|
||||
$numCharacters = 26 + 26 + 10; // a-z + A-Z + 0-9
|
||||
for ($i = 0; $i < $length; $i++)
|
||||
{
|
||||
$num = random_int(0, $numCharacters - 1);
|
||||
try {
|
||||
$num = random_int(0, $numCharacters - 1);
|
||||
} catch (Exception $e) {
|
||||
$num = rand(0, $numCharacters - 1);
|
||||
}
|
||||
|
||||
if($num < 26) $randomString .= chr(ord('a') + $num);
|
||||
else if($num - 26 < 26) $randomString .= chr(ord('A') + $num - 26);
|
||||
else $randomString .= chr(ord('0') + $num - 26 - 26);
|
||||
@ -61,20 +34,6 @@
|
||||
return $randomString;
|
||||
}
|
||||
|
||||
function cleanPath($path) {
|
||||
if($path === '')
|
||||
return $path;
|
||||
|
||||
$path = str_replace('\\', '/', $path);
|
||||
$path = str_replace('/./', '/', $path);
|
||||
|
||||
if($path[0] !== '/')
|
||||
$path = '/' . $path;
|
||||
|
||||
$path = str_replace('/../', '/', $path);
|
||||
return $path;
|
||||
}
|
||||
|
||||
function startsWith($haystack, $needle) {
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
@ -88,21 +47,6 @@
|
||||
return (substr($haystack, -$length) === $needle);
|
||||
}
|
||||
|
||||
function isCalledDirectly($file) {
|
||||
return $_SERVER['SCRIPT_FILENAME'] === $file;
|
||||
}
|
||||
|
||||
function anonymzeEmail($mail) {
|
||||
if(($pos = strpos($mail, '@')) !== -1) {
|
||||
$name = substr($mail, 0, $pos);
|
||||
$host = substr($mail, $pos + 1);
|
||||
if(strlen($name) > 2) $mail = substr($name, 0, 2) . str_repeat('*', strlen($name) - 2) . "@$host";
|
||||
else $mail = $mail = str_repeat('*', strlen($name)) . "@$host";
|
||||
}
|
||||
|
||||
return $mail;
|
||||
}
|
||||
|
||||
function intendCode($code, $escape=true) {
|
||||
$newCode = "";
|
||||
$first = true;
|
||||
@ -138,4 +82,13 @@
|
||||
function replaceCssSelector($sel) {
|
||||
return preg_replace("~[.#<>]~", "_", preg_replace("~[:\-]~", "", $sel));
|
||||
}
|
||||
?>
|
||||
|
||||
function getClassPath($class, $suffix=true) {
|
||||
$path = str_replace('\\', '/', $class);
|
||||
$suffix = ($suffix ? ".class" : "");
|
||||
return "core/$path$suffix.php";
|
||||
}
|
||||
|
||||
function createError($msg) {
|
||||
return json_encode(array("success" => false, "msg" => $msg));
|
||||
}
|
||||
|
@ -1,5 +1,26 @@
|
||||
<?php
|
||||
|
||||
function setTimezone($default) {
|
||||
$timezone = "";
|
||||
if (is_link("/etc/localtime")) {
|
||||
$filename = readlink("/etc/localtime");
|
||||
$pos = strpos($filename, "zoneinfo");
|
||||
if ($pos) {
|
||||
$timezone = substr($filename, $pos + strlen("zoneinfo/"));
|
||||
} else {
|
||||
$timezone = $default;
|
||||
}
|
||||
} else {
|
||||
$timezone = file_get_contents("/etc/timezone");
|
||||
if (!strlen($timezone)) {
|
||||
$timezone = $default;
|
||||
}
|
||||
}
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
|
||||
setTimezone("UTC");
|
||||
|
||||
function getFirstWeekDayOfMonth($d = NULL) {
|
||||
if(is_null($d)) $d = date('Y-m-d H:i:s');
|
||||
$dt = new DateTime($d);
|
||||
@ -58,8 +79,8 @@ function formatPeriod($d1, $d2) {
|
||||
|
||||
function now() { return new DateTime(); }
|
||||
function getTime($d = NULL) { return dateFunction('H:i', $d); }
|
||||
function getHour($d = NULL){ return dateFunction('H', $d); }
|
||||
function getMinute($d = NULL){ return dateFunction('i', $d); }
|
||||
function getHour($d = NULL) { return dateFunction('H', $d); }
|
||||
function getMinute($d = NULL) { return dateFunction('i', $d); }
|
||||
function getYear($d = NULL) { return intval(dateFunction('Y', $d)); }
|
||||
function getMonth($d = NULL) { return intval(dateFunction('n', $d)); }
|
||||
function getDay($d = NULL) { return intval(dateFunction('d', $d)); }
|
||||
@ -118,4 +139,25 @@ function dateFunction($str, $d = NULL) {
|
||||
return $d->format($str);
|
||||
}
|
||||
|
||||
?>
|
||||
function getPeriodString($d) {
|
||||
if(!is_a($d, "DateTime")) $d = new DateTime($d);
|
||||
$diff = datetimeDiff(new DateTime(), $d);
|
||||
$diff = abs($diff);
|
||||
|
||||
|
||||
if ($diff < 60) {
|
||||
$str = "< %d min";
|
||||
$diff = 1;
|
||||
} else if($diff < 60*60) {
|
||||
$diff = intval($diff / 60);
|
||||
$str = "%d min.";
|
||||
} else if($diff < 60*60*24) {
|
||||
$diff = intval($diff / (60*60));
|
||||
$str = "%d h.";
|
||||
} else {
|
||||
$diff = intval($diff / (60*60*24));
|
||||
$str = "%d d.";
|
||||
}
|
||||
|
||||
return L(sprintf($str, $diff));
|
||||
}
|
||||
|
16
index.php
16
index.php
@ -1,14 +1,8 @@
|
||||
<?php
|
||||
|
||||
function getClassPath($class, $suffix=true) {
|
||||
$path = str_replace('\\', '/', $class);
|
||||
$suffix = ($suffix ? ".class" : "");
|
||||
return "core/$path$suffix.php";
|
||||
}
|
||||
|
||||
function createError($msg) {
|
||||
return json_encode(array("success" => false, "msg" => $msg));
|
||||
}
|
||||
include_once 'core/core.php';
|
||||
include_once 'core/datetime.php';
|
||||
include_once 'core/constants.php';
|
||||
|
||||
spl_autoload_extensions(".php");
|
||||
spl_autoload_register(function($class) {
|
||||
@ -19,10 +13,6 @@ spl_autoload_register(function($class) {
|
||||
include_once getClassPath($class, false);
|
||||
});
|
||||
|
||||
include_once 'core/core.php';
|
||||
include_once 'core/datetime.php';
|
||||
include_once 'core/constants.php';
|
||||
|
||||
$config = new Configuration\Configuration();
|
||||
$installation = (!$config->load());
|
||||
$user = new Objects\User($config);
|
||||
|
Loading…
Reference in New Issue
Block a user