If a Micropub h-entry post's title matches an existing article that's still a draft, update that article in place rather than trying to insert a duplicate. If it matches one that's already published, reject the request with a clear error instead of silently colliding. Also set includeTrashed on Article's slug config as a safety net: this model soft-deletes, and Sluggable's uniqueness check ignores trashed rows by default, so a previously-deleted article's title could crash new inserts with a raw unique constraint violation (this is exactly what surfaced in Flare as a UniqueConstraintViolationException on articles_titleurl_unique once the prior swallowed-exception fix shipped). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
36 lines
868 B
PHP
36 lines
868 B
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Article;
|
|
|
|
class ArticleService
|
|
{
|
|
/**
|
|
* @throws \InvalidArgumentException if a published article already has this title
|
|
*/
|
|
public function create(array $data): Article
|
|
{
|
|
$attributes = [
|
|
'title' => $data['name'],
|
|
'main' => $data['content'],
|
|
'published' => ($data['post-status'] ?? null) !== 'draft',
|
|
];
|
|
|
|
$existing = Article::where('title', $data['name'])->first();
|
|
|
|
if ($existing !== null) {
|
|
if ($existing->published) {
|
|
throw new \InvalidArgumentException("An article titled \"{$data['name']}\" has already been published");
|
|
}
|
|
|
|
$existing->update($attributes);
|
|
|
|
return $existing;
|
|
}
|
|
|
|
return Article::create($attributes);
|
|
}
|
|
}
|