diff --git a/.gitignore b/.gitignore index a350838..b98d922 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ /config/github.ini /.debug /.migrating +/lib/index-dev # Storage /store diff --git a/lib/index b/lib/index index ac2255d..d166428 160000 --- a/lib/index +++ b/lib/index @@ -1 +1 @@ -Subproject commit ac2255d24d7dd39ac91fa50d3a7aa71ce0a92188 +Subproject commit d16642872948d348f1bed805e1ce96175917aaa0 diff --git a/misuzu.php b/misuzu.php index 1ff1ff0..c9c75ad 100644 --- a/misuzu.php +++ b/misuzu.php @@ -4,6 +4,8 @@ namespace Misuzu; use PDO; use Index\Autoloader; use Index\Environment; +use Index\Data\ConnectionFailedException; +use Index\Data\DbTools; use Misuzu\Net\GeoIP; use Misuzu\Net\IPAddress; use Misuzu\Users\User; @@ -15,14 +17,16 @@ 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_PHP_MIN_VER', '7.4.0'); define('MSZ_PUBLIC', MSZ_ROOT . '/public'); define('MSZ_SOURCE', MSZ_ROOT . '/src'); define('MSZ_LIBRARIES', MSZ_ROOT . '/lib'); define('MSZ_CONFIG', MSZ_ROOT . '/config'); define('MSZ_TEMPLATES', MSZ_ROOT . '/templates'); -require_once MSZ_LIBRARIES . '/index/index.php'; +define('MSZ_NDX_PATH', MSZ_LIBRARIES . '/index'); +define('MSZ_NDX_PATH_DEV', MSZ_LIBRARIES . '/index-dev'); + +require_once (MSZ_DEBUG && is_dir(MSZ_NDX_PATH_DEV) ? MSZ_NDX_PATH_DEV : MSZ_NDX_PATH) . '/index.php'; Autoloader::addNamespace(__NAMESPACE__, MSZ_SOURCE); Environment::setDebug(MSZ_DEBUG); @@ -74,9 +78,14 @@ if(empty($dbConfig)) { exit; } -$dbConfig = $dbConfig['Database'] ?? $dbConfig['Database.mysql-main'] ?? []; +define('MSZ_DB_INIT', 'SET SESSION time_zone = \'+00:00\', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\';'); +$db = DbTools::create($dbConfig['dsn']); +$db->execute(MSZ_DB_INIT); + +$dbConfig = $dbConfig['Database'] ?? $dbConfig['Database.mysql-main'] ?? []; DB::init(DB::buildDSN($dbConfig), $dbConfig['username'] ?? '', $dbConfig['password'] ?? '', DB::ATTRS); +DB::exec(MSZ_DB_INIT); Config::init(); Mailer::init(Config::get('mail.method', Config::TYPE_STR), [ @@ -104,7 +113,7 @@ if(MSZ_CLI) { // Temporary backwards compatibility measure, remove this later return; } -$ctx = new MszContext(DB::getInstance()); +$ctx = new MszContext($db); // Everything below here should eventually be moved to index.php, probably only initialised when required. // Serving things like the css/js doesn't need to initialise sessions. @@ -133,7 +142,7 @@ if(!MSZ_DEBUG) { mkdir($twigCache, 0775, true); } -Template::init($twigCache ?? null, MSZ_DEBUG); +Template::init($ctx, $twigCache ?? null, MSZ_DEBUG); Template::set('globals', [ 'site_name' => Config::get('site.name', Config::TYPE_STR, 'Misuzu'), diff --git a/public/manage/general/setting.php b/public/manage/general/setting.php index 0735092..1ba28af 100644 --- a/public/manage/general/setting.php +++ b/public/manage/general/setting.php @@ -74,7 +74,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { if(str_starts_with($fv, 's:')) { $fv = substr($fv, 2); } elseif(str_starts_with($fv, 'i:')) { - $fv = intval(substr($fv, 2)); + $fv = (int)substr($fv, 2); } elseif(str_starts_with($fv, 'b:')) { $fv = strtolower(substr($fv, 2)); $fv = $fv !== 'false' && $fv !== '0' && $fv !== ''; @@ -88,7 +88,7 @@ if($_SERVER['REQUEST_METHOD'] === 'POST') { } else { $sValue = (string)filter_input(INPUT_POST, 'conf_value'); if($sType === 'integer') - $sValue = intval($sValue); + $sValue = (int)$sValue; } $sVar['value'] = $sValue; diff --git a/public/settings/sessions.php b/public/settings/sessions.php index 2e1064a..cdbd32d 100644 --- a/public/settings/sessions.php +++ b/public/settings/sessions.php @@ -24,7 +24,7 @@ if(!empty($_POST['session']) && CSRF::validateRequest()) { if(is_array($_POST['session'])) { foreach($_POST['session'] as $sessionId) { - $sessionId = intval($sessionId); + $sessionId = (int)$sessionId; try { $sessionInfo = UserSession::byId($sessionId); diff --git a/src/DB.php b/src/DB.php index 4f67130..7fa9625 100644 --- a/src/DB.php +++ b/src/DB.php @@ -23,8 +23,6 @@ final class DB { PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, PDO::ATTR_STRINGIFY_FETCHES => false, PDO::ATTR_EMULATE_PREPARES => false, - PDO::MYSQL_ATTR_INIT_COMMAND => 'SET SESSION time_zone = \'+00:00\'' - . ', sql_mode = \'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION\'', ]; public static function init(...$args) { diff --git a/src/Http/Handlers/AssetsHandler.php b/src/Http/Handlers/AssetsHandler.php index 8a4da49..1ecc07c 100644 --- a/src/Http/Handlers/AssetsHandler.php +++ b/src/Http/Handlers/AssetsHandler.php @@ -102,7 +102,7 @@ final class AssetsHandler extends Handler { } public function serveAvatar($response, $request, string $fileName) { - $userId = intval(pathinfo($fileName, PATHINFO_FILENAME)); + $userId = (int)pathinfo($fileName, PATHINFO_FILENAME); $type = pathinfo($fileName, PATHINFO_EXTENSION); if($type !== '' && $type !== 'png') @@ -124,7 +124,7 @@ final class AssetsHandler extends Handler { } public function serveProfileBackground($response, $request, string $fileName) { - $userId = intval(pathinfo($fileName, PATHINFO_FILENAME)); + $userId = (int)pathinfo($fileName, PATHINFO_FILENAME); $type = pathinfo($fileName, PATHINFO_EXTENSION); if($type !== '' && $type !== 'png') diff --git a/src/Http/Handlers/ChangelogHandler.php b/src/Http/Handlers/ChangelogHandler.php index f423b18..729e3b7 100644 --- a/src/Http/Handlers/ChangelogHandler.php +++ b/src/Http/Handlers/ChangelogHandler.php @@ -25,7 +25,7 @@ class ChangelogHandler extends Handler { if($filterDate !== null) try { $dateParts = explode('-', $filterDate, 3); - $filterDate = gmmktime(12, 0, 0, intval($dateParts[1]), intval($dateParts[2]), intval($dateParts[0])); + $filterDate = gmmktime(12, 0, 0, (int)$dateParts[1], (int)$dateParts[2], (int)$dateParts[0]); } catch(ErrorException $ex) { return 404; } diff --git a/src/Http/Handlers/NewsHandler.php b/src/Http/Handlers/NewsHandler.php index 2739ac4..f461287 100644 --- a/src/Http/Handlers/NewsHandler.php +++ b/src/Http/Handlers/NewsHandler.php @@ -32,7 +32,7 @@ final class NewsHandler extends Handler { } public function viewCategory($response, $request, string $fileName) { - $categoryId = intval(pathinfo($fileName, PATHINFO_FILENAME)); + $categoryId = (int)pathinfo($fileName, PATHINFO_FILENAME); $type = pathinfo($fileName, PATHINFO_EXTENSION); try { diff --git a/src/Imaging/Image.php b/src/Imaging/Image.php index 850ff96..6526645 100644 --- a/src/Imaging/Image.php +++ b/src/Imaging/Image.php @@ -40,8 +40,8 @@ abstract class Image { $targetHeight = $originalHeight * $dimensions / $originalWidth; } - $targetWidth = intval($targetWidth); - $targetHeight = intval($targetHeight); + $targetWidth = (int)$targetWidth; + $targetHeight = (int)$targetHeight; do { $this->resize($targetWidth, $targetHeight); diff --git a/src/MszContext.php b/src/MszContext.php index ff301ea..d617419 100644 --- a/src/MszContext.php +++ b/src/MszContext.php @@ -2,9 +2,9 @@ namespace Misuzu; use Misuzu\Template; -use Misuzu\Database\Database; use Misuzu\SharpChat\SharpChatRoutes; use Misuzu\Users\Users; +use Index\Data\IDbConnection; use Index\Http\HttpFx; use Index\Http\HttpRequest; use Index\Routing\Router; @@ -13,13 +13,18 @@ use Index\Routing\Router; // no more magical static classes that are just kind of assumed to exist // it currently looks Pretty Messy, but most everything else will be holding instances of other classes class MszContext { - private Database $database; - //private Users $users; + private IDbConnection $dbConn; + private Users $users; private HttpFx $router; - public function __construct(Database $database) { - $this->database = $database; - //$this->users = new Users($this->database); + public function __construct(IDbConnection $dbConn) { + $this->dbConn = $dbConn; + $this->users = new Users($this->dbConn); + } + + public function getDbQueryCount(): int { + $result = $this->dbConn->query('SHOW SESSION STATUS LIKE "Questions"'); + return $result->next() ? $result->getInteger(0) : 0; } public function getRouter(): Router { diff --git a/src/Pagination.php b/src/Pagination.php index 7f77a15..e499be6 100644 --- a/src/Pagination.php +++ b/src/Pagination.php @@ -70,7 +70,7 @@ final class Pagination { $source ??= $_GET; if(isset($source[$name]) && is_string($source[$name]) && ctype_digit($source[$name])) - return intval($source[$name]); + return (int)$source[$name]; return $default; } diff --git a/src/Template.php b/src/Template.php index 01a6a59..9f0d54a 100644 --- a/src/Template.php +++ b/src/Template.php @@ -5,6 +5,7 @@ use InvalidArgumentException; use Twig\Environment as TwigEnvironment; use Twig_Extensions_Extension_Date; use Twig\Loader\FilesystemLoader as TwigLoaderFilesystem; +use Misuzu\MszContext; final class Template { private const FILE_EXT = '.twig'; @@ -13,7 +14,7 @@ final class Template { private static $env; private static $vars = []; - public static function init(?string $cache = null, bool $debug = false): void { + public static function init(MszContext $ctx, ?string $cache = null, bool $debug = false): void { self::$loader = new TwigLoaderFilesystem; self::$env = new TwigEnvironment(self::$loader, [ 'cache' => $cache ?? false, @@ -21,8 +22,7 @@ final class Template { 'auto_reload' => $debug, 'debug' => $debug, ]); - //self::$env->addExtension(new Twig_Extensions_Extension_Date); - self::$env->addExtension(new TwigMisuzu); + self::$env->addExtension(new TwigMisuzu($ctx)); } public static function addPath(string $path): void { diff --git a/src/TwigMisuzu.php b/src/TwigMisuzu.php index 0460423..61b3267 100644 --- a/src/TwigMisuzu.php +++ b/src/TwigMisuzu.php @@ -6,9 +6,16 @@ use Twig\TwigFilter; use Twig\TwigFunction; use Twig\Environment as TwigEnvironment; use Misuzu\Parsers\Parser; +use Misuzu\MszContext; use Index\Environment; final class TwigMisuzu extends AbstractExtension { + private MszContext $ctx; + + public function __construct(MszContext $ctx) { + $this->ctx = $ctx; + } + public function getFilters() { return [ new TwigFilter('html_colour', 'html_colour'), @@ -34,7 +41,7 @@ final class TwigMisuzu extends AbstractExtension { new TwigFunction('git_tag', fn() => GitInfo::tag()), new TwigFunction('git_branch', fn() => GitInfo::branch()), new TwigFunction('startup_time', fn(float $time = MSZ_STARTUP) => microtime(true) - $time), - new TwigFunction('sql_query_count', fn() => DB::queries()), + new TwigFunction('sql_query_count', fn() => DB::queries() + $this->ctx->getDbQueryCount()), new TwigFunction('ndx_version', fn() => Environment::getIndexVersion()), ]; } diff --git a/src/Users/User.php b/src/Users/User.php index 2fb7889..13db1cb 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -323,12 +323,12 @@ class User implements HasRankInterface, JsonSerializable { return $this; } public function hasAge(): bool { - return $this->hasBirthdate() && intval($this->getBirthdate()->format('Y')) > 1900; + return $this->hasBirthdate() && (int)$this->getBirthdate()->format('Y') > 1900; } public function getAge(): int { if(!$this->hasAge()) return -1; - return intval($this->getBirthdate()->diff(new DateTime('now', new DateTimeZone('UTC')))->format('%y')); + return (int)$this->getBirthdate()->diff(new DateTime('now', new DateTimeZone('UTC')))->format('%y'); } public function profileFields(bool $filterEmpty = true): array { diff --git a/src/Users/UserInfo.php b/src/Users/UserInfo.php new file mode 100644 index 0000000..e5bc47e --- /dev/null +++ b/src/Users/UserInfo.php @@ -0,0 +1,38 @@ +getColour() !== null; + } + + private static DateTime $epoch; + public function isDeleted(): bool { + return self::$epoch->diff($this->getDeletedDate())->totalSeconds() > 0; + } + + public static function init(): void { + self::$epoch = DateTime::fromUnixTimeSeconds(0); + } +} + +UserInfo::init(); diff --git a/src/Users/Users.php b/src/Users/Users.php index 7a1099e..4832403 100644 --- a/src/Users/Users.php +++ b/src/Users/Users.php @@ -2,15 +2,15 @@ namespace Misuzu\Users; use DateTimeImmutable; -use Misuzu\Database\Database; +use Index\Data\IDbConnection; final class Users { - private Database $db; + private IDbConnection $dbConn; private array $cached = []; - public function __construct(Database $db) { - $this->db = $db; + public function __construct(IDbConnection $dbConn) { + $this->dbConn = $dbConn; } public function getById(string $userId): User { diff --git a/src/perms.php b/src/perms.php index 875a2c6..e36e5fb 100644 --- a/src/perms.php +++ b/src/perms.php @@ -19,7 +19,7 @@ define('MSZ_PERM_USER_MANAGE_ROLES', 0x00200000); define('MSZ_PERM_USER_MANAGE_PERMS', 0x00400000); define('MSZ_PERM_USER_MANAGE_REPORTS', 0x00800000); define('MSZ_PERM_USER_MANAGE_WARNINGS', 0x01000000); -//define('MSZ_PERM_USER_MANAGE_BLACKLISTS', 0x02000000); // Replaced with MSZ_PERM_MANAGE_BLACKLIST +//define('MSZ_PERM_USER_MANAGE_BLACKLISTS', 0x02000000); // Replaced with MSZ_PERM_GENERAL_MANAGE_BLACKLIST define('MSZ_PERMS_CHANGELOG', 'changelog'); define('MSZ_PERM_CHANGELOG_MANAGE_CHANGES', 0x00000001); diff --git a/utility.php b/utility.php index b79a09e..c93acd8 100644 --- a/utility.php +++ b/utility.php @@ -30,7 +30,7 @@ function array_find(array $array, callable $callback) { } function clamp($num, int $min, int $max): int { - return max($min, min($max, intval($num))); + return max($min, min($max, (int)$num)); } function starts_with(string $string, string $text): bool {