Skip to content

Commit dc57dcf

Browse files
feat:[LAR-85] add articles Approuved in sitemap (#261)
Co-authored-by: Arthur Monney <[email protected]>
1 parent 9d5c622 commit dc57dcf

File tree

13 files changed

+148
-51
lines changed

13 files changed

+148
-51
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ composer.phar
2020
/public/hot
2121
/public/storage
2222
/public/media
23-
/public/sitemap.xml
23+
/public/**/*.xml
2424
/storage/*.key
2525
/storage/framework/cache
2626
.env
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Actions\Article;
6+
7+
use App\Gamify\Points\ArticlePublished;
8+
use App\Models\Article;
9+
10+
final class ApprovedArticleAction
11+
{
12+
public function execute(Article $article): Article
13+
{
14+
$article->approved_at = now();
15+
$article->save();
16+
17+
givePoint(new ArticlePublished($article));
18+
19+
return $article;
20+
}
21+
}

app/Console/Commands/GenerateSitemap.php

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,47 +5,44 @@
55
namespace App\Console\Commands;
66

77
use Illuminate\Console\Command;
8-
use Illuminate\Support\Str;
9-
use Psr\Http\Message\UriInterface;
10-
use Spatie\Sitemap\SitemapGenerator;
8+
use Spatie\Sitemap\Sitemap;
9+
use Spatie\Sitemap\SitemapIndex;
1110
use Spatie\Sitemap\Tags\Url;
1211

1312
final class GenerateSitemap extends Command
1413
{
1514
protected $signature = 'sitemap:generate';
1615

17-
protected $description = 'Crawl the site to generate a sitemap.xml file';
18-
19-
/**
20-
* @var array|string[]
21-
*/
22-
private array $noIndexPaths = [
23-
'',
24-
'/forum/*',
25-
'/user/*',
26-
];
16+
protected $description = 'Generate the sitemap';
2717

2818
public function handle(): void
2919
{
30-
SitemapGenerator::create(config('app.url'))
31-
->shouldCrawl(fn (UriInterface $url) => $this->shouldIndex($url->getPath()))
32-
->hasCrawled(function (Url $url) {
33-
if ($this->shouldNotIndex($url->path())) {
34-
return;
35-
}
36-
37-
return $url;
38-
})
39-
->writeToFile(public_path('sitemap.xml'));
40-
}
41-
42-
private function shouldNotIndex(string $path): bool
43-
{
44-
return Str::is($this->noIndexPaths, $path);
45-
}
46-
47-
private function shouldIndex(string $path): bool
48-
{
49-
return ! $this->shouldNotIndex($path);
20+
Sitemap::create()
21+
->add(
22+
Url::create(route('home'))
23+
->setLastModificationDate(now()->subMinutes(10))
24+
->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)
25+
->setPriority(0.5)
26+
)
27+
->add(
28+
Url::create(route('sponsors'))
29+
->setLastModificationDate(now()->subMinutes(10))
30+
->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)
31+
->setPriority(0.5)
32+
)
33+
->add(
34+
Url::create(route('about'))
35+
->setLastModificationDate(now()->subMinutes(10))
36+
->setChangeFrequency(Url::CHANGE_FREQUENCY_DAILY)
37+
->setPriority(0.5)
38+
)
39+
->writeToFile(public_path('sitemaps/base_sitemap.xml'));
40+
41+
$sitemap = SitemapIndex::create()
42+
->add('/sitemaps/base_sitemap.xml')
43+
->add('/sitemaps/discussion_sitemap.xml')
44+
->add('/sitemaps/blog_sitemap.xml');
45+
46+
$sitemap->writeToFile(public_path('sitemap.xml'));
5047
}
5148
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Console\Commands\Sitemap;
6+
7+
use App\Models\Article;
8+
use Illuminate\Console\Command;
9+
use Spatie\Sitemap\Sitemap;
10+
11+
final class GenerateArticlesSitemapCommand extends Command
12+
{
13+
protected $signature = 'sitemap:blog-generate';
14+
15+
protected $description = 'Generate the articles sitemaps.';
16+
17+
public function handle(): void
18+
{
19+
$sitemap = Sitemap::create();
20+
21+
Article::query()->whereNotNull('approved_at')->each(function ($article) use ($sitemap): void {
22+
$sitemap->add($article); // @phpstan-ignore-line
23+
});
24+
25+
$sitemap->writeToFile(public_path('sitemaps/blog_sitemap.xml'));
26+
}
27+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Console\Commands\Sitemap;
6+
7+
use App\Models\Discussion;
8+
use Illuminate\Console\Command;
9+
use Spatie\Sitemap\Sitemap;
10+
11+
final class GenerateDiscussionsSitemapCommand extends Command
12+
{
13+
protected $signature = 'sitemap:discussion-generate';
14+
15+
protected $description = 'Generate the discussions sitemaps.';
16+
17+
public function handle(): void
18+
{
19+
$sitemap = Sitemap::create();
20+
21+
Discussion::query()->whereHas('replies')->each(function ($discussion) use ($sitemap): void {
22+
$sitemap->add($discussion); // @phpstan-ignore-line
23+
});
24+
25+
$sitemap->writeToFile(public_path('sitemaps/discussion_sitemap.xml'));
26+
}
27+
}

app/Filament/Resources/ArticleResource.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
namespace App\Filament\Resources;
66

7+
use App\Actions\Article\ApprovedArticleAction;
78
use App\Filament\Resources\ArticleResource\Pages;
8-
use App\Gamify\Points\ArticlePublished;
99
use App\Models\Article;
1010
use Filament\Resources\Resource;
1111
use Filament\Support\Enums\MaxWidth;
@@ -89,10 +89,7 @@ public static function table(Table $table): Table
8989
->action(function ($record): void {
9090
Gate::authorize('approve', $record);
9191

92-
$record->approved_at = now();
93-
$record->save();
94-
95-
givePoint(new ArticlePublished($record));
92+
app(ApprovedArticleAction::class)->execute($record);
9693
}),
9794
Action::make('declined')
9895
->visible(fn (Article $record) => $record->isAwaitingApproval())

app/Livewire/Components/Discussion/Comments.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ public function comments(): Collection
7474
{
7575
$replies = collect();
7676

77+
// @phpstan-ignore-next-line
7778
foreach ($this->discussion->replies->load(['allChildReplies', 'user']) as $reply) {
7879
/** @var Reply $reply */
7980
if ($reply->allChildReplies->isNotEmpty()) {

app/Models/Article.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,16 @@
1212
use App\Traits\HasTags;
1313
use App\Traits\Reactable;
1414
use App\Traits\RecordsActivity;
15+
use Carbon\Carbon;
1516
use CyrildeWit\EloquentViewable\Contracts\Viewable;
1617
use CyrildeWit\EloquentViewable\InteractsWithViews;
1718
use Illuminate\Database\Eloquent\Factories\HasFactory;
1819
use Illuminate\Database\Eloquent\Model;
1920
use Illuminate\Support\Str;
2021
use Spatie\MediaLibrary\HasMedia;
2122
use Spatie\MediaLibrary\InteractsWithMedia;
23+
use Spatie\Sitemap\Contracts\Sitemapable;
24+
use Spatie\Sitemap\Tags\Url;
2225

2326
/**
2427
* @property-read int $id
@@ -33,17 +36,17 @@
3336
* @property int $user_id
3437
* @property string | null $locale
3538
* @property-read User $user
36-
* @property \Carbon\Carbon | null $published_at
37-
* @property \Carbon\Carbon | null $submitted_at
38-
* @property \Carbon\Carbon | null $approved_at
39-
* @property \Carbon\Carbon | null $shared_at
40-
* @property \Carbon\Carbon | null $declined_at
41-
* @property \Carbon\Carbon | null $sponsored_at
42-
* @property \Carbon\Carbon $created_at
43-
* @property \Carbon\Carbon $updated_at
39+
* @property Carbon | null $published_at
40+
* @property Carbon | null $submitted_at
41+
* @property Carbon | null $approved_at
42+
* @property Carbon | null $shared_at
43+
* @property Carbon | null $declined_at
44+
* @property Carbon | null $sponsored_at
45+
* @property Carbon $created_at
46+
* @property Carbon $updated_at
4447
* @property \Illuminate\Database\Eloquent\Collection | Tag[] $tags
4548
*/
46-
final class Article extends Model implements HasMedia, ReactableInterface, Viewable
49+
final class Article extends Model implements HasMedia, ReactableInterface, Sitemapable, Viewable
4750
{
4851
use HasAuthor;
4952
use HasFactory;
@@ -96,6 +99,14 @@ public function newEloquentBuilder($query): ArticleQueryBuilder
9699
return new ArticleQueryBuilder($query);
97100
}
98101

102+
public function toSitemapTag(): Url
103+
{
104+
return Url::create(route('articles.show', $this))
105+
->setLastModificationDate(Carbon::create($this->updated_at)) // @phpstan-ignore-line
106+
->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
107+
->setPriority(0.5);
108+
}
109+
99110
public function excerpt(int $limit = 110): string
100111
{
101112
return Str::limit(strip_tags((string) md_to_html($this->body)), $limit);

app/Models/Discussion.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
use Illuminate\Database\Eloquent\Model;
2727
use Illuminate\Support\Collection;
2828
use Illuminate\Support\Str;
29+
use Spatie\Sitemap\Contracts\Sitemapable;
30+
use Spatie\Sitemap\Tags\Url;
2931

3032
/**
3133
* @property-read int $id
@@ -41,8 +43,9 @@
4143
* @property Carbon $updated_at
4244
* @property User $user
4345
* @property Collection | SpamReport[] $spamReports
46+
* @property Collection | Reply[] $replies
4447
*/
45-
final class Discussion extends Model implements ReactableInterface, ReplyInterface, SpamReportableContract, SubscribeInterface, Viewable
48+
final class Discussion extends Model implements ReactableInterface, ReplyInterface, Sitemapable, SpamReportableContract, SubscribeInterface, Viewable
4649
{
4750
use HasAuthor;
4851
use HasFactory;
@@ -107,6 +110,14 @@ public function excerpt(int $limit = 110): string
107110
return Str::limit(strip_tags((string) md_to_html($this->body)), $limit);
108111
}
109112

113+
public function toSitemapTag(): Url
114+
{
115+
return Url::create(route('discussions.show', $this))
116+
->setLastModificationDate(Carbon::create($this->updated_at)) // @phpstan-ignore-line
117+
->setChangeFrequency(Url::CHANGE_FREQUENCY_YEARLY)
118+
->setPriority(0.5);
119+
}
120+
110121
public function isPinned(): bool
111122
{
112123
return $this->is_pinned;

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"spatie/laravel-feed": "^4.2.1",
4242
"spatie/laravel-google-fonts": "^1.2.3",
4343
"spatie/laravel-permission": "^6.10.0",
44-
"spatie/laravel-sitemap": "^7.2.1",
44+
"spatie/laravel-sitemap": "^7.3",
4545
"stevebauman/location": "^7.4.0",
4646
"symfony/http-client": "^7.1.8",
4747
"symfony/mailgun-mailer": "^7.1",

composer.lock

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

public/sitemaps/.gitkeep

Whitespace-only changes.

routes/console.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,12 @@
44

55
use Illuminate\Foundation\Inspiring;
66
use Illuminate\Support\Facades\Artisan;
7+
use Illuminate\Support\Facades\Schedule;
78

89
Artisan::command('inspire', function (): void {
910
$this->comment(Inspiring::quote());
1011
})->purpose('Display an inspiring quote')->hourly();
12+
13+
Schedule::command('sitemap:blog-generate')->dailyAt('01:00');
14+
Schedule::command('sitemap:discussion-generate')->dailyAt('01:10');
15+
Schedule::command('sitemap:generate')->dailyAt('02:00');

0 commit comments

Comments
 (0)