Skip to content

Commit

Permalink
Merge branch 'master' into release-date-precision-validation
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored Sep 10, 2024
2 parents a7f7049 + 4d2068b commit 6ca6cb7
Show file tree
Hide file tree
Showing 98 changed files with 1,719 additions and 1,624 deletions.
31 changes: 24 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: pint
steps:
- name: Checkout code
uses: actions/checkout@v2
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
Expand All @@ -28,7 +28,7 @@ jobs:
name: phpstan
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
Expand All @@ -48,7 +48,7 @@ jobs:
name: phpunit
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
Expand All @@ -61,16 +61,33 @@ jobs:
- name: Test
run: composer paratest

tsc:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
name: tsc
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Use Node 20
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install
run: npm install
- name: Type check
run: npm run tsc

eslint:
runs-on: ubuntu-22.04
strategy:
fail-fast: true
name: eslint
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Use Node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install
Expand All @@ -85,9 +102,9 @@ jobs:
name: vitest
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Use Node 20
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install
Expand Down
3 changes: 3 additions & 0 deletions .hooks/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ vendor/bin/phpstan analyse --memory-limit 512M
printf "\n⏳ npm run lint:eslint\n"
npx eslint --quiet

printf "\n⏳ npm run tsc\n"
npm run tsc

printf "\n⏳ npm run test\n"
npm run test

Expand Down
5 changes: 3 additions & 2 deletions app/Community/Components/UserProfileMeta.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use App\Platform\Enums\PlayerStatType;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\View\Component;

Expand Down Expand Up @@ -322,13 +323,13 @@ private function buildRankMetadata(
private function buildSocialStats(User $user): array
{
$userSetRequestInformation = getUserRequestsInformation($user);
$numForumPosts = $user->forumPosts()->count();
$numForumPosts = $user->forumPosts()->authorized()->viewable(Auth::user())->count();

// Forum posts
$forumPostsStat = [
'label' => 'Forum posts',
'value' => localized_number($numForumPosts),
'href' => $numForumPosts ? route('user.posts', ['user' => $user]) : null,
'href' => $numForumPosts ? route('user.posts.index', ['user' => $user]) : null,
'isMuted' => $numForumPosts === 0,
];

Expand Down
13 changes: 9 additions & 4 deletions app/Community/Components/UserProgressionStatus.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace App\Community\Components;

use App\Models\System;
use App\Platform\Services\PlayerProgressionService;
use Illuminate\Contracts\View\View;
use Illuminate\View\Component;
Expand Down Expand Up @@ -83,9 +84,11 @@ private function buildProgressMetrics(array $userJoinedGamesAndAwards): array
$userJoinedGamesAndAwards
);

$validConsoleIds = array_filter(getValidConsoleIds(), fn ($n) => System::isGameSystem($n));

// Loop through joinedData to calculate counts for individual consoles.
foreach ($allConsoleIds as $consoleId) {
if ($consoleId !== -1 && (!$consoleId || $consoleId == 101 || !isValidConsoleId($consoleId))) {
if ($consoleId !== -1 && (!in_array($consoleId, $validConsoleIds))) {
continue;
}

Expand Down Expand Up @@ -113,11 +116,13 @@ private function sortConsoleProgress(
array $userCompletionProgress,
array $userSiteAwards
): array {
$validConsoleIds = getValidConsoleIds();

$mostRecentlyPlayedConsole = collect($userRecentlyPlayed)
->reject(fn ($game) => (
$game['ConsoleID'] == 101
|| !isValidConsoleId($game['ConsoleID'])
!System::isGameSystem($game['ConsoleID'])
|| !$game['AchievementsTotal']
|| !in_array($game['ConsoleID'], $validConsoleIds)
))
->groupBy('ConsoleID')
->map(fn ($games) => $games->max('LastPlayed'))
Expand All @@ -134,7 +139,7 @@ private function sortConsoleProgress(

$mostRecentlyAwardedConsole = collect($userSiteAwardsWithConsoleID)
->reject(fn ($award) => $award['ConsoleID'] == 101
|| (isset($award['ConsoleID']) && !isValidConsoleId($award['ConsoleID']))
|| (isset($award['ConsoleID']) && !in_array($award['ConsoleID'], $validConsoleIds))
)
->groupBy('ConsoleID')
->map(fn ($awards) => $awards->max('AwardedAt'))
Expand Down
51 changes: 0 additions & 51 deletions app/Community/Controllers/ForumTopicCommentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,13 @@
use App\Community\Actions\AddCommentAction;
use App\Community\Actions\GetUrlToCommentDestinationAction;
use App\Community\Requests\ForumTopicCommentRequest;
use App\Community\Services\ForumRecentPostsPageService;
use App\Models\ForumTopic;
use App\Models\ForumTopicComment;
use App\Support\Shortcode\Shortcode;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class ForumTopicCommentController extends CommentController
{
public function __construct(
protected ForumRecentPostsPageService $recentPostsPageService
) {
}

/**
* There is no create form for creating a new comment.
* comments have to be created for something -> use sub resource create route, e.g.
Expand Down Expand Up @@ -92,46 +83,4 @@ protected function destroy(ForumTopicComment $comment): RedirectResponse
return redirect($return)
->with('success', $this->resourceActionSuccessMessage('comment', 'delete'));
}

public function showRecentPosts(): InertiaResponse
{
$this->authorize('viewAny', ForumTopicComment::class);

// TODO after POC: thin this out
$pageProps = $this->recentPostsPageService->buildViewData(
request()->user(),
(int) request()->input('offset', 0)
);

// TODO after POC: migrate the query to Eloquent ORM and have it do these mappings automatically
$mappedRecentForumPosts = [];
foreach ($pageProps['recentForumPosts'] as &$recentForumPost) {
$mappedRecentForumPost = [];

$mappedRecentForumPost['forumTopicId'] = (int) $recentForumPost['ForumTopicID'];
$mappedRecentForumPost['forumTopicTitle'] = $recentForumPost['ForumTopicTitle'];
$mappedRecentForumPost['commentId'] = (int) $recentForumPost['CommentID'];
$mappedRecentForumPost['postedAt'] = $recentForumPost['PostedAt'];
$mappedRecentForumPost['authorDisplayName'] = $recentForumPost['Author'];
$mappedRecentForumPost['shortMessage'] = Shortcode::stripAndClamp($recentForumPost['ShortMsg'], 999);
$mappedRecentForumPost['commentIdDay'] = isset($recentForumPost['CommentID_1d']) ? (int) $recentForumPost['CommentID_1d'] : null;
$mappedRecentForumPost['commentCountDay'] = isset($recentForumPost['Count_1d']) ? (int) $recentForumPost['Count_1d'] : null;
$mappedRecentForumPost['commentIdWeek'] = isset($recentForumPost['CommentID_7d']) ? (int) $recentForumPost['CommentID_7d'] : null;
$mappedRecentForumPost['commentCountWeek'] = isset($recentForumPost['Count_7d']) ? (int) $recentForumPost['Count_7d'] : null;

$mappedRecentForumPosts[] = $mappedRecentForumPost;
}
unset($pageProps['recentForumPosts']);
$pageProps['recentForumPosts'] = $mappedRecentForumPosts;

// TODO after POC: remove this code
if (isset($pageProps['previousPageUrl'])) {
$pageProps['previousPageUrl'] = str_replace('recent-posts', 'recent-posts2', $pageProps['previousPageUrl']);
}
if (isset($pageProps['nextPageUrl'])) {
$pageProps['nextPageUrl'] = str_replace('recent-posts', 'recent-posts2', $pageProps['nextPageUrl']);
}

return Inertia::render('forums/recent-posts', $pageProps);
}
}
103 changes: 103 additions & 0 deletions app/Community/Controllers/UserForumTopicCommentController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

declare(strict_types=1);

namespace App\Community\Controllers;

use App\Community\Data\UserRecentPostsPagePropsData;
use App\Data\ForumTopicData;
use App\Data\PaginatedData;
use App\Data\UserData;
use App\Enums\Permissions;
use App\Http\Controller;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Inertia\Inertia;
use Inertia\Response as InertiaResponse;

class UserForumTopicCommentController extends Controller
{
public function index(Request $request, User $user): InertiaResponse
{
$this->authorize('view', $user);

$offset = $request->input('page', 1) - 1;
$count = 25;

/** @var User $me */
$me = auth()->user();
$permissions = Permissions::Unregistered;
if ($me) {
$permissions = (int) $me->getAttribute('Permissions');
}

$posts = $this->getUserPosts(
$user,
page: (int) $request->input('page', 1),
permissions: $permissions,
);

$transformedPosts = array_map(
fn ($post) => ForumTopicData::fromUserPost($post)->include('latestComment'),
$posts
);

$paginator = new LengthAwarePaginator(
items: $transformedPosts,
total: $user->forumPosts()->authorized()->viewable($me)->count(),
perPage: $count,
currentPage: $offset + 1,
options: [
'path' => $request->url(),
'query' => $request->query(),
]
);

$paginatedPosts = PaginatedData::fromLengthAwarePaginator($paginator);

$props = new UserRecentPostsPagePropsData(
UserData::fromUser($user),
$paginatedPosts
);

return Inertia::render('user/[user]/posts', $props);
}

private function getUserPosts(User $user, int $page = 1, int $permissions = Permissions::Unregistered): array
{
$count = 25;
$offset = ($page - 1) * $count;

$query = "
SELECT
ft.ID AS ForumTopicID,
ft.Title AS ForumTopicTitle,
f.ID AS ForumID,
f.Title AS ForumTitle,
lftc.ID AS CommentID,
lftc.DateCreated AS PostedAt,
lftc.author_id,
ua.User AS Author,
ua.display_name AS AuthorDisplayName,
LEFT(lftc.Payload, 260) AS ShortMsg,
LENGTH(lftc.Payload) > 260 AS IsTruncated
FROM ForumTopicComment AS lftc
INNER JOIN ForumTopic AS ft ON ft.ID = lftc.ForumTopicID
INNER JOIN Forum AS f ON f.ID = ft.ForumID
LEFT JOIN UserAccounts AS ua ON ua.ID = lftc.author_id
WHERE lftc.author_id = :author_id
AND lftc.Authorised = 1
AND ft.RequiredPermissions <= :permissions
AND ft.deleted_at IS NULL
ORDER BY lftc.DateCreated DESC
LIMIT :offset, :count";

return legacyDbFetchAll($query, [
'author_id' => $user->id,
'offset' => $offset,
'count' => $count,
'permissions' => $permissions,
])->toArray();
}
}
4 changes: 2 additions & 2 deletions app/Community/Data/UpdateProfileData.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ public static function fromRequest(UpdateProfileRequest $request): self
$user = $request->user();

return new self(
motto: $request->motto ?? $user->Motto,
userWallActive: $request->userWallActive ?? $user->UserWallActive,
motto: $request->motto,
userWallActive: $request->userWallActive,
);
}

Expand Down
20 changes: 20 additions & 0 deletions app/Community/Data/UserRecentPostsPagePropsData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace App\Community\Data;

use App\Data\PaginatedData;
use App\Data\UserData;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript('UserRecentPostsPageProps<TItems = App.Data.ForumTopic>')]
class UserRecentPostsPagePropsData extends Data
{
public function __construct(
public UserData $targetUser,
public PaginatedData $paginatedTopics,
) {
}
}
12 changes: 9 additions & 3 deletions app/Community/Livewire/Forms/ForumTopicCommentForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,17 @@
namespace App\Community\Livewire\Forms;

use App\Models\ForumTopicComment;
use App\Support\Rules\ContainsRegularCharacter;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Http\RedirectResponse;
use Livewire\Attributes\Locked;
use Livewire\Attributes\Validate;
use Livewire\Features\SupportRedirects\Redirector;
use Livewire\Form;

class ForumTopicCommentForm extends Form
{
use AuthorizesRequests;

#[Validate('required|max:60000')]
public string $body = '';

#[Locked]
Expand All @@ -31,7 +30,14 @@ public function setForumTopicComment(ForumTopicComment $forumTopicComment): void
public function update(): RedirectResponse|Redirector
{
$this->authorize('update', [ForumTopicComment::class, $this->forumTopicComment]);
$this->validate();
$this->validate([
'body' => [
'required',
'string',
'max:60000',
new ContainsRegularCharacter(),
],
]);

editTopicComment($this->forumTopicComment->id, $this->body);

Expand Down
Loading

0 comments on commit 6ca6cb7

Please sign in to comment.