New config system, define a root dir constant and deprecate more of Application.

This commit is contained in:
flash 2018-10-04 22:30:55 +02:00
parent d0ddd07079
commit c6018d0a4d
27 changed files with 120 additions and 168 deletions

View file

@ -2,14 +2,15 @@
namespace Misuzu; namespace Misuzu;
define('MSZ_STARTUP', microtime(true)); define('MSZ_STARTUP', microtime(true));
define('MSZ_DEBUG', file_exists(__DIR__ . '/.debug')); define('MSZ_ROOT', __DIR__);
define('MSZ_DEBUG', is_file(MSZ_ROOT . '/.debug'));
error_reporting(MSZ_DEBUG ? -1 : 0); error_reporting(MSZ_DEBUG ? -1 : 0);
ini_set('display_errors', MSZ_DEBUG ? 'On' : 'Off'); ini_set('display_errors', MSZ_DEBUG ? 'On' : 'Off');
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
mb_internal_encoding('UTF-8'); mb_internal_encoding('UTF-8');
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__); set_include_path(get_include_path() . PATH_SEPARATOR . MSZ_ROOT);
require_once 'vendor/autoload.php'; require_once 'vendor/autoload.php';
@ -30,6 +31,7 @@ require_once 'src/audit_log.php';
require_once 'src/changelog.php'; require_once 'src/changelog.php';
require_once 'src/colour.php'; require_once 'src/colour.php';
require_once 'src/comments.php'; require_once 'src/comments.php';
require_once 'src/config.php';
require_once 'src/csrf.php'; require_once 'src/csrf.php';
require_once 'src/general.php'; require_once 'src/general.php';
require_once 'src/git.php'; require_once 'src/git.php';
@ -55,10 +57,15 @@ require_once 'src/Users/session.php';
require_once 'src/Users/user.php'; require_once 'src/Users/user.php';
require_once 'src/Users/validation.php'; require_once 'src/Users/validation.php';
$app = new Application(__DIR__ . '/config/config.ini'); config_load(MSZ_ROOT . '/config/config.ini');
$app = new Application;
if (!empty($errorReporter)) { if (!empty($errorReporter)) {
$errorReporter->setReportInfo(...$app->getReportInfo()); $errorReporter->setReportInfo(
config_get('Exceptions', 'report_url'),
config_get('Exceptions', 'hash_key')
);
} }
$app->startDatabase(); $app->startDatabase();
@ -135,7 +142,7 @@ if (PHP_SAPI === 'cli') {
case 'migrate': case 'migrate':
$migrationTargets = [ $migrationTargets = [
'mysql-main' => __DIR__ . '/database', 'mysql-main' => MSZ_ROOT . '/database',
]; ];
$doRollback = !empty($argv[2]) && $argv[2] === 'rollback'; $doRollback = !empty($argv[2]) && $argv[2] === 'rollback';
$targetDb = isset($argv[$doRollback ? 3 : 2]) ? $argv[$doRollback ? 3 : 2] : null; $targetDb = isset($argv[$doRollback ? 3 : 2]) ? $argv[$doRollback ? 3 : 2] : null;
@ -187,7 +194,7 @@ if (PHP_SAPI === 'cli') {
} }
$filename = date('Y_m_d_His_') . trim($argv[2], '_') . '.php'; $filename = date('Y_m_d_His_') . trim($argv[2], '_') . '.php';
$filepath = __DIR__ . '/database/' . $filename; $filepath = MSZ_ROOT . '/database/' . $filename;
$namespace = snake_to_camel($argv[2]); $namespace = snake_to_camel($argv[2]);
$template = <<<MIG $template = <<<MIG
<?php <?php
@ -227,7 +234,8 @@ MIG;
// we're running this again because ob_clean breaks gzip otherwise // we're running this again because ob_clean breaks gzip otherwise
ob_start(); ob_start();
if (!$app->canAccessStorage()) { $mszStoragePath = $app->getStoragePath();
if (!is_readable($mszStoragePath) || !is_writable($mszStoragePath)) {
echo 'Cannot access storage directory.'; echo 'Cannot access storage directory.';
exit; exit;
} }
@ -237,10 +245,15 @@ MIG;
tpl_init([ tpl_init([
'debug' => MSZ_DEBUG, 'debug' => MSZ_DEBUG,
'auto_reload' => MSZ_DEBUG, 'auto_reload' => MSZ_DEBUG,
'cache' => MSZ_DEBUG ? false : create_directory(build_path(sys_get_temp_dir(), 'msz-tpl-cache-' . md5(__DIR__))), 'cache' => MSZ_DEBUG ? false : create_directory(build_path(sys_get_temp_dir(), 'msz-tpl-cache-' . md5(MSZ_ROOT))),
]); ]);
tpl_var('globals', $app->getSiteInfo()); tpl_var('globals', [
'site_name' => config_get_default('Misuzu', 'Site', 'name'),
'site_description' => config_get('Site', 'description'),
'site_twitter' => config_get('Site', 'twitter'),
'site_url' => config_get('Site', 'url'),
]);
tpl_add_function('json_decode', true); tpl_add_function('json_decode', true);
tpl_add_function('byte_symbol', true); tpl_add_function('byte_symbol', true);
@ -273,7 +286,7 @@ MIG;
}); });
tpl_add_function('sql_query_count', false, [Database::class, 'queryCount']); tpl_add_function('sql_query_count', false, [Database::class, 'queryCount']);
tpl_add_path(__DIR__ . '/templates'); tpl_add_path(MSZ_ROOT . '/templates');
$misuzuBypassLockdown = !empty($misuzuBypassLockdown); $misuzuBypassLockdown = !empty($misuzuBypassLockdown);
@ -302,7 +315,10 @@ MIG;
$userDisplayInfo = $getUserDisplayInfo->execute() ? $getUserDisplayInfo->fetch() : []; $userDisplayInfo = $getUserDisplayInfo->execute() ? $getUserDisplayInfo->fetch() : [];
} }
csrf_init($app->getCsrfSecretKey(), empty($userDisplayInfo) ? ip_remote_address() : $_COOKIE['msz_sid']); csrf_init(
config_get_default('insecure', 'CSRF', 'secret_key'),
empty($userDisplayInfo) ? ip_remote_address() : $_COOKIE['msz_sid']
);
$privateInfo = $app->getPrivateInfo(); $privateInfo = $app->getPrivateInfo();

View file

@ -6,7 +6,7 @@ $isSubmission = !empty($_POST['auth']) && is_array($_POST['auth']);
$authMode = $isSubmission ? ($_POST['auth']['mode'] ?? '') : ($_GET['m'] ?? 'login'); $authMode = $isSubmission ? ($_POST['auth']['mode'] ?? '') : ($_GET['m'] ?? 'login');
$misuzuBypassLockdown = $authMode === 'login' || $authMode === 'get_user'; $misuzuBypassLockdown = $authMode === 'login' || $authMode === 'get_user';
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$usernameValidationErrors = [ $usernameValidationErrors = [
'trim' => 'Your username may not start or end with spaces!', 'trim' => 'Your username may not start or end with spaces!',

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$changelogOffset = max((int)($_GET['o'] ?? 0), 0); $changelogOffset = max((int)($_GET['o'] ?? 0), 0);
$changelogRange = 30; $changelogRange = 30;

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
// basing whether or not this is an xhr request on whether a referrer header is present // basing whether or not this is an xhr request on whether a referrer header is present
// this page is never directy accessed, under normal circumstances // this page is never directy accessed, under normal circumstances

View file

@ -1,5 +1,5 @@
<?php <?php
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$forumId = max((int)($_GET['f'] ?? 0), 0); $forumId = max((int)($_GET['f'] ?? 0), 0);
$topicsOffset = max((int)($_GET['o'] ?? 0), 0); $topicsOffset = max((int)($_GET['o'] ?? 0), 0);

View file

@ -1,5 +1,5 @@
<?php <?php
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$categories = forum_get_root_categories(user_session_current('user_id', 0)); $categories = forum_get_root_categories(user_session_current('user_id', 0));
$blankForum = count($categories) <= 1 && $categories[0]['forum_children'] < 1; $blankForum = count($categories) <= 1 && $categories[0]['forum_children'] < 1;

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
if (!user_session_active()) { if (!user_session_active()) {
echo render_error(403); echo render_error(403);

View file

@ -1,5 +1,5 @@
<?php <?php
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$postId = (int)($_GET['p'] ?? 0); $postId = (int)($_GET['p'] ?? 0);
$topicId = (int)($_GET['t'] ?? 0); $topicId = (int)($_GET['t'] ?? 0);

View file

@ -3,9 +3,16 @@ use Misuzu\Application;
use Misuzu\Cache; use Misuzu\Cache;
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
tpl_vars($app->getLinkedData()); if (config_get_default(false, 'Site', 'embed_linked_data')) {
tpl_var('linked_data', [
'name' => config_get('Site', 'name'),
'url' => config_get('Site', 'url'),
'logo' => config_get('Site', 'external_logo'),
'same_as' => explode(',', config_get_default('', 'Site', 'social_media')),
]);
}
$news = Database::query(' $news = Database::query('
SELECT SELECT

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$pathInfo = $_SERVER['PATH_INFO'] ?? ''; $pathInfo = $_SERVER['PATH_INFO'] ?? '';
@ -37,7 +37,7 @@ if ($filename !== 'LICENSE') {
$filename .= '.md'; $filename .= '.md';
} }
$filename = __DIR__ . '/../' . ($isMisuzuDoc ? '' : 'docs/') . $filename; $filename = MSZ_ROOT . ($isMisuzuDoc ? '/' : '/docs/') . $filename;
$document['content'] = is_file($filename) ? file_get_contents($filename) : ''; $document['content'] = is_file($filename) ? file_get_contents($filename) : '';
if (empty($document['content'])) { if (empty($document['content'])) {

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$changelogPerms = perms_get_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id', 0)); $changelogPerms = perms_get_user(MSZ_PERMS_CHANGELOG, user_session_current('user_id', 0));
$queryOffset = (int)($_GET['o'] ?? 0); $queryOffset = (int)($_GET['o'] ?? 0);

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
switch ($_GET['v'] ?? null) { switch ($_GET['v'] ?? null) {
case 'listing': case 'listing':

View file

@ -1,5 +1,5 @@
<?php <?php
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$generalPerms = perms_get_user(MSZ_PERMS_GENERAL, user_session_current('user_id', 0)); $generalPerms = perms_get_user(MSZ_PERMS_GENERAL, user_session_current('user_id', 0));

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../../misuzu.php'; require_once '../../misuzu.php';
$userPerms = perms_get_user(MSZ_PERMS_USER, user_session_current('user_id', 0)); $userPerms = perms_get_user(MSZ_PERMS_USER, user_session_current('user_id', 0));
$isPostRequest = $_SERVER['REQUEST_METHOD'] === 'POST'; $isPostRequest = $_SERVER['REQUEST_METHOD'] === 'POST';

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$usersOffset = max((int)($_GET['o'] ?? 0), 0); $usersOffset = max((int)($_GET['o'] ?? 0), 0);
$usersTake = 30; $usersTake = 30;

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$categoryId = isset($_GET['c']) ? (int)$_GET['c'] : null; $categoryId = isset($_GET['c']) ? (int)$_GET['c'] : null;
$postId = isset($_GET['p']) ? (int)$_GET['p'] : (isset($_GET['n']) ? (int)$_GET['n'] : null); $postId = isset($_GET['p']) ? (int)$_GET['p'] : (isset($_GET['n']) ? (int)$_GET['n'] : null);

View file

@ -1,4 +1,4 @@
<?php <?php
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
echo render_error(404); echo render_error(404);

View file

@ -4,13 +4,16 @@ use Misuzu\Database;
$mode = (string)($_GET['m'] ?? null); $mode = (string)($_GET['m'] ?? null);
$misuzuBypassLockdown = $mode === 'avatar'; $misuzuBypassLockdown = $mode === 'avatar';
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$userId = (int)($_GET['u'] ?? 0); $userId = (int)($_GET['u'] ?? 0);
switch ($mode) { switch ($mode) {
case 'avatar': case 'avatar':
$avatar_filename = $app->getDefaultAvatar(); $avatar_filename = build_path(
MSZ_ROOT,
config_get_default('public/images/no-avatar.png', 'Avatar', 'default_path')
);
$user_avatar = "{$userId}.msz"; $user_avatar = "{$userId}.msz";
$cropped_avatar = build_path( $cropped_avatar = build_path(
create_directory(build_path($app->getStoragePath(), 'avatars/200x200')), create_directory(build_path($app->getStoragePath(), 'avatars/200x200')),

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
if (empty($_SERVER['HTTP_REFERER']) || !is_local_url($_SERVER['HTTP_REFERER'])) { if (empty($_SERVER['HTTP_REFERER']) || !is_local_url($_SERVER['HTTP_REFERER'])) {
header('Location: /'); header('Location: /');

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/../misuzu.php'; require_once '../misuzu.php';
$queryOffset = (int)($_GET['o'] ?? 0); $queryOffset = (int)($_GET['o'] ?? 0);
$queryTake = 15; $queryTake = 15;

View file

@ -2,7 +2,6 @@
namespace Misuzu; namespace Misuzu;
use UnexpectedValueException; use UnexpectedValueException;
use InvalidArgumentException;
use Swift_Mailer; use Swift_Mailer;
use Swift_NullTransport; use Swift_NullTransport;
use Swift_SmtpTransport; use Swift_SmtpTransport;
@ -30,51 +29,17 @@ final class Application
'sendmail' => Swift_SendmailTransport::class, 'sendmail' => Swift_SendmailTransport::class,
]; ];
private $config = [];
private $mailerInstance = null; private $mailerInstance = null;
private $geoipInstance = null; private $geoipInstance = null;
/** public function __construct()
* Constructor, called by ApplicationBase::start() which also passes the arguments through.
* @param null|string $configFile
* @param bool $debug
*/
public function __construct(?string $configFile = null)
{ {
if (!empty(self::$instance)) { if (!empty(self::$instance)) {
throw new UnexpectedValueException('An Application has already been set up.'); throw new UnexpectedValueException('An Application has already been set up.');
} }
self::$instance = $this; self::$instance = $this;
$this->config = is_file($configFile) ? parse_ini_file($configFile, true, INI_SCANNER_TYPED) : [];
if ($this->config === false) {
throw new UnexpectedValueException('Failed to parse configuration.');
}
}
public function getReportInfo(): array
{
return [
$this->config['Exceptions']['report_url'] ?? null,
$this->config['Exceptions']['hash_key'] ?? null,
];
}
/**
* Gets a storage path.
* @param string $path
* @return string
*/
public function getPath(string $path): string
{
if (!starts_with($path, '/') && mb_substr($path, 1, 2) !== ':\\') {
$path = __DIR__ . '/../' . $path;
}
return fix_path_separator(rtrim($path, '/'));
} }
/** /**
@ -83,13 +48,7 @@ final class Application
*/ */
public function getStoragePath(): string public function getStoragePath(): string
{ {
return create_directory($this->config['Storage']['path'] ?? __DIR__ . '/../store'); return create_directory(config_get_default(MSZ_ROOT . '/store', 'Storage', 'path'));
}
public function canAccessStorage(): bool
{
$path = $this->getStoragePath();
return is_readable($path) && is_writable($path);
} }
/** /**
@ -104,7 +63,7 @@ final class Application
$connections = []; $connections = [];
foreach (self::DATABASE_CONNECTIONS as $name) { foreach (self::DATABASE_CONNECTIONS as $name) {
$connections[$name] = $this->config["Database.{$name}"] ?? []; $connections[$name] = config_get_default([], "Database.{$name}");
} }
new Database($connections, self::DATABASE_CONNECTIONS[0]); new Database($connections, self::DATABASE_CONNECTIONS[0]);
@ -120,11 +79,11 @@ final class Application
} }
new Cache( new Cache(
$this->config['Cache']['host'] ?? null, config_get('Cache', 'host'),
$this->config['Cache']['port'] ?? null, config_get('Cache', 'port'),
$this->config['Cache']['database'] ?? null, config_get('Cache', 'database'),
$this->config['Cache']['password'] ?? null, config_get('Cache', 'password'),
$this->config['Cache']['prefix'] ?? '' config_get_default('', 'Cache', 'prefix')
); );
} }
@ -134,11 +93,9 @@ final class Application
return; return;
} }
if (array_key_exists('Mail', $this->config) && array_key_exists('method', $this->config['Mail'])) { $method = mb_strtolower(config_get('Mail', 'method'));
$method = mb_strtolower($this->config['Mail']['method'] ?? '');
}
if (empty($method) || !array_key_exists($method, self::MAIL_TRANSPORT)) { if (!array_key_exists($method, self::MAIL_TRANSPORT)) {
$method = 'null'; $method = 'null';
} }
@ -147,25 +104,27 @@ final class Application
switch ($method) { switch ($method) {
case 'sendmail': case 'sendmail':
if (array_key_exists('command', $this->config['Mail'])) { $command = config_get('Mail', 'command');
$transport->setCommand($this->config['Mail']['command']);
if (!empty($command)) {
$transport->setCommand($command);
} }
break; break;
case 'smtp': case 'smtp':
$transport->setHost($this->config['Mail']['host'] ?? ''); $transport->setHost(config_get_default('', 'Mail', 'host'));
$transport->setPort(intval($this->config['Mail']['port'] ?? 25)); $transport->setPort(intval(config_get_default(25, 'Mail', 'port')));
if (array_key_exists('encryption', $this->config['Mail'])) { $extra = [
$transport->setEncryption($this->config['Mail']['encryption']); 'setEncryption' => config_get('Mail', 'encryption'),
'setUsername' => config_get('Mail', 'username'),
'setPassword' => config_get('Mail', 'password'),
];
foreach ($extra as $method => $value) {
if (!empty($value)) {
$transport->{$method}($value);
} }
if (array_key_exists('username', $this->config['Mail'])) {
$transport->setUsername($this->config['Mail']['username']);
}
if (array_key_exists('password', $this->config['Mail'])) {
$transport->setPassword($this->config['Mail']['password']);
} }
break; break;
} }
@ -190,7 +149,7 @@ final class Application
public function getMailSender(): array public function getMailSender(): array
{ {
return [ return [
($this->config['Mail']['sender_email'] ?? 'sys@msz.lh') => ($this->config['Mail']['sender_name'] ?? 'Misuzu System') config_get_default('sys@msz.lh', 'Mail', 'sender_email') => config_get_default('Misuzu System', 'Mail', 'sender_name'),
]; ];
} }
@ -200,7 +159,7 @@ final class Application
return; return;
} }
$this->geoipInstance = new GeoIP($this->config['GeoIP']['database_path'] ?? ''); $this->geoipInstance = new GeoIP(config_get_default('', 'GeoIP', 'database_path'));
} }
public function getGeoIP(): GeoIP public function getGeoIP(): GeoIP
@ -220,79 +179,39 @@ final class Application
public function getAvatarProps(): array public function getAvatarProps(): array
{ {
return [ return [
'max_width' => intval($this->config['Avatar']['max_width'] ?? 4000), 'max_width' => intval(config_get_default(1000, 'Avatar', 'max_width')),
'max_height' => intval($this->config['Avatar']['max_height'] ?? 4000), 'max_height' => intval(config_get_default(1000, 'Avatar', 'max_height')),
'max_size' => intval($this->config['Avatar']['max_filesize'] ?? 1000000), 'max_size' => intval(config_get_default(500000, 'Avatar', 'max_filesize')),
]; ];
} }
public function getBackgroundProps(): array public function getBackgroundProps(): array
{ {
return [ return [
'max_width' => intval($this->config['Background']['max_width'] ?? 3840), 'max_width' => intval(config_get_default(3840, 'Avatar', 'max_width')),
'max_height' => intval($this->config['Background']['max_height'] ?? 2160), 'max_height' => intval(config_get_default(2160, 'Avatar', 'max_height')),
'max_size' => intval($this->config['Background']['max_filesize'] ?? 1000000), 'max_size' => intval(config_get_default(1000000, 'Avatar', 'max_filesize')),
]; ];
} }
public function underLockdown(): bool public function underLockdown(): bool
{ {
return boolval($this->config['Auth']['lockdown'] ?? false); return boolval(config_get_default(false, 'Auth', 'lockdown'));
} }
public function disableRegistration(): bool public function disableRegistration(): bool
{ {
return $this->underLockdown() return $this->underLockdown()
|| $this->getPrivateInfo()['enabled'] || $this->getPrivateInfo()['enabled']
|| boolval($this->config['Auth']['prevent_registration'] ?? false); || boolval(config_get_default(false, 'Auth', 'prevent_registration'));
} }
public function getPrivateInfo(): array public function getPrivateInfo(): array
{ {
return !empty($this->config['Private']) && boolval($this->config['Private']['enabled']) return config_get_default(['enabled' => false], 'Private');
? $this->config['Private']
: ['enabled' => false];
} }
public function getLinkedData(): array // used in some of the user functions still, fix that
{
if (!($this->config['Site']['embed_linked_data'] ?? false)) {
return ['embed_linked_data' => false];
}
return [
'embed_linked_data' => true,
'embed_name' => $this->config['Site']['name'] ?? 'Flashii',
'embed_url' => $this->config['Site']['url'] ?? '',
'embed_logo' => $this->config['Site']['external_logo'] ?? '',
'embed_same_as' => explode(',', $this->config['Site']['social_media'] ?? '')
];
}
public function getSiteInfo(): array
{
return [
'site_name' => $this->config['Site']['name'] ?? 'Flashii',
'site_description' => $this->config['Site']['description'] ?? '',
'site_twitter' => $this->config['Site']['twitter'] ?? '',
'site_url' => $this->config['Site']['url'] ?? '',
];
}
public function getDefaultAvatar(): string
{
return $this->getPath($this->config['Avatar']['default_path'] ?? 'public/images/no-avatar.png');
}
public function getCsrfSecretKey(): string
{
return $this->config['CSRF']['secret_key'] ?? 'insecure';
}
/**
* Gets the currently active instance of Application
* @return Application
*/
public static function getInstance(): Application public static function getInstance(): Application
{ {
if (empty(self::$instance)) { if (empty(self::$instance)) {

View file

@ -131,7 +131,7 @@ final class Database
if ($info['memory']) { if ($info['memory']) {
$dsn .= ':memory:'; $dsn .= ':memory:';
} else { } else {
$databasePath = realpath($info['database'] ?? __DIR__ . '/../store/misuzu.db'); $databasePath = realpath($info['database'] ?? MSZ_ROOT . '/store/misuzu.db');
if ($databasePath === false) { if ($databasePath === false) {
throw new UnexpectedValueException("Database does not exist."); throw new UnexpectedValueException("Database does not exist.");

View file

@ -74,7 +74,7 @@ HTML;
], ],
'misuzu' => [ 'misuzu' => [
'trace_txt' => $this->getException()->getTraceAsString(), 'trace_txt' => $this->getException()->getTraceAsString(),
'directory' => dirname(__DIR__, 1), 'directory' => MSZ_ROOT,
], ],
'exception' => Formatter::formatExceptionAsDataArray( 'exception' => Formatter::formatExceptionAsDataArray(
$this->getInspector(), $this->getInspector(),

View file

@ -1,7 +1,7 @@
<?php <?php
use Misuzu\Database; use Misuzu\Database;
require_once __DIR__ . '/Users/validation.php'; require_once 'Users/validation.php';
define('MSZ_PERM_COMMENTS_CREATE', 1); define('MSZ_PERM_COMMENTS_CREATE', 1);
define('MSZ_PERM_COMMENTS_EDIT_OWN', 1 << 1); define('MSZ_PERM_COMMENTS_EDIT_OWN', 1 << 1);

View file

@ -7,22 +7,29 @@ function config_load(string $path, bool $isText = false): void
? parse_ini_string($path, true, INI_SCANNER_TYPED) ? parse_ini_string($path, true, INI_SCANNER_TYPED)
: parse_ini_file($path, true, INI_SCANNER_TYPED); : parse_ini_file($path, true, INI_SCANNER_TYPED);
if (!is_array($GLOBALS[MSZ_CONFIG_STORE])) { if (!is_array($GLOBALS[MSZ_CONFIG_STORE] ?? null)) {
$GLOBALS[MSZ_CONFIG_STORE] = []; $GLOBALS[MSZ_CONFIG_STORE] = [];
} }
$GLOBALS[MSZ_CONFIG_STORE] = array_merge_recursive($GLOBALS[MSZ_CONFIG_STORE], $config); $GLOBALS[MSZ_CONFIG_STORE] = array_merge_recursive($GLOBALS[MSZ_CONFIG_STORE], $config);
} }
function config_get(string $key, $default = null) function config_get(string ...$key)
{ {
$lastDot = strrpos($key, '.'); $value = $GLOBALS[MSZ_CONFIG_STORE];
if ($lastDot !== false) { for ($i = 0; $i < count($key); $i++) {
$section = substr($key, 0, $lastDot); if (empty($value[$key[$i]])) {
$key = substr($key, $lastDot + 1); return null;
return $GLOBALS[MSZ_CONFIG_STORE][$section][$key] ?? $default;
} }
return $GLOBALS[MSZ_CONFIG_STORE][$key] ?? $default; $value = $value[$key[$i]];
}
return $value;
}
function config_get_default($default, string ...$key)
{
return config_get(...$key) ?? $default;
} }

View file

@ -58,16 +58,16 @@
</div> </div>
</div> </div>
{% if embed_linked_data is defined and embed_linked_data %} {% if linked_data is defined and linked_data is iterable %}
<script type="application/ld+json"> <script type="application/ld+json">
{ {
"@context": "http://schema.org", "@context": "http://schema.org",
"@type": "Organization", "@type": "Organization",
"name": "{{ embed_name }}", "name": "{{ linked_data.name }}",
"url": "{{ embed_url }}", "url": "{{ linked_data.url }}",
"logo": "{{ embed_logo }}", "logo": "{{ linked_data.logo }}",
"sameAs": [ "sameAs": [
"{{ embed_same_as|join('", "')|raw }}" "{{ linked_data.same_as|join('", "')|raw }}"
] ]
} }
</script> </script>

View file

@ -86,7 +86,7 @@ function check_mx_record(string $email): bool
function asset_url(string $path): string function asset_url(string $path): string
{ {
$realPath = realpath(__DIR__ . '/public/' . $path); $realPath = realpath(MSZ_ROOT . '/public/' . $path);
if ($realPath === false || !file_exists($realPath)) { if ($realPath === false || !file_exists($realPath)) {
return $path; return $path;