Make WordPress Core


Ignore:
Timestamp:
09/30/2024 10:48:16 PM (7 months ago)
Author:
SergeyBiryukov
Message:

External Libraries: Update the SimplePie library to version 1.8.0.

The most notable change in this update is that all code is now namespaced and uses PSR-4 classes, though there is a compatibility layer available for extenders using the older class names, so plugin or theme authors directly using SimplePie can decide for themselves when they want to change to using the namespaced names for SimplePie classes.

Note: This commit includes additional fixes for PHP 8.4 compatibility (PR 875, PR 888) from the one-dot-eight branch of SimplePie, which is expected to be released as SimplePie 1.8.1 soon.

References:

Follow-up to [47733], [49176], [52393], [52413].

Props jrf, peterwilsoncc, chaion07, cu121, markparnell, audrasjb, costdev, Presskopp, desrosj, faisal03, mukesh27, SergeyBiryukov.
See #55604.

Location:
trunk/src/wp-includes/SimplePie/src
Files:
1 added
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/SimplePie/src/Locator.php

    r59140 r59141  
    11<?php
     2
    23/**
    34 * SimplePie
     
    67 * Takes the hard work out of managing a complete RSS/Atom solution.
    78 *
    8  * Copyright (c) 2004-2016, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
     9 * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
    910 * All rights reserved.
    1011 *
     
    4243 */
    4344
     45namespace SimplePie;
     46
    4447/**
    4548 * Used for feed auto-discovery
    4649 *
    4750 *
    48  * This class can be overloaded with {@see SimplePie::set_locator_class()}
     51 * This class can be overloaded with {@see \SimplePie\SimplePie::set_locator_class()}
    4952 *
    5053 * @package SimplePie
    5154 */
    52 class SimplePie_Locator
     55class Locator implements RegistryAware
    5356{
    54     var $useragent;
    55     var $timeout;
    56     var $file;
    57     var $local = array();
    58     var $elsewhere = array();
    59     var $cached_entities = array();
    60     var $http_base;
    61     var $base;
    62     var $base_location = 0;
    63     var $checked_feeds = 0;
    64     var $max_checked_feeds = 10;
    65     var $force_fsockopen = false;
    66     var $curl_options = array();
    67     var $dom;
    68     protected $registry;
    69 
    70     public function __construct(SimplePie_File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10, $force_fsockopen = false, $curl_options = array())
    71     {
    72         $this->file = $file;
    73         $this->useragent = $useragent;
    74         $this->timeout = $timeout;
    75         $this->max_checked_feeds = $max_checked_feeds;
    76         $this->force_fsockopen = $force_fsockopen;
    77         $this->curl_options = $curl_options;
    78 
    79         if (class_exists('DOMDocument') && $this->file->body != '')
    80         {
    81             $this->dom = new DOMDocument();
    82 
    83             set_error_handler(array('SimplePie_Misc', 'silence_errors'));
    84             try
    85             {
    86                 $this->dom->loadHTML($this->file->body);
    87             }
    88             catch (Throwable $ex)
    89             {
    90                 $this->dom = null;
    91             }
    92             restore_error_handler();
    93         }
    94         else
    95         {
    96             $this->dom = null;
    97         }
    98     }
    99 
    100     public function set_registry(SimplePie_Registry $registry)
    101     {
    102         $this->registry = $registry;
    103     }
    104 
    105     public function find($type = SIMPLEPIE_LOCATOR_ALL, &$working = null)
    106     {
    107         if ($this->is_feed($this->file))
    108         {
    109             return $this->file;
    110         }
    111 
    112         if ($this->file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
    113         {
    114             $sniffer = $this->registry->create('Content_Type_Sniffer', array($this->file));
    115             if ($sniffer->get_type() !== 'text/html')
    116             {
    117                 return null;
    118             }
    119         }
    120 
    121         if ($type & ~SIMPLEPIE_LOCATOR_NONE)
    122         {
    123             $this->get_base();
    124         }
    125 
    126         if ($type & SIMPLEPIE_LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery())
    127         {
    128             return $working[0];
    129         }
    130 
    131         if ($type & (SIMPLEPIE_LOCATOR_LOCAL_EXTENSION | SIMPLEPIE_LOCATOR_LOCAL_BODY | SIMPLEPIE_LOCATOR_REMOTE_EXTENSION | SIMPLEPIE_LOCATOR_REMOTE_BODY) && $this->get_links())
    132         {
    133             if ($type & SIMPLEPIE_LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local))
    134             {
    135                 return $working[0];
    136             }
    137 
    138             if ($type & SIMPLEPIE_LOCATOR_LOCAL_BODY && $working = $this->body($this->local))
    139             {
    140                 return $working[0];
    141             }
    142 
    143             if ($type & SIMPLEPIE_LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere))
    144             {
    145                 return $working[0];
    146             }
    147 
    148             if ($type & SIMPLEPIE_LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere))
    149             {
    150                 return $working[0];
    151             }
    152         }
    153         return null;
    154     }
    155 
    156     public function is_feed($file, $check_html = false)
    157     {
    158         if ($file->method & SIMPLEPIE_FILE_SOURCE_REMOTE)
    159         {
    160             $sniffer = $this->registry->create('Content_Type_Sniffer', array($file));
    161             $sniffed = $sniffer->get_type();
    162             $mime_types = array('application/rss+xml', 'application/rdf+xml',
    163                                 'text/rdf', 'application/atom+xml', 'text/xml',
    164                                 'application/xml', 'application/x-rss+xml');
    165             if ($check_html)
    166             {
    167                 $mime_types[] = 'text/html';
    168             }
    169 
    170             return in_array($sniffed, $mime_types);
    171         }
    172         elseif ($file->method & SIMPLEPIE_FILE_SOURCE_LOCAL)
    173         {
    174             return true;
    175         }
    176         else
    177         {
    178             return false;
    179         }
    180     }
    181 
    182     public function get_base()
    183     {
    184         if ($this->dom === null)
    185         {
    186             throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
    187         }
    188         $this->http_base = $this->file->url;
    189         $this->base = $this->http_base;
    190         $elements = $this->dom->getElementsByTagName('base');
    191         foreach ($elements as $element)
    192         {
    193             if ($element->hasAttribute('href'))
    194             {
    195                 $base = $this->registry->call('Misc', 'absolutize_url', array(trim($element->getAttribute('href')), $this->http_base));
    196                 if ($base === false)
    197                 {
    198                     continue;
    199                 }
    200                 $this->base = $base;
    201                 $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
    202                 break;
    203             }
    204         }
    205     }
    206 
    207     public function autodiscovery()
    208     {
    209         $done = array();
    210         $feeds = array();
    211         $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
    212         $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
    213         $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
    214 
    215         if (!empty($feeds))
    216         {
    217             return array_values($feeds);
    218         }
    219 
    220         return null;
    221     }
    222 
    223     protected function search_elements_by_tag($name, &$done, $feeds)
    224     {
    225         if ($this->dom === null)
    226         {
    227             throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
    228         }
    229 
    230         $links = $this->dom->getElementsByTagName($name);
    231         foreach ($links as $link)
    232         {
    233             if ($this->checked_feeds === $this->max_checked_feeds)
    234             {
    235                 break;
    236             }
    237             if ($link->hasAttribute('href') && $link->hasAttribute('rel'))
    238             {
    239                 $rel = array_unique($this->registry->call('Misc', 'space_separated_tokens', array(strtolower($link->getAttribute('rel')))));
    240                 $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
    241 
    242                 if ($this->base_location < $line)
    243                 {
    244                     $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
    245                 }
    246                 else
    247                 {
    248                     $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
    249                 }
    250                 if ($href === false)
    251                 {
    252                     continue;
    253                 }
    254 
    255                 if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call('Misc', 'parse_mime', array($link->getAttribute('type')))), array('text/html', 'application/rss+xml', 'application/atom+xml'))) && !isset($feeds[$href]))
    256                 {
    257                     $this->checked_feeds++;
    258                     $headers = array(
    259                         'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
    260                     );
    261                     $feed = $this->registry->create('File', array($href, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
    262                     if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true))
    263                     {
    264                         $feeds[$href] = $feed;
    265                     }
    266                 }
    267                 $done[] = $href;
    268             }
    269         }
    270 
    271         return $feeds;
    272     }
    273 
    274     public function get_links()
    275     {
    276         if ($this->dom === null)
    277         {
    278             throw new SimplePie_Exception('DOMDocument not found, unable to use locator');
    279         }
    280 
    281         $links = $this->dom->getElementsByTagName('a');
    282         foreach ($links as $link)
    283         {
    284             if ($link->hasAttribute('href'))
    285             {
    286                 $href = trim($link->getAttribute('href'));
    287                 $parsed = $this->registry->call('Misc', 'parse_url', array($href));
    288                 if ($parsed['scheme'] === '' || preg_match('/^(https?|feed)?$/i', $parsed['scheme']))
    289                 {
    290                     if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo())
    291                     {
    292                         $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->base));
    293                     }
    294                     else
    295                     {
    296                         $href = $this->registry->call('Misc', 'absolutize_url', array(trim($link->getAttribute('href')), $this->http_base));
    297                     }
    298                     if ($href === false)
    299                     {
    300                         continue;
    301                     }
    302 
    303                     $current = $this->registry->call('Misc', 'parse_url', array($this->file->url));
    304 
    305                     if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority'])
    306                     {
    307                         $this->local[] = $href;
    308                     }
    309                     else
    310                     {
    311                         $this->elsewhere[] = $href;
    312                     }
    313                 }
    314             }
    315         }
    316         $this->local = array_unique($this->local);
    317         $this->elsewhere = array_unique($this->elsewhere);
    318         if (!empty($this->local) || !empty($this->elsewhere))
    319         {
    320             return true;
    321         }
    322         return null;
    323     }
    324 
    325     public function get_rel_link($rel)
    326     {
    327         if ($this->dom === null)
    328         {
    329             throw new SimplePie_Exception('DOMDocument not found, unable to use '.
    330                                           'locator');
    331         }
    332         if (!class_exists('DOMXpath'))
    333         {
    334             throw new SimplePie_Exception('DOMXpath not found, unable to use '.
    335                                           'get_rel_link');
    336         }
    337 
    338         $xpath = new DOMXpath($this->dom);
    339         $query = '//a[@rel and @href] | //link[@rel and @href]';
    340         foreach ($xpath->query($query) as $link)
    341         {
    342             $href = trim($link->getAttribute('href'));
    343             $parsed = $this->registry->call('Misc', 'parse_url', array($href));
    344             if ($parsed['scheme'] === '' ||
    345                 preg_match('/^https?$/i', $parsed['scheme']))
    346             {
    347                 if (method_exists($link, 'getLineNo') &&
    348                     $this->base_location < $link->getLineNo())
    349                 {
    350                     $href =
    351                         $this->registry->call('Misc', 'absolutize_url',
    352                                               array(trim($link->getAttribute('href')),
    353                                                     $this->base));
    354                 }
    355                 else
    356                 {
    357                     $href =
    358                         $this->registry->call('Misc', 'absolutize_url',
    359                                               array(trim($link->getAttribute('href')),
    360                                                     $this->http_base));
    361                 }
    362                 if ($href === false)
    363                 {
    364                     return null;
    365                 }
    366                 $rel_values = explode(' ', strtolower($link->getAttribute('rel')));
    367                 if (in_array($rel, $rel_values))
    368                 {
    369                     return $href;
    370                 }
    371             }
    372         }
    373         return null;
    374     }
    375 
    376     public function extension(&$array)
    377     {
    378         foreach ($array as $key => $value)
    379         {
    380             if ($this->checked_feeds === $this->max_checked_feeds)
    381             {
    382                 break;
    383             }
    384             if (in_array(strtolower(strrchr($value, '.')), array('.rss', '.rdf', '.atom', '.xml')))
    385             {
    386                 $this->checked_feeds++;
    387 
    388                 $headers = array(
    389                     'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
    390                 );
    391                 $feed = $this->registry->create('File', array($value, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options));
    392                 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
    393                 {
    394                     return array($feed);
    395                 }
    396                 else
    397                 {
    398                     unset($array[$key]);
    399                 }
    400             }
    401         }
    402         return null;
    403     }
    404 
    405     public function body(&$array)
    406     {
    407         foreach ($array as $key => $value)
    408         {
    409             if ($this->checked_feeds === $this->max_checked_feeds)
    410             {
    411                 break;
    412             }
    413             if (preg_match('/(feed|rss|rdf|atom|xml)/i', $value))
    414             {
    415                 $this->checked_feeds++;
    416                 $headers = array(
    417                     'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
    418                 );
    419                 $feed = $this->registry->create('File', array($value, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->curl_options));
    420                 if ($feed->success && ($feed->method & SIMPLEPIE_FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed))
    421                 {
    422                     return array($feed);
    423                 }
    424                 else
    425                 {
    426                     unset($array[$key]);
    427                 }
    428             }
    429         }
    430         return null;
    431     }
     57    public $useragent;
     58    public $timeout;
     59    public $file;
     60    public $local = [];
     61    public $elsewhere = [];
     62    public $cached_entities = [];
     63    public $http_base;
     64    public $base;
     65    public $base_location = 0;
     66    public $checked_feeds = 0;
     67    public $max_checked_feeds = 10;
     68    public $force_fsockopen = false;
     69    public $curl_options = [];
     70    public $dom;
     71    protected $registry;
     72
     73    public function __construct(\SimplePie\File $file, $timeout = 10, $useragent = null, $max_checked_feeds = 10, $force_fsockopen = false, $curl_options = [])
     74    {
     75        $this->file = $file;
     76        $this->useragent = $useragent;
     77        $this->timeout = $timeout;
     78        $this->max_checked_feeds = $max_checked_feeds;
     79        $this->force_fsockopen = $force_fsockopen;
     80        $this->curl_options = $curl_options;
     81
     82        if (class_exists('DOMDocument') && $this->file->body != '') {
     83            $this->dom = new \DOMDocument();
     84
     85            set_error_handler(['SimplePie\Misc', 'silence_errors']);
     86            try {
     87                $this->dom->loadHTML($this->file->body);
     88            } catch (\Throwable $ex) {
     89                $this->dom = null;
     90            }
     91            restore_error_handler();
     92        } else {
     93            $this->dom = null;
     94        }
     95    }
     96
     97    public function set_registry(\SimplePie\Registry $registry)/* : void */
     98    {
     99        $this->registry = $registry;
     100    }
     101
     102    public function find($type = \SimplePie\SimplePie::LOCATOR_ALL, &$working = null)
     103    {
     104        if ($this->is_feed($this->file)) {
     105            return $this->file;
     106        }
     107
     108        if ($this->file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE) {
     109            $sniffer = $this->registry->create(Content\Type\Sniffer::class, [$this->file]);
     110            if ($sniffer->get_type() !== 'text/html') {
     111                return null;
     112            }
     113        }
     114
     115        if ($type & ~\SimplePie\SimplePie::LOCATOR_NONE) {
     116            $this->get_base();
     117        }
     118
     119        if ($type & \SimplePie\SimplePie::LOCATOR_AUTODISCOVERY && $working = $this->autodiscovery()) {
     120            return $working[0];
     121        }
     122
     123        if ($type & (\SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION | \SimplePie\SimplePie::LOCATOR_LOCAL_BODY | \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION | \SimplePie\SimplePie::LOCATOR_REMOTE_BODY) && $this->get_links()) {
     124            if ($type & \SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION && $working = $this->extension($this->local)) {
     125                return $working[0];
     126            }
     127
     128            if ($type & \SimplePie\SimplePie::LOCATOR_LOCAL_BODY && $working = $this->body($this->local)) {
     129                return $working[0];
     130            }
     131
     132            if ($type & \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION && $working = $this->extension($this->elsewhere)) {
     133                return $working[0];
     134            }
     135
     136            if ($type & \SimplePie\SimplePie::LOCATOR_REMOTE_BODY && $working = $this->body($this->elsewhere)) {
     137                return $working[0];
     138            }
     139        }
     140        return null;
     141    }
     142
     143    public function is_feed($file, $check_html = false)
     144    {
     145        if ($file->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE) {
     146            $sniffer = $this->registry->create(Content\Type\Sniffer::class, [$file]);
     147            $sniffed = $sniffer->get_type();
     148            $mime_types = ['application/rss+xml', 'application/rdf+xml',
     149                                'text/rdf', 'application/atom+xml', 'text/xml',
     150                                'application/xml', 'application/x-rss+xml'];
     151            if ($check_html) {
     152                $mime_types[] = 'text/html';
     153            }
     154
     155            return in_array($sniffed, $mime_types);
     156        } elseif ($file->method & \SimplePie\SimplePie::FILE_SOURCE_LOCAL) {
     157            return true;
     158        } else {
     159            return false;
     160        }
     161    }
     162
     163    public function get_base()
     164    {
     165        if ($this->dom === null) {
     166            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
     167        }
     168        $this->http_base = $this->file->url;
     169        $this->base = $this->http_base;
     170        $elements = $this->dom->getElementsByTagName('base');
     171        foreach ($elements as $element) {
     172            if ($element->hasAttribute('href')) {
     173                $base = $this->registry->call(Misc::class, 'absolutize_url', [trim($element->getAttribute('href')), $this->http_base]);
     174                if ($base === false) {
     175                    continue;
     176                }
     177                $this->base = $base;
     178                $this->base_location = method_exists($element, 'getLineNo') ? $element->getLineNo() : 0;
     179                break;
     180            }
     181        }
     182    }
     183
     184    public function autodiscovery()
     185    {
     186        $done = [];
     187        $feeds = [];
     188        $feeds = array_merge($feeds, $this->search_elements_by_tag('link', $done, $feeds));
     189        $feeds = array_merge($feeds, $this->search_elements_by_tag('a', $done, $feeds));
     190        $feeds = array_merge($feeds, $this->search_elements_by_tag('area', $done, $feeds));
     191
     192        if (!empty($feeds)) {
     193            return array_values($feeds);
     194        }
     195
     196        return null;
     197    }
     198
     199    protected function search_elements_by_tag($name, &$done, $feeds)
     200    {
     201        if ($this->dom === null) {
     202            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
     203        }
     204
     205        $links = $this->dom->getElementsByTagName($name);
     206        foreach ($links as $link) {
     207            if ($this->checked_feeds === $this->max_checked_feeds) {
     208                break;
     209            }
     210            if ($link->hasAttribute('href') && $link->hasAttribute('rel')) {
     211                $rel = array_unique($this->registry->call(Misc::class, 'space_separated_tokens', [strtolower($link->getAttribute('rel'))]));
     212                $line = method_exists($link, 'getLineNo') ? $link->getLineNo() : 1;
     213
     214                if ($this->base_location < $line) {
     215                    $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->base]);
     216                } else {
     217                    $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->http_base]);
     218                }
     219                if ($href === false) {
     220                    continue;
     221                }
     222
     223                if (!in_array($href, $done) && in_array('feed', $rel) || (in_array('alternate', $rel) && !in_array('stylesheet', $rel) && $link->hasAttribute('type') && in_array(strtolower($this->registry->call(Misc::class, 'parse_mime', [$link->getAttribute('type')])), ['text/html', 'application/rss+xml', 'application/atom+xml'])) && !isset($feeds[$href])) {
     224                    $this->checked_feeds++;
     225                    $headers = [
     226                        'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
     227                    ];
     228                    $feed = $this->registry->create(File::class, [$href, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
     229                    if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed, true)) {
     230                        $feeds[$href] = $feed;
     231                    }
     232                }
     233                $done[] = $href;
     234            }
     235        }
     236
     237        return $feeds;
     238    }
     239
     240    public function get_links()
     241    {
     242        if ($this->dom === null) {
     243            throw new \SimplePie\Exception('DOMDocument not found, unable to use locator');
     244        }
     245
     246        $links = $this->dom->getElementsByTagName('a');
     247        foreach ($links as $link) {
     248            if ($link->hasAttribute('href')) {
     249                $href = trim($link->getAttribute('href'));
     250                $parsed = $this->registry->call(Misc::class, 'parse_url', [$href]);
     251                if ($parsed['scheme'] === '' || preg_match('/^(https?|feed)?$/i', $parsed['scheme'])) {
     252                    if (method_exists($link, 'getLineNo') && $this->base_location < $link->getLineNo()) {
     253                        $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->base]);
     254                    } else {
     255                        $href = $this->registry->call(Misc::class, 'absolutize_url', [trim($link->getAttribute('href')), $this->http_base]);
     256                    }
     257                    if ($href === false) {
     258                        continue;
     259                    }
     260
     261                    $current = $this->registry->call(Misc::class, 'parse_url', [$this->file->url]);
     262
     263                    if ($parsed['authority'] === '' || $parsed['authority'] === $current['authority']) {
     264                        $this->local[] = $href;
     265                    } else {
     266                        $this->elsewhere[] = $href;
     267                    }
     268                }
     269            }
     270        }
     271        $this->local = array_unique($this->local);
     272        $this->elsewhere = array_unique($this->elsewhere);
     273        if (!empty($this->local) || !empty($this->elsewhere)) {
     274            return true;
     275        }
     276        return null;
     277    }
     278
     279    public function get_rel_link($rel)
     280    {
     281        if ($this->dom === null) {
     282            throw new \SimplePie\Exception('DOMDocument not found, unable to use '.
     283                                          'locator');
     284        }
     285        if (!class_exists('DOMXpath')) {
     286            throw new \SimplePie\Exception('DOMXpath not found, unable to use '.
     287                                          'get_rel_link');
     288        }
     289
     290        $xpath = new \DOMXpath($this->dom);
     291        $query = '//a[@rel and @href] | //link[@rel and @href]';
     292        foreach ($xpath->query($query) as $link) {
     293            $href = trim($link->getAttribute('href'));
     294            $parsed = $this->registry->call(Misc::class, 'parse_url', [$href]);
     295            if ($parsed['scheme'] === '' ||
     296                preg_match('/^https?$/i', $parsed['scheme'])) {
     297                if (method_exists($link, 'getLineNo') &&
     298                    $this->base_location < $link->getLineNo()) {
     299                    $href = $this->registry->call(
     300                        Misc::class,
     301                        'absolutize_url',
     302                        [trim($link->getAttribute('href')), $this->base]
     303                    );
     304                } else {
     305                    $href = $this->registry->call(
     306                        Misc::class,
     307                        'absolutize_url',
     308                        [trim($link->getAttribute('href')), $this->http_base]
     309                    );
     310                }
     311                if ($href === false) {
     312                    return null;
     313                }
     314                $rel_values = explode(' ', strtolower($link->getAttribute('rel')));
     315                if (in_array($rel, $rel_values)) {
     316                    return $href;
     317                }
     318            }
     319        }
     320        return null;
     321    }
     322
     323    public function extension(&$array)
     324    {
     325        foreach ($array as $key => $value) {
     326            if ($this->checked_feeds === $this->max_checked_feeds) {
     327                break;
     328            }
     329            if (in_array(strtolower(strrchr($value, '.')), ['.rss', '.rdf', '.atom', '.xml'])) {
     330                $this->checked_feeds++;
     331
     332                $headers = [
     333                    'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
     334                ];
     335                $feed = $this->registry->create(File::class, [$value, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]);
     336                if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) {
     337                    return [$feed];
     338                } else {
     339                    unset($array[$key]);
     340                }
     341            }
     342        }
     343        return null;
     344    }
     345
     346    public function body(&$array)
     347    {
     348        foreach ($array as $key => $value) {
     349            if ($this->checked_feeds === $this->max_checked_feeds) {
     350                break;
     351            }
     352            if (preg_match('/(feed|rss|rdf|atom|xml)/i', $value)) {
     353                $this->checked_feeds++;
     354                $headers = [
     355                    'Accept' => 'application/atom+xml, application/rss+xml, application/rdf+xml;q=0.9, application/xml;q=0.8, text/xml;q=0.8, text/html;q=0.7, unknown/unknown;q=0.1, application/unknown;q=0.1, */*;q=0.1',
     356                ];
     357                $feed = $this->registry->create(File::class, [$value, $this->timeout, 5, null, $this->useragent, $this->force_fsockopen, $this->curl_options]);
     358                if ($feed->success && ($feed->method & \SimplePie\SimplePie::FILE_SOURCE_REMOTE === 0 || ($feed->status_code === 200 || $feed->status_code > 206 && $feed->status_code < 300)) && $this->is_feed($feed)) {
     359                    return [$feed];
     360                } else {
     361                    unset($array[$key]);
     362                }
     363            }
     364        }
     365        return null;
     366    }
    432367}
     368
     369class_alias('SimplePie\Locator', 'SimplePie_Locator', false);
Note: See TracChangeset for help on using the changeset viewer.