Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions app/Concerns/HasEditLog.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

namespace App\Concerns;

use App\Models\Edit;
use Illuminate\Database\Eloquent\Relations\MorphMany;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;

trait HasEditLog
{
public static function bootHasEditLog()
{
static::updated(function ($model) {
Edit::create([
'author_id' => $model->author_id,
'editable_id' => $model->id,
'editable_type' => constant($model::class.'::TABLE') ?? $model::class,
'edited_at' => now(),
]);

$cacheKey = sprintf('%s-%s', Str::slug($model::class), $model->id);
if (Cache::has($cacheKey)) {
Cache::forget($cacheKey);
}
});
}

public function edits(): MorphMany
{
return $this->morphMany(Edit::class, 'editable');
}

public function getLatestEditAttribute(): ?Edit
{
$cacheKey = sprintf('%s-%s', Str::slug($this::class), $this->id);

return Cache::rememberForever($cacheKey, function () {
return $this->edits()->latest('edited_at')->first();
});
}
}
2 changes: 2 additions & 0 deletions app/Models/Article.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Models;

use App\Concerns\HasAuthor;
use App\Concerns\HasEditLog;
use App\Concerns\HasLikes;
use App\Concerns\HasSlug;
use App\Concerns\HasTags;
Expand All @@ -19,6 +20,7 @@ final class Article extends Model
{
use HasFactory;
use HasAuthor;
use HasEditLog;
use HasSlug;
use HasLikes;
use HasTimestamps;
Expand Down
35 changes: 35 additions & 0 deletions app/Models/Edit.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Models;

use App\Concerns\HasAuthor;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Edit extends Model
{
use HasAuthor;
use HasFactory;

protected $fillable = [
'author_id',
'editable_id',
'editable_type',
'edited_at',
];

protected $dates = [
'edited_at',
];

protected $with = [
'authorRelation',
];

public $timestamps = false;

public function editable()
{
return $this->morphTo();
}
}
2 changes: 2 additions & 0 deletions app/Models/Reply.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Models;

use App\Concerns\HasAuthor;
use App\Concerns\HasEditLog;
use App\Concerns\HasLikes;
use App\Concerns\HasTimestamps;
use Illuminate\Database\Eloquent\Builder;
Expand All @@ -16,6 +17,7 @@ final class Reply extends Model
{
use HasFactory;
use HasAuthor;
use HasEditLog;
use HasLikes;
use HasTimestamps;

Expand Down
2 changes: 2 additions & 0 deletions app/Models/Thread.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Models;

use App\Concerns\HasAuthor;
use App\Concerns\HasEditLog;
use App\Concerns\HasLikes;
use App\Concerns\HasSlug;
use App\Concerns\HasTags;
Expand Down Expand Up @@ -30,6 +31,7 @@ final class Thread extends Model implements ReplyAble, SubscriptionAble, Feedabl
{
use HasFactory;
use HasAuthor;
use HasEditLog;
use HasLikes;
use HasSlug;
use HasTags;
Expand Down
44 changes: 44 additions & 0 deletions database/factories/EditFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Database\Factories;

use App\Models\Article;
use App\Models\Edit;
use App\Models\Reply;
use App\Models\Thread;
use App\Models\User;
use Illuminate\Database\Eloquent\Factories\Factory;

class EditFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var string
*/
protected $model = Edit::class;

/**
* Define the model's default state.
*
* @return array
*/
public function definition()
{
$editableClass = $this->faker->randomElement([Article::class, Reply::class, Thread::class]);
$editableFactory = call_user_func([$editableClass, 'factory']);

return [
'author_id' => function () {
return User::factory()->create()->id;
},
'editable_id' => function () use ($editableFactory) {
return $editableFactory->create()->id;
},
'editable_type' => function () use ($editableClass) {
return constant($editableClass.'::TABLE') ?? $editableClass;
},
'edited_at' => $this->faker->dateTimeThisMonth(),
];
}
}
28 changes: 28 additions & 0 deletions database/migrations/2021_11_05_194336_create_edits_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use App\Models\User;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateEditsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('edits', function (Blueprint $table) {
$table->id();

$table->foreignIdFor(User::class, 'author_id');

$table->unsignedBigInteger('editable_id');
$table->string('editable_type');

$table->timestamp('edited_at');
});
}
}
8 changes: 8 additions & 0 deletions resources/views/articles/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ class="prose prose-lg text-gray-800 prose-lio"
<x-buk-markdown>{!! $article->body() !!}</x-buk-markdown>
</div>

@if($article->latestEdit)
<div class="text-sm text-gray-900 py-6">
Last edit by
<a href="{{ route('profile', $article->latestEdit->author()->username()) }}" class="text-lio-500 border-b-2 pb-0.5 border-lio-100 hover:text-lio-600">{{ $article->latestEdit->author()->name() }}</a>
on {{ $article->latestEdit->edited_at->format('j M, Y') }}.
</div>
@endif

<div class="flex items-center gap-x-6 pt-6 pb-10">
<livewire:like-article :article="$article" :isSidebar="false" />

Expand Down
8 changes: 8 additions & 0 deletions resources/views/components/threads/reply.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ class="prose prose-lio max-w-none p-6 break-words"
>
</div>

@if($reply->latestEdit)
<div class="text-sm text-gray-900 p-6">
Last edit by
<a href="{{ route('profile', $reply->latestEdit->author()->username()) }}" class="text-lio-500 border-b-2 pb-0.5 border-lio-100 hover:text-lio-600">{{ $reply->latestEdit->author()->name() }}</a>
on {{ $reply->latestEdit->edited_at->format('j M, Y') }}.
</div>
@endif

<div class="flex justify-between">
<div class="px-6 pb-6">
<livewire:like-reply :reply="$reply"/>
Expand Down
8 changes: 8 additions & 0 deletions resources/views/components/threads/thread.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ class="prose prose-lio max-w-none p-6 break-words"
>
</div>

@if($thread->latestEdit)
<div class="text-sm text-gray-900 p-6">
Last edit by
<a href="{{ route('profile', $thread->latestEdit->author()->username()) }}" class="text-lio-500 border-b-2 pb-0.5 border-lio-100 hover:text-lio-600">{{ $thread->latestEdit->author()->name() }}</a>
on {{ $thread->latestEdit->edited_at->format('j M, Y') }}.
</div>
@endif

<div class="px-6 pb-6">
<livewire:like-thread :thread="$thread"/>
</div>
Expand Down