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
|
|
|
|
2023-01-16 21:47:23 +01:00
|
|
|
use Core\API\Request;
|
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;
|
2022-11-27 12:33:27 +01:00
|
|
|
use Core\Objects\DatabaseEntity\Route;
|
|
|
|
use Core\Objects\Router\DocumentRoute;
|
|
|
|
use Core\Objects\Router\StaticFileRoute;
|
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
|
|
|
|
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),
|
2022-12-01 11:01:49 +01:00
|
|
|
new StaticFileRoute("/", true, "/static/welcome.html"),
|
2022-11-27 12:33:27 +01:00
|
|
|
]);
|
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");
|
|
|
|
|
2023-01-16 21:47:23 +01:00
|
|
|
self::loadDefaultACL($queries, $sql);
|
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-06-17 22:58:42 +02:00
|
|
|
|
2023-01-16 21:47:23 +01:00
|
|
|
private 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) {
|
|
|
|
$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);
|
2023-01-09 17:10:47 +01:00
|
|
|
if ($reflectionClass->isSubclassOf(DatabaseEntity::class)) {
|
2022-11-20 17:13:53 +01:00
|
|
|
$method = "$className::getHandler";
|
2023-01-09 17:10:47 +01:00
|
|
|
$handler = call_user_func($method, $sql, null, true);
|
2022-11-20 17:13:53 +01:00
|
|
|
$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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-01-09 17:10:47 +01:00
|
|
|
}
|
2022-06-20 19:52:31 +02:00
|
|
|
|
2023-01-09 17:10:47 +01:00
|
|
|
$tableCount = count($persistables);
|
|
|
|
$createdTables = [];
|
|
|
|
while (!empty($persistables)) {
|
|
|
|
$prevCount = $tableCount;
|
|
|
|
$unmetDependenciesTotal = [];
|
|
|
|
|
|
|
|
foreach ($persistables as $tableName => $persistable) {
|
|
|
|
$dependsOn = $persistable->dependsOn();
|
|
|
|
$unmetDependencies = array_diff($dependsOn, $createdTables);
|
|
|
|
if (empty($unmetDependencies)) {
|
|
|
|
$queries = array_merge($queries, $persistable->getCreateQueries($sql));
|
|
|
|
$createdTables[] = $tableName;
|
|
|
|
unset($persistables[$tableName]);
|
|
|
|
} else {
|
|
|
|
$unmetDependenciesTotal = array_merge($unmetDependenciesTotal, $unmetDependencies);
|
2022-06-17 22:58:42 +02:00
|
|
|
}
|
2023-01-09 17:10:47 +01:00
|
|
|
}
|
2022-06-20 19:52:31 +02:00
|
|
|
|
2023-01-09 17:10:47 +01:00
|
|
|
$tableCount = count($persistables);
|
|
|
|
if ($tableCount === $prevCount) {
|
|
|
|
throw new Exception("Circular or unmet table dependency detected. Unmet dependencies: "
|
|
|
|
. implode(", ", $unmetDependenciesTotal));
|
2022-06-17 22:58:42 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-01-16 21:47:23 +01:00
|
|
|
|
|
|
|
public static function loadDefaultACL(array &$queries, SQL $sql) {
|
|
|
|
$query = $sql->insert("ApiPermission", ["method", "groups", "description"]);
|
|
|
|
|
|
|
|
foreach (Request::getApiEndpoints() as $reflectionClass) {
|
|
|
|
$method = $reflectionClass->getName() . "::getDefaultACL";
|
|
|
|
$method($query);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($query->hasRows()) {
|
|
|
|
$queries[] = $query;
|
|
|
|
}
|
|
|
|
}
|
2020-04-02 00:02:51 +02:00
|
|
|
}
|