diff --git a/.htaccess b/.htaccess index a9c317a..8f8fde7 100644 --- a/.htaccess +++ b/.htaccess @@ -9,7 +9,7 @@ RewriteRule ^(api(/.*)?)$ /index.php?api=$1 [L,QSA] RewriteEngine On RewriteOptions AllowNoSlash -RewriteRule ^((\.idea|\.git|src|test|core|docker|files)(/.*)?)$ /index.php?site=$1 [L,QSA] +RewriteRule ^((\.idea|\.git|src|test|Site|Core|docker|files)(/.*)?)$ /index.php?site=$1 [L,QSA] FallbackResource /index.php diff --git a/core/Api/ApiKeyAPI.class.php b/Core/API/ApiKeyAPI.class.php similarity index 93% rename from core/Api/ApiKeyAPI.class.php rename to Core/API/ApiKeyAPI.class.php index 852695f..99d7676 100644 --- a/core/Api/ApiKeyAPI.class.php +++ b/Core/API/ApiKeyAPI.class.php @@ -1,9 +1,9 @@ context); + $request = new \Core\API\Mail\Send($this->context); $this->success = $request->execute(array( "subject" => $subject, "body" => $message, @@ -34,17 +34,17 @@ namespace Api { } } -namespace Api\Contact { +namespace Core\API\Contact { - use Api\ContactAPI; - use Api\Parameter\Parameter; - use Api\Parameter\StringType; - use Api\VerifyCaptcha; - use Driver\SQL\Condition\Compare; - use Driver\SQL\Condition\CondNot; - use Driver\SQL\Expression\CaseWhen; - use Driver\SQL\Expression\Sum; - use Objects\Context; + use Core\API\ContactAPI; + use Core\API\Parameter\Parameter; + use Core\API\Parameter\StringType; + use Core\API\VerifyCaptcha; + use Core\Driver\SQL\Condition\Compare; + use Core\Driver\SQL\Condition\CondNot; + use Core\Driver\SQL\Expression\CaseWhen; + use Core\Driver\SQL\Expression\Sum; + use Core\Objects\Context; class Request extends ContactAPI { diff --git a/core/Api/GroupsAPI.class.php b/Core/API/GroupsAPI.class.php similarity index 94% rename from core/Api/GroupsAPI.class.php rename to Core/API/GroupsAPI.class.php index cefc7f3..7823482 100644 --- a/core/Api/GroupsAPI.class.php +++ b/Core/API/GroupsAPI.class.php @@ -1,9 +1,9 @@ context); + $req = new \Core\API\Settings\Get($this->context); $this->success = $req->execute(array("key" => "^mail_")); $this->lastError = $req->getLastError(); @@ -40,19 +40,19 @@ namespace Api { } } -namespace Api\Mail { +namespace Core\API\Mail { - use Api\MailAPI; - use Api\Parameter\Parameter; - use Api\Parameter\StringType; + use Core\API\MailAPI; + use Core\API\Parameter\Parameter; + use Core\API\Parameter\StringType; use DateTimeInterface; - use Driver\SQL\Column\Column; - use Driver\SQL\Condition\Compare; - use Driver\SQL\Condition\CondIn; - use External\PHPMailer\Exception; - use External\PHPMailer\PHPMailer; - use Objects\Context; - use Objects\DatabaseEntity\GpgKey; + use Core\Driver\SQL\Column\Column; + use Core\Driver\SQL\Condition\Compare; + use Core\Driver\SQL\Condition\CondIn; + use Core\External\PHPMailer\Exception; + use Core\External\PHPMailer\PHPMailer; + use Core\Objects\Context; + use Core\Objects\DatabaseEntity\GpgKey; class Test extends MailAPI { @@ -66,7 +66,7 @@ namespace Api\Mail { public function _execute(): bool { $receiver = $this->getParam("receiver"); - $req = new \Api\Mail\Send($this->context); + $req = new \Core\API\Mail\Send($this->context); $this->success = $req->execute(array( "to" => $receiver, "subject" => "Test E-Mail", diff --git a/core/Api/NewsAPI.class.php b/Core/API/NewsAPI.class.php similarity index 94% rename from core/Api/NewsAPI.class.php rename to Core/API/NewsAPI.class.php index 830681f..9d889fd 100644 --- a/core/Api/NewsAPI.class.php +++ b/Core/API/NewsAPI.class.php @@ -1,8 +1,8 @@ context); + if (!($this instanceof \API\Permission\Save)) { + $req = new \Core\API\Permission\Check($this->context); $this->success = $req->execute(array("method" => $this->getMethod())); $this->lastError = $req->getLastError(); if (!$this->success) { diff --git a/core/Api/RoutesAPI.class.php b/Core/API/RoutesAPI.class.php similarity index 95% rename from core/Api/RoutesAPI.class.php rename to Core/API/RoutesAPI.class.php index f2d3093..0d63af1 100644 --- a/core/Api/RoutesAPI.class.php +++ b/Core/API/RoutesAPI.class.php @@ -1,15 +1,15 @@ success; } } + + class GenerateJWT extends SettingsAPI { + + public function __construct(Context $context, bool $externalCall = false) { + parent::__construct($context, $externalCall, [ + "type" => new StringType("type", 32, true, "HS512") + ]); + } + + protected function _execute(): bool { + $algorithm = $this->getParam("type"); + if (!Settings::isJwtAlgorithmSupported($algorithm)) { + return $this->createError("Algorithm is not supported"); + } + + $settings = $this->context->getSettings(); + if (!$settings->generateJwtKey($algorithm)) { + return $this->createError("Error generating JWT-Key: " . $settings->getLogger()->getLastMessage()); + } + + $saveRequest = $settings->saveJwtKey($this->context); + if (!$saveRequest->success()) { + return $this->createError("Error saving JWT-Key: " . $saveRequest->getLastError()); + } + + $this->result["jwt_public_key"] = $settings->getJwtPublicKey(false)?->getKeyMaterial(); + return true; + } + } } \ No newline at end of file diff --git a/core/Api/Stats.class.php b/Core/API/Stats.class.php similarity index 91% rename from core/Api/Stats.class.php rename to Core/API/Stats.class.php index 5e18fa8..d59f819 100644 --- a/core/Api/Stats.class.php +++ b/Core/API/Stats.class.php @@ -1,12 +1,12 @@ context); + $req = new \Core\API\Settings\Get($this->context); $this->success = $req->execute(array("key" => "^(mail_enabled|recaptcha_enabled)$")); $this->lastError = $req->getLastError(); @@ -71,7 +71,7 @@ class Stats extends Request { public function _execute(): bool { $userCount = $this->getUserCount(); $pageCount = $this->getPageCount(); - $req = new \Api\Visitors\Stats($this->context); + $req = new \Core\API\Visitors\Stats($this->context); $this->success = $req->execute(array("type"=>"monthly")); $this->lastError = $req->getLastError(); if (!$this->success) { diff --git a/core/Api/Swagger.class.php b/Core/API/Swagger.class.php similarity index 84% rename from core/Api/Swagger.class.php rename to Core/API/Swagger.class.php index 3191bb7..03ccc2b 100644 --- a/core/Api/Swagger.class.php +++ b/Core/API/Swagger.class.php @@ -1,10 +1,10 @@ isSubclassOf(Request::class) || $reflection->isAbstract()) { - continue; - } + foreach (scandir($basePath) as $fileName) { + $fullPath = $basePath . "/" . $fileName; + if (is_file($fullPath) && endsWith($fileName, ".class.php")) { + require_once $fullPath; + $apiName = explode(".", $fileName)[0]; + $className = "\\API\\$apiName"; + if (!class_exists($className)) { + var_dump("Class not exist: $className"); + continue; + } - $endpoint = "/" . strtolower($apiName); - $classes[$endpoint] = $reflection; + $reflection = new \ReflectionClass($className); + if (!$reflection->isSubclassOf(Request::class) || $reflection->isAbstract()) { + continue; + } + + $endpoint = "/" . strtolower($apiName); + $classes[$endpoint] = $reflection; + } } } diff --git a/core/Api/TemplateAPI.class.php b/Core/API/TemplateAPI.class.php similarity index 84% rename from core/Api/TemplateAPI.class.php rename to Core/API/TemplateAPI.class.php index a13c15e..39a7edc 100644 --- a/core/Api/TemplateAPI.class.php +++ b/Core/API/TemplateAPI.class.php @@ -1,8 +1,8 @@ createError("Invalid template file extension. Allowed: " . implode(",", $allowedExtensions)); } - $templateDir = WEBROOT . "/core/Templates/"; - $templateCache = WEBROOT . "/core/Cache/Templates/"; + $templateDir = WEBROOT . "/Core/Templates/"; + $templateCache = WEBROOT . "/Core/Cache/Templates/"; $path = realpath($templateDir . $templateFile); if (!startsWith($path, realpath($templateDir))) { return $this->createError("Template file not in template directory"); diff --git a/core/Api/TfaAPI.class.php b/Core/API/TfaAPI.class.php similarity index 95% rename from core/Api/TfaAPI.class.php rename to Core/API/TfaAPI.class.php index a3a366c..a78b335 100644 --- a/core/Api/TfaAPI.class.php +++ b/Core/API/TfaAPI.class.php @@ -1,10 +1,10 @@ success && $token->isConfirmed()) { // send an email $settings = $this->context->getSettings(); - $req = new \Api\Template\Render($this->context); + $req = new \Core\API\Template\Render($this->context); $this->success = $req->execute([ "file" => "mail/2fa_remove.twig", "parameters" => [ @@ -123,7 +123,7 @@ namespace Api\TFA { if ($this->success) { $body = $req->getResult()["html"]; $gpg = $currentUser->getGPG(); - $req = new \Api\Mail\Send($this->context); + $req = new \Core\API\Mail\Send($this->context); $this->success = $req->execute([ "to" => $currentUser->getEmail(), "subject" => "[Security Lab] 2FA-Authentication removed", diff --git a/core/Api/UserAPI.class.php b/Core/API/UserAPI.class.php similarity index 98% rename from core/Api/UserAPI.class.php rename to Core/API/UserAPI.class.php index 8159036..5f62faa 100644 --- a/core/Api/UserAPI.class.php +++ b/Core/API/UserAPI.class.php @@ -1,11 +1,11 @@ context->getSQL(); - $user = new \Objects\DatabaseEntity\User(); + $user = new \Core\Objects\DatabaseEntity\User(); $user->language = Language::DEFAULT_LANGUAGE(false); $user->registeredAt = new \DateTime(); $user->password = $this->hashPassword($password); @@ -151,27 +151,27 @@ namespace Api { } -namespace Api\User { +namespace Core\API\User { - use Api\Parameter\Parameter; - use Api\Parameter\StringType; - use Api\Template\Render; - use Api\UserAPI; - use Api\VerifyCaptcha; + use Core\API\Parameter\Parameter; + use Core\API\Parameter\StringType; + use Core\API\Template\Render; + use Core\API\UserAPI; + use Core\API\VerifyCaptcha; use DateTime; - use Driver\SQL\Column\Column; - use Driver\SQL\Condition\Compare; - use Driver\SQL\Condition\CondBool; - use Driver\SQL\Condition\CondIn; - use Driver\SQL\Condition\CondNot; - use Driver\SQL\Expression\JsonArrayAgg; + use Core\Driver\SQL\Column\Column; + use Core\Driver\SQL\Condition\Compare; + use Core\Driver\SQL\Condition\CondBool; + use Core\Driver\SQL\Condition\CondIn; + use Core\Driver\SQL\Condition\CondNot; + use Core\Driver\SQL\Expression\JsonArrayAgg; use ImagickException; - use Objects\Context; - use Objects\DatabaseEntity\DatabaseEntityHandler; - use Objects\DatabaseEntity\GpgKey; - use Objects\DatabaseEntity\TwoFactorToken; - use Objects\TwoFactor\KeyBasedTwoFactorToken; - use Objects\DatabaseEntity\User; + use Core\Objects\Context; + use Core\Objects\DatabaseEntity\DatabaseEntityHandler; + use Core\Objects\DatabaseEntity\GpgKey; + use Core\Objects\DatabaseEntity\TwoFactorToken; + use Core\Objects\TwoFactor\KeyBasedTwoFactorToken; + use Core\Objects\DatabaseEntity\User; class Create extends UserAPI { @@ -534,7 +534,7 @@ namespace Api\User { if ($this->success) { $messageBody = $req->getResult()["html"]; - $request = new \Api\Mail\Send($this->context); + $request = new \Core\API\Mail\Send($this->context); $this->success = $request->execute(array( "to" => $email, "subject" => "[$siteName] Account Invitation", @@ -863,7 +863,7 @@ namespace Api\User { if ($this->success) { $messageBody = $req->getResult()["html"]; - $request = new \Api\Mail\Send($this->context); + $request = new \Core\API\Mail\Send($this->context); $this->success = $request->execute(array( "to" => $email, "subject" => "[$siteName] E-Mail Confirmation", @@ -1146,7 +1146,7 @@ namespace Api\User { $gpgFingerprint = $user["gpg_fingerprint"]; } - $request = new \Api\Mail\Send($this->context); + $request = new \Core\API\Mail\Send($this->context); $this->success = $request->execute(array( "to" => $email, "subject" => "[$siteName] Password Reset", @@ -1272,7 +1272,7 @@ namespace Api\User { if ($this->success) { $messageBody = $req->getResult()["html"]; - $request = new \Api\Mail\Send($this->context); + $request = new \Core\API\Mail\Send($this->context); $this->success = $request->execute(array( "to" => $email, "subject" => "[$siteName] E-Mail Confirmation", @@ -1517,7 +1517,7 @@ namespace Api\User { Best Regards
ilum:e Security Lab"; - $sendMail = new \Api\Mail\Send($this->context); + $sendMail = new \Core\API\Mail\Send($this->context); $this->success = $sendMail->execute(array( "to" => $currentUser->getEmail(), "subject" => "Security Lab - Confirm GPG-Key", diff --git a/core/Api/VerifyCaptcha.class.php b/Core/API/VerifyCaptcha.class.php similarity index 95% rename from core/Api/VerifyCaptcha.class.php rename to Core/API/VerifyCaptcha.class.php index 486a5d4..6db6bb2 100644 --- a/core/Api/VerifyCaptcha.class.php +++ b/Core/API/VerifyCaptcha.class.php @@ -1,9 +1,9 @@ database = null; $this->settings = Settings::loadDefaults(); - $class = \Configuration\Database::class; - $path = getClassPath($class, ".class"); + $className = self::className; + $path = getClassPath($className, ".class"); if (file_exists($path) && is_readable($path)) { include_once $path; - if (class_exists($class)) { - $this->database = new \Configuration\Database(); + if (class_exists($className)) { + $this->database = new $className(); } } } @@ -32,7 +33,9 @@ class Configuration { } public static function create(string $className, $data) { - $path = getClassPath("\\Configuration\\$className"); + $path = getClassPath($className); + $classNameShort = explode("\\", $className); + $classNameShort = end($classNameShort); if ($data) { if (is_string($data)) { @@ -40,9 +43,9 @@ class Configuration { $code = intendCode( "database = $connectionData; } } \ No newline at end of file diff --git a/core/Configuration/CreateDatabase.class.php b/Core/Configuration/CreateDatabase.class.php similarity index 74% rename from core/Configuration/CreateDatabase.class.php rename to Core/Configuration/CreateDatabase.class.php index f59c3fb..5e8ff85 100644 --- a/core/Configuration/CreateDatabase.class.php +++ b/Core/Configuration/CreateDatabase.class.php @@ -1,11 +1,11 @@ unique("request"); $queries[] = $sql->insert("Route", ["request", "action", "target", "extra", "exact"]) - ->addRow("/admin", "dynamic", "\\Documents\\Admin", NULL, false) - ->addRow("/register", "dynamic", "\\Documents\\Account", json_encode(["account/register.twig"]), true) - ->addRow("/confirmEmail", "dynamic", "\\Documents\\Account", json_encode(["account/confirm_email.twig"]), true) - ->addRow("/acceptInvite", "dynamic", "\\Documents\\Account", json_encode(["account/accept_invite.twig"]), true) - ->addRow("/resetPassword", "dynamic", "\\Documents\\Account", json_encode(["account/reset_password.twig"]), true) - ->addRow("/login", "dynamic", "\\Documents\\Account", json_encode(["account/login.twig"]), true) - ->addRow("/resendConfirmEmail", "dynamic", "\\Documents\\Account", json_encode(["account/resend_confirm_email.twig"]), true) - ->addRow("/debug", "dynamic", "\\Documents\\Info", NULL, true) + ->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") @@ -141,12 +141,13 @@ class CreateDatabase extends DatabaseScript { ->addString("replyTo", 64, true) ->addString("replyName", 32, true) ->addString("gpgFingerprint", 64, true) - ->addEnum("status", ["waiting","success","error"], false, 'waiting') + ->addEnum("status", ["waiting", "success", "error"], false, 'waiting') ->addInt("retryCount", false, 5) ->addDateTime("nextTry", false, $sql->now()) - ->addString("errorMessage", NULL, true) + ->addString("errorMessage", NULL, true) ->primaryKey("id"); - $queries = array_merge($queries, \Configuration\Patch\EntityLog_2021_04_08::createTableLog($sql, "MailQueue", 30)); + + $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") @@ -181,40 +182,46 @@ class CreateDatabase extends DatabaseScript { } private static function loadPatches(&$queries, $sql) { - $patchDirectory = './core/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 = "\\Configuration\\Patch\\$className"; - $method = "$className::createQueries"; - $patchQueries = call_user_func($method, $sql); - foreach ($patchQueries as $query) $queries[] = $query; + $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) { - $entityDirectory = './core/Objects/DatabaseEntity/'; - if (file_exists($entityDirectory) && is_dir($entityDirectory)) { - $scan_arr = scandir($entityDirectory); - $files_arr = array_diff($scan_arr, array('.', '..')); - $handlers = []; - 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 = "\\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; + $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; + } } } } diff --git a/core/Configuration/DatabaseScript.class.php b/Core/Configuration/DatabaseScript.class.php similarity index 64% rename from core/Configuration/DatabaseScript.class.php rename to Core/Configuration/DatabaseScript.class.php index 90d3018..93c69b4 100644 --- a/core/Configuration/DatabaseScript.class.php +++ b/Core/Configuration/DatabaseScript.class.php @@ -1,8 +1,8 @@ logger = new Logger("Settings"); } - public function getJwtPublicKey(): \Firebase\JWT\Key { - return new \Firebase\JWT\Key($this->jwtPublicKey ?? $this->jwtSecretKey, $this->jwtAlgorithm); + 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 { @@ -109,18 +114,24 @@ class Settings { 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 \Api\Settings\Set($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 \Api\Settings\Get($context); + $req = new \Core\API\Settings\Get($context); $success = $req->execute(); if ($success) { @@ -203,4 +214,8 @@ class Settings { public function getDomain(): string { return parse_url($this->getBaseUrl(), PHP_URL_HOST); } + + public function getLogger(): Logger { + return $this->logger; + } } \ No newline at end of file diff --git a/core/Documents/Account.class.php b/Core/Documents/Account.class.php similarity index 91% rename from core/Documents/Account.class.php rename to Core/Documents/Account.class.php index 1d4d9fe..49e1df1 100644 --- a/core/Documents/Account.class.php +++ b/Core/Documents/Account.class.php @@ -1,10 +1,10 @@ getTemplateName() === "account/reset_password.twig") { if (isset($_GET["token"]) && is_string($_GET["token"]) && !empty($_GET["token"])) { $this->parameters["view"]["token"] = $_GET["token"]; - $req = new \Api\User\CheckToken($this->getContext()); + $req = new \Core\API\User\CheckToken($this->getContext()); $this->parameters["view"]["success"] = $req->execute(array("token" => $_GET["token"])); if ($this->parameters["view"]["success"]) { if (strcmp($req->getResult()["token"]["type"], "password_reset") !== 0) { @@ -48,7 +48,7 @@ class Account extends TemplateDocument { } else if ($this->getTemplateName() === "account/accept_invite.twig") { if (isset($_GET["token"]) && is_string($_GET["token"]) && !empty($_GET["token"])) { $this->parameters["view"]["token"] = $_GET["token"]; - $req = new \Api\User\CheckToken($this->getContext()); + $req = new \Core\API\User\CheckToken($this->getContext()); $this->parameters["view"]["success"] = $req->execute(array("token" => $_GET["token"])); if ($this->parameters["view"]["success"]) { if (strcmp($req->getResult()["token"]["type"], "invite") !== 0) { diff --git a/core/Documents/Admin.class.php b/Core/Documents/Admin.class.php similarity index 80% rename from core/Documents/Admin.class.php rename to Core/Documents/Admin.class.php index 1a6ba0f..bf72ec4 100644 --- a/core/Documents/Admin.class.php +++ b/Core/Documents/Admin.class.php @@ -1,9 +1,9 @@ execute(array("key" => "^mail_enabled$")); if (!$success) { $this->errorString = $req->getLastError(); @@ -193,12 +193,12 @@ namespace Documents\Install { } else if (isset($req->getResult()["settings"]["mail_enabled"])) { $step = self::FINISH_INSTALLATION; - $req = new \Api\Settings\Set($context); + $req = new \Core\API\Settings\Set($context); $success = $req->execute(array("settings" => array("installation_completed" => "1"))); if (!$success) { $this->errorString = $req->getLastError(); } else { - $req = new \Api\Notifications\Create($context); + $req = new \Core\API\Notifications\Create($context); $req->execute(array( "title" => "Welcome", "message" => "Your Web-base was successfully installed. Check out the admin dashboard. Have fun!", @@ -369,7 +369,7 @@ namespace Documents\Install { if ($success) { $context = $this->getDocument()->getContext(); $config = $context->getConfig(); - if (Configuration::create("Database", $connectionData) === false) { + if (Configuration::create(\Site\Configuration\Database::class, $connectionData) === false) { $success = false; $msg = "Unable to write database file"; } else { @@ -378,7 +378,7 @@ namespace Documents\Install { $success = false; $msg = "Unable to verify database connection after installation"; } else { - $req = new \Api\Routes\GenerateCache($context); + $req = new \Core\API\Routes\GenerateCache($context); if (!$req->execute()) { $success = false; $msg = "Unable to write route file: " . $req->getLastError(); @@ -430,7 +430,7 @@ namespace Documents\Install { $msg = "Please fill out the following inputs:
" . $this->createUnorderedList($missingInputs); } else { - $req = new \Api\User\Create($context); + $req = new \Core\API\User\Create($context); $success = $req->execute(array( 'username' => $username, 'email' => $email, @@ -462,7 +462,7 @@ namespace Documents\Install { } if ($this->getParameter("skip") === "true") { - $req = new \Api\Settings\Set($context); + $req = new \Core\API\Settings\Set($context); $success = $req->execute(array("settings" => array("mail_enabled" => "0"))); $msg = $req->getLastError(); } else { @@ -528,7 +528,7 @@ namespace Documents\Install { } if ($success) { - $req = new \Api\Settings\Set($context); + $req = new \Core\API\Settings\Set($context); $success = $req->execute(array("settings" => array( "mail_enabled" => "1", "mail_host" => "$address", diff --git a/core/Driver/Logger/Logger.class.php b/Core/Driver/Logger/Logger.class.php similarity index 93% rename from core/Driver/Logger/Logger.class.php rename to Core/Driver/Logger/Logger.class.php index e059dd9..2062a46 100644 --- a/core/Driver/Logger/Logger.class.php +++ b/Core/Driver/Logger/Logger.class.php @@ -1,8 +1,8 @@ getStackTrace(); } + $this->lastMessage = $message; + $this->lastLevel = $severity; if ($this->unitTestMode) { - $this->lastMessage = $message; - $this->lastLevel = $severity; return; } @@ -109,14 +109,6 @@ class Logger { return self::$INSTANCE; } - /** - * Calling this method will prevent the logger from persisting log messages (writing to database/file), - * and allow to access the last logged message via #getLastMessage() and #getLastLevel() - */ - public function unitTestMode() { - $this->unitTestMode = true; - } - public function getLastMessage(): ?string { return $this->lastMessage; } @@ -124,4 +116,11 @@ class Logger { public function getLastLevel(): ?string { return $this->lastLevel; } + + /** + * Calling this method will prevent the logger from persisting log messages (writing to database/file), + */ + public function unitTestMode() { + $this->unitTestMode = true; + } } \ No newline at end of file diff --git a/core/Driver/SQL/Column/BigIntColumn.class.php b/Core/Driver/SQL/Column/BigIntColumn.class.php similarity index 87% rename from core/Driver/SQL/Column/BigIntColumn.class.php rename to Core/Driver/SQL/Column/BigIntColumn.class.php index a065f31..7bfe5bb 100644 --- a/core/Driver/SQL/Column/BigIntColumn.class.php +++ b/Core/Driver/SQL/Column/BigIntColumn.class.php @@ -1,6 +1,6 @@ columnNames = (!is_array($columnNames) ? array($columnNames) : $columnNames); + $this->name = $constraintName; + } + + public function getColumnNames(): array { return $this->columnNames; } + public function getName(): ?string { return $this->name; } + public function setName(string $name) { $this->name = $name; } +} \ No newline at end of file diff --git a/core/Driver/SQL/Constraint/ForeignKey.class.php b/Core/Driver/SQL/Constraint/ForeignKey.class.php similarity index 68% rename from core/Driver/SQL/Constraint/ForeignKey.class.php rename to Core/Driver/SQL/Constraint/ForeignKey.class.php index 221001d..f4cef1a 100644 --- a/core/Driver/SQL/Constraint/ForeignKey.class.php +++ b/Core/Driver/SQL/Constraint/ForeignKey.class.php @@ -1,8 +1,8 @@ referencedTable = $refTable; $this->referencedColumn = $refColumn; $this->strategy = $strategy; diff --git a/core/Driver/SQL/Constraint/PrimaryKey.class.php b/Core/Driver/SQL/Constraint/PrimaryKey.class.php similarity index 82% rename from core/Driver/SQL/Constraint/PrimaryKey.class.php rename to Core/Driver/SQL/Constraint/PrimaryKey.class.php index b7398df..60b04d6 100644 --- a/core/Driver/SQL/Constraint/PrimaryKey.class.php +++ b/Core/Driver/SQL/Constraint/PrimaryKey.class.php @@ -1,6 +1,6 @@ sql->setLastError("DROP CONSTRAINT foreign key is not supported yet."); - return null; + } else { + $constraintName = $constraint->getName(); + if ($constraintName) { + $query .= "CONSTRAINT " . $this->sql->columnName($constraintName); + } else { + $this->sql->setLastError("Cannot DROP CONSTRAINT without a constraint name."); + return null; + } } } else if ($action === "ADD") { $query .= "CONSTRAINT "; diff --git a/core/Driver/SQL/Query/Commit.class.php b/Core/Driver/SQL/Query/Commit.class.php similarity index 76% rename from core/Driver/SQL/Query/Commit.class.php rename to Core/Driver/SQL/Query/Commit.class.php index a6b9c34..4188fa0 100644 --- a/core/Driver/SQL/Query/Commit.class.php +++ b/Core/Driver/SQL/Query/Commit.class.php @@ -1,8 +1,8 @@ constraints[] = new PrimaryKey($names); + $pk = new PrimaryKey($names); + $pk->setName(strtolower("pk_{$this->tableName}")); + $this->constraints[] = $pk; return $this; } @@ -112,8 +114,10 @@ class CreateTable extends Query { return $this; } - public function foreignKey(string $name, string $refTable, string $refColumn, ?Strategy $strategy = NULL): CreateTable { - $this->constraints[] = new ForeignKey($name, $refTable, $refColumn, $strategy); + public function foreignKey(string $column, string $refTable, string $refColumn, ?Strategy $strategy = NULL): CreateTable { + $fk = new ForeignKey($column, $refTable, $refColumn, $strategy); + $fk->setName(strtolower("fk_{$this->tableName}_${refTable}_${refColumn}")); + $this->constraints[] = $fk; return $this; } diff --git a/core/Driver/SQL/Query/CreateTrigger.class.php b/Core/Driver/SQL/Query/CreateTrigger.class.php similarity index 96% rename from core/Driver/SQL/Query/CreateTrigger.class.php rename to Core/Driver/SQL/Query/CreateTrigger.class.php index 4f0344e..1552028 100644 --- a/core/Driver/SQL/Query/CreateTrigger.class.php +++ b/Core/Driver/SQL/Query/CreateTrigger.class.php @@ -1,9 +1,9 @@ columnName($constraint->getColumnNames()); + if ($constraint instanceof PrimaryKey) { return "PRIMARY KEY ($columnName)"; } else if ($constraint instanceof Unique) { diff --git a/core/Driver/SQL/Strategy/CascadeStrategy.class.php b/Core/Driver/SQL/Strategy/CascadeStrategy.class.php similarity index 70% rename from core/Driver/SQL/Strategy/CascadeStrategy.class.php rename to Core/Driver/SQL/Strategy/CascadeStrategy.class.php index b72f5db..0be359f 100644 --- a/core/Driver/SQL/Strategy/CascadeStrategy.class.php +++ b/Core/Driver/SQL/Strategy/CascadeStrategy.class.php @@ -1,6 +1,6 @@ execute(["cookie" => $cookie]); } } diff --git a/core/Objects/CustomTwigFunctions.class.php b/Core/Objects/CustomTwigFunctions.class.php similarity index 92% rename from core/Objects/CustomTwigFunctions.class.php rename to Core/Objects/CustomTwigFunctions.class.php index 5399993..ba0934b 100644 --- a/core/Objects/CustomTwigFunctions.class.php +++ b/Core/Objects/CustomTwigFunctions.class.php @@ -1,6 +1,6 @@ properties[$propertyName] = $property; if ($isUnique) { - $this->constraints[] = new \Driver\SQL\Constraint\Unique($columnName); + $this->constraints[] = new \Core\Driver\SQL\Constraint\Unique($columnName); } } } diff --git a/core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php b/Core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php similarity index 96% rename from core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php rename to Core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php index 00ba75d..53c5178 100644 --- a/core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php +++ b/Core/Objects/DatabaseEntity/DatabaseEntityQuery.class.php @@ -1,11 +1,11 @@ pattern, $this->exact]; } + public function getClass(): \ReflectionClass { + return new \ReflectionClass($this); + } + public function generateCache(): string { - $reflection = new \ReflectionClass($this); - $className = $reflection->getName(); + $reflection = $this->getClass(); + $className = $reflection->getShortName(); $args = implode(", ", array_map(function ($arg) { return var_export($arg, true); }, $this->getArgs())); - return "new \\$className($args)"; + return "new $className($args)"; } public function match(string $url) { diff --git a/core/Objects/Router/ApiRoute.class.php b/Core/Objects/Router/ApiRoute.class.php similarity index 77% rename from core/Objects/Router/ApiRoute.class.php rename to Core/Objects/Router/ApiRoute.class.php index 187e1cc..c601e72 100644 --- a/core/Objects/Router/ApiRoute.class.php +++ b/Core/Objects/Router/ApiRoute.class.php @@ -1,8 +1,9 @@ load(); } else if (!preg_match("/[a-zA-Z]+/", $params["endpoint"])) { http_response_code(400); @@ -30,10 +31,10 @@ class ApiRoute extends AbstractRoute { $isNestedAPI = !empty($params["method"]); if ($isNestedAPI) { $apiMethod = ucfirst($params["method"]); - $parentClass = "\\Api\\${apiEndpoint}API"; - $apiClass = "\\Api\\${apiEndpoint}\\${apiMethod}"; + $parentClass = "\\API\\${apiEndpoint}API"; + $apiClass = "\\API\\${apiEndpoint}\\${apiMethod}"; } else { - $apiClass = "\\Api\\${apiEndpoint}"; + $apiClass = "\\API\\${apiEndpoint}"; $parentClass = $apiClass; } @@ -43,9 +44,13 @@ class ApiRoute extends AbstractRoute { // first: check if the parent class exists, for example: // /stats => Stats.class.php // /mail/send => MailAPI.class.php - if ($this->checkClass($parentClass)) { - if (!$isNestedAPI || class_exists($apiClass)) { - $classFound = true; + foreach (["Site", "Core"] as $module) { + if ($this->checkClass("\\$module$parentClass")) { + if (!$isNestedAPI || class_exists("\\$module$apiClass")) { + $classFound = true; + $apiClass = "\\$module$apiClass"; + break; + } } } diff --git a/core/Objects/Router/DocumentRoute.class.php b/Core/Objects/Router/DocumentRoute.class.php similarity index 93% rename from core/Objects/Router/DocumentRoute.class.php rename to Core/Objects/Router/DocumentRoute.class.php index 0a3b730..f7c5450 100644 --- a/core/Objects/Router/DocumentRoute.class.php +++ b/Core/Objects/Router/DocumentRoute.class.php @@ -1,11 +1,11 @@ call($this, $params); } else { - $req = new \Api\Template\Render($this->context); + $req = new \Core\API\Template\Render($this->context); $res = $req->execute(["file" => "error_document.twig", "parameters" => $params]); if ($res) { return $req->getResult()["html"]; @@ -86,16 +86,24 @@ class Router { public function writeCache(string $file): bool { $routes = ""; + $uses = [ + "Core\Objects\Context", + "Core\Objects\Router\Router", + ]; + foreach ($this->routes as $route) { // do not generate cache for static api route if ($route instanceof ApiRoute) { continue; } + $class = $route->getClass(); $constructor = $route->generateCache(); + $uses[] = $class->getName(); $routes .= "\n \$this->addRoute($constructor);"; } + $uses = implode("\n", array_map(function ($use) { return "use $use;"; }, array_unique($uses))); $date = (new \DateTime())->format("Y/m/d H:i:s"); $code = " 2 && strcasecmp($path[0], "api") === 0 && strcasecmp($path[1], "Parameter") !== 0) { - $path = "Api/" . $path[1] . "API"; - } else { - $path = implode("/", $path); + if ($pathCount >= 3) { + if (strcasecmp($pathParts[$pathCount - 3], "API") === 0) { + $group = $pathParts[$pathCount - 2]; + if (strcasecmp($group, "Parameter") !== 0) { + $pathParts = array_slice($pathParts, 0, $pathCount - 2); + $pathParts[] = "${group}API"; + } + } } - return "core/$path$suffix.php"; + $path = implode("/", $pathParts); + return "$path$suffix.php"; } function getClassName($class, bool $short = true): string { diff --git a/core/datetime.php b/Core/datetime.php similarity index 100% rename from core/datetime.php rename to Core/datetime.php diff --git a/README.md b/README.md index 6400368..b95d79e 100644 --- a/README.md +++ b/README.md @@ -58,8 +58,8 @@ Each endpoint is represented by a class inheriting the [Request Class](/core/Api ```php namespace Api; -use Api\Parameter\Parameter; -use Objects\DatabaseEntity\User; +use Core\API\Parameter\Parameter; +use Core\Objects\DatabaseEntity\User; class SingleEndpoint extends Request { @@ -108,7 +108,7 @@ Some endpoints are set to private, which means, they can be only accessed inside can be used by creating the desired request object, and calling the execute function with our parameters like shown below: ```php -$req = new \Api\Mail\Send($context); +$req = new \Core\API\Mail\Send($context); $success = $req->execute(array( "to" => "mail@example.org", "subject" => "Example Mail", @@ -132,7 +132,7 @@ an additional patch file, which can be executed using the [CLI](#CLI), can be cr located in [/core/Configuration/Patch](/core/Configuration/Patch) and have the following structure: ```php -namespace Configuration\Patch; +namespace Core\Configuration\Patch; use Configuration\DatabaseScript; use Driver\SQL\SQL; diff --git a/Site/.gitignore b/Site/.gitignore new file mode 100644 index 0000000..d69060d --- /dev/null +++ b/Site/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!*/.gitkeep diff --git a/Site/API/.gitkeep b/Site/API/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Site/Configuration/.gitkeep b/Site/Configuration/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Site/Documents/.gitkeep b/Site/Documents/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Site/Objects/.gitkeep b/Site/Objects/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/cli.php b/cli.php index 637375b..383ae97 100644 --- a/cli.php +++ b/cli.php @@ -2,17 +2,17 @@ define('WEBROOT', realpath(".")); -include_once 'core/core.php'; -require_once 'core/datetime.php'; -include_once 'core/constants.php'; +include_once 'Core/core.php'; +require_once 'Core/datetime.php'; +include_once 'Core/constants.php'; -use Configuration\DatabaseScript; -use Driver\SQL\Column\Column; -use Driver\SQL\Condition\Compare; -use Driver\SQL\Condition\CondIn; -use Driver\SQL\Expression\DateSub; -use Driver\SQL\SQL; -use Objects\ConnectionData; +use Core\Configuration\DatabaseScript; +use Core\Driver\SQL\Column\Column; +use Core\Driver\SQL\Condition\Compare; +use Core\Driver\SQL\Condition\CondIn; +use Core\Driver\SQL\Expression\DateSub; +use Core\Driver\SQL\SQL; +use Core\Objects\ConnectionData; function printLine(string $line = "") { echo $line . PHP_EOL; @@ -34,7 +34,7 @@ function getDatabaseConfig(): ConnectionData { return new $configClass(); } -$context = new \Objects\Context(); +$context = new \Core\Objects\Context(); if (!$context->isCLI()) { _exit("Can only be executed via CLI"); } @@ -74,7 +74,7 @@ function printHelp() { // TODO: help } -function applyPatch(\Driver\SQL\SQL $sql, string $patchName): bool { +function applyPatch(\Core\Driver\SQL\SQL $sql, string $patchName): bool { $class = str_replace('/', '\\', $patchName); $className = "\\Configuration\\$class"; $classPath = getClassPath($className); @@ -420,7 +420,7 @@ function onSettings(array $argv) { if ($action === "list" || $action === "get") { $key = (($action === "list" || count($argv) < 4) ? null : $argv[3]); - $req = new Api\Settings\Get($context); + $req = new \Core\API\Settings\Get($context); $success = $req->execute(["key" => $key]); if (!$success) { _exit("Error listings settings: " . $req->getLastError()); @@ -437,7 +437,7 @@ function onSettings(array $argv) { } else { $key = $argv[3]; $value = $argv[4]; - $req = new Api\Settings\Set($context); + $req = new \Core\API\Settings\Set($context); $success = $req->execute(["settings" => [$key => $value]]); if (!$success) { _exit("Error updating settings: " . $req->getLastError()); @@ -448,7 +448,7 @@ function onSettings(array $argv) { _exit("Usage: $argv[0] settings $argv[2] "); } else { $key = $argv[3]; - $req = new Api\Settings\Set($context); + $req = new \Core\API\Settings\Set($context); $success = $req->execute(["settings" => [$key => null]]); if (!$success) { _exit("Error updating settings: " . $req->getLastError()); @@ -465,7 +465,7 @@ function onRoutes(array $argv) { $action = $argv[2] ?? "list"; if ($action === "list") { - $req = new Api\Routes\Fetch($context); + $req = new \Core\API\Routes\Fetch($context); $success = $req->execute(); if (!$success) { _exit("Error fetching routes: " . $req->getLastError()); @@ -493,7 +493,7 @@ function onRoutes(array $argv) { "extra" => $argv[7] ?? "", ); - $req = new Api\Routes\Add($context); + $req = new \Core\API\Routes\Add($context); $success = $req->execute($params); if (!$success) { _exit($req->getLastError()); @@ -520,13 +520,13 @@ function onRoutes(array $argv) { echo "Remove route #$uid? (y|n): "; } while(($input = trim(fgets(STDIN))) !== "y"); - $req = new Api\Routes\Remove($context); + $req = new \Core\API\Routes\Remove($context); } else if ($action === "enable") { - $req = new Api\Routes\Enable($context); + $req = new \Core\API\Routes\Enable($context); } else if ($action === "disable") { - $req = new Api\Routes\Disable($context); + $req = new \Core\API\Routes\Disable($context); } else if ($action === "modify") { - $req = new Api\Routes\Update($context); + $req = new \Core\API\Routes\Update($context); $params["request"] = $argv[4]; $params["action"] = $argv[5]; $params["target"] = $argv[6]; @@ -606,28 +606,14 @@ function onTest($argv) { function onMail($argv) { global $context; $action = $argv[2] ?? null; - if ($action === "sync") { - $sql = connectSQL() or die(); - if (!$context->getSettings()->isMailEnabled()) { - _exit("Mails are not configured yet."); - } - - $req = new Api\Mail\Sync($context); - printLine("Syncing emails…"); - if (!$req->execute()) { - _exit("Error syncing mails: " . $req->getLastError()); - } - - _exit("Done."); - } else if ($action === "send_queue") { - $sql = connectSQL() or die(); - $req = new \Api\Mail\SendQueue($context); + if ($action === "send_queue") { + $req = new \Core\API\Mail\SendQueue($context); $debug = in_array("debug", $argv); if (!$req->execute(["debug" => $debug])) { _exit("Error processing mail queue: " . $req->getLastError()); } } else { - _exit("Usage: cli.php mail [options...]"); + _exit("Usage: cli.php mail [options...]"); } } @@ -653,8 +639,8 @@ function onImpersonate($argv) { } } - $user = new \Objects\DatabaseEntity\User($userId); - $session = new \Objects\DatabaseEntity\Session($context, $user); + $user = new \Core\Objects\DatabaseEntity\User($userId); + $session = new \Core\Objects\DatabaseEntity\Session($context, $user); $session->setData(["2faAuthenticated" => true]); $session->update(); echo "session=" . $session->getCookie() . PHP_EOL; diff --git a/core/Cache/.gitignore b/core/Cache/.gitignore deleted file mode 100644 index f0fa09f..0000000 --- a/core/Cache/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitkeep \ No newline at end of file diff --git a/core/Configuration/.gitignore b/core/Configuration/.gitignore deleted file mode 100644 index bd1b2f7..0000000 --- a/core/Configuration/.gitignore +++ /dev/null @@ -1 +0,0 @@ -Database\.class\.php diff --git a/core/Configuration/.htaccess b/core/Configuration/.htaccess deleted file mode 100644 index d3223d4..0000000 --- a/core/Configuration/.htaccess +++ /dev/null @@ -1 +0,0 @@ -DENY FROM ALL diff --git a/core/Driver/SQL/Condition/Condition.class.php b/core/Driver/SQL/Condition/Condition.class.php deleted file mode 100644 index d8266ec..0000000 --- a/core/Driver/SQL/Condition/Condition.class.php +++ /dev/null @@ -1,9 +0,0 @@ -columnNames = (!is_array($columnNames) ? array($columnNames) : $columnNames); - } - - public function getColumnNames(): array { return $this->columnNames; } -} \ No newline at end of file diff --git a/core/Driver/SQL/Expression/Expression.class.php b/core/Driver/SQL/Expression/Expression.class.php deleted file mode 100644 index 33f6611..0000000 --- a/core/Driver/SQL/Expression/Expression.class.php +++ /dev/null @@ -1,9 +0,0 @@ - false, "msg" => "Configuration class is not readable, check permissions before proceeding." ])); } -$context = new \Objects\Context(); +$context = new \Core\Objects\Context(); $sql = $context->initSQL(); $settings = $context->getSettings(); $context->parseCookies(); @@ -34,13 +34,13 @@ if ($installation) { $response = "Redirecting to /"; header("Location: /"); } else { - $document = new Documents\Install(new Router($context)); + $document = new \Core\Documents\Install(new Router($context)); $response = $document->load(); } } else { $router = null; - $routerCacheClass = '\Cache\RouterCache'; + $routerCacheClass = '\Core\Cache\RouterCache'; $routerCachePath = getClassPath($routerCacheClass); if (is_file($routerCachePath)) { @include_once $routerCachePath; @@ -50,7 +50,7 @@ if ($installation) { } if ($router === null) { - $req = new \Api\Routes\GenerateCache($context); + $req = new \Core\API\Routes\GenerateCache($context); if ($req->execute()) { $router = $req->getRouter(); } else { diff --git a/robots.txt b/robots.txt index 3f5c8f8..7e85f31 100644 --- a/robots.txt +++ b/robots.txt @@ -1,2 +1,3 @@ User-agent: * -Disallow: /core +Disallow: /Core +Disallow: /Site diff --git a/test/AesStream.test.php b/test/AesStream.test.php index a2dddf2..84970be 100644 --- a/test/AesStream.test.php +++ b/test/AesStream.test.php @@ -1,6 +1,6 @@ assertEquals($entity2->d, $entity->d); $this->assertNotNull($entity2->e); $this->assertEquals( - $entity2->e->format(\Api\Parameter\Parameter::DATE_TIME_FORMAT), - $entity->e->format(\Api\Parameter\Parameter::DATE_TIME_FORMAT) + $entity2->e->format(Parameter::DATE_TIME_FORMAT), + $entity->e->format(Parameter::DATE_TIME_FORMAT) ); $this->assertNull($entity2->f); @@ -100,7 +101,7 @@ class DatabaseEntityTest extends \PHPUnit\Framework\TestCase { } } -class TestEntity extends \Objects\DatabaseEntity\DatabaseEntity { +class TestEntity extends DatabaseEntity { public int $a; public string $b; public bool $c; diff --git a/test/Parameter.test.php b/test/Parameter.test.php index 261e91f..269469a 100644 --- a/test/Parameter.test.php +++ b/test/Parameter.test.php @@ -1,8 +1,8 @@