8000 Implement Verified Author Logic for Publishing Without Review (#1276) by AbdulrahmanReda70 · Pull Request #1303 · laravelio/laravel.io · GitHub
[go: up one dir, main page]

Skip to content

Implement Verified Author Logic for Publishing Without Review (#1276) #1303

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 27, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
wip
  • Loading branch information
driesvints committed Jun 27, 2025
commit c70bf09170f1498a41cf3bbd26895417f72456b6
19 changes: 7 additions & 12 deletions app/Http/Controllers/Articles/ArticlesController.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,13 @@ public function store(ArticleRequest $request)

$article = Article::findByUuidOrFail($uuid);

$this->maybeFlashSuccessMessage($article, $request);
if ($article->isNotApproved()) {
$this->success(
$request->shouldBeSubmitted()
? 'Thank you for submitting, unfortunately we can\'t accept every submission. You\'ll only hear back from us when we accept your article.'
: 'Article successfully created!'
);
}

return $request->wantsJson()
? ArticleResource::make($article)
Expand Down Expand Up @@ -172,15 +178,4 @@ public function delete(Request $request, Article $article)
? response()->json([], Response::HTTP_NO_CONTENT)
: redirect()->route('articles');
}

private function maybeFlashSuccessMessage(Article $article, ArticleRequest $request): void
{
if ($article->isNotApproved()) {
$this->success(
$request->shouldBeSubmitted()
? 'Thank you for submitting, unfortunately we can\'t accept every submission. You\'ll only hear back from us when we accept your article.'
: ' 8000 Article successfully created!'
);
}
}
}
3 changes: 2 additions & 1 deletion app/Jobs/UnVerifyAuthor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function __construct(private User $user)
*/
public function handle(): void
{
$this->user->unverifyAuthor();
$this->user->author_verified_at = null;
$this->user->save();
}
}
3 changes: 2 additions & 1 deletion app/Jobs/VerifyAuthor.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public function __construct(private User $user)
*/
public function handle(): void
{
$this->user->verifyAuthor();
$this->user->author_verified_at = now();
$this->user->save();
}
}
31 changes: 9 additions & 22 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -307,25 +307,7 @@ public function delete()

public function isVerifiedAuthor(): bool
{
return ! is_null($this->author_verified_at);
}

public function isNotVerifiedAuthor(): bool
{
return !$this->isVerifiedAuthor();
}

public function verifyAuthor(): void
{
$this->author_verified_at = now();
$this->save();
}


public function unverifyAuthor(): void
{
$this->author_verified_at = null;
$this->save();
return ! is_null($this->author_verified_at) || $this->isAdmin();
}

/**
Expand All @@ -338,14 +320,19 @@ public function unverifyAuthor(): void
*/
public function verifiedAuthorCanPublishMoreToday(): bool
{
$limit = 2; // Default limit for verified authors
if ($this->isNotVerifiedAuthor()) {
if ($this->isAdmin()) {
return true;
}

if (! $this->isVerifiedAuthor()) {
return false;
}

$publishedTodayCount = $this->articles()
->whereDate('submitted_at', today())
->where('submitted_at', '>', $this->author_verified_at)->count(); // to ensure we only count articles published after verify the author
return $publishedTodayCount < $limit;

return $publishedTodayCount < 2;
}

public function countSolutions(): int
Expand Down
7 changes: 7 additions & 0 deletions database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,11 @@ public function moderator(): self
return ['type' => User::MODERATOR];
});
}

public function verifiedAuthor(): self
{
return $this->state(function () {
return ['author_verified_at' => now()];
});
}
}
1 change: 0 additions & 1 deletion database/seeders/UserSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public function run(): void
'github_username' => 'driesvints',
'password' => bcrypt('password'),
'type' => User::ADMIN,
'author_verified_at' => now(),
]);

User::factory()->createQuietly([
Expand Down
13 changes: 3 additions & 10 deletions tests/CreatesUsers.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Tests;

use App\Models\User;
use Database\Factories\UserFactory;

trait CreatesUsers
{
Expand Down Expand Up @@ -30,22 +31,14 @@ protected function loginAsAdmin(array $attributes = []): User
return $this->login(array_merge($attributes, ['type' => User::ADMIN]));
}

protected function createUser(array $attributes = []): User
protected function createUser(array $attributes = [], ?UserFactory $userFactory = null): User
{
return User::factory()->create(array_merge([
return ($userFactory ?? User::factory())->create(array_merge([
'name' => 'John Doe',
'username' => 'johndoe',
'email' => 'john@example.com',
'password' => bcrypt('password'),
'github_username' => 'johndoe',
], $attributes));
}

protected function createVerifiedAuthor(array $attributes = []): User
{
return $this->createUser(array_merge($attributes, [
'author_verified_at' => now(),
]));
}

}
5 changes: 3 additions & 2 deletions tests/Feature/ArticleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use App\Jobs\SyncArticleImage;
use App\Models\Article;
use App\Models\Tag;
use App\Models\User;
use App\Notifications\ArticleApprovedNotification;
use App\Notifications\ArticleSubmitted;
use Illuminate\Foundation\Testing\DatabaseMigrations;
Expand Down Expand Up @@ -586,7 +587,7 @@
});

test('verified authors can publish two articles per day with no approval needed', function () {
$author = $this->createVerifiedAuthor();
$author = $this->createUser(userFactory: User::factory()->verifiedAuthor());

Article::factory()->count(2)->create([
'author_id' => $author->id,
Expand All @@ -599,7 +600,7 @@
test('verified authors skip the approval message when submitting new article', function () {
Bus::fake(SyncArticleImage::class);

$author = $this->createVerifiedAuthor();
$author = $this->createUser(userFactory: User::factory()->verifiedAuthor());
$this->loginAs($author);

$response = $this->post('/articles', [
Expand Down
0