Skip to content

Commit 2dc89eb

Browse files
committed
✨ ajout de la publication des articles sur Twiter
1 parent 08ca2ea commit 2dc89eb

File tree

5 files changed

+252
-4
lines changed

5 files changed

+252
-4
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace App\Console\Commands;
4+
5+
use App\Models\Article;
6+
use App\Notifications\PostArticleToTwitter as PostArticleToTwitterNotification;
7+
use Illuminate\Console\Command;
8+
use Illuminate\Notifications\AnonymousNotifiable;
9+
10+
class PostArticleToTwitter extends Command
11+
{
12+
protected $signature = 'lcm:post-article-to-twitter';
13+
14+
protected $description = 'Posts the latest unshared article to Twitter';
15+
16+
public function handle(AnonymousNotifiable $notifiable): void
17+
{
18+
if ($article = Article::nextForSharing()) {
19+
$notifiable->notify(new PostArticleToTwitterNotification($article));
20+
21+
$article->markAsShared();
22+
}
23+
}
24+
}

app/Models/Article.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Article extends Model implements ReactableInterface, HasMedia, Viewable
4747
'tweet_id',
4848
'submitted_at',
4949
'approved_at',
50+
'declined_at',
5051
'shared_at',
5152
'sponsored_at',
5253
];
@@ -59,6 +60,7 @@ class Article extends Model implements ReactableInterface, HasMedia, Viewable
5960
protected $casts = [
6061
'submitted_at' => 'datetime',
6162
'approved_at' => 'datetime',
63+
'declined_at' => 'datetime',
6264
'shared_at' => 'datetime',
6365
'sponsored_at' => 'datetime',
6466
'show_toc' => 'boolean',
@@ -169,6 +171,16 @@ public function isNotApproved(): bool
169171
return $this->approved_at === null;
170172
}
171173

174+
public function isDeclined(): bool
175+
{
176+
return ! $this->isNotDeclined();
177+
}
178+
179+
public function isNotDeclined(): bool
180+
{
181+
return $this->declined_at === null;
182+
}
183+
172184
public function isPublished(): bool
173185
{
174186
return ! $this->isNotPublished();
@@ -201,7 +213,7 @@ public function isShared(): bool
201213

202214
public function isAwaitingApproval(): bool
203215
{
204-
return $this->isSubmitted() && $this->isNotApproved();
216+
return $this->isSubmitted() && $this->isNotApproved() && $this->isNotDeclined();
205217
}
206218

207219
public function isNotAwaitingApproval(): bool
@@ -227,7 +239,8 @@ public function scopeNotApproved(Builder $query): Builder
227239
public function scopeAwaitingApproval(Builder $query): Builder
228240
{
229241
return $query->submitted()
230-
->notApproved();
242+
->notApproved()
243+
->notDeclined();
231244
}
232245

233246
public function scopePublished(Builder $query): Builder
@@ -240,7 +253,8 @@ public function scopeNotPublished(Builder $query): Builder
240253
{
241254
return $query->where(function ($query) {
242255
$query->whereNull('submitted_at')
243-
->orWhereNull('approved_at');
256+
->orWhereNull('approved_at')
257+
->orWhereNotNull('declined_at');
244258
});
245259
}
246260

@@ -264,6 +278,16 @@ public function scopeNotShared(Builder $query): Builder
264278
return $query->whereNull('shared_at');
265279
}
266280

281+
public function scopeDeclined(Builder $query): Builder
282+
{
283+
return $query->whereNotNull('declined_at');
284+
}
285+
286+
public function scopeNotDeclined(Builder $query): Builder
287+
{
288+
return $query->whereNull('declined_at');
289+
}
290+
267291
public function scopeForTag(Builder $query, string $tag): Builder
268292
{
269293
return $query->whereHas('tags', function ($query) use ($tag) {
@@ -305,4 +329,5 @@ public static function nextForSharing(): ?self
305329
->orderBy('submitted_at', 'asc')
306330
->first();
307331
}
332+
308333
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace App\Notifications;
4+
5+
use App\Models\Article;
6+
use Illuminate\Bus\Queueable;
7+
use Illuminate\Notifications\Notification;
8+
use NotificationChannels\Twitter\TwitterChannel;
9+
use NotificationChannels\Twitter\TwitterStatusUpdate;
10+
11+
class PostArticleToTwitter extends Notification
12+
{
13+
use Queueable;
14+
15+
public function __construct(public Article $article)
16+
{
17+
}
18+
19+
public function via($notifiable)
20+
{
21+
return [TwitterChannel::class];
22+
}
23+
24+
public function toTwitter($notifiable)
25+
{
26+
return new TwitterStatusUpdate($this->generateTweet());
27+
}
28+
29+
public function generateTweet()
30+
{
31+
$title = $this->article->title;
32+
$url = route('articles.show', $this->article->slug());
33+
$author = $this->article->author;
34+
$author = $author->twitter() ? "@{$author->twitter()}" : $author->name;
35+
36+
return "{$title} by {$author}\n\n{$url}";
37+
}
38+
}

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"guzzlehttp/guzzle": "^7.0.1",
2020
"jenssegers/agent": "^2.6",
2121
"laravel-notification-channels/telegram": "^0.7.0",
22+
"laravel-notification-channels/twitter": "^5.1",
2223
"laravel/fortify": "^1.7",
2324
"laravel/framework": "^8.12",
2425
"laravel/slack-notification-channel": "^2.3",

composer.lock

Lines changed: 161 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)