Added kaomoji list to the database.
This commit is contained in:
parent
45635ddc5b
commit
1d57fc3b45
6 changed files with 221 additions and 0 deletions
15
database/2025_04_21_005231_kaomoji_table.php
Normal file
15
database/2025_04_21_005231_kaomoji_table.php
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<?php
|
||||||
|
use Index\Db\DbConnection;
|
||||||
|
use Index\Db\Migration\DbMigration;
|
||||||
|
|
||||||
|
final class KaomojiTable_20250421_005231 implements DbMigration {
|
||||||
|
public function migrate(DbConnection $conn): void {
|
||||||
|
$conn->execute(<<<SQL
|
||||||
|
CREATE TABLE msz_kaomoji (
|
||||||
|
kao_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
kao_string VARCHAR(255) NOT NULL COLLATE 'utf8mb4_bin',
|
||||||
|
PRIMARY KEY (kao_id)
|
||||||
|
) COLLATE='utf8mb4_bin' ENGINE=InnoDB
|
||||||
|
SQL);
|
||||||
|
}
|
||||||
|
}
|
76
src/Kaomoji/KaomojiApiRoutes.php
Normal file
76
src/Kaomoji/KaomojiApiRoutes.php
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Kaomoji;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Index\XArray;
|
||||||
|
use Index\Http\{HttpRequest,HttpResponseBuilder};
|
||||||
|
use Index\Http\Routing\AccessControl\AccessControl;
|
||||||
|
use Index\Http\Routing\Routes\{ExactRoute,PatternRoute};
|
||||||
|
use Misuzu\FieldTransformer;
|
||||||
|
use Misuzu\Routing\{HandlerRoles,RouteHandler,RouteHandlerCommon};
|
||||||
|
|
||||||
|
#[HandlerRoles('main')]
|
||||||
|
final class KaomojiApiRoutes implements RouteHandler {
|
||||||
|
use RouteHandlerCommon;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private KaomojiContext $kaomojiCtx
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/** @return FieldTransformer<KaomojiInfo> */
|
||||||
|
private function createKaomojiTransformer(): FieldTransformer {
|
||||||
|
return new FieldTransformer([
|
||||||
|
'id' => [
|
||||||
|
'transform' => fn($kaomoji) => $kaomoji->id,
|
||||||
|
],
|
||||||
|
'string' => [
|
||||||
|
'default' => true,
|
||||||
|
'transform' => fn($kaomoji) => $kaomoji->string,
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return int|mixed[] */
|
||||||
|
#[AccessControl]
|
||||||
|
#[ExactRoute('GET', '/api/v1/kaomoji')]
|
||||||
|
public function getEmotes(HttpResponseBuilder $response, HttpRequest $request): array|int {
|
||||||
|
$kaomoji = $this->kaomojiCtx->kaomoji->getAllKaomoji();
|
||||||
|
|
||||||
|
if($request->hasParam('as')) {
|
||||||
|
if($request->getParam('as') === 'array') {
|
||||||
|
$response->setCacheControl('max-age=3600', 'stale-if-error=86400', 'public', 'immutable');
|
||||||
|
return XArray::select($kaomoji, fn($kaomoji) => (string)$kaomoji);
|
||||||
|
} else return 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
$transformer = $this->createKaomojiTransformer();
|
||||||
|
if(!$transformer->filter($request))
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
$response->setCacheControl('max-age=3600', 'stale-if-error=86400', 'public', 'immutable');
|
||||||
|
|
||||||
|
return XArray::select($kaomoji, fn($kaomoji) => $transformer->convert($kaomoji));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return int|mixed[] */
|
||||||
|
#[AccessControl]
|
||||||
|
#[PatternRoute('GET', '/api/v1/kaomoji/([0-9]+)')]
|
||||||
|
public function getEmote(HttpResponseBuilder $response, HttpRequest $request, string $id): array|int {
|
||||||
|
if(empty($id))
|
||||||
|
return 404;
|
||||||
|
|
||||||
|
$transformer = $this->createKaomojiTransformer();
|
||||||
|
if(!$transformer->filter($request))
|
||||||
|
return 400;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$kaomoji = $this->kaomojiCtx->kaomoji->getKaomoji($id);
|
||||||
|
} catch(RuntimeException $ex) {
|
||||||
|
return 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
$response->setCacheControl('max-age=3600', 'stale-if-error=86400', 'public', 'immutable');
|
||||||
|
|
||||||
|
return $transformer->convert($kaomoji);
|
||||||
|
}
|
||||||
|
}
|
12
src/Kaomoji/KaomojiContext.php
Normal file
12
src/Kaomoji/KaomojiContext.php
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Kaomoji;
|
||||||
|
|
||||||
|
use Index\Db\DbConnection;
|
||||||
|
|
||||||
|
class KaomojiContext {
|
||||||
|
public private(set) KaomojiData $kaomoji;
|
||||||
|
|
||||||
|
public function __construct(DbConnection $dbConn) {
|
||||||
|
$this->kaomoji = new KaomojiData($dbConn);
|
||||||
|
}
|
||||||
|
}
|
92
src/Kaomoji/KaomojiData.php
Normal file
92
src/Kaomoji/KaomojiData.php
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Kaomoji;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Index\Db\{DbConnection,DbStatementCache};
|
||||||
|
|
||||||
|
class KaomojiData {
|
||||||
|
private DbStatementCache $cache;
|
||||||
|
|
||||||
|
public function __construct(DbConnection $dbConn) {
|
||||||
|
$this->cache = new DbStatementCache($dbConn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getKaomoji(string $kaoId): KaomojiInfo {
|
||||||
|
$stmt = $this->cache->get(<<<SQL
|
||||||
|
SELECT kao_id, kao_string
|
||||||
|
FROM msz_kaomoji
|
||||||
|
WHERE kao_id = ?
|
||||||
|
SQL);
|
||||||
|
$stmt->nextParameter($kaoId);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
$result = $stmt->getResult();
|
||||||
|
if(!$result->next())
|
||||||
|
throw new RuntimeException('No kaomoji with that ID exists.');
|
||||||
|
|
||||||
|
return KaomojiInfo::fromResult($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo pagination
|
||||||
|
* @return \Iterator<int, KaomojiInfo>
|
||||||
|
*/
|
||||||
|
public function getAllKaomoji(): iterable {
|
||||||
|
$stmt = $this->cache->get(<<<SQL
|
||||||
|
SELECT kao_id, kao_string
|
||||||
|
FROM msz_kaomoji
|
||||||
|
SQL);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
return $stmt->getResultIterator(KaomojiInfo::fromResult(...));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createKaomoji(string $string): KaomojiInfo {
|
||||||
|
$stmt = $this->cache->get(<<<SQL
|
||||||
|
INSERT INTO msz_kaomoji (kao_string) VALUES (?)
|
||||||
|
SQL);
|
||||||
|
$stmt->nextParameter($string);
|
||||||
|
$stmt->execute();
|
||||||
|
|
||||||
|
return $this->getKaomoji((string)$stmt->lastInsertId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteKaomoji(KaomojiInfo|string $infoOrId): void {
|
||||||
|
if($infoOrId instanceof KaomojiInfo)
|
||||||
|
$infoOrId = $infoOrId->id;
|
||||||
|
|
||||||
|
$stmt = $this->cache->get(<<<SQL
|
||||||
|
DELETE FROM msz_kaomoji
|
||||||
|
WHERE kao_id = ?
|
||||||
|
SQL);
|
||||||
|
$stmt->nextParameter($infoOrId);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateKaomoji(
|
||||||
|
KaomojiInfo|string $infoOrId,
|
||||||
|
?string $string = null
|
||||||
|
): void {
|
||||||
|
$fields = [];
|
||||||
|
$values = [];
|
||||||
|
|
||||||
|
if($string !== null) {
|
||||||
|
$fields[] = 'kao_string = ?';
|
||||||
|
$values[] = $string;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(empty($fields))
|
||||||
|
return;
|
||||||
|
|
||||||
|
$fields = implode(', ', $fields);
|
||||||
|
$stmt = $this->cache->get(<<<SQL
|
||||||
|
UPDATE msz_kaomoji
|
||||||
|
SET {$fields}
|
||||||
|
WHERE kao_id = ?
|
||||||
|
SQL);
|
||||||
|
foreach($values as $value)
|
||||||
|
$stmt->nextParameter($value);
|
||||||
|
$stmt->nextParameter($infoOrId instanceof KaomojiInfo ? $infoOrId->id : $infoOrId);
|
||||||
|
$stmt->execute();
|
||||||
|
}
|
||||||
|
}
|
23
src/Kaomoji/KaomojiInfo.php
Normal file
23
src/Kaomoji/KaomojiInfo.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
namespace Misuzu\Kaomoji;
|
||||||
|
|
||||||
|
use Stringable;
|
||||||
|
use Index\Db\DbResult;
|
||||||
|
|
||||||
|
class KaomojiInfo implements Stringable {
|
||||||
|
public function __construct(
|
||||||
|
public private(set) string $id,
|
||||||
|
public private(set) string $string,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public static function fromResult(DbResult $result): KaomojiInfo {
|
||||||
|
return new KaomojiInfo(
|
||||||
|
id: $result->getString(0),
|
||||||
|
string: $result->getString(1),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString(): string {
|
||||||
|
return $this->string;
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,7 @@ class MisuzuContext implements RouteHandler {
|
||||||
public private(set) Comments\CommentsContext $commentsCtx;
|
public private(set) Comments\CommentsContext $commentsCtx;
|
||||||
public private(set) Emoticons\EmotesContext $emotesCtx;
|
public private(set) Emoticons\EmotesContext $emotesCtx;
|
||||||
public private(set) Forum\ForumContext $forumCtx;
|
public private(set) Forum\ForumContext $forumCtx;
|
||||||
|
public private(set) Kaomoji\KaomojiContext $kaomojiCtx;
|
||||||
public private(set) Logs\LogsContext $logsCtx;
|
public private(set) Logs\LogsContext $logsCtx;
|
||||||
public private(set) Messages\MessagesContext $messagesCtx;
|
public private(set) Messages\MessagesContext $messagesCtx;
|
||||||
public private(set) OAuth2\OAuth2Context $oauth2Ctx;
|
public private(set) OAuth2\OAuth2Context $oauth2Ctx;
|
||||||
|
@ -105,6 +106,7 @@ class MisuzuContext implements RouteHandler {
|
||||||
Forum\ForumContext::class,
|
Forum\ForumContext::class,
|
||||||
config: $this->config->scopeTo('forum'),
|
config: $this->config->scopeTo('forum'),
|
||||||
));
|
));
|
||||||
|
$this->deps->register($this->kaomojiCtx = $this->deps->constructLazy(Kaomoji\KaomojiContext::class));
|
||||||
$this->deps->register($this->logsCtx = $this->deps->constructLazy(Logs\LogsContext::class));
|
$this->deps->register($this->logsCtx = $this->deps->constructLazy(Logs\LogsContext::class));
|
||||||
$this->deps->register($this->messagesCtx = $this->deps->constructLazy(
|
$this->deps->register($this->messagesCtx = $this->deps->constructLazy(
|
||||||
Messages\MessagesContext::class,
|
Messages\MessagesContext::class,
|
||||||
|
@ -185,6 +187,7 @@ class MisuzuContext implements RouteHandler {
|
||||||
|
|
||||||
$this->routingCtx->register($this->deps->constructLazy(Colours\ColoursApiRoutes::class), $roles);
|
$this->routingCtx->register($this->deps->constructLazy(Colours\ColoursApiRoutes::class), $roles);
|
||||||
$this->routingCtx->register($this->deps->constructLazy(Emoticons\EmotesApiRoutes::class), $roles);
|
$this->routingCtx->register($this->deps->constructLazy(Emoticons\EmotesApiRoutes::class), $roles);
|
||||||
|
$this->routingCtx->register($this->deps->constructLazy(Kaomoji\KaomojiApiRoutes::class), $roles);
|
||||||
$this->routingCtx->register($this->deps->constructLazy(Users\UsersApiRoutes::class), $roles);
|
$this->routingCtx->register($this->deps->constructLazy(Users\UsersApiRoutes::class), $roles);
|
||||||
|
|
||||||
$this->routingCtx->register($this->deps->constructLazy(Home\HomeRoutes::class), $roles);
|
$this->routingCtx->register($this->deps->constructLazy(Home\HomeRoutes::class), $roles);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue