Skip to content

Commit 7ddf5be

Browse files
committed
🗃️ ajout du model et migration pour les discussions
1 parent 1183d79 commit 7ddf5be

File tree

5 files changed

+192
-8
lines changed

5 files changed

+192
-8
lines changed

app/Models/Article.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,6 @@ public function scopeNotDeclined(Builder $query): Builder
288288
return $query->whereNull('declined_at');
289289
}
290290

291-
public function scopeForTag(Builder $query, string $tag): Builder
292-
{
293-
return $query->whereHas('tags', function ($query) use ($tag) {
294-
$query->where('tags.slug', $tag);
295-
});
296-
}
297-
298291
public function scopeRecent(Builder $query): Builder
299292
{
300293
return $query->orderBy('is_pinned', 'desc')

app/Models/Discussion.php

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use App\Contracts\ReactableInterface;
6+
use App\Contracts\ReplyInterface;
7+
use App\Traits\HasAuthor;
8+
use App\Traits\HasReplies;
9+
use App\Traits\HasSlug;
10+
use App\Traits\HasTags;
11+
use App\Traits\Reactable;
12+
use App\Traits\RecordsActivity;
13+
use CyrildeWit\EloquentViewable\Contracts\Viewable;
14+
use CyrildeWit\EloquentViewable\InteractsWithViews;
15+
use Illuminate\Database\Eloquent\Builder;
16+
use Illuminate\Database\Eloquent\Factories\HasFactory;
17+
use Illuminate\Database\Eloquent\Model;
18+
use Illuminate\Support\Str;
19+
20+
class Discussion extends Model implements ReactableInterface, ReplyInterface, Viewable
21+
{
22+
use HasAuthor,
23+
HasFactory,
24+
HasReplies,
25+
HasSlug,
26+
HasTags,
27+
InteractsWithViews,
28+
Reactable,
29+
RecordsActivity;
30+
31+
/**
32+
* The attributes that are mass assignable.
33+
*
34+
* @var string[]
35+
*/
36+
protected $fillable = [
37+
'title',
38+
'body',
39+
'slug',
40+
'user_id',
41+
'is_pinned',
42+
'locked',
43+
];
44+
45+
/**
46+
* The attributes that should be cast to native types.
47+
*
48+
* @var array
49+
*/
50+
protected $casts = [
51+
'locked' => 'boolean',
52+
'is_pinned' => 'boolean',
53+
];
54+
55+
/**
56+
* The relations to eager load on every query.
57+
*
58+
* @var array
59+
*/
60+
protected $with = [
61+
'tags',
62+
'author',
63+
];
64+
65+
protected $removeViewsOnDelete = true;
66+
67+
public static function boot()
68+
{
69+
parent::boot();
70+
}
71+
72+
/**
73+
* Get the route key for the model.
74+
*
75+
* @return string
76+
*/
77+
public function getRouteKeyName(): string
78+
{
79+
return 'slug';
80+
}
81+
82+
public function subject(): string
83+
{
84+
return $this->title;
85+
}
86+
87+
public function replyAbleSubject(): string
88+
{
89+
return $this->title;
90+
}
91+
92+
public function getPathUrl(): string
93+
{
94+
return "/discussions/{$this->slug()}";
95+
}
96+
97+
public function excerpt(int $limit = 110): string
98+
{
99+
return Str::limit(strip_tags(md_to_html($this->body)), $limit);
100+
}
101+
102+
public function isPinned(): bool
103+
{
104+
return (bool) $this->is_pinned;
105+
}
106+
107+
public function isLocked(): bool
108+
{
109+
return (bool) $this->locked;
110+
}
111+
112+
public function scopePinned(Builder $query): Builder
113+
{
114+
return $query->where('is_pinned', true);
115+
}
116+
117+
public function scopeNotPinned(Builder $query): Builder
118+
{
119+
return $query->where('is_pinned', false);
120+
}
121+
122+
public function scopeRecent(Builder $query): Builder
123+
{
124+
return $query->orderBy('is_pinned', 'desc')
125+
->orderBy('created_at', 'desc');
126+
}
127+
128+
public function scopePopular(Builder $query): Builder
129+
{
130+
return $query->withCount('reactions')
131+
->orderBy('reactions_count', 'desc');
132+
}
133+
134+
public function scopeActive(Builder $query): Builder
135+
{
136+
return $query->withCount(['replies' => function ($query) {
137+
$query->where('created_at', '>=', now()->subWeek());
138+
}])
139+
->orderBy('replies_count', 'desc');
140+
}
141+
142+
public function lockedDiscussion()
143+
{
144+
$this->update(['locked' => true]);
145+
}
146+
}

app/Models/Thread.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ public function replyAbleSubject(): string
104104

105105
public function getPathUrl(): string
106106
{
107-
return "/forum/{$this->slug}";
107+
return "/forum/{$this->slug()}";
108108
}
109109

110110
public function excerpt(int $limit = 100): string

app/Traits/HasTags.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\Traits;
44

55
use App\Models\Tag;
6+
use Illuminate\Database\Eloquent\Builder;
67
use Illuminate\Database\Eloquent\Relations\MorphToMany;
78

89
trait HasTags
@@ -22,6 +23,13 @@ public function removeTags()
2223
$this->unsetRelation('tags');
2324
}
2425

26+
public function scopeForTag(Builder $query, string $tag): Builder
27+
{
28+
return $query->whereHas('tags', function ($query) use ($tag) {
29+
$query->where('tags.slug', $tag);
30+
});
31+
}
32+
2533
public function tags(): MorphToMany
2634
{
2735
return $this->morphToMany(Tag::class, 'taggable');
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class CreateDiscussionsTable extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::create('discussions', function (Blueprint $table) {
17+
$table->id();
18+
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
19+
$table->string('title');
20+
$table->string('slug')->unique();
21+
$table->text('body');
22+
$table->boolean('is_pinned')->default(false);
23+
$table->boolean('locked')->default(false);
24+
$table->timestamps();
25+
});
26+
}
27+
28+
/**
29+
* Reverse the migrations.
30+
*
31+
* @return void
32+
*/
33+
public function down()
34+
{
35+
Schema::dropIfExists('discussions');
36+
}
37+
}

0 commit comments

Comments
 (0)