Seditio Source
Root |
./othercms/xenForo 2.2.8/src/XF/Service/Feed/Reader.php
<?php

namespace XF\Service\Feed;

class
Reader extends \XF\Service\AbstractService
{
    protected
$url;

   
/** @var \GuzzleHttp\Client */
   
protected $client;

   
/** @var \Laminas\Feed\Reader\Feed\Rss */
   
protected $feed;

    protected
$feedData;

   
/** @var \Exception */
   
protected $exception;

    public function
__construct(\XF\App $app, $url)
    {
       
parent::__construct($app);
       
$this->setUrl($url);
       
$this->setClient();
       
$this->setFeed();
    }

    public function
setUrl($url)
    {
       
/** @var \XF\Validator\Url $validator */
       
$validator = $this->app->validator('Url');
       
$validator->coerceValue($url);
        if (!
$validator->isValid($url))
        {
            throw new \
XF\PrintableException(\XF::phrase('please_enter_valid_url'));
        }
       
$this->url = $url;
    }

    protected function
setClient()
    {
       
$this->client = $this->app->http()->client();
    }

    protected function
setFeed()
    {
        try
        {
           
$content = $this->client->get($this->url)
                ->
getBody()
                ->
getContents();

           
$this->feed = \Laminas\Feed\Reader\Reader::importString($content);
        }
        catch (\
Exception $e) { $this->exception = $e; }
    }

    public function
getFeed()
    {
        return
$this->feed;
    }

    public function
getTitle()
    {
       
$feed = $this->feed;
        if (
$feed)
        {
            return
$feed->getTitle();
        }

        return
'';
    }

    public function
getFeedData($withEntries = true)
    {
       
$feed = $this->feed;

        if (empty(
$feed))
        {
            return [];
        }

       
$this->feedData = [
           
'id' => $feed->getId(),
           
'title' => $feed->getTitle(),
           
'link' => $feed->getLink(),
           
'date_modified' => $feed->getDateModified(),
           
'description' => $feed->getDescription(),
           
'language' => $feed->getLanguage(),
           
'image' => $feed->getImage(),
           
'generator' => $feed->getGenerator(),
           
'baseUrl' => dirname($this->url),
           
'entries' => []
        ];

        if (
$withEntries)
        {
           
$this->feedData['entries'] = $this->getFeedEntries();
        }

       
$this->feedData = \XF::cleanArrayStrings($this->feedData);

        return
$this->feedData;
    }

    public function
getFeedEntries()
    {
       
$entries = [];

       
$feed = $this->feed;
        foreach (
$feed AS $entry)
        {
            try
            {
               
$content = $entry->getContent();
            }
            catch (\
Exception $e)
            {
               
// there's a situation where getting the content can trigger an exception if malformed,
                // so ensure this doesn't error
               
$content = $entry->getDescription();
            }

           
// if wrong date format is used or date is missing from the entry then the feed
            // is invalid but try to workaround it by getting the feed date or current time
           
$dateModified = $entry->getDateModified() ?: $feed->getDateModified();
            if (
$dateModified)
            {
               
$dateModified = $dateModified->getTimestamp();
            }
            else
            {
               
$dateModified = time();
            }

           
$entryData = [
               
'id' => $entry->getId(),
               
'title' => html_entity_decode($entry->getTitle(), ENT_COMPAT, 'utf-8'),
               
'description' => html_entity_decode($entry->getDescription(), ENT_COMPAT, 'utf-8'),
               
'date_modified' => $dateModified,
               
'author' => $this->getAuthorsAsString($entry->getAuthors()),
               
'link' => $entry->getLink(),
               
'content' => $this->getContent($content)
            ];

           
$enclosure = $entry->getEnclosure();
            if (
$enclosure)
            {
               
$entryData['enclosure_url'] = $enclosure->url;
               
$entryData['enclosure_length'] = $enclosure->length;
               
$entryData['enclosure_type'] = $enclosure->type;
            }

            if (
utf8_strlen($entryData['id']) > 250)
            {
               
$entryData['id'] = md5($entryData['id']);
            }

           
$entries[] = $entryData;
        }

        return
$entries;
    }

    public function
getException()
    {
        return
$this->exception;
    }

    protected function
getAuthorsAsString($feedAuthors)
    {
       
$authorNames = [];

        if (
$feedAuthors)
        {
            foreach (
$feedAuthors AS $author)
            {
                if (isset(
$author['name']))
                {
                   
$authorNames[] = $author['name'];
                }
                else if (isset(
$author['email']))
                {
                   
$authorNames[] = $author['email'];
                }
            }
        }

       
$authorNames = array_unique($authorNames);

        return
implode(', ', $authorNames);
    }

    protected function
getContent($html)
    {
       
$html = preg_replace('#<p#i', '<br>$0', $html);
       
$html = preg_replace('#</p>(?!\s*<br)#i', '$0<br>', $html);

        return \
XF\Html\Renderer\BbCode::renderFromHtml($html, [
           
'baseUrl' => $this->feedData['baseUrl']
        ]);
    }
}