From 556c908e77a4382819a774a88065e5a5ff4e72d2 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 14 Jan 2026 11:52:27 +0100 Subject: [PATCH 1/3] Add complete compatibility directory for SimplePie 1.9.0 --- .../1.9.0/feedwordpie_cache.class.php | 177 ++++++++++++++++++ .../1.9.0/feedwordpie_item.class.php | 56 ++++++ .../1.9.0/feedwordpie_parser.class.php | 128 +++++++++++++ 3 files changed, 361 insertions(+) create mode 100644 extend/SimplePie/1.9.0/feedwordpie_cache.class.php create mode 100644 extend/SimplePie/1.9.0/feedwordpie_item.class.php create mode 100644 extend/SimplePie/1.9.0/feedwordpie_parser.class.php diff --git a/extend/SimplePie/1.9.0/feedwordpie_cache.class.php b/extend/SimplePie/1.9.0/feedwordpie_cache.class.php new file mode 100644 index 0000000..6fa4af3 --- /dev/null +++ b/extend/SimplePie/1.9.0/feedwordpie_cache.class.php @@ -0,0 +1,177 @@ +name = 'feed_' . $filename; + $this->mod_name = 'feed_mod_' . $filename; + + $lifetime = $this->lifetime; + /** + * Filters the transient lifetime of the feed cache. + * + * @since 2.8.0 + * + * @param int $lifetime Cache duration in seconds. Default is 43200 seconds (12 hours). + * @param string $filename Unique identifier for the cache object. + */ + $this->lifetime = apply_filters( 'wp_feed_cache_transient_lifetime', $lifetime, $filename ); + } + + /** + * Sets the transient. + * + * @since 2.8.0 + * + * @param SimplePie $data Data to save. + * @return true Always true. + */ + public function save( $data ) { + if ( $data instanceof SimplePie ) { + $data = $data->data; + } + + set_transient( $this->name, $data, $this->lifetime ); + set_transient( $this->mod_name, time(), $this->lifetime ); + return true; + } + + /** + * Gets the transient. + * + * @since 2.8.0 + * + * @return mixed Transient value. + */ + public function load() { + return get_transient( $this->name ); + } + + /** + * Gets mod transient. + * + * @since 2.8.0 + * + * @return mixed Transient value. + */ + public function mtime() { + return get_transient( $this->mod_name ); + } + + /** + * Sets mod transient. + * + * @since 2.8.0 + * + * @return bool False if value was not set and true if value was set. + */ + public function touch() { + return set_transient( $this->mod_name, time(), $this->lifetime ); + } + + /** + * Deletes transients. + * + * @since 2.8.0 + * + * @return true Always true. + */ + public function unlink() { + delete_transient( $this->name ); + delete_transient( $this->mod_name ); + return true; + } + + /** + * Create a new SimplePie_Cache object + * + * @param string $location URL location (scheme is used to determine handler) + * @param string $filename Unique identifier for cache object + * @param string $extension 'spi' or 'spc' + * @return SimplePie_Cache_Base Type of object depends on scheme of `$location` + */ + public static function get_handler($location, $filename, $extension) + { + + $type = explode(':', $location, 2); + $type = $type[0]; + if ( !empty(self::$handlers[$type])) + { + $class = self::$handlers[$type]; + return $class($location, $filename, $extension); + } + + return new FeedWordPie_Cache($location, $filename, $extension); + } + + /** + * Create a new SimplePie_Cache object + * + * @deprecated Use {@see get_handler} instead + */ + public function create($location, $filename, $extension) + { + trigger_error('Cache::create() has been replaced with Cache::get_handler(). Switch to the registry system to use this.', E_USER_DEPRECATED); + return self::get_handler($location, $filename, $extension); + } + +} \ No newline at end of file diff --git a/extend/SimplePie/1.9.0/feedwordpie_item.class.php b/extend/SimplePie/1.9.0/feedwordpie_item.class.php new file mode 100644 index 0000000..1bd5b9c --- /dev/null +++ b/extend/SimplePie/1.9.0/feedwordpie_item.class.php @@ -0,0 +1,56 @@ +namespace = array(''); + $this->element = array(''); + $this->xml_base = array(''); + $this->xml_base_explicit = array(false); + $this->xml_lang = array(''); + $this->data = array(); + $this->datas = array(array()); + $this->current_xhtml_construct = -1; + $this->xmlns_stack = array(); + $this->xmlns_current = array(); + + if (is_resource($xml)) { + xml_parser_free($xml); + } + + $xml = xml_parser_create_ns($this->encoding, $this->separator); + xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xml, $this); + xml_set_character_data_handler($xml, 'cdata'); + xml_set_element_handler($xml, 'tag_open', 'tag_close'); + xml_set_start_namespace_decl_handler($xml, 'start_xmlns'); + } + + public function parse(string &$data, string $encoding, string $url = '') { + $data = apply_filters('feedwordpress_parser_parse', $data, $encoding, $this, $url); + + if (strtoupper($encoding) === 'US-ASCII') { + $this->encoding = 'UTF-8'; + } else { + $this->encoding = $encoding; + } + + // Strip BOM + if (substr($data, 0, 4) === "\x00\x00\xFE\xFF" || substr($data, 0, 4) === "\xFF\xFE\x00\x00") { + $data = substr($data, 4); + } elseif (substr($data, 0, 2) === "\xFE\xFF" || substr($data, 0, 2) === "\xFF\xFE") { + $data = substr($data, 2); + } elseif (substr($data, 0, 3) === "\xEF\xBB\xBF") { + $data = substr($data, 3); + } + + if (substr($data, 0, 5) === '')) !== false) { + $declaration = $this->registry->create('XML_Declaration_Parser', array(substr($data, 5, $pos - 5))); + if ($declaration->parse()) { + $data = substr($data, $pos + 2); + $data = 'version . '" encoding="' . $encoding . '" standalone="' . (($declaration->standalone) ? 'yes' : 'no') . '"?>' . "\n" . self::declare_html_entities() . $data; + } + } + + $xml = xml_parser_create_ns($this->encoding, $this->separator); + xml_parser_set_option($xml, XML_OPTION_SKIP_WHITE, 1); + xml_parser_set_option($xml, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xml, $this); + xml_set_character_data_handler($xml, 'cdata'); + xml_set_element_handler($xml, 'tag_open', 'tag_close'); + xml_set_start_namespace_decl_handler($xml, 'start_xmlns'); + + $results = $this->do_xml_parse_attempt($xml, $data); + $parseResults = $results[0]; + + if (!$parseResults) { + $this->error_code = xml_get_error_code($xml); + $this->error_string = xml_error_string($this->error_code); + xml_parser_free($xml); + return false; + } + + xml_parser_free($xml); + return true; + } + + public function do_xml_parse_attempt($xml, $data) { + xml_set_start_namespace_decl_handler($xml, 'start_xmlns'); + $parseResults = xml_parse($xml, $data, true); + + if (!$parseResults && (xml_get_error_code($xml) == 26)) { + $data = $this->html_convert_entities($data); + $this->reset_parser($xml); + $parseResults = xml_parse($xml, $data, true); + } + + return array($parseResults, $data); + } + + function tag_open($parser, $tag, $attributes) { + $ret = parent::tag_open($parser, $tag, $attributes); + if ($this->current_xhtml_construct < 0) { + $this->data['xmlns'] = $this->xmlns_current; + $this->xmlns_stack[] = $this->xmlns_current; + } + return $ret; + } + + function tag_close($parser, $tag) { + if ($this->current_xhtml_construct < 0) { + $this->xmlns_current = array_pop($this->xmlns_stack); + } + return parent::tag_close($parser, $tag); + } + + function start_xmlns($parser, $prefix, $uri) { + if (!$prefix) $prefix = ''; + if ($this->current_xhtml_construct < 0) { + $this->xmlns_current[$prefix] = $uri; + } + return true; + } + + public function html_convert_entities($string) { + return preg_replace_callback('/&([a-zA-Z][a-zA-Z0-9]+);/S', array($this, 'convert_entity'), $string); + } + + public function convert_entity($matches) { + static $table = array('quot'=>'"','amp'=>'&','lt'=>'<','gt'=>'>','nbsp'=>' ','copy'=>'©','reg'=>'®'); + return isset($table[$matches[1]]) ? $table[$matches[1]] : ''; + } + + public static function declare_html_entities() { + return ' ]>'; + } +} \ No newline at end of file From abb085f4da7e0a4142f239081ac61a6d46c0298a Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 14 Jan 2026 21:00:17 +0100 Subject: [PATCH 2/3] Fix PHP Warning: Invalid argument supplied for foreach() in diagnostic() When feedwordpress_diagnostics_output option doesn't exist in the database, get_option() returns false instead of the default array() value, causing a PHP Warning when attempting to iterate over $output in foreach(). This issue affected installations without saved diagnostic settings. The admin interface already handled this case correctly with an is_array() check (diagostics-page.php:190-193), but the diagnostic() method did not. Cast to array() ensures $output is always iterable, preventing the warning. --- feedwordpress.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feedwordpress.php b/feedwordpress.php index bcfd2d8..78cad71 100644 --- a/feedwordpress.php +++ b/feedwordpress.php @@ -2127,7 +2127,7 @@ static function affirmative ($f, $setting = null) { static function diagnostic( $level, $out, $persist = null, $since = null, $mostRecent = null ) { global $feedwordpress_admin_footer; - $output = get_option( 'feedwordpress_diagnostics_output', array() ); + $output = (array) get_option( 'feedwordpress_diagnostics_output', array() ); $dlog = get_option( 'feedwordpress_diagnostics_log', array() ); $diagnostic_nesting = count( explode( ":", $level ) ); From cb0ebce8cae595800764cfe56aa4c5572e69ceca Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 27 Jan 2026 13:10:21 +0100 Subject: [PATCH 3/3] Fix PHP Warning: Undefined array key in author mapping Fixes PHP warnings when author mapping rules don't contain enough newline characters. Uses array_pad() to ensure explode() always returns at least 3 elements, preventing undefined array key warnings for $author_name and $author_action. --- syndicatedlink.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/syndicatedlink.class.php b/syndicatedlink.class.php index 9518c54..0b85d6f 100644 --- a/syndicatedlink.class.php +++ b/syndicatedlink.class.php @@ -618,7 +618,8 @@ protected function get_settings_from_notes () { $author_rules = explode("\n\n", $this->settings['map authors']); $ma = array(); foreach ($author_rules as $rule) : - list($rule_type, $author_name, $author_action) = explode("\n", $rule); + $parts = array_pad(explode("\n", $rule), 3, ''); + list($rule_type, $author_name, $author_action) = $parts; // Normalize for case and whitespace $rule_type = strtolower(trim($rule_type));