From 4110cd519054d6e9d2bee2bd5c184d76bf476f01 Mon Sep 17 00:00:00 2001
From: flashwave <me@flash.moe>
Date: Sun, 9 Feb 2025 20:44:10 +0000
Subject: [PATCH] Moved constants out of misuzu.php.

---
 misuzu.php                          | 15 ++-------------
 phpstan.neon                        |  4 +---
 public-legacy/_github-callback.php  |  2 +-
 public/index.php                    |  8 ++++----
 src/DatabaseContext.php             |  4 ++--
 src/Info/InfoRoutes.php             | 17 ++++++++++-------
 src/Mailer.php                      |  2 +-
 src/Messages/MessagesRoutes.php     |  4 ++--
 src/Misuzu.php                      | 26 ++++++++++++++++++++++++--
 src/MisuzuContext.php               |  4 ++--
 src/Perms/PermissionsData.php       |  2 +-
 src/Routing/RoutingErrorHandler.php |  4 ++--
 src/Users/Assets/AssetsRoutes.php   |  6 +++---
 src/Users/Assets/UserImageAsset.php |  3 ++-
 tools/migrate                       | 14 ++++++++------
 tools/migrate-override-toggle       | 12 ++++++++++++
 16 files changed, 77 insertions(+), 50 deletions(-)
 create mode 100755 tools/migrate-override-toggle

diff --git a/misuzu.php b/misuzu.php
index 6e1bf829..d60d1c6c 100644
--- a/misuzu.php
+++ b/misuzu.php
@@ -5,21 +5,10 @@ use Index\Config\Fs\FsConfig;
 
 define('MSZ_STARTUP', microtime(true));
 define('MSZ_ROOT', __DIR__);
-define('MSZ_CLI', PHP_SAPI === 'cli');
-define('MSZ_DEBUG', is_file(MSZ_ROOT . '/.debug'));
-define('MSZ_PUBLIC', MSZ_ROOT . '/public');
-define('MSZ_SOURCE', MSZ_ROOT . '/src');
-define('MSZ_CONFIG', MSZ_ROOT . '/config');
-define('MSZ_TEMPLATES', MSZ_ROOT . '/templates');
-define('MSZ_MIGRATIONS', MSZ_ROOT . '/database');
 
-require_once MSZ_ROOT . '/vendor/autoload.php';
+require_once __DIR__ . '/vendor/autoload.php';
 
-error_reporting(MSZ_DEBUG ? -1 : 0);
-mb_internal_encoding('UTF-8');
-date_default_timezone_set('GMT');
-
-$env = FsConfig::fromFile(MSZ_CONFIG . '/config.cfg');
+$env = FsConfig::fromFile(Misuzu::PATH_CONFIG . '/config.cfg');
 
 if($env->hasValues('sentry:dsn'))
     (function($env) {
diff --git a/phpstan.neon b/phpstan.neon
index b9f04442..f3747dad 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -6,11 +6,9 @@ parameters:
     - src
     - public
     - public-legacy
+    - tools
   bootstrapFiles:
     - misuzu.php
-  dynamicConstantNames:
-    - MSZ_CLI
-    - MSZ_DEBUG
   ignoreErrors:
     -
       identifier: variable.undefined
diff --git a/public-legacy/_github-callback.php b/public-legacy/_github-callback.php
index dda9ee9d..cb58430a 100644
--- a/public-legacy/_github-callback.php
+++ b/public-legacy/_github-callback.php
@@ -46,7 +46,7 @@ header('Content-Type: text/plain; charset=utf-8');
 if($_SERVER['REQUEST_METHOD'] !== 'POST')
     die('no');
 
-$config = MSZ_CONFIG . '/github.ini';
+$config = Misuzu::PATH_CONFIG . '/github.ini';
 if(!is_file($config))
     die('config missing');
 
diff --git a/public/index.php b/public/index.php
index 120453ed..ef83817c 100644
--- a/public/index.php
+++ b/public/index.php
@@ -29,17 +29,17 @@ else
 // The whole wall of shit before the router setup and dispatch should be worked away
 // Lockdown things should be middleware when there's no more legacy files
 
-$request = \Index\Http\HttpRequest::fromRequest();
-
 ob_start();
 
-if(is_file(MSZ_ROOT . '/.migrating')) {
+if(is_file($msz->dbCtx->getMigrateLockPath())) {
     http_response_code(503);
     header('Content-Type: text/html; charset=utf-8');
     header('X-Accel-Redirect: /error-503.html');
     exit;
 }
 
+$request = \Index\Http\HttpRequest::fromRequest();
+
 $tokenPacker = $msz->authCtx->createAuthTokenPacker();
 
 if(filter_has_var(INPUT_COOKIE, 'msz_auth'))
@@ -130,7 +130,7 @@ $msz->startTemplating();
 
 if(in_array('main', $msz->env->getArray(sprintf('domain:%s', $request->getHeaderLine('Host'))))) {
     $mszRequestPath = substr($request->path, 1);
-    $mszLegacyPathPrefix = MSZ_PUBLIC . '-legacy/';
+    $mszLegacyPathPrefix = Misuzu::PATH_PUBLIC_LEGACY . '/';
     $mszLegacyPath = $mszLegacyPathPrefix . $mszRequestPath;
 
     if(str_starts_with($mszLegacyPath, $mszLegacyPathPrefix)) {
diff --git a/src/DatabaseContext.php b/src/DatabaseContext.php
index 805343bb..24f9a65b 100644
--- a/src/DatabaseContext.php
+++ b/src/DatabaseContext.php
@@ -30,11 +30,11 @@ class DatabaseContext implements RouteHandler {
     }
 
     public function createMigrationRepo(): DbMigrationRepo {
-        return new FsDbMigrationRepo(MSZ_MIGRATIONS);
+        return new FsDbMigrationRepo(Misuzu::PATH_DATABASE);
     }
 
     public function getMigrateLockPath(): string {
-        return sys_get_temp_dir() . '/misuzu-migration-' . hash('sha256', MSZ_ROOT) . '.lock';
+        return sys_get_temp_dir() . '/misuzu-migration-' . hash('sha256', Misuzu::PATH_ROOT) . '.lock';
     }
 
     /** @return void|int */
diff --git a/src/Info/InfoRoutes.php b/src/Info/InfoRoutes.php
index f500964a..e191bbc0 100644
--- a/src/Info/InfoRoutes.php
+++ b/src/Info/InfoRoutes.php
@@ -1,23 +1,26 @@
 <?php
 namespace Misuzu\Info;
 
+use Index\Index;
 use Index\Http\{HttpRequest,HttpResponseBuilder};
 use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
 use Index\Urls\{UrlFormat,UrlSource,UrlSourceCommon};
-use Misuzu\Template;
+use Misuzu\{Misuzu,Template};
 use Misuzu\Parsers\{Parsers,TextFormat};
+use RPCii\RPCii;
 
 class InfoRoutes implements RouteHandler, UrlSource {
     use RouteHandlerCommon, UrlSourceCommon;
 
-    private const DOCS_PATH = MSZ_ROOT . '/docs';
     private const PROJECT_PATHS = [
-        'misuzu' => MSZ_ROOT,
-        'index' => MSZ_ROOT . '/vendor/flashwave/index',
+        'misuzu' => Misuzu::PATH_ROOT,
+        'index' => Index::PATH_ROOT,
+        'rpcii' => RPCii::PATH_ROOT,
     ];
     private const PROJECT_SUFFIXES = [
-        'misuzu' => 'Misuzu Project » %s',
-        'index' => 'Index Project » %s',
+        'misuzu' => 'Misuzu » %s',
+        'index' => 'Index » %s',
+        'rpcii' => 'RPCii » %s',
     ];
 
     #[HttpGet('/info')]
@@ -31,7 +34,7 @@ class InfoRoutes implements RouteHandler, UrlSource {
     #[UrlFormat('info-doc', '/info/<title>')]
     public function getDocsPage(HttpResponseBuilder $response, HttpRequest $request, string $name): string {
         return $this->serveMarkdownDocument(
-            sprintf('%s/%s.md', self::DOCS_PATH, $name)
+            sprintf('%s/%s.md', Misuzu::PATH_DOCS, $name)
         );
     }
 
diff --git a/src/Mailer.php b/src/Mailer.php
index f4f89005..d5e98159 100644
--- a/src/Mailer.php
+++ b/src/Mailer.php
@@ -9,7 +9,7 @@ use Symfony\Component\Mailer\Transport as SymfonyTransport;
 use Symfony\Component\Mailer\Transport\TransportInterface as SymfonyTransportInterface;
 
 final class Mailer {
-    private const TEMPLATE_PATH = MSZ_ROOT . '/config/emails/%s.txt';
+    private const TEMPLATE_PATH = Misuzu::PATH_CONFIG . '/emails/%s.txt';
 
     private static Config $config;
     private static ?SymfonyTransportInterface $transport;
diff --git a/src/Messages/MessagesRoutes.php b/src/Messages/MessagesRoutes.php
index f0da0f1d..be47d717 100644
--- a/src/Messages/MessagesRoutes.php
+++ b/src/Messages/MessagesRoutes.php
@@ -10,7 +10,7 @@ use Index\Colour\Colour;
 use Index\Http\{FormHttpContent,HttpRequest,HttpResponseBuilder};
 use Index\Http\Routing\{HttpGet,HttpMiddleware,HttpPost,RouteHandler,RouteHandlerCommon};
 use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
-use Misuzu\{CSRF,Pagination,Perm,Template};
+use Misuzu\{CSRF,Misuzu,Pagination,Perm,Template};
 use Misuzu\Auth\AuthInfo;
 use Misuzu\Parsers\TextFormat;
 use Misuzu\Perms\PermissionsData;
@@ -45,7 +45,7 @@ class MessagesRoutes implements RouteHandler, UrlSource {
             return 401;
 
         // do not allow access to PMs when impersonating in production mode
-        if(!MSZ_DEBUG && $this->authInfo->impersonating)
+        if(!Misuzu::debug() && $this->authInfo->impersonating)
             return 403;
 
         $globalPerms = $this->authInfo->getPerms('global');
diff --git a/src/Misuzu.php b/src/Misuzu.php
index c4787685..91699354 100644
--- a/src/Misuzu.php
+++ b/src/Misuzu.php
@@ -1,10 +1,28 @@
 <?php
 namespace Misuzu;
 
+if(!defined('MSZ_ROOT')) {
+    define('MSZ_ROOT', (function() {
+        $root = __DIR__ . DIRECTORY_SEPARATOR . '..';
+        $path = realpath($root);
+        if(!is_string($path))
+            $path = $root;
+
+        return $path;
+    })());
+}
+
 final class Misuzu {
-    public const string PATH_SOURCE = __DIR__;
-    public const string PATH_ROOT = self::PATH_SOURCE . DIRECTORY_SEPARATOR . '..';
+    public const string PATH_ROOT = MSZ_ROOT;
     public const string PATH_ASSETS = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'assets';
+    public const string PATH_CONFIG = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'config';
+    public const string PATH_DATABASE = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'database';
+    public const string PATH_DOCS = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'docs';
+    public const string PATH_PUBLIC = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'public';
+    public const string PATH_PUBLIC_LEGACY = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'public-legacy';
+    public const string PATH_SOURCE = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'src';
+    public const string PATH_STORE = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'store';
+    public const string PATH_TEMPLATES = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'templates';
     public const string PATH_VERSION = self::PATH_ROOT . DIRECTORY_SEPARATOR . 'VERSION';
 
     public static function version(): string {
@@ -17,4 +35,8 @@ final class Misuzu {
 
         return trim($version);
     }
+
+    public static function debug(): bool {
+        return !empty(ini_get('display_errors'));
+    }
 }
diff --git a/src/MisuzuContext.php b/src/MisuzuContext.php
index 6a79c25b..16a8b1fd 100644
--- a/src/MisuzuContext.php
+++ b/src/MisuzuContext.php
@@ -120,14 +120,14 @@ class MisuzuContext {
             ['eeprom.appmsgs:s', '', 'eeprom_app_messages'],
         ]);
 
-        $isDebug = MSZ_DEBUG;
+        $isDebug = Misuzu::debug();
         $globals['site_info'] = $this->siteInfo;
         $globals['auth_info'] = $this->authInfo;
         $globals['active_ban_info'] = $this->usersCtx->tryGetActiveBan($this->authInfo->userInfo);
         $globals['display_timings_info'] = $isDebug || $this->authInfo->getPerms('global')->check(Perm::G_TIMINGS_VIEW);
 
         $this->templating = new TplEnvironment(
-            MSZ_TEMPLATES,
+            Misuzu::PATH_TEMPLATES,
             cache: $isDebug || !$cache ? null : ['Misuzu', GitInfo::hash(true)],
             debug: $isDebug
         );
diff --git a/src/Perms/PermissionsData.php b/src/Perms/PermissionsData.php
index 2efd37e1..3eb24bce 100644
--- a/src/Perms/PermissionsData.php
+++ b/src/Perms/PermissionsData.php
@@ -381,7 +381,7 @@ class PermissionsData {
      * @param bool|float|int|string|null ...$args
      */
     private static function precalculatePermissionsLog(string $fmt, ...$args): void {
-        if(!MSZ_CLI)
+        if(php_sapi_name() === 'cli')
             return;
 
         echo XDateTime::now()->format('[H:i:s.u] ');
diff --git a/src/Routing/RoutingErrorHandler.php b/src/Routing/RoutingErrorHandler.php
index 406ca222..87fff7a7 100644
--- a/src/Routing/RoutingErrorHandler.php
+++ b/src/Routing/RoutingErrorHandler.php
@@ -2,7 +2,7 @@
 namespace Misuzu\Routing;
 
 use Index\Http\{HtmlHttpErrorHandler,HttpResponseBuilder,HttpRequest};
-use Misuzu\Template;
+use Misuzu\{Misuzu,Template};
 
 class RoutingErrorHandler extends HtmlHttpErrorHandler {
     public function handle(HttpResponseBuilder $response, HttpRequest $request, int $code, string $message): void {
@@ -13,7 +13,7 @@ class RoutingErrorHandler extends HtmlHttpErrorHandler {
         }
 
         $path = sprintf('/error-%03d.html', $code);
-        if(is_file(MSZ_PUBLIC . $path)) {
+        if(is_file(Misuzu::PATH_PUBLIC . $path)) {
             $response->setTypeHTML();
             $response->accelRedirect($path);
             return;
diff --git a/src/Users/Assets/AssetsRoutes.php b/src/Users/Assets/AssetsRoutes.php
index 4982e17b..a0693c3e 100644
--- a/src/Users/Assets/AssetsRoutes.php
+++ b/src/Users/Assets/AssetsRoutes.php
@@ -6,7 +6,7 @@ use RuntimeException;
 use Index\Http\{HttpRequest,HttpResponseBuilder};
 use Index\Http\Routing\{HttpGet,RouteHandler,RouteHandlerCommon};
 use Index\Urls\{UrlFormat,UrlRegistry,UrlSource,UrlSourceCommon};
-use Misuzu\Perm;
+use Misuzu\{Misuzu,Perm};
 use Misuzu\Auth\AuthInfo;
 use Misuzu\Users\{UsersContext,UserInfo};
 
@@ -34,13 +34,13 @@ class AssetsRoutes implements RouteHandler, UrlSource {
     #[HttpGet('/assets/avatar/([0-9]+)(?:\.[a-z]+)?')]
     #[UrlFormat('user-avatar', '/assets/avatar/<user>', ['res' => '<res>'])]
     public function getAvatar(HttpResponseBuilder $response, HttpRequest $request, string $userId = '') {
-        $assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/no-avatar.png', MSZ_PUBLIC);
+        $assetInfo = new StaticUserImageAsset(Misuzu::PATH_PUBLIC . '/images/no-avatar.png', Misuzu::PATH_PUBLIC);
 
         try {
             $userInfo = $this->usersCtx->getUserInfo($userId);
 
             if(!$this->canViewAsset($request, $userInfo)) {
-                $assetInfo = new StaticUserImageAsset(MSZ_PUBLIC . '/images/banned-avatar.png', MSZ_PUBLIC);
+                $assetInfo = new StaticUserImageAsset(Misuzu::PATH_PUBLIC . '/images/banned-avatar.png', Misuzu::PATH_PUBLIC);
             } else {
                 $userAssetInfo = new UserAvatarAsset($userInfo);
                 if($userAssetInfo->isPresent())
diff --git a/src/Users/Assets/UserImageAsset.php b/src/Users/Assets/UserImageAsset.php
index 2717c063..59061cd6 100644
--- a/src/Users/Assets/UserImageAsset.php
+++ b/src/Users/Assets/UserImageAsset.php
@@ -3,6 +3,7 @@ namespace Misuzu\Users\Assets;
 
 use InvalidArgumentException;
 use RuntimeException;
+use Misuzu\Misuzu;
 use Misuzu\Users\UserInfo;
 
 abstract class UserImageAsset implements UserImageAssetInterface {
@@ -77,7 +78,7 @@ abstract class UserImageAsset implements UserImageAssetInterface {
     }
 
     public function getStoragePath(): string {
-        return MSZ_ROOT . DIRECTORY_SEPARATOR . 'store';
+        return Misuzu::PATH_STORE;
     }
 
     public function getPath(): string {
diff --git a/tools/migrate b/tools/migrate
index 73be4e08..09e09e7f 100755
--- a/tools/migrate
+++ b/tools/migrate
@@ -1,13 +1,13 @@
 #!/usr/bin/env php
 <?php
-use Index\Db\Migration\FsDbMigrationRepo;
-
 require_once __DIR__ . '/../misuzu.php';
 
-try {
-    touch(MSZ_ROOT . '/.migrating');
-    chmod(MSZ_ROOT . '/.migrating', 0777);
+$lockPath = $msz->dbCtx->getMigrateLockPath();
+if(is_file($lockPath))
+    die('A migration script is already running.' . PHP_EOL);
 
+touch($lockPath);
+try {
     echo 'Creating migration manager...' . PHP_EOL;
     $manager = $msz->dbCtx->createMigrationManager();
 
@@ -29,6 +29,8 @@ try {
     }
 
     echo PHP_EOL;
+} catch(Exception $ex) {
+    var_dump($ex);
 } finally {
-    unlink(MSZ_ROOT . '/.migrating');
+    unlink($lockPath);
 }
diff --git a/tools/migrate-override-toggle b/tools/migrate-override-toggle
new file mode 100755
index 00000000..b8d7ebd4
--- /dev/null
+++ b/tools/migrate-override-toggle
@@ -0,0 +1,12 @@
+#!/usr/bin/env php
+<?php
+require_once __DIR__ . '/../misuzu.php';
+
+$lockPath = $msz->dbCtx->getMigrateLockPath();
+if(is_file($lockPath)) {
+    printf('Removing migration lock...%s', PHP_EOL);
+    unlink($lockPath);
+} else {
+    printf('Setting migration lock...%s', PHP_EOL);
+    touch($lockPath);
+}