web-base/Core/Configuration/CreateDatabase.class.php

177 lines
8.7 KiB
PHP
Raw Normal View History

2020-04-02 00:02:51 +02:00
<?php
2022-11-18 18:06:46 +01:00
namespace Core\Configuration;
2020-04-02 00:02:51 +02:00
2022-11-18 18:06:46 +01:00
use Core\Driver\SQL\SQL;
2022-11-20 17:13:53 +01:00
use Core\Objects\DatabaseEntity\Controller\DatabaseEntity;
use Core\Objects\DatabaseEntity\Group;
use Core\Objects\DatabaseEntity\Language;
2022-11-27 12:33:27 +01:00
use Core\Objects\DatabaseEntity\Route;
use Core\Objects\Router\DocumentRoute;
use Core\Objects\Router\StaticFileRoute;
use Core\Objects\Router\StaticRoute;
2022-06-20 19:52:31 +02:00
use PHPUnit\Util\Exception;
2020-04-02 00:02:51 +02:00
2021-01-07 15:54:19 +01:00
class CreateDatabase extends DatabaseScript {
2020-04-02 00:02:51 +02:00
2021-04-02 21:58:06 +02:00
public static function createQueries(SQL $sql): array {
2020-04-02 00:02:51 +02:00
$queries = array();
2022-06-20 19:52:31 +02:00
self::loadEntities($queries, $sql);
2020-04-02 00:02:51 +02:00
2022-11-20 17:13:53 +01:00
$queries[] = Language::getHandler($sql)->getInsertQuery([
new Language(Language::AMERICAN_ENGLISH, "en_US", 'American English'),
new Language(Language::AMERICAN_ENGLISH, "de_DE", 'Deutsch Standard'),
]);
$queries[] = Group::getHandler($sql)->getInsertQuery([
new Group(Group::ADMIN, Group::GROUPS[Group::ADMIN], "#dc3545"),
2022-11-20 17:13:53 +01:00
new Group(Group::MODERATOR, Group::GROUPS[Group::MODERATOR], "#28a745"),
new Group(Group::SUPPORT, Group::GROUPS[Group::SUPPORT], "#007bff"),
2022-11-20 17:13:53 +01:00
]);
2020-04-02 21:19:06 +02:00
2020-06-17 23:50:08 +02:00
$queries[] = $sql->createTable("Visitor")
2020-07-01 21:10:25 +02:00
->addInt("day")
2020-06-17 23:50:08 +02:00
->addInt("count", false, 1)
->addString("cookie", 26)
2020-07-01 21:10:25 +02:00
->unique("day", "cookie");
2020-06-17 23:50:08 +02:00
2022-11-27 12:33:27 +01:00
$queries[] = Route::getHandler($sql)->getInsertQuery([
new DocumentRoute("/admin", false, \Core\Documents\Admin::class),
new DocumentRoute("/register", true, \Core\Documents\Account::class, "account/register.twig"),
new DocumentRoute("/confirmEmail", true, \Core\Documents\Account::class, "account/confirm_email.twig"),
new DocumentRoute("/acceptInvite", true, \Core\Documents\Account::class, "account/accept_invite.twig"),
new DocumentRoute("/resetPassword", true, \Core\Documents\Account::class, "account/reset_password.twig"),
new DocumentRoute("/login", true, \Core\Documents\Account::class, "account/login.twig"),
new DocumentRoute("/resendConfirmEmail", true, \Core\Documents\Account::class, "account/resend_confirm_email.twig"),
new DocumentRoute("/debug", true, \Core\Documents\Info::class),
new StaticFileRoute("/static", true, "/static/welcome.html"),
]);
2020-06-19 13:13:13 +02:00
2020-06-25 16:54:58 +02:00
$queries[] = $sql->createTable("Settings")
->addString("name", 32)
->addString("value", 1024, true)
2020-06-26 23:32:45 +02:00
->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
2020-06-25 16:54:58 +02:00
->primaryKey("name");
2022-11-20 17:13:53 +01:00
$settingsQuery = $sql->insert("Settings", array("name", "value", "private", "readonly"));
2020-06-25 16:54:58 +02:00
(Settings::loadDefaults())->addRows($settingsQuery);
$queries[] = $settingsQuery;
2020-06-27 01:18:10 +02:00
$queries[] = $sql->createTable("ApiPermission")
->addString("method", 32)
->addJson("groups", true, '[]')
2020-06-27 22:47:12 +02:00
->addString("description", 128, false, "")
2020-06-27 01:18:10 +02:00
->primaryKey("method");
2020-06-27 22:47:12 +02:00
$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")
2022-11-20 17:13:53 +01:00
->addRow("Groups/fetch", array(Group::SUPPORT, Group::ADMIN), "Allows users to list all available groups")
->addRow("Groups/create", array(Group::ADMIN), "Allows users to create a new groups")
->addRow("Groups/delete", array(Group::ADMIN), "Allows users to delete a group")
->addRow("Routes/fetch", array(Group::ADMIN), "Allows users to list all configured routes")
->addRow("Routes/save", array(Group::ADMIN), "Allows users to create, delete and modify routes")
->addRow("Mail/test", array(Group::SUPPORT, Group::ADMIN), "Allows users to send a test email to a given address")
->addRow("Mail/Sync", array(Group::SUPPORT, Group::ADMIN), "Allows users to synchronize mails with the database")
->addRow("Settings/get", array(Group::ADMIN), "Allows users to fetch server settings")
->addRow("Settings/set", array(Group::ADMIN), "Allows users create, delete or modify server settings")
->addRow("Settings/generateJWT", array(Group::ADMIN), "Allows users generate a new jwt key")
2022-11-20 17:13:53 +01:00
->addRow("Stats", array(Group::ADMIN, Group::SUPPORT), "Allows users to fetch server stats")
->addRow("User/create", array(Group::ADMIN), "Allows users to create a new user, email address does not need to be confirmed")
->addRow("User/fetch", array(Group::ADMIN, Group::SUPPORT), "Allows users to list all registered users")
->addRow("User/get", array(Group::ADMIN, Group::SUPPORT), "Allows users to get information about a single user")
->addRow("User/invite", array(Group::ADMIN), "Allows users to create a new user and send them an invitation link")
->addRow("User/edit", array(Group::ADMIN), "Allows users to edit details and group memberships of any user")
->addRow("User/delete", array(Group::ADMIN), "Allows users to delete any other user")
->addRow("Permission/fetch", array(Group::ADMIN), "Allows users to list all API permissions")
->addRow("Visitors/stats", array(Group::ADMIN, Group::SUPPORT), "Allows users to see visitor statistics")
->addRow("Contact/respond", array(Group::ADMIN, Group::SUPPORT), "Allows users to respond to contact requests")
->addRow("Contact/fetch", array(Group::ADMIN, Group::SUPPORT), "Allows users to fetch all contact requests")
->addRow("Contact/get", array(Group::ADMIN, Group::SUPPORT), "Allows users to see messages within a contact request")
->addRow("Logs/get", [Group::ADMIN], "Allows users to fetch system logs");
2021-01-07 15:54:19 +01:00
self::loadPatches($queries, $sql);
2020-06-27 01:18:10 +02:00
2020-04-02 00:02:51 +02:00
return $queries;
}
2020-06-26 14:58:17 +02:00
2021-01-07 15:54:19 +01:00
private static function loadPatches(&$queries, $sql) {
2022-11-18 18:06:46 +01:00
$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;
}
2021-01-07 15:54:19 +01:00
}
}
}
}
2022-08-20 22:17:17 +02:00
public static function loadEntities(&$queries, $sql) {
2022-11-20 17:13:53 +01:00
$persistables = [];
2022-11-18 18:06:46 +01:00
$baseDirs = ["Core", "Site"];
foreach ($baseDirs as $baseDir) {
2022-11-20 17:13:53 +01:00
2022-11-18 18:06:46 +01:00
$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));
2022-11-20 17:13:53 +01:00
$className = "\\$baseDir\\Objects\\DatabaseEntity\\$className";
$reflectionClass = new \ReflectionClass($className);
2022-11-27 12:33:27 +01:00
if ($reflectionClass->getParentClass()?->getName() === DatabaseEntity::class) {
2022-11-20 17:13:53 +01:00
$method = "$className::getHandler";
$handler = call_user_func($method, $sql);
$persistables[$handler->getTableName()] = $handler;
foreach ($handler->getNMRelations() as $nmTableName => $nmRelation) {
$persistables[$nmTableName] = $nmRelation;
2022-11-18 18:06:46 +01:00
}
2022-06-20 19:52:31 +02:00
}
}
}
}
2022-11-20 17:13:53 +01:00
$tableCount = count($persistables);
2022-06-20 19:52:31 +02:00
$createdTables = [];
2022-11-20 17:13:53 +01:00
while (!empty($persistables)) {
2022-06-20 19:52:31 +02:00
$prevCount = $tableCount;
$unmetDependenciesTotal = [];
2022-11-20 17:13:53 +01:00
foreach ($persistables as $tableName => $persistable) {
$dependsOn = $persistable->dependsOn();
2022-06-20 19:52:31 +02:00
$unmetDependencies = array_diff($dependsOn, $createdTables);
if (empty($unmetDependencies)) {
2022-11-20 17:13:53 +01:00
$queries = array_merge($queries, $persistable->getCreateQueries($sql));
2022-06-20 19:52:31 +02:00
$createdTables[] = $tableName;
2022-11-20 17:13:53 +01:00
unset($persistables[$tableName]);
2022-06-20 19:52:31 +02:00
} else {
$unmetDependenciesTotal = array_merge($unmetDependenciesTotal, $unmetDependencies);
}
}
2022-06-20 19:52:31 +02:00
2022-11-20 17:13:53 +01:00
$tableCount = count($persistables);
2022-06-20 19:52:31 +02:00
if ($tableCount === $prevCount) {
throw new Exception("Circular or unmet table dependency detected. Unmet dependencies: "
. implode(", ", $unmetDependenciesTotal));
}
}
}
}
2020-04-02 00:02:51 +02:00
}