Added lazy database object creation.

This commit is contained in:
flash 2024-02-07 00:04:45 +00:00
parent b89621cb1a
commit 070dc5e782
55 changed files with 772 additions and 817 deletions

View file

@ -1,4 +1,4 @@
Copyright (c) 2017-2023, flashwave <me@flash.moe> Copyright (c) 2017-2024, flashwave <me@flash.moe>
All rights reserved. All rights reserved.
Redistribution and use in source and binary forms, with or without Redistribution and use in source and binary forms, with or without

244
composer.lock generated
View file

@ -8,16 +8,16 @@
"packages": [ "packages": [
{ {
"name": "chillerlan/php-qrcode", "name": "chillerlan/php-qrcode",
"version": "4.4.0", "version": "4.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/chillerlan/php-qrcode.git", "url": "https://github.com/chillerlan/php-qrcode.git",
"reference": "52889cd7ab1b78e6a345edafe24aa74bc5becc08" "reference": "f5e243f3b61a60934780579430a951460f40888d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/52889cd7ab1b78e6a345edafe24aa74bc5becc08", "url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/f5e243f3b61a60934780579430a951460f40888d",
"reference": "52889cd7ab1b78e6a345edafe24aa74bc5becc08", "reference": "f5e243f3b61a60934780579430a951460f40888d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -27,10 +27,10 @@
}, },
"require-dev": { "require-dev": {
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpmd/phpmd": "^2.13", "phpmd/phpmd": "^2.15",
"phpunit/phpunit": "^9.6", "phpunit/phpunit": "^9.6",
"setasign/fpdf": "^1.8.2", "setasign/fpdf": "^1.8.2",
"squizlabs/php_codesniffer": "^3.7" "squizlabs/php_codesniffer": "^3.8"
}, },
"suggest": { "suggest": {
"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.", "chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
@ -73,7 +73,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/chillerlan/php-qrcode/issues", "issues": "https://github.com/chillerlan/php-qrcode/issues",
"source": "https://github.com/chillerlan/php-qrcode/tree/4.4.0" "source": "https://github.com/chillerlan/php-qrcode/tree/4.4.1"
}, },
"funding": [ "funding": [
{ {
@ -85,20 +85,20 @@
"type": "ko_fi" "type": "ko_fi"
} }
], ],
"time": "2023-11-23T23:53:20+00:00" "time": "2024-01-06T16:56:58+00:00"
}, },
{ {
"name": "chillerlan/php-settings-container", "name": "chillerlan/php-settings-container",
"version": "3.1.0", "version": "3.1.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/chillerlan/php-settings-container.git", "url": "https://github.com/chillerlan/php-settings-container.git",
"reference": "4d02944424fa1f48abca96353257c93cbac856c1" "reference": "c41e89f8bf963d1e88584a47fb78d1cd204b6e2a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/4d02944424fa1f48abca96353257c93cbac856c1", "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/c41e89f8bf963d1e88584a47fb78d1cd204b6e2a",
"reference": "4d02944424fa1f48abca96353257c93cbac856c1", "reference": "c41e89f8bf963d1e88584a47fb78d1cd204b6e2a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -107,9 +107,9 @@
}, },
"require-dev": { "require-dev": {
"phan/phan": "^5.4", "phan/phan": "^5.4",
"phpmd/phpmd": "^2.13", "phpcsstandards/php_codesniffer": "^3.8",
"phpunit/phpunit": "^10.2", "phpmd/phpmd": "^2.15",
"squizlabs/php_codesniffer": "^3.7" "phpunit/phpunit": "^10.5"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -150,31 +150,31 @@
"type": "ko_fi" "type": "ko_fi"
} }
], ],
"time": "2023-07-17T20:46:37+00:00" "time": "2024-01-05T23:55:20+00:00"
}, },
{ {
"name": "doctrine/lexer", "name": "doctrine/lexer",
"version": "3.0.0", "version": "3.0.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/doctrine/lexer.git", "url": "https://github.com/doctrine/lexer.git",
"reference": "84a527db05647743d50373e0ec53a152f2cde568" "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/84a527db05647743d50373e0ec53a152f2cde568", "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
"reference": "84a527db05647743d50373e0ec53a152f2cde568", "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": "^8.1" "php": "^8.1"
}, },
"require-dev": { "require-dev": {
"doctrine/coding-standard": "^10", "doctrine/coding-standard": "^12",
"phpstan/phpstan": "^1.9", "phpstan/phpstan": "^1.10",
"phpunit/phpunit": "^9.5", "phpunit/phpunit": "^10.5",
"psalm/plugin-phpunit": "^0.18.3", "psalm/plugin-phpunit": "^0.18.3",
"vimeo/psalm": "^5.0" "vimeo/psalm": "^5.21"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -211,7 +211,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/doctrine/lexer/issues", "issues": "https://github.com/doctrine/lexer/issues",
"source": "https://github.com/doctrine/lexer/tree/3.0.0" "source": "https://github.com/doctrine/lexer/tree/3.0.1"
}, },
"funding": [ "funding": [
{ {
@ -227,7 +227,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2022-12-15T16:57:16+00:00" "time": "2024-02-05T11:56:58+00:00"
}, },
{ {
"name": "egulias/email-validator", "name": "egulias/email-validator",
@ -352,7 +352,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://patchii.net/flash/index.git", "url": "https://patchii.net/flash/index.git",
"reference": "e31781c69f0b13fe251771c8e7e529222630a44f" "reference": "73051dc71ee2d0045e5dbe5d846bb665a8b1c39c"
}, },
"require": { "require": {
"ext-mbstring": "*", "ext-mbstring": "*",
@ -390,7 +390,7 @@
], ],
"description": "Composer package for the common library for my projects.", "description": "Composer package for the common library for my projects.",
"homepage": "https://railgun.sh/index", "homepage": "https://railgun.sh/index",
"time": "2023-11-20T19:01:19+00:00" "time": "2024-02-06T23:52:46+00:00"
}, },
{ {
"name": "flashwave/sasae", "name": "flashwave/sasae",
@ -398,7 +398,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://patchii.net/flash/sasae.git", "url": "https://patchii.net/flash/sasae.git",
"reference": "b56dd222acb8f138729e6258d4a90bbb8401ff52" "reference": "c8a9f2974e6591215b3f898dd5525de1e8367f66"
}, },
"require": { "require": {
"flashwave/index": "dev-master", "flashwave/index": "dev-master",
@ -431,7 +431,7 @@
], ],
"description": "A wrapper for Twig with added common functionality.", "description": "A wrapper for Twig with added common functionality.",
"homepage": "https://railgun.sh/sasae", "homepage": "https://railgun.sh/sasae",
"time": "2023-11-20T19:09:35+00:00" "time": "2024-01-04T02:13:42+00:00"
}, },
{ {
"name": "flashwave/syokuhou", "name": "flashwave/syokuhou",
@ -439,7 +439,7 @@
"source": { "source": {
"type": "git", "type": "git",
"url": "https://patchii.net/flash/syokuhou.git", "url": "https://patchii.net/flash/syokuhou.git",
"reference": "fdf3c38cc216bf7024af331cbe1758532355c22f" "reference": "c1fe9371ada20fcea51c225cc53b9ceae4642bc4"
}, },
"require": { "require": {
"flashwave/index": "dev-master", "flashwave/index": "dev-master",
@ -470,7 +470,7 @@
], ],
"description": "Configuration library for PHP.", "description": "Configuration library for PHP.",
"homepage": "https://railgun.sh/syokuhou", "homepage": "https://railgun.sh/syokuhou",
"time": "2023-11-20T19:10:04+00:00" "time": "2024-01-04T02:12:49+00:00"
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
@ -649,16 +649,16 @@
}, },
{ {
"name": "matomo/device-detector", "name": "matomo/device-detector",
"version": "6.2.0", "version": "6.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/matomo-org/device-detector.git", "url": "https://github.com/matomo-org/device-detector.git",
"reference": "3577abbfea71eaf88d4cd432274428c39601754f" "reference": "19138b0c4b9ddf4ffd8e423d6af3764b7317cb0b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/3577abbfea71eaf88d4cd432274428c39601754f", "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/19138b0c4b9ddf4ffd8e423d6af3764b7317cb0b",
"reference": "3577abbfea71eaf88d4cd432274428c39601754f", "reference": "19138b0c4b9ddf4ffd8e423d6af3764b7317cb0b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -670,8 +670,8 @@
}, },
"require-dev": { "require-dev": {
"matthiasmullie/scrapbook": "^1.4.7", "matthiasmullie/scrapbook": "^1.4.7",
"mayflower/mo4-coding-standard": "^v8.0.0", "mayflower/mo4-coding-standard": "^v9.0.0",
"phpstan/phpstan": "^0.12.52", "phpstan/phpstan": "^1.10.44",
"phpunit/phpunit": "^8.5.8", "phpunit/phpunit": "^8.5.8",
"psr/cache": "^1.0.1", "psr/cache": "^1.0.1",
"psr/simple-cache": "^1.0.1", "psr/simple-cache": "^1.0.1",
@ -714,7 +714,7 @@
"source": "https://github.com/matomo-org/matomo", "source": "https://github.com/matomo-org/matomo",
"wiki": "https://dev.matomo.org/" "wiki": "https://dev.matomo.org/"
}, },
"time": "2023-11-15T09:44:42+00:00" "time": "2024-01-05T09:03:21+00:00"
}, },
{ {
"name": "mustangostang/spyc", "name": "mustangostang/spyc",
@ -1128,16 +1128,16 @@
}, },
{ {
"name": "sentry/sentry", "name": "sentry/sentry",
"version": "4.1.0", "version": "4.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/getsentry/sentry-php.git", "url": "https://github.com/getsentry/sentry-php.git",
"reference": "89666f297891ff937fceb2f3d1fb967a6848cf37" "reference": "a6e06f0b7a17e7f68e11297427da76bfe01a3ca3"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/getsentry/sentry-php/zipball/89666f297891ff937fceb2f3d1fb967a6848cf37", "url": "https://api.github.com/repos/getsentry/sentry-php/zipball/a6e06f0b7a17e7f68e11297427da76bfe01a3ca3",
"reference": "89666f297891ff937fceb2f3d1fb967a6848cf37", "reference": "a6e06f0b7a17e7f68e11297427da76bfe01a3ca3",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1161,7 +1161,7 @@
"phpbench/phpbench": "^1.0", "phpbench/phpbench": "^1.0",
"phpstan/phpstan": "^1.3", "phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^8.5.14|^9.4", "phpunit/phpunit": "^8.5.14|^9.4",
"symfony/phpunit-bridge": "^5.2|^6.0", "symfony/phpunit-bridge": "^5.2|^6.0|^7.0",
"vimeo/psalm": "^4.17" "vimeo/psalm": "^4.17"
}, },
"suggest": { "suggest": {
@ -1201,7 +1201,7 @@
], ],
"support": { "support": {
"issues": "https://github.com/getsentry/sentry-php/issues", "issues": "https://github.com/getsentry/sentry-php/issues",
"source": "https://github.com/getsentry/sentry-php/tree/4.1.0" "source": "https://github.com/getsentry/sentry-php/tree/4.5.0"
}, },
"funding": [ "funding": [
{ {
@ -1213,7 +1213,7 @@
"type": "custom" "type": "custom"
} }
], ],
"time": "2023-12-04T12:41:21+00:00" "time": "2024-01-29T16:16:10+00:00"
}, },
{ {
"name": "symfony/deprecation-contracts", "name": "symfony/deprecation-contracts",
@ -1284,16 +1284,16 @@
}, },
{ {
"name": "symfony/event-dispatcher", "name": "symfony/event-dispatcher",
"version": "v7.0.0", "version": "v7.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/event-dispatcher.git", "url": "https://github.com/symfony/event-dispatcher.git",
"reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e" "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e", "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/834c28d533dd0636f910909d01b9ff45cc094b5e",
"reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e", "reference": "834c28d533dd0636f910909d01b9ff45cc094b5e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1344,7 +1344,7 @@
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/event-dispatcher/tree/v7.0.0" "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.3"
}, },
"funding": [ "funding": [
{ {
@ -1360,7 +1360,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-27T16:29:09+00:00" "time": "2024-01-23T15:02:46+00:00"
}, },
{ {
"name": "symfony/event-dispatcher-contracts", "name": "symfony/event-dispatcher-contracts",
@ -1440,16 +1440,16 @@
}, },
{ {
"name": "symfony/mailer", "name": "symfony/mailer",
"version": "v6.4.0", "version": "v6.4.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mailer.git", "url": "https://github.com/symfony/mailer.git",
"reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba" "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mailer/zipball/ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", "url": "https://api.github.com/repos/symfony/mailer/zipball/74412c62f88a85a41b61f0b71ab0afcaad6f03ee",
"reference": "ca8dcf8892cdc5b4358ecf2528429bb5e706f7ba", "reference": "74412c62f88a85a41b61f0b71ab0afcaad6f03ee",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1500,7 +1500,7 @@
"description": "Helps sending emails", "description": "Helps sending emails",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/mailer/tree/v6.4.0" "source": "https://github.com/symfony/mailer/tree/v6.4.3"
}, },
"funding": [ "funding": [
{ {
@ -1516,20 +1516,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-11-12T18:02:22+00:00" "time": "2024-01-29T15:01:07+00:00"
}, },
{ {
"name": "symfony/mime", "name": "symfony/mime",
"version": "v7.0.0", "version": "v7.0.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/mime.git", "url": "https://github.com/symfony/mime.git",
"reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535" "reference": "c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/mime/zipball/0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", "url": "https://api.github.com/repos/symfony/mime/zipball/c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716",
"reference": "0a2fff95c1a10df97f571d67e76c7ae0f0d4f535", "reference": "c1ffe24ba6fdc3e3f0f3fcb93519103b326a3716",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1583,7 +1583,7 @@
"mime-type" "mime-type"
], ],
"support": { "support": {
"source": "https://github.com/symfony/mime/tree/v7.0.0" "source": "https://github.com/symfony/mime/tree/v7.0.3"
}, },
"funding": [ "funding": [
{ {
@ -1599,7 +1599,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-10-19T14:20:43+00:00" "time": "2024-01-30T08:34:29+00:00"
}, },
{ {
"name": "symfony/options-resolver", "name": "symfony/options-resolver",
@ -1670,16 +1670,16 @@
}, },
{ {
"name": "symfony/polyfill-ctype", "name": "symfony/polyfill-ctype",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git", "url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1693,9 +1693,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -1732,7 +1729,7 @@
"portable" "portable"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -1748,20 +1745,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-01-26T09:26:14+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-idn", "name": "symfony/polyfill-intl-idn",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git", "url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d" "reference": "a287ed7475f85bf6f61890146edbc932c0fff919"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a287ed7475f85bf6f61890146edbc932c0fff919",
"reference": "ecaafce9f77234a6a449d29e49267ba10499116d", "reference": "a287ed7475f85bf6f61890146edbc932c0fff919",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1774,9 +1771,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -1819,7 +1813,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -1835,20 +1829,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-01-26T09:30:37+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-intl-normalizer", "name": "symfony/polyfill-intl-normalizer",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" "reference": "bc45c394692b948b4d383a08d7753968bed9a83d"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d",
"reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "reference": "bc45c394692b948b4d383a08d7753968bed9a83d",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1859,9 +1853,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -1903,7 +1894,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -1919,20 +1910,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-01-26T09:26:14+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/polyfill-mbstring",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "42292d99c55abe617799667f454222c54c60e229" "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"reference": "42292d99c55abe617799667f454222c54c60e229", "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1946,9 +1937,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -1986,7 +1974,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -2002,20 +1990,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-28T09:04:16+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-php72", "name": "symfony/polyfill-php72",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php72.git", "url": "https://github.com/symfony/polyfill-php72.git",
"reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25",
"reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2023,9 +2011,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -2062,7 +2047,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -2078,20 +2063,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-01-26T09:26:14+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.28.0", "version": "v1.29.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2099,9 +2084,6 @@
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": {
"dev-main": "1.28-dev"
},
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill" "url": "https://github.com/symfony/polyfill"
@ -2145,7 +2127,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
}, },
"funding": [ "funding": [
{ {
@ -2161,25 +2143,25 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-01-26T09:26:14+00:00" "time": "2024-01-29T20:11:03+00:00"
}, },
{ {
"name": "symfony/service-contracts", "name": "symfony/service-contracts",
"version": "v3.4.0", "version": "v3.4.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/service-contracts.git", "url": "https://github.com/symfony/service-contracts.git",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
"reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=8.1", "php": ">=8.1",
"psr/container": "^2.0" "psr/container": "^1.1|^2.0"
}, },
"conflict": { "conflict": {
"ext-psr": "<1.1|>=2" "ext-psr": "<1.1|>=2"
@ -2227,7 +2209,7 @@
"standards" "standards"
], ],
"support": { "support": {
"source": "https://github.com/symfony/service-contracts/tree/v3.4.0" "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
}, },
"funding": [ "funding": [
{ {
@ -2243,7 +2225,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-07-30T20:28:31+00:00" "time": "2023-12-26T14:02:43+00:00"
}, },
{ {
"name": "twig/html-extra", "name": "twig/html-extra",
@ -2385,16 +2367,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "phpstan/phpstan", "name": "phpstan/phpstan",
"version": "1.10.50", "version": "1.10.57",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/phpstan/phpstan.git", "url": "https://github.com/phpstan/phpstan.git",
"reference": "06a98513ac72c03e8366b5a0cb00750b487032e4" "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/phpstan/phpstan/zipball/06a98513ac72c03e8366b5a0cb00750b487032e4", "url": "https://api.github.com/repos/phpstan/phpstan/zipball/1627b1d03446904aaa77593f370c5201d2ecc34e",
"reference": "06a98513ac72c03e8366b5a0cb00750b487032e4", "reference": "1627b1d03446904aaa77593f370c5201d2ecc34e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2443,7 +2425,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2023-12-13T10:59:42+00:00" "time": "2024-01-24T11:51:34+00:00"
} }
], ],
"aliases": [], "aliases": [],
@ -2457,5 +2439,5 @@
"prefer-lowest": false, "prefer-lowest": false,
"platform": [], "platform": [],
"platform-dev": [], "platform-dev": [],
"plugin-api-version": "2.3.0" "plugin-api-version": "2.6.0"
} }

View file

@ -18,7 +18,7 @@ else
try { try {
$isNew = false; $isNew = false;
$emoteInfo = $emotes->getEmote($emoteId); $emoteInfo = $emotes->getEmote($emoteId);
$emoteStrings = $emotes->getEmoteStrings($emoteInfo); $emoteStrings = iterator_to_array($emotes->getEmoteStrings($emoteInfo));
} catch(RuntimeException $ex) { } catch(RuntimeException $ex) {
Template::throwError(404); Template::throwError(404);
} }

View file

@ -13,7 +13,7 @@ $pagination = new Pagination($auditLog->countLogs(), 50);
if(!$pagination->hasValidOffset()) if(!$pagination->hasValidOffset())
Template::throwError(404); Template::throwError(404);
$logs = $auditLog->getLogs(pagination: $pagination); $logs = iterator_to_array($auditLog->getLogs(pagination: $pagination));
$userInfos = []; $userInfos = [];
$userColours = []; $userColours = [];

View file

@ -106,7 +106,7 @@ if(CSRF::validateRequest() && $canEdit) {
} }
$existingRoles = []; $existingRoles = [];
foreach($roles->getRoles(userInfo: $userInfo) as $roleInfo) foreach(iterator_to_array($roles->getRoles(userInfo: $userInfo)) as $roleInfo)
$existingRoles[$roleInfo->getId()] = $roleInfo; $existingRoles[$roleInfo->getId()] = $roleInfo;
$removeRoles = []; $removeRoles = [];
@ -226,7 +226,7 @@ if(CSRF::validateRequest() && $canEdit) {
return; return;
} }
$rolesAll = $roles->getRoles(); $rolesAll = iterator_to_array($roles->getRoles());
$userRoleIds = $users->hasRoles($userInfo, $rolesAll); $userRoleIds = $users->hasRoles($userInfo, $rolesAll);
Template::render('manage.users.user', [ Template::render('manage.users.user', [

View file

@ -299,7 +299,7 @@ $profileStats->forum_post_count = $forumCtx->countTotalUserPosts($userInfo);
$profileStats->comments_count = $msz->getComments()->countPosts(userInfo: $userInfo, deleted: false); $profileStats->comments_count = $msz->getComments()->countPosts(userInfo: $userInfo, deleted: false);
if(!$viewingAsGuest) { if(!$viewingAsGuest) {
Template::set('profile_warnings', $usersCtx->getWarnings()->getWarningsWithDefaultBacklog($userInfo)); Template::set('profile_warnings', iterator_to_array($usersCtx->getWarnings()->getWarningsWithDefaultBacklog($userInfo)));
if((!$isBanned || $canEdit)) { if((!$isBanned || $canEdit)) {
$unranked = $cfg->getValues([ $unranked = $cfg->getValues([

View file

@ -116,7 +116,7 @@ if($isVerifiedRequest && !empty($_POST['current_password'])) {
if($_SERVER['REQUEST_METHOD'] === 'POST' && $isVerifiedRequest) if($_SERVER['REQUEST_METHOD'] === 'POST' && $isVerifiedRequest)
$userInfo = $users->getUser($userInfo->getId(), 'id'); $userInfo = $users->getUser($userInfo->getId(), 'id');
$userRoles = $roles->getRoles(userInfo: $userInfo); $userRoles = iterator_to_array($roles->getRoles(userInfo: $userInfo));
Template::render('settings.account', [ Template::render('settings.account', [
'errors' => $errors, 'errors' => $errors,

View file

@ -15,8 +15,8 @@ $auditLog = $msz->getAuditLog();
$loginHistoryPagination = new Pagination($loginAttempts->countAttempts(userInfo: $currentUser), 5, 'hp'); $loginHistoryPagination = new Pagination($loginAttempts->countAttempts(userInfo: $currentUser), 5, 'hp');
$accountLogPagination = new Pagination($auditLog->countLogs(userInfo: $currentUser), 10, 'ap'); $accountLogPagination = new Pagination($auditLog->countLogs(userInfo: $currentUser), 10, 'ap');
$loginHistory = $loginAttempts->getAttempts(userInfo: $currentUser, pagination: $loginHistoryPagination); $loginHistory = iterator_to_array($loginAttempts->getAttempts(userInfo: $currentUser, pagination: $loginHistoryPagination));
$auditLogs = $auditLog->getLogs(userInfo: $currentUser, pagination: $accountLogPagination); $auditLogs = iterator_to_array($auditLog->getLogs(userInfo: $currentUser, pagination: $accountLogPagination));
Template::render('settings.logs', [ Template::render('settings.logs', [
'login_history_list' => $loginHistory, 'login_history_list' => $loginHistory,

View file

@ -61,7 +61,7 @@ class AuditLog {
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
IPAddress|string|null $remoteAddr = null, IPAddress|string|null $remoteAddr = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
if($remoteAddr instanceof IPAddress) if($remoteAddr instanceof IPAddress)
@ -98,13 +98,8 @@ class AuditLog {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult();
$logs = [];
while($result->next()) return $stmt->getResult()->getIterator(AuditLogInfo::fromResult(...));
$logs[] = new AuditLogInfo($result);
return $logs;
} }
public function createLog( public function createLog(

View file

@ -7,20 +7,24 @@ use Index\Data\IDbResult;
use Index\Net\IPAddress; use Index\Net\IPAddress;
class AuditLogInfo { class AuditLogInfo {
private ?string $userId; public function __construct(
private string $action; private ?string $userId,
private array $params; private string $action,
private int $created; private array $params,
private string $address; private int $created,
private string $country; private string $address,
private string $country,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): AuditLogInfo {
$this->userId = $result->isNull(0) ? null : (string)$result->getInteger(0); return new AuditLogInfo(
$this->action = $result->getString(1); userId: $result->getStringOrNull(0),
$this->params = json_decode($result->getString(2)); action: $result->getString(1),
$this->created = $result->getInteger(3); params: json_decode($result->getString(2)),
$this->address = $result->isNull(4) ? '::1' : $result->getString(4); // apparently this being NULL is possible? created: $result->getInteger(3),
$this->country = $result->getString(5); address: $result->isNull(4) ? '::1' : $result->getString(4), // apparently this being NULL is possible?
country: $result->getString(5),
);
} }
public function hasUserId(): bool { public function hasUserId(): bool {

View file

@ -7,22 +7,26 @@ use Index\Net\IPAddress;
use Misuzu\ClientInfo; use Misuzu\ClientInfo;
class LoginAttemptInfo { class LoginAttemptInfo {
private ?string $userId; public function __construct(
private bool $success; private ?string $userId,
private string $remoteAddr; private bool $success,
private string $countryCode; private string $remoteAddr,
private int $created; private string $countryCode,
private string $userAgent; private int $created,
private string $clientInfo; private string $userAgent,
private string $clientInfo,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): LoginAttemptInfo {
$this->userId = $result->isNull(0) ? null : (string)$result->getInteger(0); return new LoginAttemptInfo(
$this->success = $result->getInteger(1) !== 0; userId: $result->getStringOrNull(0),
$this->remoteAddr = $result->getString(2); success: $result->getBoolean(1),
$this->countryCode = $result->getString(3); remoteAddr: $result->getString(2),
$this->created = $result->getInteger(4); countryCode: $result->getString(3),
$this->userAgent = $result->getString(5); created: $result->getInteger(4),
$this->clientInfo = $result->getString(6); userAgent: $result->getString(5),
clientInfo: $result->getString(6),
);
} }
public function hasUserId(): bool { public function hasUserId(): bool {

View file

@ -83,7 +83,7 @@ class LoginAttempts {
IPAddress|string|null $remoteAddr = null, IPAddress|string|null $remoteAddr = null,
TimeSpan|int|null $timeRange = null, TimeSpan|int|null $timeRange = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
if($remoteAddr instanceof IPAddress) if($remoteAddr instanceof IPAddress)
@ -127,13 +127,7 @@ class LoginAttempts {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(LoginAttemptInfo::fromResult(...));
$attempts = [];
while($result->next())
$attempts[] = new LoginAttemptInfo($result);
return $attempts;
} }
public function recordAttempt( public function recordAttempt(

View file

@ -7,32 +7,36 @@ use Index\Net\IPAddress;
use Misuzu\ClientInfo; use Misuzu\ClientInfo;
class SessionInfo { class SessionInfo {
private string $id; public function __construct(
private string $userId; private string $id,
private string $token; private string $userId,
private string $firstRemoteAddr; private string $token,
private ?string $lastRemoteAddr; private string $firstRemoteAddr,
private string $userAgent; private ?string $lastRemoteAddr,
private string $clientInfo; private string $userAgent,
private string $countryCode; private string $clientInfo,
private int $expires; private string $countryCode,
private bool $bumpExpires; private int $expires,
private int $created; private bool $bumpExpires,
private ?int $lastActive; private int $created,
private ?int $lastActive,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): SessionInfo {
$this->id = (string)$result->getInteger(0); return new SessionInfo(
$this->userId = (string)$result->getInteger(1); id: $result->getString(0),
$this->token = $result->getString(2); userId: $result->getString(1),
$this->firstRemoteAddr = $result->getString(3); token: $result->getString(2),
$this->lastRemoteAddr = $result->isNull(4) ? null : $result->getString(4); firstRemoteAddr: $result->getString(3),
$this->userAgent = $result->getString(5); lastRemoteAddr: $result->getStringOrNull(4),
$this->clientInfo = $result->getString(6); userAgent: $result->getString(5),
$this->countryCode = $result->getString(7); clientInfo: $result->getString(6),
$this->expires = $result->getInteger(8); countryCode: $result->getString(7),
$this->bumpExpires = $result->getInteger(9) !== 0; expires: $result->getInteger(8),
$this->created = $result->getInteger(10); bumpExpires: $result->getBoolean(9),
$this->lastActive = $result->isNull(11) ? null : $result->getInteger(11); created: $result->getInteger(10),
lastActive: $result->getIntegerOrNull(11),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -58,7 +58,7 @@ class Sessions {
public function getSessions( public function getSessions(
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -85,13 +85,7 @@ class Sessions {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(SessionInfo::fromResult(...));
$sessions = [];
while($result->next())
$sessions[] = new SessionInfo($result);
return $sessions;
} }
public function getSession( public function getSession(
@ -124,7 +118,7 @@ class Sessions {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Session not found.'); throw new RuntimeException('Session not found.');
return new SessionInfo($result); return SessionInfo::fromResult($result);
} }
public function createSession( public function createSession(

View file

@ -5,20 +5,24 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ChangeInfo { class ChangeInfo {
private string $id; public function __construct(
private ?string $userId; private string $id,
private int $action; private ?string $userId,
private int $created; private int $action,
private string $summary; private int $created,
private string $body; private string $summary,
private string $body,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ChangeInfo {
$this->id = (string)$result->getInteger(0); return new ChangeInfo(
$this->userId = $result->isNull(1) ? null : (string)$result->getInteger(1); id: $result->getString(0),
$this->action = $result->getInteger(2); userId: $result->getStringOrNull(1),
$this->created = $result->getInteger(3); action: $result->getInteger(2),
$this->summary = $result->getString(4); created: $result->getInteger(3),
$this->body = $result->getString(5); summary: $result->getString(4),
body: $result->getString(5),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -121,7 +121,7 @@ class Changelog {
DateTime|int|null $dateTime = null, DateTime|int|null $dateTime = null,
?array $tags = null, ?array $tags = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
if($dateTime instanceof DateTime) if($dateTime instanceof DateTime)
@ -169,13 +169,7 @@ class Changelog {
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ChangeInfo::fromResult(...));
$changes = [];
while($result->next())
$changes[] = new ChangeInfo($result);
return $changes;
} }
public function getChange(string $changeId): ChangeInfo { public function getChange(string $changeId): ChangeInfo {
@ -187,7 +181,7 @@ class Changelog {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No tag with that ID exists.'); throw new RuntimeException('No tag with that ID exists.');
return new ChangeInfo($result); return ChangeInfo::fromResult($result);
} }
public function createChange( public function createChange(

View file

@ -73,15 +73,16 @@ final class ChangelogRoutes extends RouteHandler {
if(!$pagination->hasValidOffset()) if(!$pagination->hasValidOffset())
return 404; return 404;
$changeInfos = $this->changelog->getChanges(userInfo: $filterUser, dateTime: $filterDate, tags: $filterTags, pagination: $pagination);
if(empty($changeInfos))
return 404;
$changes = []; $changes = [];
$changeInfos = $this->changelog->getChanges(userInfo: $filterUser, dateTime: $filterDate, tags: $filterTags, pagination: $pagination);
$commentsCategoryName = null;
foreach($changeInfos as $changeInfo) { foreach($changeInfos as $changeInfo) {
$userInfo = $changeInfo->hasUserId() ? $this->usersCtx->getUserInfo($changeInfo->getUserId()) : null; $userInfo = $changeInfo->hasUserId() ? $this->usersCtx->getUserInfo($changeInfo->getUserId()) : null;
if($commentsCategoryName === null)
$commentsCategoryName = $changeInfo->getCommentsCategoryName();
$changes[] = [ $changes[] = [
'change' => $changeInfo, 'change' => $changeInfo,
'user' => $userInfo, 'user' => $userInfo,
@ -89,13 +90,16 @@ final class ChangelogRoutes extends RouteHandler {
]; ];
} }
if(empty($changes))
return 404;
return Template::renderRaw('changelog.index', [ return Template::renderRaw('changelog.index', [
'changelog_infos' => $changes, 'changelog_infos' => $changes,
'changelog_date' => $filterDate, 'changelog_date' => $filterDate,
'changelog_user' => $filterUser, 'changelog_user' => $filterUser,
'changelog_tags' => $filterTags, 'changelog_tags' => $filterTags,
'changelog_pagination' => $pagination, 'changelog_pagination' => $pagination,
'comments_info' => empty($filterDate) ? null : $this->getCommentsInfo($changeInfos[0]->getCommentsCategoryName()), 'comments_info' => empty($filterDate) && $commentsCategoryName !== null ? null : $this->getCommentsInfo($commentsCategoryName),
]); ]);
} }

View file

@ -46,7 +46,7 @@ class Comments {
public function getCategories( public function getCategories(
UserInfo|string|null $owner = null, UserInfo|string|null $owner = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($owner instanceof UserInfo) if($owner instanceof UserInfo)
$owner = $owner->getId(); $owner = $owner->getId();
@ -72,13 +72,7 @@ class Comments {
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(CommentsCategoryInfo::fromResult(...));
$categories = [];
while($result->next())
$categories[] = new CommentsCategoryInfo($result);
return $categories;
} }
public function getCategory( public function getCategory(
@ -124,7 +118,7 @@ class Comments {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Comments category not found.'); throw new RuntimeException('Comments category not found.');
return new CommentsCategoryInfo($result); return CommentsCategoryInfo::fromResult($result);
} }
public function checkCategoryNameExists(string $name): bool { public function checkCategoryNameExists(string $name): bool {
@ -276,7 +270,7 @@ class Comments {
?bool $deleted = null, ?bool $deleted = null,
bool $includeRepliesCount = false, bool $includeRepliesCount = false,
bool $includeVotesCount = false bool $includeVotesCount = false
): array { ): iterable {
if($categoryInfo instanceof CommentsCategoryInfo) if($categoryInfo instanceof CommentsCategoryInfo)
$categoryInfo = $categoryInfo->getId(); $categoryInfo = $categoryInfo->getId();
if($parentInfo instanceof CommentsPostInfo) if($parentInfo instanceof CommentsPostInfo)
@ -330,13 +324,7 @@ class Comments {
$stmt->addParameter(++$args, $userInfo instanceof UserInfo ? $userInfo->getId() : $userInfo); $stmt->addParameter(++$args, $userInfo instanceof UserInfo ? $userInfo->getId() : $userInfo);
$stmt->execute(); $stmt->execute();
$posts = []; return $stmt->getResult()->getIterator(fn($result) => CommentsPostInfo::fromResult($result, $includeRepliesCount, $includeVotesCount));
$result = $stmt->getResult();
while($result->next())
$posts[] = new CommentsPostInfo($result, $includeRepliesCount, $includeVotesCount);
return $posts;
} }
public function getPost( public function getPost(
@ -362,7 +350,7 @@ class Comments {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No comment with that ID exists.'); throw new RuntimeException('No comment with that ID exists.');
return new CommentsPostInfo($result, $includeRepliesCount, $includeVotesCount); return CommentsPostInfo::fromResult($result, $includeRepliesCount, $includeVotesCount);
} }
public function createPost( public function createPost(

View file

@ -6,20 +6,24 @@ use Index\Data\IDbResult;
use Misuzu\Users\UserInfo; use Misuzu\Users\UserInfo;
class CommentsCategoryInfo { class CommentsCategoryInfo {
private string $id; public function __construct(
private string $name; private string $id,
private ?string $ownerId; private string $name,
private int $created; private ?string $ownerId,
private ?int $locked; private int $created,
private int $comments; private ?int $locked,
private int $comments,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): CommentsCategoryInfo {
$this->id = (string)$result->getInteger(0); return new CommentsCategoryInfo(
$this->name = $result->getString(1); id: $result->getString(0),
$this->ownerId = $result->isNull(2) ? null : (string)$result->getInteger(2); name: $result->getString(1),
$this->created = $result->getInteger(3); ownerId: $result->getStringOrNull(2),
$this->locked = $result->isNull(4) ? null : $result->getInteger(4); created: $result->getInteger(3),
$this->comments = $result->getInteger(5); locked: $result->getIntegerOrNull(4),
comments: $result->getInteger(5),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -5,47 +5,53 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class CommentsPostInfo { class CommentsPostInfo {
private string $id;
private string $categoryId;
private ?string $userId;
private ?string $replyingTo;
private string $body;
private int $created;
private ?int $pinned;
private ?int $updated;
private ?int $deleted;
private int $replies;
private int $votesTotal;
private int $votesPositive;
private int $votesNegative;
public function __construct( public function __construct(
private string $id,
private string $categoryId,
private ?string $userId,
private ?string $replyingTo,
private string $body,
private int $created,
private ?int $pinned,
private ?int $updated,
private ?int $deleted,
private int $replies,
private int $votesTotal,
private int $votesPositive,
private int $votesNegative,
) {}
public static function fromResult(
IDbResult $result, IDbResult $result,
bool $includeRepliesCount = false, bool $includeRepliesCount = false,
bool $includeVotesCount = false bool $includeVotesCount = false
) { ): CommentsPostInfo {
$args = 0; $args = [];
$this->id = (string)$result->getInteger($args); $count = 0;
$this->categoryId = (string)$result->getInteger(++$args);
$this->userId = $result->isNull(++$args) ? null : (string)$result->getInteger($args);
$this->replyingTo = $result->isNull(++$args) ? null : (string)$result->getInteger($args);
$this->body = $result->getString(++$args);
$this->created = $result->getInteger(++$args);
$this->pinned = $result->isNull(++$args) ? null : $result->getInteger($args);
$this->updated = $result->isNull(++$args) ? null : $result->getInteger($args);
$this->deleted = $result->isNull(++$args) ? null : $result->getInteger($args);
$this->replies = $includeRepliesCount ? $result->getInteger(++$args) : 0; $args[] = $result->getString($count); // id
$args[] = $result->getString(++$count); // categoryId
$args[] = $result->getStringOrNull(++$count); // userId
$args[] = $result->getStringOrNull(++$count); // replyingTo
$args[] = $result->getString(++$count); // body
$args[] = $result->getInteger(++$count); // created
$args[] = $result->getIntegerOrNull(++$count); // pinned
$args[] = $result->getIntegerOrNull(++$count); // updated
$args[] = $result->getIntegerOrNull(++$count); // deleted
$args[] = $includeRepliesCount ? $result->getInteger(++$count) : 0;
if($includeVotesCount) { if($includeVotesCount) {
$this->votesTotal = $result->getInteger(++$args); $args[] = $result->getInteger(++$count); // votesTotal
$this->votesPositive = $result->getInteger(++$args); $args[] = $result->getInteger(++$count); // votesPositive
$this->votesNegative = $result->getInteger(++$args); $args[] = $result->getInteger(++$count); // votesNegative
} else { } else {
$this->votesTotal = 0; $args[] = 0;
$this->votesPositive = 0; $args[] = 0;
$this->votesNegative = 0; $args[] = 0;
} }
return new CommentsPostInfo(...$args);
} }
public function getId(): string { public function getId(): string {

View file

@ -5,14 +5,18 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class CounterInfo { class CounterInfo {
private string $name; public function __construct(
private int $value; private string $name,
private int $updated; private int $value,
private int $updated,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): CounterInfo {
$this->name = $result->getString(0); return new CounterInfo(
$this->value = $result->getInteger(1); name: $result->getString(0),
$this->updated = $result->getInteger(2); value: $result->getInteger(1),
updated: $result->getInteger(2),
);
} }
public function getName(): string { public function getName(): string {

View file

@ -25,7 +25,7 @@ class Counters {
public function getCounters( public function getCounters(
?string $orderBy = null, ?string $orderBy = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
$hasOrderBy = $orderBy !== null; $hasOrderBy = $orderBy !== null;
$hasPagination = $pagination !== null; $hasPagination = $pagination !== null;
@ -47,13 +47,7 @@ class Counters {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(CounterInfo::fromResult(...));
$counters = [];
while($result->next())
$counters[] = new CounterInfo($result);
return $counters;
} }
public function get(array|string $names): array|int { public function get(array|string $names): array|int {

View file

@ -5,16 +5,20 @@ use Stringable;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class EmoteInfo implements Stringable { class EmoteInfo implements Stringable {
private string $id; public function __construct(
private int $order; private string $id,
private int $rank; private int $order,
private string $url; private int $rank,
private string $url,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): EmoteInfo {
$this->id = (string)$result->getInteger(0); return new EmoteInfo(
$this->order = $result->getInteger(1); id: $result->getString(0),
$this->rank = $result->getInteger(2); order: $result->getInteger(1),
$this->url = $result->getString(3); rank: $result->getInteger(2),
url: $result->getString(3),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -5,14 +5,18 @@ use Stringable;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class EmoteStringInfo implements Stringable { class EmoteStringInfo implements Stringable {
private string $emoteId; public function __construct(
private int $order; private string $emoteId,
private string $string; private int $order,
private string $string,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): EmoteStringInfo {
$this->emoteId = (string)$result->getInteger(0); return new EmoteStringInfo(
$this->order = $result->getInteger(1); emoteId: $result->getString(0),
$this->string = $result->getString(2); order: $result->getInteger(1),
string: $result->getString(2),
);
} }
public function getEmoteId(): string { public function getEmoteId(): string {

View file

@ -31,7 +31,7 @@ class Emotes {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No emoticon with that ID exists.'); throw new RuntimeException('No emoticon with that ID exists.');
return new EmoteInfo($result); return EmoteInfo::fromResult($result);
} }
public static function emoteOrderOptions(): array { public static function emoteOrderOptions(): array {
@ -43,7 +43,7 @@ class Emotes {
?int $minRank = null, ?int $minRank = null,
?string $orderBy = null, ?string $orderBy = null,
?bool $reverse = null ?bool $reverse = null
): array { ): iterable {
$hasMinRank = $minRank !== null; $hasMinRank = $minRank !== null;
$hasOrderBy = $orderBy !== null; $hasOrderBy = $orderBy !== null;
$hasReverse = $reverse !== null; $hasReverse = $reverse !== null;
@ -65,13 +65,7 @@ class Emotes {
$stmt->addParameter(1, $minRank); $stmt->addParameter(1, $minRank);
$stmt->execute(); $stmt->execute();
$emotes = []; return $stmt->getResult()->getIterator(EmoteInfo::fromResult(...));
$result = $stmt->getResult();
while($result->next())
$emotes[] = new EmoteInfo($result);
return $emotes;
} }
private static function checkEmoteUrlInternal(string $url): string { private static function checkEmoteUrlInternal(string $url): string {
@ -156,7 +150,7 @@ class Emotes {
$stmt->execute(); $stmt->execute();
} }
public function getEmoteStrings(EmoteInfo|string $infoOrId): array { public function getEmoteStrings(EmoteInfo|string $infoOrId): iterable {
if($infoOrId instanceof EmoteInfo) if($infoOrId instanceof EmoteInfo)
$infoOrId = $infoOrId->getId(); $infoOrId = $infoOrId->getId();
@ -164,13 +158,7 @@ class Emotes {
$stmt->addParameter(1, $infoOrId); $stmt->addParameter(1, $infoOrId);
$stmt->execute(); $stmt->execute();
$strings = []; return $stmt->getResult()->getIterator(EmoteStringInfo::fromResult(...));
$result = $stmt->getResult();
while($result->next())
$strings[] = new EmoteStringInfo($result);
return $strings;
} }
private static function checkEmoteStringInternal(string $string): string { private static function checkEmoteStringInternal(string $string): string {

View file

@ -21,10 +21,13 @@ class ForumCategories {
} }
public static function convertCategoryListToTree( public static function convertCategoryListToTree(
array $catInfos, iterable $catInfos,
ForumCategoryInfo|string|null $parentInfo = null, ForumCategoryInfo|string|null $parentInfo = null,
?Colour $colour = null ?Colour $colour = null
): array { ): array {
if(!is_array($catInfos))
$catInfos = iterator_to_array($catInfos);
$colour ??= Colour::none(); $colour ??= Colour::none();
$tree = []; $tree = [];
$predicate = $parentInfo $predicate = $parentInfo
@ -103,7 +106,7 @@ class ForumCategories {
?bool $hidden = null, ?bool $hidden = null,
bool $asTree = false, bool $asTree = false,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
$isRootParent = false; $isRootParent = false;
$hasParentInfo = $parentInfo !== false; $hasParentInfo = $parentInfo !== false;
$hasType = $type !== null; $hasType = $type !== null;
@ -155,11 +158,7 @@ class ForumCategories {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); $cats = $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
$cats = [];
while($result->next())
$cats[] = new ForumCategoryInfo($result);
if($asTree) if($asTree)
$cats = self::convertCategoryListToTree($cats); $cats = self::convertCategoryListToTree($cats);
@ -216,7 +215,7 @@ class ForumCategories {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Forum category info not found.'); throw new RuntimeException('Forum category info not found.');
return new ForumCategoryInfo($result); return ForumCategoryInfo::fromResult($result);
} }
public function updateCategory( public function updateCategory(
@ -261,7 +260,7 @@ class ForumCategories {
public function getCategoryAncestry( public function getCategoryAncestry(
ForumCategoryInfo|ForumTopicInfo|ForumPostInfo|string $categoryInfo ForumCategoryInfo|ForumTopicInfo|ForumPostInfo|string $categoryInfo
): array { ): iterable {
if($categoryInfo instanceof ForumCategoryInfo) if($categoryInfo instanceof ForumCategoryInfo)
$categoryInfo = $categoryInfo->getId(); $categoryInfo = $categoryInfo->getId();
elseif($categoryInfo instanceof ForumTopicInfo || $categoryInfo instanceof ForumPostInfo) elseif($categoryInfo instanceof ForumTopicInfo || $categoryInfo instanceof ForumPostInfo)
@ -277,13 +276,7 @@ class ForumCategories {
$stmt->addParameter(1, $categoryInfo); $stmt->addParameter(1, $categoryInfo);
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
$cats = [];
while($result->next())
$cats[] = new ForumCategoryInfo($result);
return $cats;
} }
public function getCategoryChildren( public function getCategoryChildren(
@ -291,7 +284,7 @@ class ForumCategories {
bool $includeSelf = false, bool $includeSelf = false,
?bool $hidden = null, ?bool $hidden = null,
bool $asTree = false bool $asTree = false
): array { ): iterable {
if($parentInfo instanceof ForumCategoryInfo) if($parentInfo instanceof ForumCategoryInfo)
$parentInfo = $parentInfo->getId(); $parentInfo = $parentInfo->getId();
@ -319,11 +312,7 @@ class ForumCategories {
$stmt->addParameter(++$args, $parentInfo); $stmt->addParameter(++$args, $parentInfo);
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); $cats = $stmt->getResult()->getIterator(ForumCategoryInfo::fromResult(...));
$cats = [];
while($result->next())
$cats[] = new ForumCategoryInfo($result);
if($asTree) if($asTree)
$cats = self::convertCategoryListToTree($cats, $parentInfo); $cats = self::convertCategoryListToTree($cats, $parentInfo);

View file

@ -26,38 +26,42 @@ class ForumCategoryInfo {
self::TYPE_DISCUSSION, self::TYPE_DISCUSSION,
]; ];
private string $id; public function __construct(
private int $order; private string $id,
private ?string $parentId; private int $order,
private string $name; private ?string $parentId,
private int $type; private string $name,
private ?string $desc; private int $type,
private ?string $icon; private ?string $desc,
private ?int $colour; private ?string $icon,
private ?string $link; private ?int $colour,
private ?int $clicks; private ?string $link,
private int $created; private ?int $clicks,
private bool $archived; private int $created,
private bool $hidden; private bool $archived,
private int $topicsCount; private bool $hidden,
private int $postsCount; private int $topicsCount,
private int $postsCount,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ForumCategoryInfo {
$this->id = (string)$result->getInteger(0); return new ForumCategoryInfo(
$this->order = $result->getInteger(1); id: $result->getString(0),
$this->parentId = $result->isNull(2) ? null : (string)$result->getInteger(2); order: $result->getInteger(1),
$this->name = $result->getString(3); parentId: $result->getStringOrNull(2),
$this->type = $result->getInteger(4); name: $result->getString(3),
$this->desc = $result->isNull(5) ? null : $result->getString(5); type: $result->getInteger(4),
$this->icon = $result->isNull(6) ? null : $result->getString(6); desc: $result->getStringOrNull(5),
$this->colour = $result->isNull(7) ? null : $result->getInteger(7); icon: $result->getStringOrNull(6),
$this->link = $result->isNull(8) ? null : $result->getString(8); colour: $result->getIntegerOrNull(7),
$this->clicks = $result->isNull(9) ? null : $result->getInteger(9); link: $result->getStringOrNull(8),
$this->created = $result->getInteger(10); clicks: $result->getIntegerOrNull(9),
$this->archived = $result->getInteger(11) !== 0; created: $result->getInteger(10),
$this->hidden = $result->getInteger(12) !== 0; archived: $result->getBoolean(11),
$this->topicsCount = $result->getInteger(13); hidden: $result->getBoolean(12),
$this->postsCount = $result->getInteger(14); topicsCount: $result->getInteger(13),
postsCount: $result->getInteger(14),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -7,30 +7,34 @@ use Index\Net\IPAddress;
use Misuzu\Parsers\Parser; use Misuzu\Parsers\Parser;
class ForumPostInfo { class ForumPostInfo {
private string $id; public function __construct(
private string $topicId; private string $id,
private string $categoryId; private string $topicId,
private ?string $userId; private string $categoryId,
private string $remoteAddr; private ?string $userId,
private string $body; private string $remoteAddr,
private int $parser; private string $body,
private bool $displaySignature; private int $parser,
private int $created; private bool $displaySignature,
private ?int $edited; private int $created,
private ?int $deleted; private ?int $edited,
private ?int $deleted,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ForumPostInfo {
$this->id = (string)$result->getInteger(0); return new ForumPostInfo(
$this->topicId = (string)$result->getInteger(1); id: $result->getString(0),
$this->categoryId = (string)$result->getInteger(2); topicId: $result->getString(1),
$this->userId = $result->isNull(3) ? null : (string)$result->getInteger(3); categoryId: $result->getString(2),
$this->remoteAddr = $result->getString(4); userId: $result->getStringOrNull(3),
$this->body = $result->getString(5); remoteAddr: $result->getString(4),
$this->parser = $result->getInteger(6); body: $result->getString(5),
$this->displaySignature = $result->getInteger(7) !== 0; parser: $result->getInteger(6),
$this->created = $result->getInteger(8); displaySignature: $result->getBoolean(7),
$this->edited = $result->isNull(9) ? null : $result->getInteger(9); created: $result->getInteger(8),
$this->deleted = $result->isNull(10) ? null : $result->getInteger(10); edited: $result->getIntegerOrNull(9),
deleted: $result->getIntegerOrNull(10),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -84,7 +84,7 @@ class ForumPosts {
?array $searchQuery = null, ?array $searchQuery = null,
?bool $deleted = null, ?bool $deleted = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
// remove this hack when search server // remove this hack when search server
$hasSearchQuery = $searchQuery !== null; $hasSearchQuery = $searchQuery !== null;
$doSearchOrder = false; $doSearchOrder = false;
@ -189,13 +189,7 @@ class ForumPosts {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ForumPostInfo::fromResult(...));
$posts = [];
while($result->next())
$posts[] = new ForumPostInfo($result);
return $posts;
} }
public function getPost( public function getPost(
@ -267,7 +261,7 @@ class ForumPosts {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Forum post not found.'); throw new RuntimeException('Forum post not found.');
return new ForumPostInfo($result); return ForumPostInfo::fromResult($result);
} }
public function createPost( public function createPost(

View file

@ -17,32 +17,36 @@ class ForumTopicInfo {
'global' => self::TYPE_GLOBAL, 'global' => self::TYPE_GLOBAL,
]; ];
private string $id; public function __construct(
private string $categoryId; private string $id,
private ?string $userId; private string $categoryId,
private int $type; private ?string $userId,
private string $title; private int $type,
private int $postsCount; private string $title,
private int $deletedPostsCount; private int $postsCount,
private int $viewsCount; private int $deletedPostsCount,
private int $created; private int $viewsCount,
private int $bumped; private int $created,
private ?int $deleted; private int $bumped,
private ?int $locked; private ?int $deleted,
private ?int $locked,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ForumTopicInfo {
$this->id = (string)$result->getInteger(0); return new ForumTopicInfo(
$this->categoryId = (string)$result->getInteger(1); id: $result->getString(0),
$this->userId = $result->isNull(2) ? null : (string)$result->getInteger(2); categoryId: $result->getString(1),
$this->type = $result->getInteger(3); userId: $result->getStringOrNull(2),
$this->title = $result->getString(4); type: $result->getInteger(3),
$this->viewsCount = $result->getInteger(5); title: $result->getString(4),
$this->created = $result->getInteger(6); viewsCount: $result->getInteger(5),
$this->bumped = $result->getInteger(7); created: $result->getInteger(6),
$this->deleted = $result->isNull(8) ? null : $result->getInteger(8); bumped: $result->getInteger(7),
$this->locked = $result->isNull(9) ? null : $result->getInteger(9); deleted: $result->getIntegerOrNull(8),
$this->postsCount = $result->getInteger(10); locked: $result->getIntegerOrNull(9),
$this->deletedPostsCount = $result->getInteger(11); postsCount: $result->getInteger(10),
deletedPostsCount: $result->getInteger(11),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -5,16 +5,20 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ForumTopicRedirectInfo { class ForumTopicRedirectInfo {
private string $topicId; public function __construct(
private ?string $userId; private string $topicId,
private string $link; private ?string $userId,
private int $created; private string $link,
private int $created,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ForumTopicRedirectInfo {
$this->topicId = (string)$result->getInteger(0); return new ForumTopicRedirectInfo(
$this->userId = $result->isNull(1) ? null : (string)$result->getInteger(1); topicId: $result->getString(0),
$this->link = $result->getString(2); userId: $result->getStringOrNull(1),
$this->created = $result->getInteger(3); link: $result->getString(2),
created: $result->getInteger(3),
);
} }
public function getTopicId(): string { public function getTopicId(): string {

View file

@ -38,7 +38,7 @@ class ForumTopicRedirects {
public function getTopicRedirects( public function getTopicRedirects(
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -61,13 +61,7 @@ class ForumTopicRedirects {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ForumTopicRedirectInfo::fromResult(...));
$redirs = [];
while($result->next())
$redirs[] = new ForumTopicRedirectInfo($result);
return $redirs;
} }
public function hasTopicRedirect(ForumTopicInfo|string $topicInfo): bool { public function hasTopicRedirect(ForumTopicInfo|string $topicInfo): bool {
@ -97,7 +91,7 @@ class ForumTopicRedirects {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Could not find that forum topic redirect.'); throw new RuntimeException('Could not find that forum topic redirect.');
return new ForumTopicRedirectInfo($result); return ForumTopicRedirectInfo::fromResult($result);
} }
public function createTopicRedirect( public function createTopicRedirect(

View file

@ -91,7 +91,7 @@ class ForumTopics {
?bool $global = null, ?bool $global = null,
?bool $deleted = null, ?bool $deleted = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
// remove this hack when search server // remove this hack when search server
$hasSearchQuery = $searchQuery !== null; $hasSearchQuery = $searchQuery !== null;
$hasAfterTopicId = false; $hasAfterTopicId = false;
@ -194,13 +194,7 @@ class ForumTopics {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ForumTopicInfo::fromResult(...));
$topics = [];
while($result->next())
$topics[] = new ForumTopicInfo($result);
return $topics;
} }
public function getTopic( public function getTopic(
@ -239,7 +233,7 @@ class ForumTopics {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Forum topic not found.'); throw new RuntimeException('Forum topic not found.');
return new ForumTopicInfo($result); return ForumTopicInfo::fromResult($result);
} }
public function createTopic( public function createTopic(

View file

@ -43,7 +43,7 @@ class HomeRoutes extends RouteHandler {
]); ]);
} }
private function getOnlineUsers(): array { private function getOnlineUsers(): iterable {
return $this->usersCtx->getUsers()->getUsers( return $this->usersCtx->getUsers()->getUsers(
lastActiveInMinutes: 5, lastActiveInMinutes: 5,
deleted: false, deleted: false,
@ -164,9 +164,9 @@ class HomeRoutes extends RouteHandler {
public function getHome() { public function getHome() {
$stats = $this->getStats(); $stats = $this->getStats();
$onlineUserInfos = $this->getOnlineUsers(); $onlineUserInfos = iterator_to_array($this->getOnlineUsers());
$featuredNews = $this->getFeaturedNewsPosts(5, true); $featuredNews = $this->getFeaturedNewsPosts(5, true);
$changelog = $this->changelog->getChanges(pagination: new Pagination(10)); $changelog = iterator_to_array($this->changelog->getChanges(pagination: new Pagination(10)));
$stats['users:online:recent'] = count($onlineUserInfos); $stats['users:online:recent'] = count($onlineUserInfos);

View file

@ -6,32 +6,36 @@ use Index\Data\IDbResult;
use Misuzu\Parsers\Parser; use Misuzu\Parsers\Parser;
class MessageInfo { class MessageInfo {
private string $messageId; public function __construct(
private string $ownerId; private string $messageId,
private ?string $authorId; private string $ownerId,
private ?string $recipientId; private ?string $authorId,
private ?string $replyTo; private ?string $recipientId,
private string $title; private ?string $replyTo,
private string $body; private string $title,
private int $parser; private string $body,
private int $created; private int $parser,
private ?int $sent; private int $created,
private ?int $read; private ?int $sent,
private ?int $deleted; private ?int $read,
private ?int $deleted,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): MessageInfo {
$this->messageId = $result->getString(0); return new MessageInfo(
$this->ownerId = $result->getString(1); messageId: $result->getString(0),
$this->authorId = $result->getStringOrNull(2); ownerId: $result->getString(1),
$this->recipientId = $result->getStringOrNull(3); authorId: $result->getStringOrNull(2),
$this->replyTo = $result->getStringOrNull(4); recipientId: $result->getStringOrNull(3),
$this->title = $result->getString(5); replyTo: $result->getStringOrNull(4),
$this->body = $result->getString(6); title: $result->getString(5),
$this->parser = $result->getInteger(7); body: $result->getString(6),
$this->created = $result->getInteger(8); parser: $result->getInteger(7),
$this->sent = $result->getIntegerOrNull(9); created: $result->getInteger(8),
$this->read = $result->getIntegerOrNull(10); sent: $result->getIntegerOrNull(9),
$this->deleted = $result->getIntegerOrNull(11); read: $result->getIntegerOrNull(10),
deleted: $result->getIntegerOrNull(11),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -92,7 +92,7 @@ class MessagesDatabase {
?bool $read = null, ?bool $read = null,
?bool $deleted = null, ?bool $deleted = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
$hasOwnerInfo = $ownerInfo !== null; $hasOwnerInfo = $ownerInfo !== null;
$hasAuthorInfo = $authorInfo !== null; $hasAuthorInfo = $authorInfo !== null;
$hasRecipientInfo = $recipientInfo !== null; $hasRecipientInfo = $recipientInfo !== null;
@ -153,13 +153,7 @@ class MessagesDatabase {
$stmt->execute(); $stmt->execute();
$infos = []; return $stmt->getResult()->getIterator(MessageInfo::fromResult(...));
$result = $stmt->getResult();
while($result->next())
$infos[] = new MessageInfo($result);
return $infos;
} }
public function getMessageInfo( public function getMessageInfo(
@ -183,7 +177,7 @@ class MessagesDatabase {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Message not found.'); throw new RuntimeException('Message not found.');
return new MessageInfo($result); return MessageInfo::fromResult($result);
} }
public function createMessage( public function createMessage(

View file

@ -41,7 +41,7 @@ class News {
public function getCategories( public function getCategories(
?bool $hidden = null, ?bool $hidden = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
$hasHidden = $hidden !== null; $hasHidden = $hidden !== null;
$hasPagination = $pagination !== null; $hasPagination = $pagination !== null;
@ -61,13 +61,7 @@ class News {
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(NewsCategoryInfo::fromResult(...));
$categories = [];
while($result->next())
$categories[] = new NewsCategoryInfo($result);
return $categories;
} }
public function getCategory( public function getCategory(
@ -107,7 +101,7 @@ class News {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('News category not found.'); throw new RuntimeException('News category not found.');
return new NewsCategoryInfo($result); return NewsCategoryInfo::fromResult($result);
} }
public function createCategory( public function createCategory(
@ -224,7 +218,7 @@ class News {
bool $includeScheduled = false, bool $includeScheduled = false,
bool $includeDeleted = false, bool $includeDeleted = false,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($categoryInfo instanceof NewsCategoryInfo) if($categoryInfo instanceof NewsCategoryInfo)
$categoryInfo = $categoryInfo->getId(); $categoryInfo = $categoryInfo->getId();
@ -271,13 +265,7 @@ class News {
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(NewsPostInfo::fromResult(...));
$posts = [];
while($result->next())
$posts[] = new NewsPostInfo($result);
return $posts;
} }
public function getPost(string $postId): NewsPostInfo { public function getPost(string $postId): NewsPostInfo {
@ -289,7 +277,7 @@ class News {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No news post with that ID exists.'); throw new RuntimeException('No news post with that ID exists.');
return new NewsPostInfo($result); return NewsPostInfo::fromResult($result);
} }
public function createPost( public function createPost(

View file

@ -5,20 +5,24 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class NewsCategoryInfo { class NewsCategoryInfo {
private string $id; public function __construct(
private string $name; private string $id,
private string $description; private string $name,
private bool $hidden; private string $description,
private int $created; private bool $hidden,
private int $posts; private int $created,
private int $posts,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): NewsCategoryInfo {
$this->id = (string)$result->getInteger(0); return new NewsCategoryInfo(
$this->name = $result->getString(1); id: $result->getString(0),
$this->description = $result->getString(2); name: $result->getString(1),
$this->hidden = $result->getInteger(3) !== 0; description: $result->getString(2),
$this->created = $result->getInteger(4); hidden: $result->getBoolean(3),
$this->posts = $result->getInteger(5); created: $result->getInteger(4),
posts: $result->getInteger(5),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -5,30 +5,34 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class NewsPostInfo { class NewsPostInfo {
private string $id; public function __construct(
private string $categoryId; private string $id,
private ?string $userId; private string $categoryId,
private ?string $commentsSectionId; private ?string $userId,
private bool $featured; private ?string $commentsSectionId,
private string $title; private bool $featured,
private string $body; private string $title,
private int $scheduled; private string $body,
private int $created; private int $scheduled,
private int $updated; private int $created,
private ?int $deleted; private int $updated,
private ?int $deleted,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): NewsPostInfo {
$this->id = (string)$result->getInteger(0); return new NewsPostInfo(
$this->categoryId = (string)$result->getInteger(1); id: $result->getString(0),
$this->userId = $result->isNull(2) ? null : (string)$result->getInteger(2); categoryId: $result->getString(1),
$this->commentsSectionId = $result->isNull(3) ? null : (string)$result->getInteger(3); userId: $result->getStringOrNull(2),
$this->featured = $result->getInteger(4) !== 0; commentsSectionId: $result->getStringOrNull(3),
$this->title = $result->getString(5); featured: $result->getBoolean(4),
$this->body = $result->getString(6); title: $result->getString(5),
$this->scheduled = $result->getInteger(7); body: $result->getString(6),
$this->created = $result->getInteger(8); scheduled: $result->getInteger(7),
$this->updated = $result->getInteger(9); created: $result->getInteger(8),
$this->deleted = $result->isNull(10) ? null : $result->getInteger(10); updated: $result->getInteger(9),
deleted: $result->getIntegerOrNull(10),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -6,24 +6,30 @@ use Index\Data\IDbResult;
class PermissionInfo implements IPermissionResult { class PermissionInfo implements IPermissionResult {
use PermissionResultShared; use PermissionResultShared;
private ?string $userId;
private ?string $roleId;
private ?string $forumCategoryId;
private string $category;
private int $allow;
private int $deny;
private int $calculated; private int $calculated;
public function __construct(IDbResult $result) { public function __construct(
$this->userId = $result->isNull(0) ? null : $result->getString(0); private ?string $userId,
$this->roleId = $result->isNull(1) ? null : $result->getString(1); private ?string $roleId,
$this->forumCategoryId = $result->isNull(2) ? null : $result->getString(2); private ?string $forumCategoryId,
$this->category = $result->getString(3); private string $category,
$this->allow = $result->getInteger(4); private int $allow,
$this->deny = $result->getInteger(5); private int $deny,
) {
$this->calculated = $this->allow & ~$this->deny; $this->calculated = $this->allow & ~$this->deny;
} }
public static function fromResult(IDbResult $result): PermissionInfo {
return new PermissionInfo(
userId: $result->getStringOrNull(0),
roleId: $result->getStringOrNull(1),
forumCategoryId: $result->getStringOrNull(2),
category: $result->getString(3),
allow: $result->getInteger(4),
deny: $result->getInteger(5),
);
}
public function hasUserId(): bool { public function hasUserId(): bool {
return $this->userId !== null; return $this->userId !== null;
} }

View file

@ -76,11 +76,11 @@ class Permissions {
$result = $stmt->getResult(); $result = $stmt->getResult();
if(is_string($categoryNames)) if(is_string($categoryNames))
return $result->next() ? new PermissionInfo($result) : null; return $result->next() ? PermissionInfo::fromResult($result) : null;
$perms = []; $perms = [];
while($result->next()) while($result->next())
$perms[$result->getString(3)] = new PermissionInfo($result); $perms[$result->getString(3)] = PermissionInfo::fromResult($result);
return $perms; return $perms;
} }

View file

@ -4,18 +4,22 @@ namespace Misuzu\Profile;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ProfileFieldFormatInfo { class ProfileFieldFormatInfo {
private string $id; public function __construct(
private string $fieldId; private string $id,
private ?string $regex; private string $fieldId,
private ?string $linkFormat; private ?string $regex,
private string $displayFormat; private ?string $linkFormat,
private string $displayFormat,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ProfileFieldFormatInfo {
$this->id = (string)$result->getInteger(0); return new ProfileFieldFormatInfo(
$this->fieldId = (string)$result->getInteger(1); id: $result->getString(0),
$this->regex = $result->isNull(2) ? null : $result->getString(2); fieldId: $result->getString(1),
$this->linkFormat = $result->isNull(3) ? null : $result->getString(3); regex: $result->getStringOrNull(2),
$this->displayFormat = $result->getString(4); linkFormat: $result->getStringOrNull(3),
displayFormat: $result->getString(4),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -4,18 +4,22 @@ namespace Misuzu\Profile;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ProfileFieldInfo { class ProfileFieldInfo {
private string $id; public function __construct(
private int $order; private string $id,
private string $name; private int $order,
private string $title; private string $name,
private string $regex; private string $title,
private string $regex,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ProfileFieldInfo {
$this->id = (string)$result->getInteger(0); return new ProfileFieldInfo(
$this->order = $result->getInteger(1); id: $result->getString(0),
$this->name = $result->getString(2); order: $result->getInteger(1),
$this->title = $result->getString(3); name: $result->getString(2),
$this->regex = $result->getString(4); title: $result->getString(3),
regex: $result->getString(4),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -4,16 +4,20 @@ namespace Misuzu\Profile;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ProfileFieldValueInfo { class ProfileFieldValueInfo {
private string $fieldId; public function __construct(
private string $userId; private string $fieldId,
private string $formatId; private string $userId,
private string $value; private string $formatId,
private string $value,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ProfileFieldValueInfo {
$this->fieldId = (string)$result->getInteger(0); return new ProfileFieldValueInfo(
$this->userId = (string)$result->getInteger(1); fieldId: $result->getString(0),
$this->formatId = (string)$result->getInteger(2); userId: $result->getString(1),
$this->value = $result->getString(3); formatId: $result->getString(2),
value: $result->getString(3)
);
} }
public function getFieldId(): string { public function getFieldId(): string {

View file

@ -16,10 +16,15 @@ class ProfileFields {
$this->cache = new DbStatementCache($dbConn); $this->cache = new DbStatementCache($dbConn);
} }
public function getFields(?array $fieldValueInfos = null): array { public function getFields(?iterable $fieldValueInfos = null): iterable {
$hasFieldValueInfos = $fieldValueInfos !== null; $hasFieldValueInfos = $fieldValueInfos !== null;
if($hasFieldValueInfos && empty($fieldValueInfos)) if($hasFieldValueInfos) {
return []; if(!is_array($fieldValueInfos))
$fieldValueInfos = iterator_to_array($fieldValueInfos);
if(empty($fieldValueInfos))
return [];
}
$query = 'SELECT field_id, field_order, field_key, field_title, field_regex FROM msz_profile_fields'; $query = 'SELECT field_id, field_order, field_key, field_title, field_regex FROM msz_profile_fields';
if($hasFieldValueInfos) if($hasFieldValueInfos)
@ -37,13 +42,8 @@ class ProfileFields {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult();
$fields = [];
while($result->next()) return $stmt->getResult()->getIterator(ProfileFieldInfo::fromResult(...));
$fields[] = new ProfileFieldInfo($result);
return $fields;
} }
public function getField(string $fieldId): ProfileFieldInfo { public function getField(string $fieldId): ProfileFieldInfo {
@ -55,20 +55,30 @@ class ProfileFields {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No field found with the provided field id.'); throw new RuntimeException('No field found with the provided field id.');
return new ProfileFieldInfo($result); return ProfileFieldInfo::fromResult($result);
} }
public function getFieldFormats( public function getFieldFormats(
?array $fieldInfos = null, ?iterable $fieldInfos = null,
?array $fieldValueInfos = null ?iterable $fieldValueInfos = null
): array { ): iterable {
$hasFieldInfos = $fieldInfos !== null; $hasFieldInfos = $fieldInfos !== null;
$hasFieldValueInfos = $fieldValueInfos !== null; $hasFieldValueInfos = $fieldValueInfos !== null;
if($hasFieldInfos && empty($fieldInfos)) if($hasFieldInfos) {
return []; if(!is_array($fieldInfos))
if($hasFieldValueInfos && empty($fieldValueInfos)) $fieldInfos = iterator_to_array($fieldInfos);
return [];
if(empty($fieldInfos))
return [];
}
if($hasFieldValueInfos) {
if(!is_array($fieldValueInfos))
$fieldValueInfos = iterator_to_array($fieldValueInfos);
if(empty($fieldValueInfos))
return [];
}
$args = 0; $args = 0;
$query = 'SELECT format_id, field_id, format_regex, format_link, format_display FROM msz_profile_fields_formats'; $query = 'SELECT format_id, field_id, format_regex, format_link, format_display FROM msz_profile_fields_formats';
@ -101,13 +111,8 @@ class ProfileFields {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult();
$formats = [];
while($result->next()) return $stmt->getResult()->getIterator(ProfileFieldFormatInfo::fromResult(...));
$formats[] = new ProfileFieldFormatInfo($result);
return $formats;
} }
public function getFieldFormat(string $formatId): ProfileFieldFormatInfo { public function getFieldFormat(string $formatId): ProfileFieldFormatInfo {
@ -119,7 +124,7 @@ class ProfileFields {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No format found with the provided format id.'); throw new RuntimeException('No format found with the provided format id.');
return new ProfileFieldFormatInfo($result); return ProfileFieldFormatInfo::fromResult($result);
} }
public function selectFieldFormat( public function selectFieldFormat(
@ -138,10 +143,10 @@ class ProfileFields {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Could not determine an appropriate format for this field (missing default formatting)'); throw new RuntimeException('Could not determine an appropriate format for this field (missing default formatting)');
return new ProfileFieldFormatInfo($result); return ProfileFieldFormatInfo::fromResult($result);
} }
public function getFieldValues(UserInfo|string $userInfo): array { public function getFieldValues(UserInfo|string $userInfo): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -151,13 +156,7 @@ class ProfileFields {
$stmt->addParameter(1, $userInfo); $stmt->addParameter(1, $userInfo);
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ProfileFieldValueInfo::fromResult(...));
$values = [];
while($result->next())
$values[] = new ProfileFieldValueInfo($result);
return $values;
} }
public function getFieldValue( public function getFieldValue(
@ -179,7 +178,7 @@ class ProfileFields {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No value for this field and user combination found.'); throw new RuntimeException('No value for this field and user combination found.');
return new ProfileFieldValueInfo($result); return ProfileFieldValueInfo::fromResult($result);
} }
public function setFieldValues( public function setFieldValues(

View file

@ -5,24 +5,28 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class BanInfo { class BanInfo {
private string $id; public function __construct(
private string $userId; private string $id,
private ?string $modId; private string $userId,
private int $severity; private ?string $modId,
private string $publicReason; private int $severity,
private string $privateReason; private string $publicReason,
private int $created; private string $privateReason,
private ?int $expires; private int $created,
private ?int $expires,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): BanInfo {
$this->id = (string)$result->getInteger(0); return new BanInfo(
$this->userId = (string)$result->getInteger(1); id: $result->getString(0),
$this->modId = $result->isNull(2) ? null : (string)$result->getInteger(2); userId: $result->getString(1),
$this->severity = $result->getInteger(3); modId: $result->getStringOrNull(2),
$this->publicReason = $result->getString(4); severity: $result->getInteger(3),
$this->privateReason = $result->getString(5); publicReason: $result->getString(4),
$this->created = $result->getInteger(6); privateReason: $result->getString(5),
$this->expires = $result->isNull(7) ? null : $result->getInteger(7); created: $result->getInteger(6),
expires: $result->getIntegerOrNull(8),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -64,7 +64,7 @@ class Bans {
?bool $activeOnly = null, ?bool $activeOnly = null,
?bool $activeFirst = null, ?bool $activeFirst = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -101,13 +101,7 @@ class Bans {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(BanInfo::fromResult(...));
$bans = [];
while($result->next())
$bans[] = new BanInfo($result);
return $bans;
} }
public function getBan(string $banId): BanInfo { public function getBan(string $banId): BanInfo {
@ -119,7 +113,7 @@ class Bans {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No ban with ID $banId found.'); throw new RuntimeException('No ban with ID $banId found.');
return new BanInfo($result); return BanInfo::fromResult($result);
} }
public function countActiveBans( public function countActiveBans(

View file

@ -5,20 +5,24 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class ModNoteInfo { class ModNoteInfo {
private string $noteId; public function __construct(
private string $userId; private string $noteId,
private ?string $authorId; private string $userId,
private int $created; private ?string $authorId,
private string $title; private int $created,
private string $body; private string $title,
private string $body,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): ModNoteInfo {
$this->noteId = (string)$result->getInteger(0); return new ModNoteInfo(
$this->userId = (string)$result->getInteger(1); noteId: $result->getString(0),
$this->authorId = $result->isNull(2) ? null : (string)$result->getInteger(2); userId: $result->getString(1),
$this->created = $result->getInteger(3); authorId: $result->getIntegerOrNull(2),
$this->title = $result->getString(4); created: $result->getInteger(3),
$this->body = $result->getString(5); title: $result->getString(4),
body: $result->getString(5)
);
} }
public function getId(): string { public function getId(): string {

View file

@ -59,7 +59,7 @@ class ModNotes {
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
UserInfo|string|null $authorInfo = null, UserInfo|string|null $authorInfo = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
if($authorInfo instanceof UserInfo) if($authorInfo instanceof UserInfo)
@ -93,13 +93,7 @@ class ModNotes {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(ModNoteInfo::fromResult(...));
$notes = [];
while($result->next())
$notes[] = new ModNoteInfo($result);
return $notes;
} }
public function getNote(string $noteId): ModNoteInfo { public function getNote(string $noteId): ModNoteInfo {
@ -111,7 +105,7 @@ class ModNotes {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('No note with ID $noteId found.'); throw new RuntimeException('No note with ID $noteId found.');
return new ModNoteInfo($result); return ModNoteInfo::fromResult($result);
} }
public function createNote( public function createNote(

View file

@ -7,26 +7,30 @@ use Index\Colour\Colour;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class RoleInfo implements Stringable { class RoleInfo implements Stringable {
private string $id; public function __construct(
private int $rank; private string $id,
private string $name; private int $rank,
private ?string $title; private string $name,
private ?string $description; private ?string $title,
private bool $hidden; private ?string $description,
private bool $leavable; private bool $hidden,
private ?int $colour; private bool $leavable,
private int $created; private ?int $colour,
private int $created,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): RoleInfo {
$this->id = (string)$result->getInteger(0); return new RoleInfo(
$this->rank = $result->getInteger(1); id: $result->getString(0),
$this->name = $result->getString(2); rank: $result->getInteger(1),
$this->title = $result->isNull(3) ? null : $result->getString(3); name: $result->getString(2),
$this->description = $result->isNull(4) ? null : $result->getString(4); title: $result->getStringOrNull(3),
$this->hidden = $result->getInteger(5) !== 0; description: $result->getStringOrNull(4),
$this->leavable = $result->getInteger(6) !== 0; hidden: $result->getBoolean(5),
$this->colour = $result->isNull(7) ? null : $result->getInteger(7); leavable: $result->getBoolean(6),
$this->created = $result->getInteger(8); colour: $result->getIntegerOrNull(7),
created: $result->getInteger(8),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -58,7 +58,7 @@ class Roles {
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
?bool $hidden = null, ?bool $hidden = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -87,13 +87,7 @@ class Roles {
} }
$stmt->execute(); $stmt->execute();
$roles = []; return $stmt->getResult()->getIterator(RoleInfo::fromResult(...));
$result = $stmt->getResult();
while($result->next())
$roles[] = new RoleInfo($result);
return $roles;
} }
public function getRole(string $roleId): RoleInfo { public function getRole(string $roleId): RoleInfo {
@ -105,7 +99,7 @@ class Roles {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Could not find role with ID $roleId.'); throw new RuntimeException('Could not find role with ID $roleId.');
return new RoleInfo($result); return RoleInfo::fromResult($result);
} }
public function createRole( public function createRole(

View file

@ -9,50 +9,54 @@ use Index\Net\IPAddress;
use Misuzu\Parsers\Parser; use Misuzu\Parsers\Parser;
class UserInfo { class UserInfo {
private string $id; public function __construct(
private string $name; private string $id,
private ?string $passwordHash; private string $name,
private string $emailAddr; private ?string $passwordHash,
private string $registerRemoteAddr; private string $emailAddr,
private string $lastRemoteAddr; private string $registerRemoteAddr,
private bool $super; private string $lastRemoteAddr,
private string $countryCode; private bool $super,
private ?int $colour; private string $countryCode,
private int $created; private ?int $colour,
private ?int $lastActive; private int $created,
private ?int $deleted; private ?int $lastActive,
private ?string $displayRoleId; private ?int $deleted,
private ?string $totpKey; private ?string $displayRoleId,
private ?string $aboutContent; private ?string $totpKey,
private int $aboutParser; private ?string $aboutContent,
private ?string $signatureContent; private int $aboutParser,
private int $signatureParser; private ?string $signatureContent,
private ?string $birthdate; private int $signatureParser,
private ?int $backgroundSettings; private ?string $birthdate,
private ?string $title; private ?int $backgroundSettings,
private ?string $title,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): self {
$this->id = (string)$result->getInteger(0); return new UserInfo(
$this->name = $result->getString(1); id: $result->getString(0),
$this->passwordHash = $result->isNull(2) ? null : $result->getString(2); name: $result->getString(1),
$this->emailAddr = $result->getString(3); passwordHash: $result->getStringOrNull(2),
$this->registerRemoteAddr = $result->getString(4); emailAddr: $result->getString(3),
$this->lastRemoteAddr = $result->isNull(5) ? null : $result->getString(5); registerRemoteAddr: $result->getString(4),
$this->super = $result->getInteger(6) !== 0; lastRemoteAddr: $result->getStringOrNull(5),
$this->countryCode = $result->getString(7); super: $result->getBoolean(6),
$this->colour = $result->isNull(8) ? null : $result->getInteger(8); countryCode: $result->getString(7),
$this->created = $result->getInteger(9); colour: $result->getIntegerOrNull(8),
$this->lastActive = $result->isNull(10) ? null : $result->getInteger(10); created: $result->getInteger(9),
$this->deleted = $result->isNull(11) ? null : $result->getInteger(11); lastActive: $result->getIntegerOrNull(10),
$this->displayRoleId = $result->isNull(12) ? null : (string)$result->getInteger(12); deleted: $result->getIntegerOrNull(11),
$this->totpKey = $result->isNull(13) ? null : $result->getString(13); displayRoleId: $result->getIntegerOrNull(12),
$this->aboutContent = $result->isNull(14) ? null : $result->getString(14); totpKey: $result->getStringOrNull(13),
$this->aboutParser = $result->getInteger(15); aboutContent: $result->getStringOrNull(14),
$this->signatureContent = $result->isNull(16) ? null : $result->getString(16); aboutParser: $result->getInteger(15),
$this->signatureParser = $result->getInteger(17); signatureContent: $result->getStringOrNull(16),
$this->birthdate = $result->isNull(18) ? null : $result->getString(18); signatureParser: $result->getInteger(17),
$this->backgroundSettings = $result->isNull(19) ? null : $result->getInteger(19); birthdate: $result->getStringOrNull(18),
$this->title = $result->getString(20); backgroundSettings: $result->getIntegerOrNull(19),
title: $result->getString(20),
);
} }
public function getId(): string { public function getId(): string {

View file

@ -112,7 +112,7 @@ class Users {
?bool $reverseOrder = null, ?bool $reverseOrder = null,
?array $searchQuery = null, ?array $searchQuery = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
// remove this hack when search server // remove this hack when search server
$hasSearchQuery = $searchQuery !== null; $hasSearchQuery = $searchQuery !== null;
$searchLimitResults = false; $searchLimitResults = false;
@ -211,13 +211,7 @@ class Users {
} }
$stmt->execute(); $stmt->execute();
$users = []; return $stmt->getResult()->getIterator(UserInfo::fromResult(...));
$result = $stmt->getResult();
while($result->next())
$users[] = new UserInfo($result);
return $users;
} }
public const GET_USER_ID = 0x01; public const GET_USER_ID = 0x01;
@ -283,7 +277,7 @@ class Users {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('User not found.'); throw new RuntimeException('User not found.');
return new UserInfo($result); return UserInfo::fromResult($result);
} }
public function createUser( public function createUser(

View file

@ -5,18 +5,22 @@ use Index\DateTime;
use Index\Data\IDbResult; use Index\Data\IDbResult;
class WarningInfo { class WarningInfo {
private string $id; public function __construct(
private string $userId; private string $id,
private ?string $modId; private string $userId,
private string $body; private ?string $modId,
private int $created; private string $body,
private int $created,
) {}
public function __construct(IDbResult $result) { public static function fromResult(IDbResult $result): WarningInfo {
$this->id = (string)$result->getInteger(0); return new WarningInfo(
$this->userId = (string)$result->getInteger(1); id: $result->getString(0),
$this->modId = $result->isNull(2) ? null : (string)$result->getInteger(2); userId: $result->getString(1),
$this->body = $result->getString(3); modId: $result->getStringOrNull(2),
$this->created = $result->getInteger(4); body: $result->getString(3),
created: $result->getInteger(4)
);
} }
public function getId(): string { public function getId(): string {

View file

@ -53,18 +53,14 @@ class Warnings {
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); $result = $stmt->getResult();
$count = 0;
if($result->next()) return $result->next() ? $result->getInteger(0) : 0;
$count = $result->getInteger(0);
return $count;
} }
public function getWarningsWithDefaultBacklog( public function getWarningsWithDefaultBacklog(
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
return $this->getWarnings( return $this->getWarnings(
$userInfo, $userInfo,
self::VISIBLE_BACKLOG, self::VISIBLE_BACKLOG,
@ -76,7 +72,7 @@ class Warnings {
UserInfo|string|null $userInfo = null, UserInfo|string|null $userInfo = null,
?int $backlog = null, ?int $backlog = null,
?Pagination $pagination = null ?Pagination $pagination = null
): array { ): iterable {
if($userInfo instanceof UserInfo) if($userInfo instanceof UserInfo)
$userInfo = $userInfo->getId(); $userInfo = $userInfo->getId();
@ -111,13 +107,7 @@ class Warnings {
} }
$stmt->execute(); $stmt->execute();
$result = $stmt->getResult(); return $stmt->getResult()->getIterator(WarningInfo::fromResult(...));
$warns = [];
while($result->next())
$warns[] = new WarningInfo($result);
return $warns;
} }
public function getWarning(string $warnId): WarningInfo { public function getWarning(string $warnId): WarningInfo {
@ -130,7 +120,7 @@ class Warnings {
if(!$result->next()) if(!$result->next())
throw new RuntimeException('Could not find warning info for ID $warnId.'); throw new RuntimeException('Could not find warning info for ID $warnId.');
return new WarningInfo($result); return WarningInfo::fromResult($result);
} }
public function createWarning( public function createWarning(