127 lines
4.1 KiB
PHP
127 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Vdlp\RssFetcher\Http\Controllers;
|
|
|
|
use Illuminate\Database\Eloquent\Collection;
|
|
use Illuminate\Http\Response;
|
|
use Illuminate\Routing\ResponseFactory;
|
|
use Illuminate\Routing\UrlGenerator;
|
|
use Illuminate\Support\Arr;
|
|
use Laminas\Feed\Writer\Entry;
|
|
use Laminas\Feed\Writer\Exception\InvalidArgumentException;
|
|
use Laminas\Feed\Writer\Feed;
|
|
use October\Rain\Database\Relations\HasMany;
|
|
use Vdlp\RssFetcher\Models\Feed as FeedModel;
|
|
use Vdlp\RssFetcher\Models\Item;
|
|
use Vdlp\RssFetcher\Models\Source;
|
|
|
|
class FeedController
|
|
{
|
|
/**
|
|
* @var UrlGenerator
|
|
*/
|
|
private $urlGenerator;
|
|
|
|
/**
|
|
* @var ResponseFactory
|
|
*/
|
|
private $responseFactory;
|
|
|
|
/**
|
|
* @param UrlGenerator $urlGenerator
|
|
* @param ResponseFactory $responseFactory
|
|
*/
|
|
public function __construct(UrlGenerator $urlGenerator, ResponseFactory $responseFactory)
|
|
{
|
|
$this->urlGenerator = $urlGenerator;
|
|
$this->responseFactory = $responseFactory;
|
|
}
|
|
|
|
/**
|
|
* @param string $path
|
|
* @return Response
|
|
* @throws InvalidArgumentException
|
|
*/
|
|
public function all(string $path): Response
|
|
{
|
|
/** @var FeedModel $model */
|
|
$model = FeedModel::query()->where('path', '=', $path)->first();
|
|
if ($model === null) {
|
|
return $this->responseFactory->make('Not Found', 404);
|
|
}
|
|
|
|
$feed = new Feed();
|
|
$feed->setTitle($model->getAttribute('title'))
|
|
->setDescription($model->getAttribute('description'))
|
|
->setBaseUrl($this->urlGenerator->to('/'))
|
|
->setGenerator('OctoberCMS/Vdlp.RssFetcher')
|
|
->setId('Vdlp.RssFetcher.' . $model->getAttribute('id'))
|
|
->setLink($this->urlGenerator->to('/feeds/' . $path))
|
|
->setFeedLink($this->urlGenerator->to('/feeds/' . $path), $model->getAttribute('type'))
|
|
->setDateModified()
|
|
->addAuthor(['name' => 'October CMS']);
|
|
|
|
/** @var Collection $sources */
|
|
$sources = $model->getAttribute('sources');
|
|
$ids = Arr::pluck($sources->toArray(), 'id');
|
|
$items = [];
|
|
|
|
Source::with(['items' => static function (HasMany $builder) use (&$items, $model) {
|
|
$items = $builder->where('is_published', '=', 1)
|
|
->whereDate('pub_date', '<=', date('Y-m-d'))
|
|
->orderBy('pub_date', 'desc')
|
|
->limit($model->getAttribute('max_items'))
|
|
->get();
|
|
}])->whereIn('id', $ids)
|
|
->where('is_enabled', '=', 1)
|
|
->get();
|
|
|
|
/** @var Item $item */
|
|
foreach ($items as $item) {
|
|
try {
|
|
$entry = new Entry();
|
|
|
|
$entry->setId((string) $item->getAttribute('id'))
|
|
->setTitle($item->getAttribute('title'))
|
|
->setDescription($item->getAttribute('description'))
|
|
->setLink($item->getAttribute('link'))
|
|
->setDateModified($item->getAttribute('pub_date'));
|
|
|
|
$comments = $item->getAttribute('comments');
|
|
if (!empty($comments)) {
|
|
$entry->setCommentLink($comments);
|
|
}
|
|
|
|
$category = $item->getAttribute('category');
|
|
if (!empty($category)) {
|
|
$entry->addCategory(['term' => $category]);
|
|
}
|
|
|
|
$enclosureUrl = $item->getAttribute('enclosure_url');
|
|
|
|
if (!empty($enclosureUrl)) {
|
|
$entry->setEnclosure([
|
|
'uri' => $enclosureUrl,
|
|
'type' => $item->getAttribute('enclosure_type'),
|
|
'length' => $item->getAttribute('enclosure_length'),
|
|
]);
|
|
}
|
|
|
|
$feed->addEntry($entry);
|
|
} catch (InvalidArgumentException $e) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return $this->responseFactory->make(
|
|
$feed->export($model->getAttribute('type')),
|
|
200,
|
|
[
|
|
'Content-Type' => sprintf('application/%s+xml', $model->getAttribute('type')),
|
|
]
|
|
);
|
|
}
|
|
}
|