108 lines
3.6 KiB
PHP
108 lines
3.6 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Actions;
|
||
|
|
|
||
|
|
use App\Enums\LogLevelEnum;
|
||
|
|
use App\Enums\NotificationSeverityEnum;
|
||
|
|
use App\Enums\NotificationTypeEnum;
|
||
|
|
use App\Enums\PublishStatusEnum;
|
||
|
|
use App\Events\ActionPerformed;
|
||
|
|
use App\Exceptions\PublishException;
|
||
|
|
use App\Models\RouteArticle;
|
||
|
|
use App\Services\Article\ArticleFetcher;
|
||
|
|
use App\Services\Notification\NotificationService;
|
||
|
|
use App\Services\Publishing\ArticlePublishingService;
|
||
|
|
use App\Services\Publishing\PublishOutcome;
|
||
|
|
use Exception;
|
||
|
|
|
||
|
|
class PublishRouteArticleAction
|
||
|
|
{
|
||
|
|
public function __construct(
|
||
|
|
private ArticleFetcher $articleFetcher,
|
||
|
|
private ArticlePublishingService $publishingService,
|
||
|
|
private NotificationService $notificationService,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @throws PublishException
|
||
|
|
*/
|
||
|
|
public function execute(RouteArticle $routeArticle): PublishOutcome
|
||
|
|
{
|
||
|
|
$article = $routeArticle->article;
|
||
|
|
|
||
|
|
$routeArticle->update(['publish_status' => PublishStatusEnum::PUBLISHING]);
|
||
|
|
|
||
|
|
try {
|
||
|
|
$extractedData = $this->articleFetcher->fetchArticleData($article);
|
||
|
|
$outcome = $this->publishingService->publishRouteArticle($routeArticle, $extractedData);
|
||
|
|
} catch (Exception $e) {
|
||
|
|
$routeArticle->update(['publish_status' => PublishStatusEnum::ERROR]);
|
||
|
|
|
||
|
|
ActionPerformed::dispatch('Failed to publish article', LogLevelEnum::ERROR, [
|
||
|
|
'article_id' => $article->id,
|
||
|
|
'error' => $e->getMessage(),
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->notificationService->send(
|
||
|
|
NotificationTypeEnum::PUBLISH_FAILED,
|
||
|
|
NotificationSeverityEnum::ERROR,
|
||
|
|
"Publish failed: {$article->title}",
|
||
|
|
$e->getMessage(),
|
||
|
|
$article,
|
||
|
|
);
|
||
|
|
|
||
|
|
throw $e;
|
||
|
|
}
|
||
|
|
|
||
|
|
match (true) {
|
||
|
|
$outcome->succeeded() => $this->recordPublished($routeArticle),
|
||
|
|
$outcome->wasSkipped() => $this->recordSkipped($routeArticle, $outcome),
|
||
|
|
default => $this->recordFailed($routeArticle, $outcome),
|
||
|
|
};
|
||
|
|
|
||
|
|
return $outcome;
|
||
|
|
}
|
||
|
|
|
||
|
|
private function recordPublished(RouteArticle $routeArticle): void
|
||
|
|
{
|
||
|
|
$routeArticle->update(['publish_status' => PublishStatusEnum::PUBLISHED]);
|
||
|
|
|
||
|
|
ActionPerformed::dispatch('Published article', LogLevelEnum::INFO, [
|
||
|
|
'article_id' => $routeArticle->article->id,
|
||
|
|
'title' => $routeArticle->article->title,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function recordSkipped(RouteArticle $routeArticle, PublishOutcome $outcome): void
|
||
|
|
{
|
||
|
|
$routeArticle->update(['publish_status' => PublishStatusEnum::SKIPPED]);
|
||
|
|
|
||
|
|
ActionPerformed::dispatch('Skipped publishing article', LogLevelEnum::INFO, [
|
||
|
|
'article_id' => $routeArticle->article->id,
|
||
|
|
'title' => $routeArticle->article->title,
|
||
|
|
'reason' => $outcome->reason,
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
private function recordFailed(RouteArticle $routeArticle, PublishOutcome $outcome): void
|
||
|
|
{
|
||
|
|
$article = $routeArticle->article;
|
||
|
|
|
||
|
|
$routeArticle->update(['publish_status' => PublishStatusEnum::ERROR]);
|
||
|
|
|
||
|
|
ActionPerformed::dispatch('No publication created for article', LogLevelEnum::WARNING, [
|
||
|
|
'article_id' => $article->id,
|
||
|
|
'title' => $article->title,
|
||
|
|
'reason' => $outcome->reason,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$this->notificationService->send(
|
||
|
|
NotificationTypeEnum::PUBLISH_FAILED,
|
||
|
|
NotificationSeverityEnum::WARNING,
|
||
|
|
"Publish failed: {$article->title}",
|
||
|
|
$outcome->reason ?? 'No publication was created for this article.',
|
||
|
|
$article,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|