castopod/modules/WebSub/Commands/Publish.php

94 lines
2.9 KiB
PHP

<?php
declare(strict_types=1);
namespace Modules\WebSub\Commands;
use App\Models\EpisodeModel;
use App\Models\PodcastModel;
use CodeIgniter\CLI\BaseCommand;
use CodeIgniter\HTTP\CURLRequest;
use Exception;
class Publish extends BaseCommand
{
protected $group = 'Websub';
protected $name = 'websub:publish';
protected $description = 'Publishes feed updates to websub hubs.';
public function run(array $params): void
{
if (ENVIRONMENT !== 'production') {
return;
}
helper('misc');
// get all podcasts that haven't been published yet
// or having a published episode that hasn't been pushed yet
$podcastModel = new PodcastModel();
$podcastModel->builder()
->select('podcasts.*')
->distinct()
->join('episodes', 'podcasts.id = episodes.podcast_id', 'left outer')
->where('podcasts.is_published_on_hubs', false)
->where('`' . $podcastModel->db->getPrefix() . 'podcasts`.`published_at` <= UTC_TIMESTAMP()', null, false)
->orGroupStart()
->where('episodes.is_published_on_hubs', false)
->where('`' . $podcastModel->db->getPrefix() . 'episodes`.`published_at` <= UTC_TIMESTAMP()', null, false)
->groupEnd();
$podcasts = $podcastModel->findAll();
if ($podcasts === []) {
return;
}
/** @var CURLRequest $request */
$request = service('curlrequest');
$requestOptions = [
'headers' => [
'User-Agent' => 'Castopod/' . CP_VERSION . '; +' . base_url('', 'https'),
'Content-Type' => 'application/x-www-form-urlencoded',
],
];
$hubUrls = config('WebSub')
->hubs;
foreach ($podcasts as $podcast) {
$requestOptions['form_params'] = [
'hub.mode' => 'publish',
'hub.url' => $podcast->feed_url,
];
foreach ($hubUrls as $hub) {
try {
$request->post($hub, $requestOptions);
} catch (Exception $exception) {
log_message(
'warning',
"COULD NOT PUBLISH @{$podcast->handle} ON {$hub}" . PHP_EOL . $exception->getMessage()
);
}
}
// set podcast feed as having been pushed onto hubs
(new PodcastModel())->update($podcast->id, [
'is_published_on_hubs' => 1,
]);
// set newly published episodes as pushed onto hubs
(new EpisodeModel())->set('is_published_on_hubs', true)
->where([
'podcast_id' => $podcast->id,
'is_published_on_hubs' => false,
])
->where('`published_at` <= UTC_TIMESTAMP()', null, false)
->update();
}
}
}