2023-07-29 22:18:20 +00:00
|
|
|
<?php
|
|
|
|
namespace Misuzu\Satori;
|
|
|
|
|
|
|
|
use RuntimeException;
|
2023-09-06 19:35:50 +00:00
|
|
|
use Index\Colour\Colour;
|
2023-07-29 22:18:20 +00:00
|
|
|
use Index\Routing\IRouter;
|
2023-09-06 11:59:44 +00:00
|
|
|
use Index\Routing\IRouteHandler;
|
2023-09-08 00:13:30 +00:00
|
|
|
use Index\Routing\Route;
|
2023-08-02 22:12:47 +00:00
|
|
|
use Misuzu\Pagination;
|
2023-09-08 00:13:30 +00:00
|
|
|
use Misuzu\Tools;
|
2023-07-29 22:18:20 +00:00
|
|
|
use Misuzu\Config\IConfig;
|
2023-09-06 19:35:50 +00:00
|
|
|
use Misuzu\Forum\Forum;
|
2023-07-29 22:18:20 +00:00
|
|
|
use Misuzu\Profile\ProfileFields;
|
2023-09-06 13:50:19 +00:00
|
|
|
use Misuzu\Users\UsersContext;
|
2023-07-29 22:18:20 +00:00
|
|
|
|
2023-09-06 11:59:44 +00:00
|
|
|
final class SatoriRoutes implements IRouteHandler {
|
2023-07-29 22:18:20 +00:00
|
|
|
public function __construct(
|
2023-09-06 13:50:19 +00:00
|
|
|
private IConfig $config,
|
|
|
|
private UsersContext $usersCtx,
|
2023-09-06 19:35:50 +00:00
|
|
|
private ProfileFields $profileFields,
|
|
|
|
private Forum $forum
|
2023-09-06 13:50:19 +00:00
|
|
|
) {}
|
2023-07-29 22:18:20 +00:00
|
|
|
|
2023-09-06 11:59:44 +00:00
|
|
|
public function registerRoutes(IRouter $router): void {
|
2023-09-08 00:13:30 +00:00
|
|
|
Tools::simplifyErrorPages($router, '/_satori');
|
|
|
|
Route::handleAttributes($router, $this);
|
2023-07-29 22:18:20 +00:00
|
|
|
}
|
|
|
|
|
2023-09-08 00:13:30 +00:00
|
|
|
#[Route('/_satori')]
|
2023-07-29 22:18:20 +00:00
|
|
|
public function verifyRequest($response, $request) {
|
|
|
|
$secretKey = $this->config->getString('secret');
|
|
|
|
|
|
|
|
if(!empty($secretKey)) {
|
|
|
|
$userTime = (int)$request->getHeaderLine('X-Satori-Time');
|
|
|
|
$userHash = base64_decode((string)$request->getHeaderLine('X-Satori-Hash'));
|
|
|
|
|
|
|
|
$currentTime = time();
|
|
|
|
if(empty($userHash) || $userTime < $currentTime - 60 || $userTime > $currentTime + 60)
|
|
|
|
return 403;
|
|
|
|
|
|
|
|
$verifyText = (string)$userTime . '#' . $request->getPath() . '?' . $request->getParamString();
|
|
|
|
$verifyHash = hash_hmac('sha256', $verifyText, $secretKey, true);
|
|
|
|
|
|
|
|
if(!hash_equals($verifyHash, $userHash))
|
|
|
|
return 403;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-08 00:13:30 +00:00
|
|
|
#[Route('GET', '/_satori/get-profile-field')]
|
2023-07-29 22:18:20 +00:00
|
|
|
public function getProfileField($response, $request): array {
|
|
|
|
$userId = (string)$request->getParam('user', FILTER_SANITIZE_NUMBER_INT);
|
|
|
|
$fieldId = (string)$request->getParam('field', FILTER_SANITIZE_NUMBER_INT);
|
|
|
|
|
|
|
|
try {
|
|
|
|
$fieldValue = $this->profileFields->getFieldValue($fieldId, $userId);
|
|
|
|
} catch(RuntimeException $ex) {
|
|
|
|
return ['error' => 105];
|
|
|
|
}
|
|
|
|
|
|
|
|
return [
|
|
|
|
'field_value' => $fieldValue->getValue(),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2023-09-08 00:13:30 +00:00
|
|
|
#[Route('GET', '/_satori/get-recent-forum-posts')]
|
2023-07-29 22:18:20 +00:00
|
|
|
public function getRecentForumPosts($response, $request): array {
|
|
|
|
$categoryIds = $this->config->getArray('forum.categories');
|
|
|
|
if(empty($categoryIds))
|
|
|
|
return [];
|
|
|
|
|
|
|
|
$batchSize = $this->config->getInteger('forum.batch', 6);
|
|
|
|
$backlogDays = $this->config->getInteger('forum.backlog', 7);
|
|
|
|
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
|
|
|
|
|
|
|
|
$posts = [];
|
2023-09-06 19:35:50 +00:00
|
|
|
$postInfos = $this->forum->getPosts(
|
|
|
|
categoryInfo: $categoryIds,
|
|
|
|
afterPostInfo: $startId,
|
|
|
|
newerThanDays: $backlogDays,
|
|
|
|
pagination: new Pagination($batchSize),
|
|
|
|
deleted: false,
|
|
|
|
);
|
|
|
|
|
|
|
|
foreach($postInfos as $postInfo) {
|
|
|
|
$topicInfo = $this->forum->getTopic(postInfo: $postInfo);
|
|
|
|
$firstPostInfo = $this->forum->getPost(topicInfo: $topicInfo);
|
|
|
|
$categoryInfo = $this->forum->getCategory(topicInfo: $topicInfo);
|
|
|
|
$userInfo = $postInfo->hasUserId() ? $this->usersCtx->getUserInfo($postInfo->getUserId()) : null;
|
|
|
|
$userColour = $this->usersCtx->getUserColour($userInfo);
|
2023-07-29 22:18:20 +00:00
|
|
|
|
|
|
|
$posts[] = [
|
2023-09-06 19:35:50 +00:00
|
|
|
'post_id' => (int)$postInfo->getId(),
|
|
|
|
'topic_id' => (int)$topicInfo->getId(),
|
|
|
|
'topic_title' => $topicInfo->getTitle(),
|
|
|
|
'forum_id' => (int)$categoryInfo->getId(),
|
|
|
|
'forum_name' => $categoryInfo->getName(),
|
|
|
|
'user_id' => (int)$userInfo->getId(),
|
|
|
|
'username' => $userInfo->getName(),
|
|
|
|
'user_colour' => Colour::toMisuzu($userColour),
|
2023-09-07 20:53:19 +00:00
|
|
|
'is_opening_post' => $postInfo->getId() === $firstPostInfo->getId() ? 1 : 0,
|
2023-07-29 22:18:20 +00:00
|
|
|
];
|
2023-09-06 19:35:50 +00:00
|
|
|
}
|
2023-07-29 22:18:20 +00:00
|
|
|
|
|
|
|
return $posts;
|
|
|
|
}
|
|
|
|
|
2023-09-08 00:13:30 +00:00
|
|
|
#[Route('GET', '/_satori/get-recent-registrations')]
|
2023-07-29 22:18:20 +00:00
|
|
|
public function getRecentRegistrations($response, $request) {
|
|
|
|
$batchSize = $this->config->getInteger('users.batch', 10);
|
|
|
|
$backlogDays = $this->config->getInteger('users.backlog', 7);
|
|
|
|
$startId = (string)$request->getParam('start', FILTER_SANITIZE_NUMBER_INT);
|
|
|
|
|
2023-09-06 13:50:19 +00:00
|
|
|
$userInfos = $this->usersCtx->getUsers()->getUsers(
|
2023-08-02 22:12:47 +00:00
|
|
|
after: $startId,
|
|
|
|
newerThanDays: $backlogDays,
|
|
|
|
orderBy: 'id',
|
|
|
|
pagination: new Pagination($batchSize),
|
|
|
|
deleted: false
|
2023-07-29 22:18:20 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
$users = [];
|
|
|
|
|
2023-08-02 22:12:47 +00:00
|
|
|
foreach($userInfos as $userInfo)
|
2023-07-29 22:18:20 +00:00
|
|
|
$users[] = [
|
2023-08-02 22:12:47 +00:00
|
|
|
'user_id' => (int)$userInfo->getId(),
|
|
|
|
'username' => $userInfo->getName(),
|
2023-07-29 22:18:20 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
return $users;
|
|
|
|
}
|
|
|
|
}
|