Skip to content

Commit 78d362b

Browse files
authored
Feature/lar 28 forum improvment (#165)
1 parent 70bb600 commit 78d362b

File tree

178 files changed

+3590
-3513
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

178 files changed

+3590
-3513
lines changed

app/Actions/Article/CreateArticleAction.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,13 @@
99
use App\Models\Article;
1010
use App\Notifications\PostArticleToTelegram;
1111
use Carbon\Carbon;
12-
use DateTimeInterface;
1312
use Illuminate\Support\Facades\Auth;
1413

1514
final class CreateArticleAction
1615
{
1716
public function execute(CreateArticleData $articleData): Article
1817
{
19-
if ($articleData->publishedAt && ! ($articleData->publishedAt instanceof DateTimeInterface)) {
18+
if ($articleData->publishedAt) {
2019
$articleData->publishedAt = new Carbon(
2120
time: $articleData->publishedAt,
2221
tz: config('app.timezone')
@@ -41,12 +40,14 @@ public function execute(CreateArticleData $articleData): Article
4140
}
4241

4342
if ($articleData->file) {
44-
$article->addMedia($articleData->file->getRealPath())->toMediaCollection('media');
43+
$article->addMedia($articleData->file->getRealPath())
44+
->toMediaCollection('media');
4545
}
4646

4747
if ($article->isAwaitingApproval()) {
4848
// Envoi de la notification sur le channel Telegram pour la validation de l'article.
4949
Auth::user()?->notify(new PostArticleToTelegram($article));
50+
5051
session()->flash('status', __('notifications.article.created'));
5152
}
5253

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Forum;
6+
7+
use App\Contracts\ReplyInterface;
8+
use App\Events\ReplyWasCreated;
9+
use App\Gamify\Points\ReplyCreated;
10+
use App\Models\Reply;
11+
use App\Models\User;
12+
use Illuminate\Support\Facades\Auth;
13+
14+
final class CreateReplyAction
15+
{
16+
public function execute(string $body, ReplyInterface $model): void
17+
{
18+
/** @var User $user */
19+
$user = Auth::user();
20+
21+
$reply = new Reply(['body' => $body]);
22+
$reply->authoredBy($user);
23+
$reply->to($model);
24+
$reply->save();
25+
26+
givePoint(new ReplyCreated($model, $user));
27+
event(new ReplyWasCreated($reply));
28+
}
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Forum;
6+
7+
use App\Models\Subscribe;
8+
use App\Models\Thread;
9+
use Illuminate\Support\Facades\Auth;
10+
use Ramsey\Uuid\Uuid;
11+
12+
final class SubscribeToThreadAction
13+
{
14+
public function execute(Thread $thread): void
15+
{
16+
$subscription = new Subscribe;
17+
$subscription->uuid = Uuid::uuid4()->toString();
18+
$subscription->user()->associate(Auth::user());
19+
$subscription->subscribeAble()->associate($thread);
20+
21+
$thread->subscribes()->save($subscription);
22+
}
23+
}

app/Console/Commands/UpdateUserBestRepliesPoints.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use App\Gamify\Points\BestReply;
88
use App\Models\Thread;
99
use Illuminate\Console\Command;
10+
use Illuminate\Support\Collection;
1011

1112
final class UpdateUserBestRepliesPoints extends Command
1213
{
@@ -18,10 +19,11 @@ public function handle(): void
1819
{
1920
$this->info('Updating users bests replies reputations...');
2021

21-
$resolvedThread = Thread::resolved()->with('solutionReply')->get();
22+
/** @var Collection | Thread[] $resolvedThread */
23+
$resolvedThread = Thread::with('solutionReply')->scopes('resolved')->get();
2224

2325
foreach ($resolvedThread as $thread) {
24-
givePoint(new BestReply($thread->solutionReply));
26+
givePoint(new BestReply($thread->solutionReply)); // @phpstan-ignore-line
2527
}
2628

2729
$this->info('All done!');
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Exceptions;
6+
7+
use Exception;
8+
9+
final class UnverifiedUserException extends Exception {}

app/Gamify/Points/ArticleCreated.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
namespace App\Gamify\Points;
66

77
use App\Models\Article;
8-
use App\Models\User;
98
use QCod\Gamify\PointType;
109

1110
final class ArticleCreated extends PointType
1211
{
1312
public int $points = 50;
1413

14+
protected string $payee = 'user';
15+
1516
public function __construct(Article $subject)
1617
{
1718
$this->subject = $subject;
1819
}
19-
20-
public function payee(): User
21-
{
22-
// @phpstan-ignore-next-line
23-
return $this->getSubject()->user;
24-
}
2520
}

app/Gamify/Points/BestReply.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44

55
namespace App\Gamify\Points;
66

7+
use App\Models\Reply;
78
use QCod\Gamify\PointType;
89

910
final class BestReply extends PointType
1011
{
1112
public int $points = 20;
1213

13-
protected string $payee = 'author';
14+
protected string $payee = 'user';
1415

15-
public function __construct(mixed $subject)
16+
public function __construct(Reply $subject)
1617
{
1718
$this->subject = $subject;
1819
}

app/Gamify/Points/DiscussionCreated.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
namespace App\Gamify\Points;
66

77
use App\Models\Discussion;
8-
use App\Models\User;
98
use QCod\Gamify\PointType;
109

1110
final class DiscussionCreated extends PointType
1211
{
1312
public int $points = 20;
1413

14+
protected string $payee = 'user';
15+
1516
public function __construct(Discussion $subject)
1617
{
1718
$this->subject = $subject;
1819
}
19-
20-
public function payee(): User
21-
{
22-
// @phpstan-ignore-next-line
23-
return $this->getSubject()->user;
24-
}
2520
}

app/Gamify/Points/PostCreated.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
namespace App\Gamify\Points;
66

77
use App\Models\Article;
8-
use App\Models\User;
98
use QCod\Gamify\PointType;
109

1110
final class PostCreated extends PointType
1211
{
1312
public int $points = 50;
1413

14+
protected string $payee = 'user';
15+
1516
public function __construct(Article $subject)
1617
{
1718
$this->subject = $subject;
1819
}
19-
20-
public function payee(): User
21-
{
22-
// @phpstan-ignore-next-line
23-
return $this->getSubject()->user;
24-
}
2520
}

app/Gamify/Points/ThreadCreated.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,16 @@
55
namespace App\Gamify\Points;
66

77
use App\Models\Thread;
8-
use App\Models\User;
98
use QCod\Gamify\PointType;
109

1110
final class ThreadCreated extends PointType
1211
{
1312
public int $points = 55;
1413

14+
protected string $payee = 'user';
15+
1516
public function __construct(Thread $subject)
1617
{
1718
$this->subject = $subject;
1819
}
19-
20-
public function payee(): User
21-
{
22-
// @phpstan-ignore-next-line
23-
return $this->getSubject()->user;
24-
}
2520
}

app/Http/Controllers/ThreadController.php

Lines changed: 0 additions & 62 deletions
This file was deleted.

app/Listeners/SendNewCommentNotification.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ public function handle(CommentWasAdded $event): void
1717

1818
foreach ($discussion->subscribes as $subscription) {
1919
/** @var Subscribe $subscription */
20-
// @phpstan-ignore-next-line
2120
if ($this->replyAuthorDoesNotMatchSubscriber(author: $event->reply->user, subscription: $subscription)) {
22-
// @phpstan-ignore-next-line
2321
$subscription->user->notify(new NewCommentNotification(
2422
reply: $event->reply,
2523
subscription: $subscription,

app/Listeners/SendNewReplyNotification.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,8 @@ public function handle(ReplyWasCreated $event): void
2222

2323
foreach ($thread->subscribes as $subscription) {
2424
/** @var Subscribe $subscription */
25-
// @phpstan-ignore-next-line
2625
if ($this->replyAuthorDoesNotMatchSubscriber(author: $event->reply->user, subscription: $subscription)) {
27-
$subscription->user->notify(new NewReplyNotification($event->reply, $subscription)); // @phpstan-ignore-line
26+
$subscription->user->notify(new NewReplyNotification($event->reply, $subscription));
2827
}
2928
}
3029
}

app/Listeners/SendNewThreadNotification.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ public function handle(ThreadWasCreated $event): void
1313
{
1414
$thread = $event->thread;
1515

16-
$thread->user->notify(new PostThreadToSlack($thread)); // @phpstan-ignore-line
16+
$thread->user->notify(new PostThreadToSlack($thread));
1717
}
1818
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Livewire\Components;
6+
7+
use App\Models\Channel;
8+
use Illuminate\Contracts\View\View;
9+
use Illuminate\Support\Facades\Cache;
10+
use Livewire\Attributes\Computed;
11+
use Livewire\Component;
12+
13+
/**
14+
* @property Channel | null $currentChannel
15+
*/
16+
final class ChannelsSelector extends Component
17+
{
18+
public ?string $slug = null;
19+
20+
public function selectedChannel(int $channelId): void
21+
{
22+
$this->slug = Channel::query()->find($channelId)?->slug;
23+
24+
$this->dispatch('channelUpdated', channelId: $channelId);
25+
}
26+
27+
public function resetChannel(): void
28+
{
29+
$this->slug = null;
30+
31+
$this->dispatch('channelUpdated', channelId: null);
32+
}
33+
34+
#[Computed]
35+
public function currentChannel(): ?Channel
36+
{
37+
return $this->slug ? Channel::findBySlug($this->slug) : null;
38+
}
39+
40+
public function render(): View
41+
{
42+
return view('livewire.components.channels-selector', [
43+
'channels' => Cache::remember(
44+
'channels',
45+
now()->addMonth(),
46+
fn () => Channel::with('items')->whereNull('parent_id')->get()
47+
),
48+
]);
49+
}
50+
}

0 commit comments

Comments
 (0)