Namespace and ClassPath rewrites

This commit is contained in:
2022-11-18 18:06:46 +01:00
parent c277aababc
commit 951ff14c5f
217 changed files with 1017 additions and 936 deletions

View File

@@ -0,0 +1,104 @@
<?php
namespace Core\Configuration;
use Core\Objects\ConnectionData;
class Configuration {
const className = "\Site\Configuration\Database";
private ?ConnectionData $database;
private Settings $settings;
function __construct() {
$this->database = null;
$this->settings = Settings::loadDefaults();
$className = self::className;
$path = getClassPath($className, ".class");
if (file_exists($path) && is_readable($path)) {
include_once $path;
if (class_exists($className)) {
$this->database = new $className();
}
}
}
public function getDatabase(): ?ConnectionData {
return $this->database;
}
public function getSettings(): Settings {
return $this->settings;
}
public static function create(string $className, $data) {
$path = getClassPath($className);
$classNameShort = explode("\\", $className);
$classNameShort = end($classNameShort);
if ($data) {
if (is_string($data)) {
$key = var_export($data, true);
$code = intendCode(
"<?php
namespace Core\Configuration;
class $classNameShort extends KeyData {
public function __construct() {
parent::__construct($key);
}
}", false
);
} else if ($data instanceof ConnectionData) {
$superClass = get_class($data);
$host = var_export($data->getHost(), true);
$port = var_export($data->getPort(), true);
$login = var_export($data->getLogin(), true);
$password = var_export($data->getPassword(), true);
$properties = "";
foreach ($data->getProperties() as $key => $val) {
$key = var_export($key, true);
$val = var_export($val, true);
$properties .= "\n\$this->setProperty($key, $val);";
}
$code = intendCode(
"<?php
namespace Site\Configuration;
class $classNameShort extends \\$superClass {
public function __construct() {
parent::__construct($host, $port, $login, $password);$properties
}
}", false
);
} else {
return false;
}
} else {
$code = "<?php";
}
return @file_put_contents($path, $code);
}
public function delete(string $className): bool {
$path = getClassPath("\\Configuration\\$className");
if (file_exists($path)) {
return unlink($path);
}
return true;
}
public function setDatabase(ConnectionData $connectionData): void {
$this->database = $connectionData;
}
}

View File

@@ -0,0 +1,256 @@
<?php
namespace Core\Configuration;
use Core\Driver\SQL\SQL;
use Core\Driver\SQL\Strategy\SetNullStrategy;
use Core\Driver\SQL\Strategy\CascadeStrategy;
use Core\Objects\DatabaseEntity\DatabaseEntity;
use PHPUnit\Util\Exception;
class CreateDatabase extends DatabaseScript {
public static function createQueries(SQL $sql): array {
$queries = array();
self::loadEntities($queries, $sql);
$queries[] = $sql->insert("Language", array("code", "name"))
->addRow("en_US", 'American English')
->addRow("de_DE", 'Deutsch Standard');
$queries[] = $sql->createTable("UserToken")
->addInt("user_id")
->addString("token", 36)
->addEnum("token_type", array("password_reset", "email_confirm", "invite", "gpg_confirm"))
->addDateTime("valid_until")
->addBool("used", false)
->foreignKey("user_id", "User", "id", new CascadeStrategy());
$queries[] = $sql->insert("Group", array("name", "color"))
->addRow(USER_GROUP_MODERATOR_NAME, "#007bff")
->addRow(USER_GROUP_SUPPORT_NAME, "#28a745")
->addRow(USER_GROUP_ADMIN_NAME, "#dc3545");
$queries[] = $sql->createTable("UserGroup")
->addInt("user_id")
->addInt("group_id")
->unique("user_id", "group_id")
->foreignKey("user_id", "User", "id", new CascadeStrategy())
->foreignKey("group_id", "Group", "id", new CascadeStrategy());
$queries[] = $sql->createTable("UserNotification")
->addInt("user_id")
->addInt("notification_id")
->addBool("seen", false)
->foreignKey("user_id", "User", "id")
->foreignKey("notification_id", "Notification", "id")
->unique("user_id", "notification_id");
$queries[] = $sql->createTable("GroupNotification")
->addInt("group_id")
->addInt("notification_id")
->addBool("seen", false)
->foreignKey("group_id", "Group", "id")
->foreignKey("notification_id", "Notification", "id")
->unique("group_id", "notification_id");
$queries[] = $sql->createTable("Visitor")
->addInt("day")
->addInt("count", false, 1)
->addString("cookie", 26)
->unique("day", "cookie");
$queries[] = $sql->createTable("Route")
->addSerial("id")
->addString("request", 128)
->addEnum("action", array("redirect_temporary", "redirect_permanently", "static", "dynamic"))
->addString("target", 128)
->addString("extra", 64, true)
->addBool("active", true)
->addBool("exact", true)
->primaryKey("id")
->unique("request");
$queries[] = $sql->insert("Route", ["request", "action", "target", "extra", "exact"])
->addRow("/admin", "dynamic", "\\Core\\Documents\\Admin", NULL, false)
->addRow("/register", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/register.twig"]), true)
->addRow("/confirmEmail", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/confirm_email.twig"]), true)
->addRow("/acceptInvite", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/accept_invite.twig"]), true)
->addRow("/resetPassword", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/reset_password.twig"]), true)
->addRow("/login", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/login.twig"]), true)
->addRow("/resendConfirmEmail", "dynamic", "\\Core\\Documents\\Account", json_encode(["account/resend_confirm_email.twig"]), true)
->addRow("/debug", "dynamic", "\\Core\\Documents\\Info", NULL, true)
->addRow("/", "static", "/static/welcome.html", NULL, true);
$queries[] = $sql->createTable("Settings")
->addString("name", 32)
->addString("value", 1024, true)
->addBool("private", false) // these values are not returned from '/api/settings/get', but can be changed
->addBool("readonly", false) // these values are neither returned, nor can be changed from outside
->primaryKey("name");
$settingsQuery = $sql->insert("Settings", array("name", "value", "private", "readonly"))
// ->addRow("mail_enabled", "0") # this key will be set during installation
->addRow("mail_host", "", false, false)
->addRow("mail_port", "", false, false)
->addRow("mail_username", "", false, false)
->addRow("mail_password", "", true, false)
->addRow("mail_from", "", false, false)
->addRow("mail_last_sync", "", false, false)
->addRow("mail_footer", "", false, false);
(Settings::loadDefaults())->addRows($settingsQuery);
$queries[] = $settingsQuery;
$queries[] = $sql->createTable("ContactRequest")
->addSerial("id")
->addString("from_name", 32)
->addString("from_email", 64)
->addString("message", 512)
->addString("messageId", 78, true) # null = don't sync with mails (usually if mail could not be sent)
->addDateTime("created_at", false, $sql->currentTimestamp())
->unique("messageId")
->primaryKey("id");
$queries[] = $sql->createTable("ContactMessage")
->addSerial("id")
->addInt("request_id")
->addInt("user_id", true) # null = customer has sent this message
->addString("message", 512)
->addString("messageId", 78)
->addDateTime("created_at", false, $sql->currentTimestamp())
->addBool("read", false)
->unique("messageId")
->primaryKey("id")
->foreignKey("request_id", "ContactRequest", "id", new CascadeStrategy())
->foreignKey("user_id", "User", "id", new SetNullStrategy());
$queries[] = $sql->createTable("ApiPermission")
->addString("method", 32)
->addJson("groups", true, '[]')
->addString("description", 128, false, "")
->primaryKey("method");
$queries[] = $sql->createTable("MailQueue")
->addSerial("id")
->addString("from", 64)
->addString("to", 64)
->addString("subject")
->addString("body")
->addString("replyTo", 64, true)
->addString("replyName", 32, true)
->addString("gpgFingerprint", 64, true)
->addEnum("status", ["waiting", "success", "error"], false, 'waiting')
->addInt("retryCount", false, 5)
->addDateTime("nextTry", false, $sql->now())
->addString("errorMessage", NULL, true)
->primaryKey("id");
$queries = array_merge($queries, \Core\Configuration\Patch\EntityLog_2021_04_08::createTableLog($sql, "MailQueue", 30));
$queries[] = $sql->insert("ApiPermission", array("method", "groups", "description"))
->addRow("ApiKey/create", array(), "Allows users to create API-Keys for themselves")
->addRow("ApiKey/fetch", array(), "Allows users to list their API-Keys")
->addRow("ApiKey/refresh", array(), "Allows users to refresh their API-Keys")
->addRow("ApiKey/revoke", array(), "Allows users to revoke their API-Keys")
->addRow("Groups/fetch", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to list all available groups")
->addRow("Groups/create", array(USER_GROUP_ADMIN), "Allows users to create a new groups")
->addRow("Groups/delete", array(USER_GROUP_ADMIN), "Allows users to delete a group")
->addRow("Routes/fetch", array(USER_GROUP_ADMIN), "Allows users to list all configured routes")
->addRow("Routes/save", array(USER_GROUP_ADMIN), "Allows users to create, delete and modify routes")
->addRow("Mail/test", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to send a test email to a given address")
->addRow("Mail/Sync", array(USER_GROUP_SUPPORT, USER_GROUP_ADMIN), "Allows users to synchronize mails with the database")
->addRow("Settings/get", array(USER_GROUP_ADMIN), "Allows users to fetch server settings")
->addRow("Settings/set", array(USER_GROUP_ADMIN), "Allows users create, delete or modify server settings")
->addRow("Stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to fetch server stats")
->addRow("User/create", array(USER_GROUP_ADMIN), "Allows users to create a new user, email address does not need to be confirmed")
->addRow("User/fetch", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to list all registered users")
->addRow("User/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to get information about a single user")
->addRow("User/invite", array(USER_GROUP_ADMIN), "Allows users to create a new user and send them an invitation link")
->addRow("User/edit", array(USER_GROUP_ADMIN), "Allows users to edit details and group memberships of any user")
->addRow("User/delete", array(USER_GROUP_ADMIN), "Allows users to delete any other user")
->addRow("Permission/fetch", array(USER_GROUP_ADMIN), "Allows users to list all API permissions")
->addRow("Visitors/stats", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to see visitor statistics")
->addRow("Contact/respond", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to respond to contact requests")
->addRow("Contact/fetch", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to fetch all contact requests")
->addRow("Contact/get", array(USER_GROUP_ADMIN, USER_GROUP_SUPPORT), "Allows users to see messages within a contact request");
self::loadPatches($queries, $sql);
return $queries;
}
private static function loadPatches(&$queries, $sql) {
$baseDirs = ["Core", "Site"];
foreach ($baseDirs as $baseDir) {
$patchDirectory = "./$baseDir/Configuration/Patch/";
if (file_exists($patchDirectory) && is_dir($patchDirectory)) {
$scan_arr = scandir($patchDirectory);
$files_arr = array_diff($scan_arr, array('.', '..'));
foreach ($files_arr as $file) {
$suffix = ".class.php";
if (endsWith($file, $suffix)) {
$className = substr($file, 0, strlen($file) - strlen($suffix));
$className = "\\$baseDir\\Configuration\\Patch\\$className";
$method = "$className::createQueries";
$patchQueries = call_user_func($method, $sql);
foreach ($patchQueries as $query) $queries[] = $query;
}
}
}
}
}
public static function loadEntities(&$queries, $sql) {
$handlers = [];
$baseDirs = ["Core", "Site"];
foreach ($baseDirs as $baseDir) {
$entityDirectory = "./$baseDir/Objects/DatabaseEntity/";
if (file_exists($entityDirectory) && is_dir($entityDirectory)) {
$scan_arr = scandir($entityDirectory);
$files_arr = array_diff($scan_arr, array('.', '..'));
foreach ($files_arr as $file) {
$suffix = ".class.php";
if (endsWith($file, $suffix)) {
$className = substr($file, 0, strlen($file) - strlen($suffix));
if (!in_array($className, ["DatabaseEntity", "DatabaseEntityQuery", "DatabaseEntityHandler"])) {
$className = "\\$baseDir\\Objects\\DatabaseEntity\\$className";
$reflectionClass = new \ReflectionClass($className);
if ($reflectionClass->isSubclassOf(DatabaseEntity::class)) {
$method = "$className::getHandler";
$handler = call_user_func($method, $sql);
$handlers[$handler->getTableName()] = $handler;
}
}
}
}
}
$tableCount = count($handlers);
$createdTables = [];
while (!empty($handlers)) {
$prevCount = $tableCount;
$unmetDependenciesTotal = [];
foreach ($handlers as $tableName => $handler) {
$dependsOn = $handler->dependsOn();
$unmetDependencies = array_diff($dependsOn, $createdTables);
if (empty($unmetDependencies)) {
$queries[] = $handler->getTableQuery();
$createdTables[] = $tableName;
unset($handlers[$tableName]);
} else {
$unmetDependenciesTotal = array_merge($unmetDependenciesTotal, $unmetDependencies);
}
}
$tableCount = count($handlers);
if ($tableCount === $prevCount) {
throw new Exception("Circular or unmet table dependency detected. Unmet dependencies: "
. implode(", ", $unmetDependenciesTotal));
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Core\Configuration;
use Core\Driver\SQL\SQL;
abstract class DatabaseScript {
public static abstract function createQueries(SQL $sql);
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Core\Configuration\Patch;
use Core\Configuration\DatabaseScript;
use Core\Driver\SQL\Column\IntColumn;
use Core\Driver\SQL\Condition\Compare;
use Core\Driver\SQL\Query\CreateProcedure;
use Core\Driver\SQL\SQL;
use Core\Driver\SQL\Type\CurrentColumn;
use Core\Driver\SQL\Type\CurrentTable;
use Core\Driver\SQL\Type\Trigger;
class EntityLog_2021_04_08 extends DatabaseScript {
public static function createTableLog(SQL $sql, string $table, int $lifetime = 90): array {
return [
$sql->createTrigger("${table}_trg_insert")
->after()->insert($table)
->exec(new CreateProcedure($sql, "InsertEntityLog"), [
"tableName" => new CurrentTable(),
"entityId" => new CurrentColumn("id"),
"lifetime" => $lifetime,
]),
$sql->createTrigger("${table}_trg_update")
->after()->update($table)
->exec(new CreateProcedure($sql, "UpdateEntityLog"), [
"tableName" => new CurrentTable(),
"entityId" => new CurrentColumn("id"),
]),
$sql->createTrigger("${table}_trg_delete")
->after()->delete($table)
->exec(new CreateProcedure($sql, "DeleteEntityLog"), [
"tableName" => new CurrentTable(),
"entityId" => new CurrentColumn("id"),
])
];
}
public static function createQueries(SQL $sql): array {
$queries = array();
$queries[] = $sql->createTable("EntityLog")
->addInt("entityId")
->addString("tableName")
->addDateTime("modified", false, $sql->now())
->addInt("lifetime", false, 90);
$insertProcedure = $sql->createProcedure("InsertEntityLog")
->param(new CurrentTable())
->param(new IntColumn("id"))
->param(new IntColumn("lifetime", false, 90))
->returns(new Trigger())
->exec(array(
$sql->insert("EntityLog", ["entityId", "tableName", "lifetime"])
->addRow(new CurrentColumn("id"), new CurrentTable(), new CurrentColumn("lifetime"))
));
$updateProcedure = $sql->createProcedure("UpdateEntityLog")
->param(new CurrentTable())
->param(new IntColumn("id"))
->returns(new Trigger())
->exec(array(
$sql->update("EntityLog")
->set("modified", $sql->now())
->where(new Compare("entityId", new CurrentColumn("id")))
->where(new Compare("tableName", new CurrentTable()))
));
$deleteProcedure = $sql->createProcedure("DeleteEntityLog")
->param(new CurrentTable())
->param(new IntColumn("id"))
->returns(new Trigger())
->exec(array(
$sql->delete("EntityLog")
->where(new Compare("entityId", new CurrentColumn("id")))
->where(new Compare("tableName", new CurrentTable()))
));
$queries[] = $insertProcedure;
$queries[] = $updateProcedure;
$queries[] = $deleteProcedure;
$tables = ["ContactRequest"];
foreach ($tables as $table) {
$queries = array_merge($queries, self::createTableLog($sql, $table));
}
return $queries;
}
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Core\Configuration\Patch;
use Core\Configuration\DatabaseScript;
use Core\Driver\SQL\SQL;
class SystemLog_2022_03_30 extends DatabaseScript {
public static function createQueries(SQL $sql): array {
return [
$sql->insert("ApiPermission", ["method", "groups", "description"])
->addRow("Logs/get", [USER_GROUP_ADMIN], "Allows users to fetch system logs")
];
}
}

View File

@@ -0,0 +1,221 @@
<?php
/**
* Do not change settings here, they are dynamically loaded from database.
*/
namespace Core\Configuration;
use Core\Driver\Logger\Logger;
use Core\Driver\SQL\Query\Insert;
use Core\Objects\Context;
class Settings {
//
private bool $installationComplete;
// settings
private string $siteName;
private string $baseUrl;
private ?string $jwtPublicKey;
private ?string $jwtSecretKey;
private string $jwtAlgorithm;
private bool $registrationAllowed;
private bool $recaptchaEnabled;
private bool $mailEnabled;
private string $recaptchaPublicKey;
private string $recaptchaPrivateKey;
private string $mailSender;
private string $mailFooter;
private array $allowedExtensions;
//
private Logger $logger;
public function __construct() {
$this->logger = new Logger("Settings");
}
public function getJwtPublicKey(bool $allowPrivate = true): ?\Firebase\JWT\Key {
if (empty($this->jwtPublicKey)) {
// we might have a symmetric key, should we instead return the private key?
return $allowPrivate ? new \Firebase\JWT\Key($this->jwtSecretKey, $this->jwtAlgorithm) : null;
} else {
return new \Firebase\JWT\Key($this->jwtPublicKey, $this->jwtAlgorithm);
}
}
public function getJwtSecretKey(): \Firebase\JWT\Key {
return new \Firebase\JWT\Key($this->jwtSecretKey, $this->jwtAlgorithm);
}
public function isInstalled(): bool {
return $this->installationComplete;
}
public static function loadDefaults(): Settings {
$hostname = $_SERVER["SERVER_NAME"] ?? "localhost";
$protocol = getProtocol();
$settings = new Settings();
// General
$settings->siteName = "WebBase";
$settings->baseUrl = "$protocol://$hostname";
$settings->allowedExtensions = ['png', 'jpg', 'jpeg', 'gif', 'htm', 'html'];
$settings->installationComplete = false;
$settings->registrationAllowed = false;
// JWT
$settings->jwtSecretKey = null;
$settings->jwtPublicKey = null;
$settings->jwtAlgorithm = "HS256";
// Recaptcha
$settings->recaptchaEnabled = false;
$settings->recaptchaPublicKey = "";
$settings->recaptchaPrivateKey = "";
// Mail
$settings->mailEnabled = false;
$settings->mailSender = "webmaster@localhost";
$settings->mailFooter = "";
return $settings;
}
public function generateJwtKey(string $algorithm = null): bool {
$this->jwtAlgorithm = $algorithm ?? $this->jwtAlgorithm;
// TODO: key encryption necessary?
if (in_array($this->jwtAlgorithm, ["HS256", "HS384", "HS512"])) {
$this->jwtSecretKey = generateRandomString(32);
$this->jwtPublicKey = null;
} else if (in_array($this->jwtAlgorithm, ["RS256", "RS384", "RS512"])) {
$bits = intval(substr($this->jwtAlgorithm, 2));
$private_key = openssl_pkey_new(["private_key_bits" => $bits]);
$this->jwtPublicKey = openssl_pkey_get_details($private_key)['key'];
openssl_pkey_export($private_key, $this->jwtSecretKey);
} else if (in_array($this->jwtAlgorithm, ["ES256", "ES384"])) {
// $ec = new \Elliptic\EC('secp256k1'); ??
$this->logger->error("JWT algorithm: '$this->jwtAlgorithm' is currently not supported.");
return false;
} else if ($this->jwtAlgorithm == "EdDSA") {
$keyPair = sodium_crypto_sign_keypair();
$this->jwtSecretKey = base64_encode(sodium_crypto_sign_secretkey($keyPair));
$this->jwtPublicKey = base64_encode(sodium_crypto_sign_publickey($keyPair));
} else {
$this->logger->error("Invalid JWT algorithm: '$this->jwtAlgorithm', expected one of: " .
implode(",", array_keys(\Firebase\JWT\JWT::$supported_algs)));
return false;
}
return true;
}
public static function isJwtAlgorithmSupported(string $algorithm): bool {
return in_array(strtoupper($algorithm), ["HS256", "HS384", "HS512", "RS256", "RS384", "RS512", "EDDSA"]);
}
public function saveJwtKey(Context $context) {
$req = new \Core\API\Settings\Set($context);
$req->execute(array("settings" => array(
"jwt_secret_key" => $this->jwtSecretKey,
"jwt_public_key" => $this->jwtSecretKey,
"jwt_algorithm" => $this->jwtAlgorithm,
)));
return $req;
}
public function loadFromDatabase(Context $context): bool {
$this->logger = new Logger("Settings", $context->getSQL());
$req = new \Core\API\Settings\Get($context);
$success = $req->execute();
if ($success) {
$result = $req->getResult()["settings"];
$this->siteName = $result["site_name"] ?? $this->siteName;
$this->baseUrl = $result["base_url"] ?? $this->baseUrl;
$this->registrationAllowed = $result["user_registration_enabled"] ?? $this->registrationAllowed;
$this->installationComplete = $result["installation_completed"] ?? $this->installationComplete;
$this->jwtSecretKey = $result["jwt_secret_key"] ?? $this->jwtSecretKey;
$this->jwtPublicKey = $result["jwt_public_key"] ?? $this->jwtPublicKey;
$this->jwtAlgorithm = $result["jwt_algorithm"] ?? $this->jwtAlgorithm;
$this->recaptchaEnabled = $result["recaptcha_enabled"] ?? $this->recaptchaEnabled;
$this->recaptchaPublicKey = $result["recaptcha_public_key"] ?? $this->recaptchaPublicKey;
$this->recaptchaPrivateKey = $result["recaptcha_private_key"] ?? $this->recaptchaPrivateKey;
$this->mailEnabled = $result["mail_enabled"] ?? $this->mailEnabled;
$this->mailSender = $result["mail_from"] ?? $this->mailSender;
$this->mailFooter = $result["mail_footer"] ?? $this->mailFooter;
$this->allowedExtensions = explode(",", $result["allowed_extensions"] ?? strtolower(implode(",", $this->allowedExtensions)));
if (!isset($result["jwt_secret_key"])) {
if ($this->generateJwtKey()) {
$this->saveJwtKey($context);
}
}
}
return false;
}
public function addRows(Insert $query) {
$query->addRow("site_name", $this->siteName, false, false)
->addRow("base_url", $this->baseUrl, false, false)
->addRow("user_registration_enabled", $this->registrationAllowed ? "1" : "0", false, false)
->addRow("installation_completed", $this->installationComplete ? "1" : "0", true, true)
->addRow("jwt_secret_key", $this->jwtSecretKey, true, false)
->addRow("jwt_public_key", $this->jwtPublicKey, false, false)
->addRow("jwt_algorithm", $this->jwtAlgorithm, false, false)
->addRow("recaptcha_enabled", $this->recaptchaEnabled ? "1" : "0", false, false)
->addRow("recaptcha_public_key", $this->recaptchaPublicKey, false, false)
->addRow("recaptcha_private_key", $this->recaptchaPrivateKey, true, false)
->addRow("allowed_extensions", implode(",", $this->allowedExtensions), true, false);
}
public function getSiteName(): string {
return $this->siteName;
}
public function getBaseUrl(): string {
return $this->baseUrl;
}
public function isRecaptchaEnabled(): bool {
return $this->recaptchaEnabled;
}
public function getRecaptchaSiteKey(): string {
return $this->recaptchaPublicKey;
}
public function getRecaptchaSecretKey(): string {
return $this->recaptchaPrivateKey;
}
public function isRegistrationAllowed(): bool {
return $this->registrationAllowed;
}
public function isMailEnabled(): bool {
return $this->mailEnabled;
}
public function getMailSender(): string {
return $this->mailSender;
}
public function isExtensionAllowed(string $ext): bool {
return empty($this->allowedExtensions) || in_array(strtolower(trim($ext)), $this->allowedExtensions);
}
public function getDomain(): string {
return parse_url($this->getBaseUrl(), PHP_URL_HOST);
}
public function getLogger(): Logger {
return $this->logger;
}
}