diff --git a/be/.env.example b/be/.env.example index 8ba78fd4..d2caecf5 100644 --- a/be/.env.example +++ b/be/.env.example @@ -20,4 +20,6 @@ DB_DATABASE= DB_USERNAME= DB_PASSWORD= +CACHE_STORE=file + RECAPTCHA_SECRET= diff --git a/be/app/Http/Controllers/PostsQuery.php b/be/app/Http/Controllers/PostsQuery.php index 737e3f89..2834a4e7 100644 --- a/be/app/Http/Controllers/PostsQuery.php +++ b/be/app/Http/Controllers/PostsQuery.php @@ -64,9 +64,9 @@ public function query(\Illuminate\Http\Request $request): array ->only(Helper::POST_TYPES_PLURAL) ->flatMap(static fn (Collection $posts) => $posts->pluck('authorUid')) ->concat($latestRepliers->pluck('uid')) - ->filter()->unique()->toArray() // remove NULLs + ->filter()->unique() // remove NULLs )->with(['currentForumModerator' => $whereCurrentFid, 'currentAuthorExpGrade' => $whereCurrentFid]) - ->selectPublicFields()->get()->toArray(); + ->selectPublicFields()->get(); Debugbar::stopMeasure('queryUsers'); return [ @@ -75,7 +75,7 @@ public function query(\Illuminate\Http\Request $request): array ...$query->getResultPages(), ...Arr::except($result, ['fid', ...Helper::POST_TYPES_PLURAL]) ], - 'forum' => Forum::fid($result['fid'])->selectPublicFields()->first()?->toArray(), + 'forum' => Forum::fid($result['fid'])->selectPublicFields()->first(), 'threads' => $query->reOrderNestedPosts($query::nestPostsWithParent(...$result)), 'users' => $users, 'latestRepliers' => $latestRepliers diff --git a/be/app/Http/Controllers/ThreadsSitemap.php b/be/app/Http/Controllers/ThreadsSitemap.php index 6f48da41..cc7bd1a2 100644 --- a/be/app/Http/Controllers/ThreadsSitemap.php +++ b/be/app/Http/Controllers/ThreadsSitemap.php @@ -6,22 +6,24 @@ use App\Eloquent\Model\Post\PostFactory; use App\Helper; use Illuminate\Http; +use Illuminate\Support\Facades\Cache; class ThreadsSitemap extends Controller { - public static int $maxItems = 50000; + public static int $maxUrls = 50000; public function query(Http\Request $request, int $fid): Http\Response { // https://stackoverflow.com/questions/59554777/laravel-how-to-set-default-value-in-validator-at-post-registeration/78707950#78707950 ['cursor' => $cursor] = $request->validate([ 'cursor' => 'integer' ]) + ['cursor' => 0]; - Helper::abortAPIIfNot(40406, (new Forum())->fid($fid)->exists()); + Helper::abortAPIIfNot(40406, Forum::fid($fid)->exists()); - return Helper::xmlResponse(view('sitemaps.threads', [ - 'tids' => PostFactory::newThread($fid) - ->where('tid', '>', $cursor)->limit(self::$maxItems) - ->orderByDesc('tid')->pluck('tid') - ])); + return Cache::remember("/sitemaps/forums/$fid/threads?cursor=$cursor", 86400, + static fn () => Helper::xmlResponse(view('sitemaps.threads', [ + 'tids' => PostFactory::newThread($fid) + ->where('tid', '>', $cursor)->limit(self::$maxUrls) + ->orderBy('tid')->pluck('tid') + ]))); } } diff --git a/be/app/Http/Controllers/UsersQuery.php b/be/app/Http/Controllers/UsersQuery.php index 3bdcc430..64e56d55 100644 --- a/be/app/Http/Controllers/UsersQuery.php +++ b/be/app/Http/Controllers/UsersQuery.php @@ -19,7 +19,7 @@ public function query(\Illuminate\Http\Request $request): array ]); Helper::abortAPIIf(40402, empty($queryParams)); - $queryBuilder = (new User())->newQuery(); + $queryBuilder = User::newQuery(); $nullableParams = ['name', 'displayName', 'gender']; foreach ($nullableParams as $nullableParamName) { diff --git a/be/app/Http/PostsQuery/IndexQuery.php b/be/app/Http/PostsQuery/IndexQuery.php index a478cac0..a6b98ac0 100644 --- a/be/app/Http/PostsQuery/IndexQuery.php +++ b/be/app/Http/PostsQuery/IndexQuery.php @@ -41,15 +41,16 @@ public function query(QueryParams $params, ?string $cursor): self ->only($postTypes) ->transform(static fn (Post $model, string $type) => $model->selectCurrentAndParentPostID()); $getFidByPostIDParam = static function (string $postIDName, int $postID): int { - $fids = Forum::get('fid')->pluck('fid')->toArray(); - $counts = collect($fids) + $counts = Forum::get('fid') + ->pluck('fid') ->map(static fn (int $fid) => PostFactory::getPostModelsByFid($fid)[Helper::POST_ID_TO_TYPE[$postIDName]] ->selectRaw("{$fid} AS fid, COUNT(*) AS count") ->where($postIDName, $postID)) ->reduce(static fn (?BuilderContract $acc, EloquentBuilder|QueryBuilder $cur): BuilderContract => $acc === null ? $cur : $acc->union($cur)) - ->get()->where('count', '!=', 0); + ->get() + ->where('count', '!=', 0); Helper::abortAPIIf(50001, $counts->count() > 1); Helper::abortAPIIf(40401, $counts->count() === 0); return $counts->pluck('fid')->first(); @@ -57,7 +58,7 @@ public function query(QueryParams $params, ?string $cursor): self if (\array_key_exists('fid', $flatParams)) { /** @var int $fid */ $fid = $flatParams['fid']; - if ((new Forum())->fid($fid)->exists()) { + if (Forum::fid($fid)->exists()) { /** @var Collection> $queries key by post type */ $queries = $getQueryBuilders($fid); } elseif ($hasPostIDParam) { // query by post ID and fid, but the provided fid is invalid diff --git a/be/routes/api.php b/be/routes/api.php index 1b87d2ca..3924fc9e 100644 --- a/be/routes/api.php +++ b/be/routes/api.php @@ -4,7 +4,7 @@ use App\Http\Middleware\ReCAPTCHACheck; use Illuminate\Support\Facades\Route; -Route::get('/forums', static fn () => \App\Eloquent\Model\Forum::all()->toArray()); +Route::get('/forums', static fn () => \App\Eloquent\Model\Forum::all()); Route::middleware(ReCAPTCHACheck::class)->group(static function () { Route::get('/posts', [Controllers\PostsQuery::class, 'query']); Route::get('/users', [Controllers\UsersQuery::class, 'query']); diff --git a/be/routes/web.php b/be/routes/web.php index dd467426..69ed6f09 100644 --- a/be/routes/web.php +++ b/be/routes/web.php @@ -5,12 +5,13 @@ use App\Helper; use App\Http\Controllers; -Route::get('/sitemaps/forums', static fn() => Helper::xmlResponse(view('sitemaps.forums', [ - 'tidsKeyByFid' => (new Forum())->get('fid')->pluck('fid')->mapWithKeys(fn(int $fid) => [ - $fid => DB::query() - ->fromSub(PostFactory::newThread($fid) - ->selectRaw('ROW_NUMBER() OVER (ORDER BY tid DESC) AS rn, tid'), 't') - ->whereRaw('rn % ' . Controllers\ThreadsSitemap::$maxItems . ' = 0') - ->pluck('tid') - ])]))); +Route::get('/sitemaps/forums', static fn () => Cache::remember('/sitemaps/forums', 86400, + static fn () => Helper::xmlResponse(view('sitemaps.forums', [ + 'tidsKeyByFid' => Forum::get('fid')->pluck('fid')->mapWithKeys(fn (int $fid) => [ + $fid => DB::query() + ->fromSub(PostFactory::newThread($fid) + ->selectRaw('ROW_NUMBER() OVER (ORDER BY tid DESC) AS rn, tid'), 't') + ->whereRaw('rn % ' . Controllers\ThreadsSitemap::$maxUrls . ' = 0') + ->pluck('tid') + ])])))); Route::get('/sitemaps/forums/{fid}/threads', [Controllers\ThreadsSitemap::class, 'query']);