php 7.4 dev branch

This commit is contained in:
Roman Hergenreder 2020-04-03 15:56:04 +02:00
parent 2636719583
commit a8fc52b42a
48 changed files with 456 additions and 530 deletions

2
.idea/.gitignore vendored Normal file

@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

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

@ -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

@ -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

@ -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

@ -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(),
"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,8 +25,9 @@ class SendMail extends Request {
return false;
}
try {
$mailConfig = $this->user->getConfiguration()->getMail();
$mail = new \External\PHPMailer\PHPMailer;
$mail = new PHPMailer;
$mail->IsSMTP();
$mail->setFrom($this->getParam('from'), $this->getParam('fromName'));
$mail->addAddress($this->getParam('to'));
@ -47,12 +50,14 @@ class SendMail extends Request {
$this->success = @$mail->Send();
if (!$this->success) {
$this->lastError = 'Error sending Mail: ' . $mail->ErrorInfo;
error_log("sendMail() failed: " . $mail->ErrorInfo);
$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;
}
}
?>

@ -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 {
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,6 +102,7 @@ namespace Objects {
}
namespace {
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++)
{
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);
@ -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));
}

@ -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);