Changeset 60771 for trunk/src/wp-includes/SimplePie/src/SimplePie.php
- Timestamp:
- 09/16/2025 10:45:37 PM (2 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/SimplePie/src/SimplePie.php
r60490 r60771 1 1 <?php 2 2 3 /** 4 * SimplePie 5 * 6 * A PHP-Based RSS and Atom Feed Framework. 7 * Takes the hard work out of managing a complete RSS/Atom solution. 8 * 9 * Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors 10 * All rights reserved. 11 * 12 * Redistribution and use in source and binary forms, with or without modification, are 13 * permitted provided that the following conditions are met: 14 * 15 * * Redistributions of source code must retain the above copyright notice, this list of 16 * conditions and the following disclaimer. 17 * 18 * * Redistributions in binary form must reproduce the above copyright notice, this list 19 * of conditions and the following disclaimer in the documentation and/or other materials 20 * provided with the distribution. 21 * 22 * * Neither the name of the SimplePie Team nor the names of its contributors may be used 23 * to endorse or promote products derived from this software without specific prior 24 * written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 27 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 28 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 29 * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 33 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 34 * POSSIBILITY OF SUCH DAMAGE. 35 * 36 * @package SimplePie 37 * @copyright 2004-2016 Ryan Parman, Sam Sneddon, Ryan McCue 38 * @author Ryan Parman 39 * @author Sam Sneddon 40 * @author Ryan McCue 41 * @link http://simplepie.org/ SimplePie 42 * @license http://www.opensource.org/licenses/bsd-license.php BSD License 43 */ 3 // SPDX-FileCopyrightText: 2004-2023 Ryan Parman, Sam Sneddon, Ryan McCue 4 // SPDX-License-Identifier: BSD-3-Clause 5 6 declare(strict_types=1); 44 7 45 8 namespace SimplePie; 46 9 47 10 use InvalidArgumentException; 11 use Psr\Http\Client\ClientInterface; 12 use Psr\Http\Message\RequestFactoryInterface; 13 use Psr\Http\Message\UriFactoryInterface; 48 14 use Psr\SimpleCache\CacheInterface; 49 15 use SimplePie\Cache\Base; … … 54 20 use SimplePie\Cache\Psr16; 55 21 use SimplePie\Content\Type\Sniffer; 22 use SimplePie\Exception as SimplePieException; 23 use SimplePie\HTTP\Client; 24 use SimplePie\HTTP\ClientException; 25 use SimplePie\HTTP\FileClient; 26 use SimplePie\HTTP\Psr18Client; 27 use SimplePie\HTTP\Response; 56 28 57 29 /** 58 30 * SimplePie 59 *60 * @package SimplePie61 * @subpackage API62 31 */ 63 32 class SimplePie … … 71 40 * SimplePie Version 72 41 */ 73 public const VERSION = '1. 8.1';42 public const VERSION = '1.9.0'; 74 43 75 44 /** … … 412 381 413 382 /** 414 * @var array Raw data 383 * @internal Default value of the HTTP Accept header when fetching/locating feeds 384 */ 385 public const DEFAULT_HTTP_ACCEPT_HEADER = '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'; 386 387 /** 388 * @var array<string, mixed> Raw data 415 389 * @access private 416 390 */ … … 418 392 419 393 /** 420 * @var mixed Error string394 * @var string|string[]|null Error string (or array when multiple feeds are initialized) 421 395 * @access private 422 396 */ 423 public $error ;397 public $error = null; 424 398 425 399 /** … … 431 405 432 406 /** 433 * @var object Instance of \SimplePie\Sanitize (or other class)407 * @var Sanitize instance of Sanitize class 434 408 * @see SimplePie::set_sanitize_class() 435 409 * @access private … … 452 426 453 427 /** 454 * @var string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently428 * @var ?string Original feed URL, or new feed URL iff HTTP 301 Moved Permanently 455 429 * @see SimplePie::subscribe_url() 456 430 * @access private … … 459 433 460 434 /** 461 * @var object Instance of \SimplePie\Fileto use as a feed435 * @var File Instance of File class to use as a feed 462 436 * @see SimplePie::set_file() 463 * @access private 464 */ 465 public $file; 466 467 /** 468 * @var string Raw feed data 437 */ 438 private $file; 439 440 /** 441 * @var string|false Raw feed data 469 442 * @see SimplePie::set_raw_data() 470 443 * @access private … … 480 453 481 454 /** 482 * @var array Custom curl options455 * @var array<int, mixed> Custom curl options 483 456 * @see SimplePie::set_curl_options() 484 457 * @access private … … 551 524 552 525 /** 553 * @var string Function that creates the cache filename526 * @var string&(callable(string): string) Function that creates the cache filename 554 527 * @see SimplePie::set_cache_name_function() 555 528 * @access private … … 573 546 574 547 /** 575 * @var intFeed Autodiscovery Level548 * @var self::LOCATOR_* Feed Autodiscovery Level 576 549 * @see SimplePie::set_autodiscovery_level() 577 550 * @access private … … 582 555 * Class registry object 583 556 * 584 * @var \SimplePie\Registry557 * @var Registry 585 558 */ 586 559 public $registry; … … 594 567 595 568 /** 596 * @var array All the feeds found during the autodiscovery process569 * @var array<Response>|null All the feeds found during the autodiscovery process 597 570 * @see SimplePie::get_all_discovered_feeds() 598 571 * @access private … … 608 581 609 582 /** 610 * @var array Stores the URLs when multiple feeds are being initialized.583 * @var array<string> Stores the URLs when multiple feeds are being initialized. 611 584 * @see SimplePie::set_feed_url() 612 585 * @access private … … 615 588 616 589 /** 617 * @var array Stores SimplePie objects when multiple feeds initialized.590 * @var array<int, static> Stores SimplePie objects when multiple feeds initialized. 618 591 * @access private 619 592 */ … … 621 594 622 595 /** 623 * @var array Stores the get_object_vars() array for use with multifeeds.596 * @var array<mixed> Stores the get_object_vars() array for use with multifeeds. 624 597 * @see SimplePie::set_feed_url() 625 598 * @access private … … 628 601 629 602 /** 630 * @var int egerStores the number of items to return per-feed with multifeeds.603 * @var int Stores the number of items to return per-feed with multifeeds. 631 604 * @see SimplePie::set_item_limit() 632 605 * @access private … … 641 614 642 615 /** 643 * @var array Stores the default attributes to be stripped by strip_attributes().616 * @var array<string> Stores the default attributes to be stripped by strip_attributes(). 644 617 * @see SimplePie::strip_attributes() 645 618 * @access private … … 648 621 649 622 /** 650 * @var array Stores the default attributes to add to different tags by add_attributes().623 * @var array<string, array<string, string>> Stores the default attributes to add to different tags by add_attributes(). 651 624 * @see SimplePie::add_attributes() 652 625 * @access private … … 655 628 656 629 /** 657 * @var array Stores the default tags to be stripped by strip_htmltags().630 * @var array<string> Stores the default tags to be stripped by strip_htmltags(). 658 631 * @see SimplePie::strip_htmltags() 659 632 * @access private … … 662 635 663 636 /** 664 * @var arrayStores the default attributes to be renamed by rename_attributes().637 * @var string[]|string Stores the default attributes to be renamed by rename_attributes(). 665 638 * @see SimplePie::rename_attributes() 666 639 * @access private … … 673 646 */ 674 647 public $enable_exceptions = false; 648 649 /** 650 * @var Client|null 651 */ 652 private $http_client = null; 653 654 /** @var bool Whether HTTP client has been injected */ 655 private $http_client_injected = false; 675 656 676 657 /** … … 699 680 700 681 // Other objects, instances created here so we can set options on them 701 $this->sanitize = new \SimplePie\Sanitize();702 $this->registry = new \SimplePie\Registry();682 $this->sanitize = new Sanitize(); 683 $this->registry = new Registry(); 703 684 704 685 if (func_num_args() > 0) { … … 722 703 /** 723 704 * Used for converting object to a string 705 * @return string 724 706 */ 725 707 public function __toString() … … 730 712 /** 731 713 * Remove items that link back to this before destroying this object 714 * @return void 732 715 */ 733 716 public function __destruct() … … 757 740 * @since 1.1 758 741 * @param bool $enable Force the given data/URL to be treated as a feed 759 */ 760 public function force_feed($enable = false) 761 { 762 $this->force_feed = (bool) $enable; 742 * @return void 743 */ 744 public function force_feed(bool $enable = false) 745 { 746 $this->force_feed = $enable; 763 747 } 764 748 … … 770 754 * over any set raw data. 771 755 * 772 * You can set multiple feeds to mash together by passing an array instead756 * Deprecated since 1.9.0: You can set multiple feeds to mash together by passing an array instead 773 757 * of a string for the $url. Remember that with each additional feed comes 774 758 * additional processing and resources. … … 776 760 * @since 1.0 Preview Release 777 761 * @see set_raw_data() 778 * @param string|array $url This is the URL (or array of URLs) that you want to parse. 762 * @param string|string[] $url This is the URL (or (deprecated) array of URLs) that you want to parse. 763 * @return void 779 764 */ 780 765 public function set_feed_url($url) … … 782 767 $this->multifeed_url = []; 783 768 if (is_array($url)) { 769 trigger_error('Fetching multiple feeds with single SimplePie instance is deprecated since SimplePie 1.9.0, create one SimplePie instance per feed and use SimplePie::merge_items to get a single list of items.', \E_USER_DEPRECATED); 784 770 foreach ($url as $value) { 785 771 $this->multifeed_url[] = $this->registry->call(Misc::class, 'fix_protocol', [$value, 1]); … … 792 778 793 779 /** 794 * Set an instance of {@see \SimplePie\File} to use as a feed 795 * 796 * @param \SimplePie\File &$file 780 * Set an instance of {@see File} to use as a feed 781 * 782 * @deprecated since SimplePie 1.9.0, use \SimplePie\SimplePie::set_http_client() or \SimplePie\SimplePie::set_raw_data() instead. 783 * 784 * @param File &$file 797 785 * @return bool True on success, false on failure 798 786 */ 799 public function set_file( &$file)800 { 801 if ($file instanceof \SimplePie\File) {802 $this->feed_url = $file->url; 803 $this->permanent_url = $this->feed_url;804 $this->file = &$file;805 return true;806 } 807 return false;787 public function set_file(File &$file) 788 { 789 // trigger_error(sprintf('SimplePie\SimplePie::set_file() is deprecated since SimplePie 1.9.0, please use "SimplePie\SimplePie::set_http_client()" or "SimplePie\SimplePie::set_raw_data()" instead.'), \E_USER_DEPRECATED); 790 791 $this->feed_url = $file->get_final_requested_uri(); 792 $this->permanent_url = $this->feed_url; 793 $this->file = &$file; 794 795 return true; 808 796 } 809 797 … … 820 808 * @param string $data RSS or Atom data as a string. 821 809 * @see set_feed_url() 822 */ 823 public function set_raw_data($data) 810 * @return void 811 */ 812 public function set_raw_data(string $data) 824 813 { 825 814 $this->raw_data = $data; 815 } 816 817 /** 818 * Set a PSR-18 client and PSR-17 factories 819 * 820 * Allows you to use your own HTTP client implementations. 821 * This will become required with SimplePie 2.0.0. 822 */ 823 final public function set_http_client( 824 ClientInterface $http_client, 825 RequestFactoryInterface $request_factory, 826 UriFactoryInterface $uri_factory 827 ): void { 828 $this->http_client = new Psr18Client($http_client, $request_factory, $uri_factory); 826 829 } 827 830 … … 834 837 * @since 1.0 Beta 3 835 838 * @param int $timeout The maximum number of seconds to spend waiting to retrieve a feed. 836 */ 837 public function set_timeout($timeout = 10) 838 { 839 * @return void 840 */ 841 public function set_timeout(int $timeout = 10) 842 { 843 if ($this->http_client_injected) { 844 throw new SimplePieException(sprintf( 845 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure timeout in your HTTP client instead.', 846 __METHOD__, 847 self::class 848 )); 849 } 850 839 851 $this->timeout = (int) $timeout; 852 853 // Reset a possible existing FileClient, 854 // so a new client with the changed value will be created 855 if (is_object($this->http_client) && $this->http_client instanceof FileClient) { 856 $this->http_client = null; 857 } elseif (is_object($this->http_client)) { 858 // Trigger notice if a PSR-18 client was set 859 trigger_error(sprintf( 860 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure the timeout in your HTTP client instead.', 861 __METHOD__, 862 get_class($this) 863 ), \E_USER_NOTICE); 864 } 840 865 } 841 866 … … 846 871 * 847 872 * @since 1.0 Beta 3 848 * @param array $curl_options Curl options to add to default settings 873 * @param array<int, mixed> $curl_options Curl options to add to default settings 874 * @return void 849 875 */ 850 876 public function set_curl_options(array $curl_options = []) 851 877 { 878 if ($this->http_client_injected) { 879 throw new SimplePieException(sprintf( 880 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure custom curl options in your HTTP client instead.', 881 __METHOD__, 882 self::class 883 )); 884 } 885 852 886 $this->curl_options = $curl_options; 887 888 // Reset a possible existing FileClient, 889 // so a new client with the changed value will be created 890 if (is_object($this->http_client) && $this->http_client instanceof FileClient) { 891 $this->http_client = null; 892 } elseif (is_object($this->http_client)) { 893 // Trigger notice if a PSR-18 client was set 894 trigger_error(sprintf( 895 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure the curl options in your HTTP client instead.', 896 __METHOD__, 897 get_class($this) 898 ), \E_USER_NOTICE); 899 } 853 900 } 854 901 … … 858 905 * @since 1.0 Beta 3 859 906 * @param bool $enable Force fsockopen() to be used 860 */ 861 public function force_fsockopen($enable = false) 862 { 863 $this->force_fsockopen = (bool) $enable; 907 * @return void 908 */ 909 public function force_fsockopen(bool $enable = false) 910 { 911 if ($this->http_client_injected) { 912 throw new SimplePieException(sprintf( 913 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure fsockopen in your HTTP client instead.', 914 __METHOD__, 915 self::class 916 )); 917 } 918 919 $this->force_fsockopen = $enable; 920 921 // Reset a possible existing FileClient, 922 // so a new client with the changed value will be created 923 if (is_object($this->http_client) && $this->http_client instanceof FileClient) { 924 $this->http_client = null; 925 } elseif (is_object($this->http_client)) { 926 // Trigger notice if a PSR-18 client was set 927 trigger_error(sprintf( 928 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure fsockopen in your HTTP client instead.', 929 __METHOD__, 930 get_class($this) 931 ), \E_USER_NOTICE); 932 } 864 933 } 865 934 … … 872 941 * @since 1.0 Preview Release 873 942 * @param bool $enable Enable caching 874 */ 875 public function enable_cache($enable = true) 876 { 877 $this->enable_cache = (bool) $enable; 943 * @return void 944 */ 945 public function enable_cache(bool $enable = true) 946 { 947 $this->enable_cache = $enable; 878 948 } 879 949 … … 881 951 * Set a PSR-16 implementation as cache 882 952 * 883 * @param CacheInterface $ psr16cache The PSR-16 cache implementation953 * @param CacheInterface $cache The PSR-16 cache implementation 884 954 * 885 955 * @return void … … 901 971 * 902 972 * @param bool $enable Force use of cache on fail. 903 */ 904 public function force_cache_fallback($enable = false) 973 * @return void 974 */ 975 public function force_cache_fallback(bool $enable = false) 905 976 { 906 977 // @trigger_error(sprintf('SimplePie\SimplePie::force_cache_fallback() is deprecated since SimplePie 1.8.0, expired cache will not be used anymore.'), \E_USER_DEPRECATED); 907 $this->force_cache_fallback = (bool)$enable;978 $this->force_cache_fallback = $enable; 908 979 } 909 980 … … 913 984 * 914 985 * @param int $seconds The feed content cache duration 915 */ 916 public function set_cache_duration($seconds = 3600) 917 { 918 $this->cache_duration = (int) $seconds; 986 * @return void 987 */ 988 public function set_cache_duration(int $seconds = 3600) 989 { 990 $this->cache_duration = $seconds; 919 991 } 920 992 … … 924 996 * 925 997 * @param int $seconds The autodiscovered feed URL cache duration. 926 */ 927 public function set_autodiscovery_cache_duration($seconds = 604800) 928 { 929 $this->autodiscovery_cache_duration = (int) $seconds; 998 * @return void 999 */ 1000 public function set_autodiscovery_cache_duration(int $seconds = 604800) 1001 { 1002 $this->autodiscovery_cache_duration = $seconds; 930 1003 } 931 1004 … … 933 1006 * Set the file system location where the cached files should be stored 934 1007 * 935 * @deprecated since SimplePie 1.8.0, use \SimplePie\SimplePie::set_cache() instead.1008 * @deprecated since SimplePie 1.8.0, use SimplePie::set_cache() instead. 936 1009 * 937 1010 * @param string $location The file system location. 938 */ 939 public function set_cache_location($location = './cache') 1011 * @return void 1012 */ 1013 public function set_cache_location(string $location = './cache') 940 1014 { 941 1015 // @trigger_error(sprintf('SimplePie\SimplePie::set_cache_location() is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache()" instead.'), \E_USER_DEPRECATED); 942 $this->cache_location = (string)$location;1016 $this->cache_location = $location; 943 1017 } 944 1018 … … 949 1023 * @return string A filename (i.e. hash, without path and without extension). 950 1024 */ 951 public function get_cache_filename( $url)1025 public function get_cache_filename(string $url) 952 1026 { 953 1027 // Append custom parameters to the URL to avoid cache pollution in case of multiple calls with different parameters. … … 957 1031 $options[CURLOPT_TIMEOUT] = $this->timeout; 958 1032 } 959 if ($this->useragent !== \SimplePie\Misc::get_default_useragent()) {1033 if ($this->useragent !== Misc::get_default_useragent()) { 960 1034 $options[CURLOPT_USERAGENT] = $this->useragent; 961 1035 } … … 977 1051 * 978 1052 * @param bool $enable Sort as reverse chronological order. 979 */ 980 public function enable_order_by_date($enable = true) 981 { 982 $this->order_by_date = (bool) $enable; 1053 * @return void 1054 */ 1055 public function enable_order_by_date(bool $enable = true) 1056 { 1057 $this->order_by_date = $enable; 983 1058 } 984 1059 … … 989 1064 * back to the normal encoding detection if the override fails 990 1065 * 991 * @param string $encoding Character encoding 1066 * @param string|false $encoding Character encoding 1067 * @return void 992 1068 */ 993 1069 public function set_input_encoding($encoding = false) … … 1003 1079 * Set how much feed autodiscovery to do 1004 1080 * 1005 * @see \SimplePie\SimplePie::LOCATOR_NONE 1006 * @see \SimplePie\SimplePie::LOCATOR_AUTODISCOVERY 1007 * @see \SimplePie\SimplePie::LOCATOR_LOCAL_EXTENSION 1008 * @see \SimplePie\SimplePie::LOCATOR_LOCAL_BODY 1009 * @see \SimplePie\SimplePie::LOCATOR_REMOTE_EXTENSION 1010 * @see \SimplePie\SimplePie::LOCATOR_REMOTE_BODY 1011 * @see \SimplePie\SimplePie::LOCATOR_ALL 1012 * @param int $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator) 1013 */ 1014 public function set_autodiscovery_level($level = self::LOCATOR_ALL) 1015 { 1016 $this->autodiscovery = (int) $level; 1081 * @see self::LOCATOR_NONE 1082 * @see self::LOCATOR_AUTODISCOVERY 1083 * @see self::LOCATOR_LOCAL_EXTENSION 1084 * @see self::LOCATOR_LOCAL_BODY 1085 * @see self::LOCATOR_REMOTE_EXTENSION 1086 * @see self::LOCATOR_REMOTE_BODY 1087 * @see self::LOCATOR_ALL 1088 * @param self::LOCATOR_* $level Feed Autodiscovery Level (level can be a combination of the above constants, see bitwise OR operator) 1089 * @return void 1090 */ 1091 public function set_autodiscovery_level(int $level = self::LOCATOR_ALL) 1092 { 1093 $this->autodiscovery = $level; 1017 1094 } 1018 1095 … … 1021 1098 * 1022 1099 * Use this to override SimplePie's default classes 1023 * @see \SimplePie\Registry1024 1100 * 1025 1101 * @return Registry … … 1035 1111 * @deprecated since SimplePie 1.3, use {@see set_cache()} instead 1036 1112 * 1037 * @param string$class Name of custom class1038 * 1039 * @return bool eanTrue on success, false otherwise1040 */ 1041 public function set_cache_class( $class = Cache::class)1042 { 1043 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::set_cache()" instead.', __METHOD__), \E_USER_DEPRECATED);1113 * @param class-string<Cache> $class Name of custom class 1114 * 1115 * @return bool True on success, false otherwise 1116 */ 1117 public function set_cache_class(string $class = Cache::class) 1118 { 1119 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::set_cache()" instead.', __METHOD__), \E_USER_DEPRECATED); 1044 1120 1045 1121 return $this->registry->register(Cache::class, $class, true); … … 1051 1127 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1052 1128 * 1053 * @param string$class Name of custom class1054 * 1055 * @return bool eanTrue on success, false otherwise1056 */ 1057 public function set_locator_class( $class = Locator::class)1058 { 1059 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1129 * @param class-string<Locator> $class Name of custom class 1130 * 1131 * @return bool True on success, false otherwise 1132 */ 1133 public function set_locator_class(string $class = Locator::class) 1134 { 1135 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1060 1136 1061 1137 return $this->registry->register(Locator::class, $class, true); … … 1067 1143 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1068 1144 * 1069 * @param string$class Name of custom class1070 * 1071 * @return bool eanTrue on success, false otherwise1072 */ 1073 public function set_parser_class( $class = Parser::class)1074 { 1075 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1145 * @param class-string<Parser> $class Name of custom class 1146 * 1147 * @return bool True on success, false otherwise 1148 */ 1149 public function set_parser_class(string $class = Parser::class) 1150 { 1151 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1076 1152 1077 1153 return $this->registry->register(Parser::class, $class, true); … … 1083 1159 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1084 1160 * 1085 * @param string$class Name of custom class1086 * 1087 * @return bool eanTrue on success, false otherwise1088 */ 1089 public function set_file_class( $class = File::class)1090 { 1091 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1161 * @param class-string<File> $class Name of custom class 1162 * 1163 * @return bool True on success, false otherwise 1164 */ 1165 public function set_file_class(string $class = File::class) 1166 { 1167 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1092 1168 1093 1169 return $this->registry->register(File::class, $class, true); … … 1099 1175 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1100 1176 * 1101 * @param string$class Name of custom class1102 * 1103 * @return bool eanTrue on success, false otherwise1104 */ 1105 public function set_sanitize_class( $class = Sanitize::class)1106 { 1107 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1177 * @param class-string<Sanitize> $class Name of custom class 1178 * 1179 * @return bool True on success, false otherwise 1180 */ 1181 public function set_sanitize_class(string $class = Sanitize::class) 1182 { 1183 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1108 1184 1109 1185 return $this->registry->register(Sanitize::class, $class, true); … … 1115 1191 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1116 1192 * 1117 * @param string$class Name of custom class1118 * 1119 * @return bool eanTrue on success, false otherwise1120 */ 1121 public function set_item_class( $class = Item::class)1122 { 1123 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1193 * @param class-string<Item> $class Name of custom class 1194 * 1195 * @return bool True on success, false otherwise 1196 */ 1197 public function set_item_class(string $class = Item::class) 1198 { 1199 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1124 1200 1125 1201 return $this->registry->register(Item::class, $class, true); … … 1131 1207 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1132 1208 * 1133 * @param string$class Name of custom class1134 * 1135 * @return bool eanTrue on success, false otherwise1136 */ 1137 public function set_author_class( $class = Author::class)1138 { 1139 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1209 * @param class-string<Author> $class Name of custom class 1210 * 1211 * @return bool True on success, false otherwise 1212 */ 1213 public function set_author_class(string $class = Author::class) 1214 { 1215 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1140 1216 1141 1217 return $this->registry->register(Author::class, $class, true); … … 1147 1223 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1148 1224 * 1149 * @param string$class Name of custom class1150 * 1151 * @return bool eanTrue on success, false otherwise1152 */ 1153 public function set_category_class( $class = Category::class)1154 { 1155 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1225 * @param class-string<Category> $class Name of custom class 1226 * 1227 * @return bool True on success, false otherwise 1228 */ 1229 public function set_category_class(string $class = Category::class) 1230 { 1231 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1156 1232 1157 1233 return $this->registry->register(Category::class, $class, true); … … 1163 1239 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1164 1240 * 1165 * @param string$class Name of custom class1166 * 1167 * @return bool eanTrue on success, false otherwise1168 */ 1169 public function set_enclosure_class( $class = Enclosure::class)1170 { 1171 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1241 * @param class-string<Enclosure> $class Name of custom class 1242 * 1243 * @return bool True on success, false otherwise 1244 */ 1245 public function set_enclosure_class(string $class = Enclosure::class) 1246 { 1247 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1172 1248 1173 1249 return $this->registry->register(Enclosure::class, $class, true); … … 1179 1255 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1180 1256 * 1181 * @param string$class Name of custom class1182 * 1183 * @return bool eanTrue on success, false otherwise1184 */ 1185 public function set_caption_class( $class = Caption::class)1186 { 1187 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1257 * @param class-string<Caption> $class Name of custom class 1258 * 1259 * @return bool True on success, false otherwise 1260 */ 1261 public function set_caption_class(string $class = Caption::class) 1262 { 1263 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1188 1264 1189 1265 return $this->registry->register(Caption::class, $class, true); … … 1195 1271 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1196 1272 * 1197 * @param string$class Name of custom class1198 * 1199 * @return bool eanTrue on success, false otherwise1200 */ 1201 public function set_copyright_class( $class = Copyright::class)1202 { 1203 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1273 * @param class-string<Copyright> $class Name of custom class 1274 * 1275 * @return bool True on success, false otherwise 1276 */ 1277 public function set_copyright_class(string $class = Copyright::class) 1278 { 1279 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1204 1280 1205 1281 return $this->registry->register(Copyright::class, $class, true); … … 1211 1287 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1212 1288 * 1213 * @param string$class Name of custom class1214 * 1215 * @return bool eanTrue on success, false otherwise1216 */ 1217 public function set_credit_class( $class = Credit::class)1218 { 1219 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1289 * @param class-string<Credit> $class Name of custom class 1290 * 1291 * @return bool True on success, false otherwise 1292 */ 1293 public function set_credit_class(string $class = Credit::class) 1294 { 1295 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1220 1296 1221 1297 return $this->registry->register(Credit::class, $class, true); … … 1227 1303 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1228 1304 * 1229 * @param string$class Name of custom class1230 * 1231 * @return bool eanTrue on success, false otherwise1232 */ 1233 public function set_rating_class( $class = Rating::class)1234 { 1235 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1305 * @param class-string<Rating> $class Name of custom class 1306 * 1307 * @return bool True on success, false otherwise 1308 */ 1309 public function set_rating_class(string $class = Rating::class) 1310 { 1311 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1236 1312 1237 1313 return $this->registry->register(Rating::class, $class, true); … … 1243 1319 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1244 1320 * 1245 * @param string$class Name of custom class1246 * 1247 * @return bool eanTrue on success, false otherwise1248 */ 1249 public function set_restriction_class( $class = Restriction::class)1250 { 1251 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1321 * @param class-string<Restriction> $class Name of custom class 1322 * 1323 * @return bool True on success, false otherwise 1324 */ 1325 public function set_restriction_class(string $class = Restriction::class) 1326 { 1327 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1252 1328 1253 1329 return $this->registry->register(Restriction::class, $class, true); … … 1259 1335 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1260 1336 * 1261 * @param string$class Name of custom class1262 * 1263 * @return bool eanTrue on success, false otherwise1264 */ 1265 public function set_content_type_sniffer_class( $class = Sniffer::class)1266 { 1267 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1337 * @param class-string<Sniffer> $class Name of custom class 1338 * 1339 * @return bool True on success, false otherwise 1340 */ 1341 public function set_content_type_sniffer_class(string $class = Sniffer::class) 1342 { 1343 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1268 1344 1269 1345 return $this->registry->register(Sniffer::class, $class, true); … … 1275 1351 * @deprecated since SimplePie 1.3, use {@see get_registry()} instead 1276 1352 * 1277 * @param string$class Name of custom class1278 * 1279 * @return bool eanTrue on success, false otherwise1280 */ 1281 public function set_source_class( $class = Source::class)1282 { 1283 //trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED);1353 * @param class-string<Source> $class Name of custom class 1354 * 1355 * @return bool True on success, false otherwise 1356 */ 1357 public function set_source_class(string $class = Source::class) 1358 { 1359 trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.3, please use "SimplePie\SimplePie::get_registry()" instead.', __METHOD__), \E_USER_DEPRECATED); 1284 1360 1285 1361 return $this->registry->register(Source::class, $class, true); … … 1290 1366 * 1291 1367 * @param string $ua New user agent string. 1292 */ 1293 public function set_useragent($ua = null) 1294 { 1368 * @return void 1369 */ 1370 public function set_useragent(?string $ua = null) 1371 { 1372 if ($this->http_client_injected) { 1373 throw new SimplePieException(sprintf( 1374 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure user agent string in your HTTP client instead.', 1375 __METHOD__, 1376 self::class 1377 )); 1378 } 1379 1295 1380 if ($ua === null) { 1296 $ua = \SimplePie\Misc::get_default_useragent();1381 $ua = Misc::get_default_useragent(); 1297 1382 } 1298 1383 1299 1384 $this->useragent = (string) $ua; 1385 1386 // Reset a possible existing FileClient, 1387 // so a new client with the changed value will be created 1388 if (is_object($this->http_client) && $this->http_client instanceof FileClient) { 1389 $this->http_client = null; 1390 } elseif (is_object($this->http_client)) { 1391 // Trigger notice if a PSR-18 client was set 1392 trigger_error(sprintf( 1393 'Using "%s()" has no effect, because you already provided a HTTP client with "%s::set_http_client()". Configure the useragent in your HTTP client instead.', 1394 __METHOD__, 1395 get_class($this) 1396 ), \E_USER_NOTICE); 1397 } 1300 1398 } 1301 1399 … … 1317 1415 * @deprecated since SimplePie 1.8.0, use {@see set_cache_namefilter()} instead 1318 1416 * 1319 * @param mixed $function Callback function 1320 */ 1321 public function set_cache_name_function($function = 'md5') 1417 * @param (string&(callable(string): string))|null $function Callback function 1418 * @return void 1419 */ 1420 public function set_cache_name_function(?string $function = null) 1322 1421 { 1323 1422 // trigger_error(sprintf('"%s()" is deprecated since SimplePie 1.8.0, please use "SimplePie\SimplePie::set_cache_namefilter()" instead.', __METHOD__), \E_USER_DEPRECATED); 1324 1423 1325 if (is_callable($function)) { 1326 $this->cache_name_function = $function; 1327 1328 $this->set_cache_namefilter(new CallableNameFilter($this->cache_name_function)); 1329 } 1424 if ($function === null) { 1425 $function = 'md5'; 1426 } 1427 1428 $this->cache_name_function = $function; 1429 1430 $this->set_cache_namefilter(new CallableNameFilter($this->cache_name_function)); 1330 1431 } 1331 1432 … … 1337 1438 * 1338 1439 * @param bool $set Whether to set them or not 1339 */ 1340 public function set_stupidly_fast($set = false) 1440 * @return void 1441 */ 1442 public function set_stupidly_fast(bool $set = false) 1341 1443 { 1342 1444 if ($set) { … … 1344 1446 $this->remove_div(false); 1345 1447 $this->strip_comments(false); 1346 $this->strip_htmltags( false);1347 $this->strip_attributes( false);1348 $this->add_attributes( false);1448 $this->strip_htmltags([]); 1449 $this->strip_attributes([]); 1450 $this->add_attributes([]); 1349 1451 $this->set_image_handler(false); 1350 1452 $this->set_https_domains([]); … … 1356 1458 * 1357 1459 * @param int $max Maximum number of feeds to check 1358 */ 1359 public function set_max_checked_feeds($max = 10) 1360 { 1361 $this->max_checked_feeds = (int) $max; 1362 } 1363 1364 public function remove_div($enable = true) 1460 * @return void 1461 */ 1462 public function set_max_checked_feeds(int $max = 10) 1463 { 1464 $this->max_checked_feeds = $max; 1465 } 1466 1467 /** 1468 * @return void 1469 */ 1470 public function remove_div(bool $enable = true) 1365 1471 { 1366 1472 $this->sanitize->remove_div($enable); 1367 1473 } 1368 1474 1369 public function strip_htmltags($tags = '', $encode = null) 1475 /** 1476 * @param string[]|string|false $tags Set a list of tags to strip, or set empty string to use default tags, or false to strip nothing. 1477 * @return void 1478 */ 1479 public function strip_htmltags($tags = '', ?bool $encode = null) 1370 1480 { 1371 1481 if ($tags === '') { … … 1378 1488 } 1379 1489 1380 public function encode_instead_of_strip($enable = true) 1490 /** 1491 * @return void 1492 */ 1493 public function encode_instead_of_strip(bool $enable = true) 1381 1494 { 1382 1495 $this->sanitize->encode_instead_of_strip($enable); 1383 1496 } 1384 1497 1498 /** 1499 * @param string[]|string $attribs 1500 * @return void 1501 */ 1385 1502 public function rename_attributes($attribs = '') 1386 1503 { … … 1391 1508 } 1392 1509 1510 /** 1511 * @param string[]|string $attribs 1512 * @return void 1513 */ 1393 1514 public function strip_attributes($attribs = '') 1394 1515 { … … 1399 1520 } 1400 1521 1522 /** 1523 * @param array<string, array<string, string>>|'' $attribs 1524 * @return void 1525 */ 1401 1526 public function add_attributes($attribs = '') 1402 1527 { … … 1428 1553 * 1429 1554 * @param string $encoding 1430 */ 1431 public function set_output_encoding($encoding = 'UTF-8') 1555 * @return void 1556 */ 1557 public function set_output_encoding(string $encoding = 'UTF-8') 1432 1558 { 1433 1559 $this->sanitize->set_output_encoding($encoding); 1434 1560 } 1435 1561 1436 public function strip_comments($strip = false) 1562 /** 1563 * @return void 1564 */ 1565 public function strip_comments(bool $strip = false) 1437 1566 { 1438 1567 $this->sanitize->strip_comments($strip); … … 1448 1577 * 1449 1578 * @since 1.0 1450 * @param array|null $element_attribute Element/attribute key/value pairs, null for default 1451 */ 1452 public function set_url_replacements($element_attribute = null) 1579 * @param array<string, string|string[]>|null $element_attribute Element/attribute key/value pairs, null for default 1580 * @return void 1581 */ 1582 public function set_url_replacements(?array $element_attribute = null) 1453 1583 { 1454 1584 $this->sanitize->set_url_replacements($element_attribute); … … 1457 1587 /** 1458 1588 * Set the list of domains for which to force HTTPS. 1459 * @see \SimplePie\Sanitize::set_https_domains() 1460 * @param array List of HTTPS domains. Example array('biz', 'example.com', 'example.org', 'www.example.net'). 1461 */ 1462 public function set_https_domains($domains = []) 1463 { 1464 if (is_array($domains)) { 1465 $this->sanitize->set_https_domains($domains); 1466 } 1589 * @see Sanitize::set_https_domains() 1590 * @param array<string> $domains List of HTTPS domains. Example array('biz', 'example.com', 'example.org', 'www.example.net'). 1591 * @return void 1592 */ 1593 public function set_https_domains(array $domains = []) 1594 { 1595 $this->sanitize->set_https_domains($domains); 1467 1596 } 1468 1597 … … 1470 1599 * Set the handler to enable the display of cached images. 1471 1600 * 1472 * @param string $page Web-accessible path to the handler_image.php file.1601 * @param string|false $page Web-accessible path to the handler_image.php file. 1473 1602 * @param string $qs The query string that the value should be passed to. 1474 */ 1475 public function set_image_handler($page = false, $qs = 'i') 1603 * @return void 1604 */ 1605 public function set_image_handler($page = false, string $qs = 'i') 1476 1606 { 1477 1607 if ($page !== false) { … … 1485 1615 * Set the limit for items returned per-feed with multifeeds 1486 1616 * 1487 * @param integer $limit The maximum number of items to return. 1488 */ 1489 public function set_item_limit($limit = 0) 1490 { 1491 $this->item_limit = (int) $limit; 1617 * @param int $limit The maximum number of items to return. 1618 * @return void 1619 */ 1620 public function set_item_limit(int $limit = 0) 1621 { 1622 $this->item_limit = $limit; 1492 1623 } 1493 1624 … … 1495 1626 * Enable throwing exceptions 1496 1627 * 1497 * @param boolean $enable Should we throw exceptions, or use the old-style error property? 1498 */ 1499 public function enable_exceptions($enable = true) 1628 * @param bool $enable Should we throw exceptions, or use the old-style error property? 1629 * @return void 1630 */ 1631 public function enable_exceptions(bool $enable = true) 1500 1632 { 1501 1633 $this->enable_exceptions = $enable; … … 1509 1641 * parsed, and all of that other good stuff. 1510 1642 * 1511 * @return bool eanTrue if successful, false otherwise1643 * @return bool True if successful, false otherwise 1512 1644 */ 1513 1645 public function init() … … 1524 1656 $parser_check = xml_parser_create(); 1525 1657 xml_parse_into_struct($parser_check, '<foo>&</foo>', $values); 1526 xml_parser_free($parser_check); 1658 if (\PHP_VERSION_ID < 80000) { 1659 xml_parser_free($parser_check); 1660 } 1527 1661 $xml_is_sane = isset($values[0]['value']); 1528 1662 } … … 1534 1668 // The default sanitize class gets set in the constructor, check if it has 1535 1669 // changed. 1536 if ($this->registry->get_class(Sanitize::class) !== 'SimplePie\Sanitize') {1670 if ($this->registry->get_class(Sanitize::class) !== Sanitize::class) { 1537 1671 $this->sanitize = $this->registry->create(Sanitize::class); 1538 1672 } … … 1543 1677 // Pass whatever was set with config options over to the sanitizer. 1544 1678 // Pass the classes in for legacy support; new classes should use the registry instead 1679 $cache = $this->registry->get_class(Cache::class); 1680 \assert($cache !== null, 'Cache must be defined'); 1545 1681 $this->sanitize->pass_cache_data( 1546 1682 $this->enable_cache, 1547 1683 $this->cache_location, 1548 1684 $this->cache_namefilter, 1549 $ this->registry->get_class(Cache::class),1685 $cache, 1550 1686 $this->cache 1551 1687 ); 1552 $this->sanitize->pass_file_data($this->registry->get_class(File::class), $this->timeout, $this->useragent, $this->force_fsockopen, $this->curl_options); 1688 1689 $http_client = $this->get_http_client(); 1690 1691 if ($http_client instanceof Psr18Client) { 1692 $this->sanitize->set_http_client( 1693 $http_client->getHttpClient(), 1694 $http_client->getRequestFactory(), 1695 $http_client->getUriFactory() 1696 ); 1697 } 1553 1698 1554 1699 if (!empty($this->multifeed_url)) { … … 1586 1731 } 1587 1732 1588 // Fetch the data via \SimplePie\Fileinto $this->raw_data1733 // Fetch the data into $this->raw_data 1589 1734 if (($fetched = $this->fetch_data($cache)) === true) { 1590 1735 return true; … … 1650 1795 1651 1796 // If it's parsed fine 1652 if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url )) {1797 if ($parser->parse($utf8_data, 'UTF-8', $this->permanent_url ?? '')) { 1653 1798 $this->data = $parser->get_data(); 1654 1799 if (!($this->get_type() & ~self::TYPE_NONE)) { … … 1661 1806 $this->data['headers'] = $headers; 1662 1807 } 1663 $this->data['build'] = \SimplePie\Misc::get_build();1808 $this->data['build'] = Misc::get_build(); 1664 1809 1665 1810 // Cache the file if caching is enabled 1666 1811 $this->data['cache_expiration_time'] = $this->cache_duration + time(); 1812 1667 1813 if ($cache && !$cache->set_data($this->get_cache_filename($this->feed_url), $this->data, $this->cache_duration)) { 1668 1814 trigger_error("$this->cache_location is not writable. Make sure you've set the correct relative or absolute path, and that the location is server-writable.", E_USER_WARNING); … … 1674 1820 1675 1821 if (isset($parser)) { 1676 // We have an error, just set \SimplePie\Misc::error to it and quit1822 // We have an error, just set Misc::error to it and quit 1677 1823 $this->error = $this->feed_url; 1678 1824 $this->error .= sprintf(' is invalid XML, likely due to invalid characters. XML error: %s at line %d, column %d', $parser->get_error_string(), $parser->get_current_line(), $parser->get_current_column()); … … 1702 1848 1703 1849 /** 1704 * Fetch the data via \SimplePie\File1850 * Fetch the data 1705 1851 * 1706 1852 * If the data is already cached, attempt to fetch it from there instead 1853 * 1707 1854 * @param Base|DataCache|false $cache Cache handler, or false to not load from the cache 1708 * @return array |trueReturns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type1855 * @return array{array<string, string>, string}|bool Returns true if the data was loaded from the cache, or an array of HTTP headers and sniffed type 1709 1856 */ 1710 1857 protected function fetch_data(&$cache) 1711 1858 { 1712 if ( is_object($cache) &&$cache instanceof Base) {1859 if ($cache instanceof Base) { 1713 1860 // @trigger_error(sprintf('Providing $cache as "\SimplePie\Cache\Base" in %s() is deprecated since SimplePie 1.8.0, please provide "\SimplePie\Cache\DataCache" implementation instead.', __METHOD__), \E_USER_DEPRECATED); 1714 1861 $cache = new BaseDataCache($cache); 1715 1862 } 1716 1863 1864 // @phpstan-ignore-next-line Enforce PHPDoc type. 1717 1865 if ($cache !== false && !$cache instanceof DataCache) { 1718 1866 throw new InvalidArgumentException(sprintf( … … 1732 1880 if (!empty($this->data)) { 1733 1881 // If the cache is for an outdated build of SimplePie 1734 if (!isset($this->data['build']) || $this->data['build'] !== \SimplePie\Misc::get_build()) {1882 if (!isset($this->data['build']) || $this->data['build'] !== Misc::get_build()) { 1735 1883 $cache->delete_data($cacheKey); 1736 1884 $this->data = []; … … 1764 1912 if (isset($this->data['headers']['last-modified']) || isset($this->data['headers']['etag'])) { 1765 1913 $headers = [ 1766 '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',1914 'Accept' => SimplePie::DEFAULT_HTTP_ACCEPT_HEADER, 1767 1915 ]; 1768 1916 if (isset($this->data['headers']['last-modified'])) { … … 1773 1921 } 1774 1922 1775 $file = $this->registry->create(File::class, [$this->feed_url, $this->timeout / 10, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]); 1776 $this->status_code = $file->status_code; 1777 1778 if ($file->success) { 1779 if ($file->status_code === 304) { 1780 // Set raw_data to false here too, to signify that the cache 1781 // is still valid. 1782 $this->raw_data = false; 1923 try { 1924 $file = $this->get_http_client()->request(Client::METHOD_GET, $this->feed_url, $headers); 1925 $this->status_code = $file->get_status_code(); 1926 } catch (ClientException $th) { 1927 $this->check_modified = false; 1928 $this->status_code = 0; 1929 1930 if ($this->force_cache_fallback) { 1931 $this->data['cache_expiration_time'] = $this->cache_duration + time(); 1783 1932 $cache->set_data($cacheKey, $this->data, $this->cache_duration); 1933 1784 1934 return true; 1785 1935 } 1786 } else { 1787 $this->check_modified = false; 1788 if ($this->force_cache_fallback) { 1789 $cache->set_data($cacheKey, $this->data, $this->cache_duration); 1790 return true; 1791 } 1792 1793 unset($file); 1936 1937 $failedFileReason = $th->getMessage(); 1938 } 1939 1940 if ($this->status_code === 304) { 1941 // Set raw_data to false here too, to signify that the cache 1942 // is still valid. 1943 $this->raw_data = false; 1944 $this->data['cache_expiration_time'] = $this->cache_duration + time(); 1945 $cache->set_data($cacheKey, $this->data, $this->cache_duration); 1946 1947 return true; 1794 1948 } 1795 1949 } … … 1809 1963 // If we don't already have the file (it'll only exist if we've opened it to check if the cache has been modified), open it. 1810 1964 if (!isset($file)) { 1811 if ($this->file instanceof \SimplePie\File && $this->file->url=== $this->feed_url) {1965 if ($this->file instanceof File && $this->file->get_final_requested_uri() === $this->feed_url) { 1812 1966 $file = &$this->file; 1967 } elseif (isset($failedFileReason)) { 1968 // Do not try to fetch again if we already failed once. 1969 // If the file connection had an error, set SimplePie::error to that and quit 1970 $this->error = $failedFileReason; 1971 1972 return !empty($this->data); 1813 1973 } else { 1814 1974 $headers = [ 1815 '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',1975 'Accept' => SimplePie::DEFAULT_HTTP_ACCEPT_HEADER, 1816 1976 ]; 1817 $file = $this->registry->create(File::class, [$this->feed_url, $this->timeout, 5, $headers, $this->useragent, $this->force_fsockopen, $this->curl_options]); 1818 } 1819 } 1820 $this->status_code = $file->status_code; 1977 try { 1978 $file = $this->get_http_client()->request(Client::METHOD_GET, $this->feed_url, $headers); 1979 } catch (ClientException $th) { 1980 // If the file connection has an error, set SimplePie::error to that and quit 1981 $this->error = $th->getMessage(); 1982 1983 return !empty($this->data); 1984 } 1985 } 1986 } 1987 $this->status_code = $file->get_status_code(); 1821 1988 1822 1989 // If the file connection has an error, set SimplePie::error to that and quit 1823 if (! $file->success && !($file->method & self::FILE_SOURCE_REMOTE === 0 || ($file->status_code === 200 || $file->status_code > 206 && $file->status_code< 300))) {1824 $this->error = $file->error;1990 if (!(!Misc::is_remote_uri($file->get_final_requested_uri()) || ($file->get_status_code() === 200 || $file->get_status_code() > 206 && $file->get_status_code() < 300))) { 1991 $this->error = 'Retrieved unsupported status code "' . $this->status_code . '"'; 1825 1992 return !empty($this->data); 1826 1993 } … … 1828 1995 if (!$this->force_feed) { 1829 1996 // Check if the supplied URL is a feed, if it isn't, look for it. 1830 $locate = $this->registry->create(Locator::class, [&$file, $this->timeout, $this->useragent, $this->max_checked_feeds, $this->force_fsockopen, $this->curl_options]); 1997 $locate = $this->registry->create(Locator::class, [ 1998 (!$file instanceof File) ? File::fromResponse($file) : $file, 1999 $this->timeout, 2000 $this->useragent, 2001 $this->max_checked_feeds, 2002 $this->force_fsockopen, 2003 $this->curl_options 2004 ]); 2005 2006 $http_client = $this->get_http_client(); 2007 2008 if ($http_client instanceof Psr18Client) { 2009 $locate->set_http_client( 2010 $http_client->getHttpClient(), 2011 $http_client->getRequestFactory(), 2012 $http_client->getUriFactory() 2013 ); 2014 } 1831 2015 1832 2016 if (!$locate->is_feed($file)) { 1833 $copyStatusCode = $file-> status_code;1834 $copyContentType = $file-> headers['content-type'] ?? '';2017 $copyStatusCode = $file->get_status_code(); 2018 $copyContentType = $file->get_header_line('content-type'); 1835 2019 try { 1836 2020 $microformats = false; 1837 2021 if (class_exists('DOMXpath') && function_exists('Mf2\parse')) { 1838 2022 $doc = new \DOMDocument(); 1839 @$doc->loadHTML($file-> body);2023 @$doc->loadHTML($file->get_body_content()); 1840 2024 $xpath = new \DOMXpath($doc); 1841 2025 // Check for both h-feed and h-entry, as both a feed with no entries … … 1843 2027 $query = '//*[contains(concat(" ", @class, " "), " h-feed ") or '. 1844 2028 'contains(concat(" ", @class, " "), " h-entry ")]'; 2029 2030 /** @var \DOMNodeList<\DOMElement> $result */ 1845 2031 $result = $xpath->query($query); 1846 2032 $microformats = $result->length !== 0; … … 1853 2039 ); 1854 2040 if ($microformats) { 1855 if ($hub = $locate->get_rel_link('hub')) { 1856 $self = $locate->get_rel_link('self'); 1857 $this->store_links($file, $hub, $self); 2041 $hub = $locate->get_rel_link('hub'); 2042 $self = $locate->get_rel_link('self'); 2043 if ($hub || $self) { 2044 $file = $this->store_links($file, $hub, $self); 1858 2045 } 1859 2046 // Push the current file onto all_discovered feeds so the user can 1860 2047 // be shown this as one of the options. 1861 if ( isset($this->all_discovered_feeds)) {2048 if ($this->all_discovered_feeds !== null) { 1862 2049 $this->all_discovered_feeds[] = $file; 1863 2050 } … … 1874 2061 } 1875 2062 } 1876 } catch ( \SimplePie\Exception $e) {2063 } catch (SimplePieException $e) { 1877 2064 // We need to unset this so that if SimplePie::set_file() has been called that object is untouched 1878 2065 unset($file); … … 1886 2073 $this->data = [ 1887 2074 'url' => $this->feed_url, 1888 'feed_url' => $file-> url,1889 'build' => \SimplePie\Misc::get_build(),2075 'feed_url' => $file->get_final_requested_uri(), 2076 'build' => Misc::get_build(), 1890 2077 'cache_expiration_time' => $this->cache_duration + time(), 1891 2078 ]; … … 1896 2083 } 1897 2084 } 1898 $this->feed_url = $file-> url;2085 $this->feed_url = $file->get_final_requested_uri(); 1899 2086 $locate = null; 1900 2087 } 1901 2088 1902 $this->raw_data = $file->body; 1903 $this->permanent_url = $file->permanent_url; 1904 $headers = $file->headers; 2089 $this->raw_data = $file->get_body_content(); 2090 $this->permanent_url = $file->get_permanent_uri(); 2091 2092 $headers = []; 2093 foreach ($file->get_headers() as $key => $values) { 2094 $headers[$key] = implode(', ', $values); 2095 } 2096 1905 2097 $sniffer = $this->registry->create(Sniffer::class, [&$file]); 1906 2098 $sniffed = $sniffer->get_type(); … … 1912 2104 * Get the error message for the occurred error 1913 2105 * 1914 * @return string| arrayError message, or array of messages for multifeeds2106 * @return string|string[]|null Error message, or array of messages for multifeeds 1915 2107 */ 1916 2108 public function error() … … 1935 2127 * the data instead of printing it. 1936 2128 * 1937 * @return string| booleanRaw XML data, false if the cache is used2129 * @return string|false Raw XML data, false if the cache is used 1938 2130 */ 1939 2131 public function get_raw_data() … … 1971 2163 * 1972 2164 * @param string $mime MIME type to serve the page as 1973 */ 1974 public function handle_content_type($mime = 'text/html') 2165 * @return void 2166 */ 2167 public function handle_content_type(string $mime = 'text/html') 1975 2168 { 1976 2169 if (!headers_sent()) { … … 1988 2181 * Get the type of the feed 1989 2182 * 1990 * This returns a \SimplePie\SimplePie::TYPE_* constant, which can be tested against2183 * This returns a self::TYPE_* constant, which can be tested against 1991 2184 * using {@link http://php.net/language.operators.bitwise bitwise operators} 1992 2185 * 1993 2186 * @since 0.8 (usage changed to using constants in 1.0) 1994 * @see \SimplePie\SimplePie::TYPE_NONE Unknown.1995 * @see \SimplePie\SimplePie::TYPE_RSS_090 RSS 0.90.1996 * @see \SimplePie\SimplePie::TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape).1997 * @see \SimplePie\SimplePie::TYPE_RSS_091_USERLAND RSS 0.91 (Userland).1998 * @see \SimplePie\SimplePie::TYPE_RSS_091 RSS 0.91.1999 * @see \SimplePie\SimplePie::TYPE_RSS_092 RSS 0.92.2000 * @see \SimplePie\SimplePie::TYPE_RSS_093 RSS 0.93.2001 * @see \SimplePie\SimplePie::TYPE_RSS_094 RSS 0.94.2002 * @see \SimplePie\SimplePie::TYPE_RSS_10 RSS 1.0.2003 * @see \SimplePie\SimplePie::TYPE_RSS_20 RSS 2.0.x.2004 * @see \SimplePie\SimplePie::TYPE_RSS_RDF RDF-based RSS.2005 * @see \SimplePie\SimplePie::TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format).2006 * @see \SimplePie\SimplePie::TYPE_RSS_ALL Any version of RSS.2007 * @see \SimplePie\SimplePie::TYPE_ATOM_03 Atom 0.3.2008 * @see \SimplePie\SimplePie::TYPE_ATOM_10 Atom 1.0.2009 * @see \SimplePie\SimplePie::TYPE_ATOM_ALL Any version of Atom.2010 * @see \SimplePie\SimplePie::TYPE_ALL Any known/supported feed type.2011 * @return int \SimplePie\SimplePie::TYPE_*constant2187 * @see self::TYPE_NONE Unknown. 2188 * @see self::TYPE_RSS_090 RSS 0.90. 2189 * @see self::TYPE_RSS_091_NETSCAPE RSS 0.91 (Netscape). 2190 * @see self::TYPE_RSS_091_USERLAND RSS 0.91 (Userland). 2191 * @see self::TYPE_RSS_091 RSS 0.91. 2192 * @see self::TYPE_RSS_092 RSS 0.92. 2193 * @see self::TYPE_RSS_093 RSS 0.93. 2194 * @see self::TYPE_RSS_094 RSS 0.94. 2195 * @see self::TYPE_RSS_10 RSS 1.0. 2196 * @see self::TYPE_RSS_20 RSS 2.0.x. 2197 * @see self::TYPE_RSS_RDF RDF-based RSS. 2198 * @see self::TYPE_RSS_SYNDICATION Non-RDF-based RSS (truly intended as syndication format). 2199 * @see self::TYPE_RSS_ALL Any version of RSS. 2200 * @see self::TYPE_ATOM_03 Atom 0.3. 2201 * @see self::TYPE_ATOM_10 Atom 1.0. 2202 * @see self::TYPE_ATOM_ALL Any version of Atom. 2203 * @see self::TYPE_ALL Any known/supported feed type. 2204 * @return int-mask-of<self::TYPE_*> constant 2012 2205 */ 2013 2206 public function get_type() … … 2094 2287 * @return string|null 2095 2288 */ 2096 public function subscribe_url( $permanent = false)2289 public function subscribe_url(bool $permanent = false) 2097 2290 { 2098 2291 if ($permanent) { … … 2152 2345 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 2153 2346 * @param string $tag Tag name 2154 * @return array 2155 */ 2156 public function get_feed_tags( $namespace,$tag)2347 * @return array<array<string, mixed>>|null 2348 */ 2349 public function get_feed_tags(string $namespace, string $tag) 2157 2350 { 2158 2351 $type = $this->get_type(); … … 2192 2385 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 2193 2386 * @param string $tag Tag name 2194 * @return array 2195 */ 2196 public function get_channel_tags( $namespace,$tag)2387 * @return array<array<string, mixed>>|null 2388 */ 2389 public function get_channel_tags(string $namespace, string $tag) 2197 2390 { 2198 2391 $type = $this->get_type(); … … 2238 2431 * @param string $namespace The URL of the XML namespace of the elements you're trying to access 2239 2432 * @param string $tag Tag name 2240 * @return array 2241 */ 2242 public function get_image_tags( $namespace,$tag)2433 * @return array<array<string, mixed>>|null 2434 */ 2435 public function get_image_tags(string $namespace, string $tag) 2243 2436 { 2244 2437 $type = $this->get_type(); … … 2270 2463 * Get the base URL value from the feed 2271 2464 * 2272 * Uses `<xml:base>` if available, otherwise uses the first link in the 2273 * feed, or failing that, the URL of the feed itself. 2465 * Uses `<xml:base>` if available, 2466 * otherwise uses the first 'self' link or the first 'alternate' link of the feed, 2467 * or failing that, the URL of the feed itself. 2274 2468 * 2275 2469 * @see get_link 2276 2470 * @see subscribe_url 2277 2471 * 2278 * @param array $element2472 * @param array<string, mixed> $element 2279 2473 * @return string 2280 2474 */ 2281 public function get_base( $element = [])2475 public function get_base(array $element = []) 2282 2476 { 2283 2477 if (!empty($element['xml_base_explicit']) && isset($element['xml_base'])) { 2284 2478 return $element['xml_base']; 2285 } elseif ($this->get_link() !== null) { 2286 return $this->get_link(); 2287 } 2288 2289 return $this->subscribe_url(); 2479 } 2480 if (($link = $this->get_link(0, 'alternate')) !== null) { 2481 return $link; 2482 } 2483 if (($link = $this->get_link(0, 'self')) !== null) { 2484 return $link; 2485 } 2486 2487 return $this->subscribe_url() ?? ''; 2290 2488 } 2291 2489 … … 2294 2492 * 2295 2493 * @access private 2296 * @see \SimplePie\Sanitize::sanitize()2494 * @see Sanitize::sanitize() 2297 2495 * @param string $data Data to sanitize 2298 * @param int $type One of the \SimplePie\SimplePie::CONSTRUCT_* constants2496 * @param int-mask-of<SimplePie::CONSTRUCT_*> $type 2299 2497 * @param string $base Base URL to resolve URLs against 2300 2498 * @return string Sanitized data 2301 2499 */ 2302 public function sanitize( $data, $type,$base = '')2500 public function sanitize(string $data, int $type, string $base = '') 2303 2501 { 2304 2502 try { 2503 // This really returns string|false but changing encoding is uncommon and we are going to deprecate it, so let’s just lie to PHPStan in the interest of cleaner annotations. 2305 2504 return $this->sanitize->sanitize($data, $type, $base); 2306 } catch ( \SimplePie\Exception $e) {2505 } catch (SimplePieException $e) { 2307 2506 if (!$this->enable_exceptions) { 2308 2507 $this->error = $e->getMessage(); … … 2349 2548 * @since Unknown 2350 2549 * @param int $key The category that you want to return. Remember that arrays begin with 0, not 1 2351 * @return \SimplePie\Category|null2352 */ 2353 public function get_category( $key = 0)2550 * @return Category|null 2551 */ 2552 public function get_category(int $key = 0) 2354 2553 { 2355 2554 $categories = $this->get_categories(); … … 2367 2566 * 2368 2567 * @since Unknown 2369 * @return array |null List of {@see \SimplePie\Category} objects2568 * @return array<Category>|null List of {@see Category} objects 2370 2569 */ 2371 2570 public function get_categories() … … 2418 2617 * @since 1.1 2419 2618 * @param int $key The author that you want to return. Remember that arrays begin with 0, not 1 2420 * @return \SimplePie\Author|null2421 */ 2422 public function get_author( $key = 0)2619 * @return Author|null 2620 */ 2621 public function get_author(int $key = 0) 2423 2622 { 2424 2623 $authors = $this->get_authors(); … … 2436 2635 * 2437 2636 * @since 1.1 2438 * @return array |null List of {@see \SimplePie\Author} objects2637 * @return array<Author>|null List of {@see Author} objects 2439 2638 */ 2440 2639 public function get_authors() … … 2449 2648 } 2450 2649 if (isset($author['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'])) { 2451 $uri = $this->sanitize($author['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($author['child'][self::NAMESPACE_ATOM_10]['uri'][0])); 2650 $uri = $author['child'][self::NAMESPACE_ATOM_10]['uri'][0]; 2651 $uri = $this->sanitize($uri['data'], self::CONSTRUCT_IRI, $this->get_base($uri)); 2452 2652 } 2453 2653 if (isset($author['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'])) { … … 2466 2666 } 2467 2667 if (isset($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'])) { 2468 $url = $this->sanitize($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0])); 2668 $url = $author[0]['child'][self::NAMESPACE_ATOM_03]['url'][0]; 2669 $url = $this->sanitize($url['data'], self::CONSTRUCT_IRI, $this->get_base($url)); 2469 2670 } 2470 2671 if (isset($author[0]['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'])) { … … 2497 2698 * @since 1.1 2498 2699 * @param int $key The contrbutor that you want to return. Remember that arrays begin with 0, not 1 2499 * @return \SimplePie\Author|null2500 */ 2501 public function get_contributor( $key = 0)2700 * @return Author|null 2701 */ 2702 public function get_contributor(int $key = 0) 2502 2703 { 2503 2704 $contributors = $this->get_contributors(); … … 2515 2716 * 2516 2717 * @since 1.1 2517 * @return array |null List of {@see \SimplePie\Author} objects2718 * @return array<Author>|null List of {@see Author} objects 2518 2719 */ 2519 2720 public function get_contributors() … … 2528 2729 } 2529 2730 if (isset($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'])) { 2530 $uri = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0])); 2731 $uri = $contributor['child'][self::NAMESPACE_ATOM_10]['uri'][0]; 2732 $uri = $this->sanitize($uri['data'], self::CONSTRUCT_IRI, $this->get_base($uri)); 2531 2733 } 2532 2734 if (isset($contributor['child'][self::NAMESPACE_ATOM_10]['email'][0]['data'])) { … … 2545 2747 } 2546 2748 if (isset($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'])) { 2547 $url = $this->sanitize($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]['data'], self::CONSTRUCT_IRI, $this->get_base($contributor['child'][self::NAMESPACE_ATOM_03]['url'][0])); 2749 $url = $contributor['child'][self::NAMESPACE_ATOM_03]['url'][0]; 2750 $url = $this->sanitize($url['data'], self::CONSTRUCT_IRI, $this->get_base($url)); 2548 2751 } 2549 2752 if (isset($contributor['child'][self::NAMESPACE_ATOM_03]['email'][0]['data'])) { … … 2570 2773 * @return string|null Link URL 2571 2774 */ 2572 public function get_link( $key = 0,$rel = 'alternate')2775 public function get_link(int $key = 0, string $rel = 'alternate') 2573 2776 { 2574 2777 $links = $this->get_links($rel); … … 2603 2806 * @since Beta 2 2604 2807 * @param string $rel The relationship of links to return 2605 * @return array |null Links found for the feed (strings)2606 */ 2607 public function get_links( $rel = 'alternate')2808 * @return array<string>|null Links found for the feed (strings) 2809 */ 2810 public function get_links(string $rel = 'alternate') 2608 2811 { 2609 2812 if (!isset($this->data['links'])) { … … 2670 2873 } 2671 2874 2875 /** 2876 * @return ?array<Response> 2877 */ 2672 2878 public function get_all_discovered_feeds() 2673 2879 { … … 2773 2979 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo 2774 2980 * @link http://www.georss.org/ GeoRSS 2775 * @return string|null2981 * @return float|null 2776 2982 */ 2777 2983 public function get_latitude() … … 2796 3002 * @link http://www.w3.org/2003/01/geo/ W3C WGS84 Basic Geo 2797 3003 * @link http://www.georss.org/ GeoRSS 2798 * @return string|null3004 * @return float|null 2799 3005 */ 2800 3006 public function get_longitude() … … 2943 3149 * @return int Number of items in the feed 2944 3150 */ 2945 public function get_item_quantity($max = 0) 2946 { 2947 $max = (int) $max; 3151 public function get_item_quantity(int $max = 0) 3152 { 2948 3153 $qty = count($this->get_items()); 2949 3154 if ($max === 0) { … … 2951 3156 } 2952 3157 2953 return ($qty > $max) ? $max : $qty;3158 return min($qty, $max); 2954 3159 } 2955 3160 … … 2964 3169 * @since Beta 2 2965 3170 * @param int $key The item that you want to return. Remember that arrays begin with 0, not 1 2966 * @return \SimplePie\Item|null2967 */ 2968 public function get_item( $key = 0)3171 * @return Item|null 3172 */ 3173 public function get_item(int $key = 0) 2969 3174 { 2970 3175 $items = $this->get_items(); … … 2987 3192 * @param int $start Index to start at 2988 3193 * @param int $end Number of items to return. 0 for all items after `$start` 2989 * @return \SimplePie\Item[]|null List of {@see \SimplePie\Item} objects2990 */ 2991 public function get_items( $start = 0,$end = 0)3194 * @return Item[] List of {@see Item} objects 3195 */ 3196 public function get_items(int $start = 0, int $end = 0) 2992 3197 { 2993 3198 if (!isset($this->data['items'])) { … … 3003 3208 $keys = array_keys($items); 3004 3209 foreach ($keys as $key) { 3005 $this->data['items'][] = $this-> registry->create(Item::class, [$this, $items[$key]]);3210 $this->data['items'][] = $this->make_item($items[$key]); 3006 3211 } 3007 3212 } … … 3009 3214 $keys = array_keys($items); 3010 3215 foreach ($keys as $key) { 3011 $this->data['items'][] = $this-> registry->create(Item::class, [$this, $items[$key]]);3216 $this->data['items'][] = $this->make_item($items[$key]); 3012 3217 } 3013 3218 } … … 3015 3220 $keys = array_keys($items); 3016 3221 foreach ($keys as $key) { 3017 $this->data['items'][] = $this-> registry->create(Item::class, [$this, $items[$key]]);3222 $this->data['items'][] = $this->make_item($items[$key]); 3018 3223 } 3019 3224 } … … 3021 3226 $keys = array_keys($items); 3022 3227 foreach ($keys as $key) { 3023 $this->data['items'][] = $this-> registry->create(Item::class, [$this, $items[$key]]);3228 $this->data['items'][] = $this->make_item($items[$key]); 3024 3229 } 3025 3230 } … … 3027 3232 $keys = array_keys($items); 3028 3233 foreach ($keys as $key) { 3029 $this->data['items'][] = $this-> registry->create(Item::class, [$this, $items[$key]]);3234 $this->data['items'][] = $this->make_item($items[$key]); 3030 3235 } 3031 3236 } … … 3057 3262 * 3058 3263 * @deprecated Use your own favicon handling instead 3059 */ 3060 public function set_favicon_handler($page = false, $qs = 'i') 3061 { 3062 trigger_error('Favicon handling has been removed, please use your own handling', \E_USER_DEPRECATED); 3264 * @param string|false $page 3265 * @return bool 3266 */ 3267 public function set_favicon_handler($page = false, string $qs = 'i') 3268 { 3269 trigger_error('Favicon handling has been removed since SimplePie 1.3, please use your own handling', \E_USER_DEPRECATED); 3063 3270 return false; 3064 3271 } … … 3068 3275 * 3069 3276 * @deprecated Use your own favicon handling instead 3277 * @return string|bool 3070 3278 */ 3071 3279 public function get_favicon() 3072 3280 { 3073 trigger_error('Favicon handling has been removed , please use your own handling', \E_USER_DEPRECATED);3281 trigger_error('Favicon handling has been removed since SimplePie 1.3, please use your own handling', \E_USER_DEPRECATED); 3074 3282 3075 3283 if (($url = $this->get_link()) !== null) { … … 3084 3292 * 3085 3293 * @param string $method Method name 3086 * @param array $args Arguments to the method3294 * @param array<mixed> $args Arguments to the method 3087 3295 * @return mixed 3088 3296 */ 3089 public function __call( $method,$args)3297 public function __call(string $method, array $args) 3090 3298 { 3091 3299 if (strpos($method, 'subscribe_') === 0) { 3092 trigger_error('subscribe_*() has been deprecated , implement the callback yourself', \E_USER_DEPRECATED);3300 trigger_error('subscribe_*() has been deprecated since SimplePie 1.3, implement the callback yourself', \E_USER_DEPRECATED); 3093 3301 return ''; 3094 3302 } 3095 3303 if ($method === 'enable_xml_dump') { 3096 trigger_error('enable_xml_dump() has been deprecated , use get_raw_data() instead', \E_USER_DEPRECATED);3304 trigger_error('enable_xml_dump() has been deprecated since SimplePie 1.3, use get_raw_data() instead', \E_USER_DEPRECATED); 3097 3305 return false; 3098 3306 } … … 3100 3308 $class = get_class($this); 3101 3309 $trace = debug_backtrace(); // phpcs:ignore PHPCompatibility.FunctionUse.ArgumentFunctionsReportCurrentValue.NeedsInspection 3102 $file = $trace[0]['file'] ;3103 $line = $trace[0]['line'] ;3310 $file = $trace[0]['file'] ?? ''; 3311 $line = $trace[0]['line'] ?? ''; 3104 3312 throw new SimplePieException("Call to undefined method $class::$method() in $file on line $line"); 3105 3313 } 3106 3314 3107 3315 /** 3316 * Item factory 3317 * 3318 * @param array<string, mixed> $data 3319 */ 3320 private function make_item(array $data): Item 3321 { 3322 $item = $this->registry->create(Item::class, [$this, $data]); 3323 $item->set_sanitize($this->sanitize); 3324 3325 return $item; 3326 } 3327 3328 /** 3108 3329 * Sorting callback for items 3109 3330 * 3110 3331 * @access private 3111 * @param SimplePie$a3112 * @param SimplePie$b3113 * @return boolean3114 */ 3115 public static function sort_items( $a,$b)3332 * @param Item $a 3333 * @param Item $b 3334 * @return -1|0|1 3335 */ 3336 public static function sort_items(Item $a, Item $b) 3116 3337 { 3117 3338 $a_date = $a->get_date('U'); … … 3137 3358 * 3138 3359 * @link http://simplepie.org/wiki/tutorial/sort_multiple_feeds_by_time_and_date#if_feeds_require_separate_per-feed_settings 3139 * @param array $urls List of SimplePie feed objects to merge3360 * @param array<SimplePie> $urls List of SimplePie feed objects to merge 3140 3361 * @param int $start Starting item 3141 3362 * @param int $end Number of items to return 3142 3363 * @param int $limit Maximum number of items per feed 3143 * @return array 3144 */ 3145 public static function merge_items( $urls, $start = 0, $end = 0,$limit = 0)3146 { 3147 if ( is_array($urls) && sizeof($urls) > 0) {3364 * @return array<Item> 3365 */ 3366 public static function merge_items(array $urls, int $start = 0, int $end = 0, int $limit = 0) 3367 { 3368 if (count($urls) > 0) { 3148 3369 $items = []; 3149 3370 foreach ($urls as $arg) { 3150 3371 if ($arg instanceof SimplePie) { 3151 3372 $items = array_merge($items, $arg->get_items(0, $limit)); 3373 3374 // @phpstan-ignore-next-line Enforce PHPDoc type. 3152 3375 } else { 3153 3376 trigger_error('Arguments must be SimplePie objects', E_USER_WARNING); … … 3173 3396 * There is no way to find PuSH links in the body of a microformats feed, 3174 3397 * so they are added to the headers when found, to be used later by get_links. 3175 * @param \SimplePie\File $file 3176 * @param string $hub 3177 * @param string $self 3178 */ 3179 private function store_links(&$file, $hub, $self) 3180 { 3181 if (isset($file->headers['link']['hub']) || 3182 (isset($file->headers['link']) && 3183 preg_match('/rel=hub/', $file->headers['link']))) { 3184 return; 3185 } 3186 3187 if ($hub) { 3188 if (isset($file->headers['link'])) { 3189 if ($file->headers['link'] !== '') { 3190 $file->headers['link'] = ', '; 3191 } 3192 } else { 3193 $file->headers['link'] = ''; 3194 } 3195 $file->headers['link'] .= '<'.$hub.'>; rel=hub'; 3196 if ($self) { 3197 $file->headers['link'] .= ', <'.$self.'>; rel=self'; 3198 } 3199 } 3398 */ 3399 private function store_links(Response $file, ?string $hub, ?string $self): Response 3400 { 3401 $linkHeaderLine = $file->get_header_line('link'); 3402 $linkHeader = $file->get_header('link'); 3403 3404 if ($hub && !preg_match('/rel=hub/', $linkHeaderLine)) { 3405 $linkHeader[] = '<'.$hub.'>; rel=hub'; 3406 } 3407 3408 if ($self && !preg_match('/rel=self/', $linkHeaderLine)) { 3409 $linkHeader[] = '<'.$self.'>; rel=self'; 3410 } 3411 3412 if (count($linkHeader) > 0) { 3413 $file = $file->with_header('link', $linkHeader); 3414 } 3415 3416 return $file; 3200 3417 } 3201 3418 … … 3207 3424 * @return DataCache 3208 3425 */ 3209 private function get_cache( $feed_url = '')3426 private function get_cache(string $feed_url = ''): DataCache 3210 3427 { 3211 3428 if ($this->cache === null) { … … 3222 3439 return $this->cache; 3223 3440 } 3441 3442 /** 3443 * Get a HTTP client 3444 */ 3445 private function get_http_client(): Client 3446 { 3447 if ($this->http_client === null) { 3448 $this->http_client = new FileClient( 3449 $this->get_registry(), 3450 [ 3451 'timeout' => $this->timeout, 3452 'redirects' => 5, 3453 'useragent' => $this->useragent, 3454 'force_fsockopen' => $this->force_fsockopen, 3455 'curl_options' => $this->curl_options, 3456 ] 3457 ); 3458 $this->http_client_injected = true; 3459 } 3460 3461 return $this->http_client; 3462 } 3224 3463 } 3225 3464
Note: See TracChangeset
for help on using the changeset viewer.