80 lines
2.7 KiB
PHP
80 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Publishing;
|
|
|
|
use App\Enums\PlatformEnum;
|
|
use App\Exceptions\PublishException;
|
|
use App\Models\Article;
|
|
use App\Models\ArticlePublication;
|
|
use App\Models\PlatformChannel;
|
|
use App\Modules\Lemmy\Services\LemmyPublisher;
|
|
use App\Services\Log\LogSaver;
|
|
use Exception;
|
|
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
|
|
use Illuminate\Support\Collection;
|
|
use RuntimeException;
|
|
|
|
class ArticlePublishingService
|
|
{
|
|
/**
|
|
* @throws PublishException
|
|
*/
|
|
public function publishToRoutedChannels(Article $article, array $extractedData): Collection
|
|
{
|
|
if (! $article->is_valid) {
|
|
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
|
|
}
|
|
|
|
$feed = $article->feed;
|
|
|
|
/** @var EloquentCollection<int, PlatformChannel> $activeChannels */
|
|
$activeChannels = $feed->activeChannels()->with(['platformInstance', 'activePlatformAccounts'])->get();
|
|
|
|
return $activeChannels->map(function (PlatformChannel $channel) use ($article, $extractedData) {
|
|
$account = $channel->activePlatformAccounts()->first();
|
|
|
|
if (! $account) {
|
|
LogSaver::warning('No active account for channel', $channel, [
|
|
'article_id' => $article->id
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
|
|
return $this->publishToChannel($article, $extractedData, $channel, $account);
|
|
})
|
|
->filter();
|
|
}
|
|
|
|
private function publishToChannel(Article $article, array $extractedData, $channel, $account): ?ArticlePublication
|
|
{
|
|
try {
|
|
$publisher = new LemmyPublisher($account);
|
|
$postData = $publisher->publishToChannel($article, $extractedData, $channel);
|
|
|
|
$publication = ArticlePublication::create([
|
|
'article_id' => $article->id,
|
|
'post_id' => $postData['post_view']['post']['id'],
|
|
'platform_channel_id' => $channel->id,
|
|
'published_by' => $account->username,
|
|
'published_at' => now(),
|
|
'platform' => $channel->platformInstance->platform->value,
|
|
'publication_data' => $postData,
|
|
]);
|
|
|
|
LogSaver::info('Published to channel via routing', $channel, [
|
|
'article_id' => $article->id,
|
|
'priority' => $channel->pivot->priority
|
|
]);
|
|
|
|
return $publication;
|
|
} catch (Exception $e) {
|
|
LogSaver::warning('Failed to publish to channel', $channel, [
|
|
'article_id' => $article->id,
|
|
'error' => $e->getMessage()
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
}
|