ssddanbrown/mailbag

View on GitHub
app/Services/Rss/RssParser.php

Summary

Maintainability
A
0 mins
Test Coverage
<?php

namespace App\Services\Rss;

use DateTime;
use Exception;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use SimpleXMLElement;

class RssParser
{
    /**
     * Get articles from the RSS URL.
     *
     * @return ?Collection<int, RssArticle>
     */
    public function getArticles(string $url): ?Collection
    {
        $response = Http::get($url);
        if (!$response->ok()) {
            return null;
        }

        libxml_use_internal_errors(true);

        try {
            $rss = new SimpleXMLElement($response->body());
        } catch (Exception $exception) {
            return null;
        }
        $items = $rss->channel->item ?? null;

        if (is_null($items)) {
            return null;
        }

        /** @var Collection<int, RssArticle> $articles */
        $articles = new Collection();
        foreach ($rss->channel->item as $item) {
            $articles->push(new RssArticle(
                html_entity_decode(strval($item->title ?? '')),
                html_entity_decode(strval($item->link ?? '')),
                html_entity_decode(strval($item->description ?? '')),
                Carbon::createFromFormat(DateTime::RSS, strval($item->pubDate)),
            ));
        }

        return $articles;
    }
}