diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/feed.php --- a/wp/wp-includes/feed.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/feed.php Tue Dec 15 13:49:49 2020 +0100 @@ -18,6 +18,7 @@ * are retrieved for use in the feeds. * * @since 1.5.1 + * * @see get_bloginfo() For the list of possible values to display. * * @param string $show See get_bloginfo() for possible values. @@ -47,6 +48,7 @@ * are retrieved for use in the feeds. * * @since 0.71 + * * @see get_bloginfo() For the list of possible values to display. * * @param string $show See get_bloginfo() for possible values. @@ -85,7 +87,8 @@ * Default 'rss2'. */ $default_feed = apply_filters( 'default_feed', 'rss2' ); - return 'rss' == $default_feed ? 'rss2' : $default_feed; + + return ( 'rss' === $default_feed ) ? 'rss2' : $default_feed; } /** @@ -99,7 +102,7 @@ */ function get_wp_title_rss( $deprecated = '–' ) { if ( '–' !== $deprecated ) { - /* translators: %s: 'document_title_separator' filter name */ + /* translators: %s: 'document_title_separator' filter name. */ _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), 'document_title_separator' ) ); } @@ -125,7 +128,7 @@ */ function wp_title_rss( $deprecated = '–' ) { if ( '–' !== $deprecated ) { - /* translators: %s: 'document_title_separator' filter name */ + /* translators: %s: 'document_title_separator' filter name. */ _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), 'document_title_separator' ) ); } @@ -160,8 +163,7 @@ * * @param string $title The current post title. */ - $title = apply_filters( 'the_title_rss', $title ); - return $title; + return apply_filters( 'the_title_rss', $title ); } /** @@ -177,6 +179,7 @@ * Retrieve the post content for feeds. * * @since 2.9.0 + * * @see get_the_content() * * @param string $feed_type The type of feed. rss2 | atom | rss | rdf @@ -190,6 +193,7 @@ /** This filter is documented in wp-includes/post-template.php */ $content = apply_filters( 'the_content', get_the_content() ); $content = str_replace( ']]>', ']]>', $content ); + /** * Filters the post content for use in feeds. * @@ -250,7 +254,6 @@ * Outputs the link to the comments for the current post in an xml safe way * * @since 3.0.0 - * @return none */ function comments_link_feed() { /** @@ -269,7 +272,7 @@ * * @since 2.5.0 * - * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object. + * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object. */ function comment_guid( $comment_id = null ) { echo esc_url( get_comment_guid( $comment_id ) ); @@ -280,8 +283,8 @@ * * @since 2.5.0 * - * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object. - * @return false|string false on failure or guid for comment on success. + * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object. + * @return string|false GUID for comment on success, false on failure. */ function get_comment_guid( $comment_id = null ) { $comment = get_comment( $comment_id ); @@ -299,7 +302,7 @@ * @since 1.5.0 * @since 4.4.0 Introduced the `$comment` argument. * - * @param int|WP_Comment $comment Optional. Comment object or id. Defaults to global comment object. + * @param int|WP_Comment $comment Optional. Comment object or ID. Defaults to global comment object. */ function comment_link( $comment = null ) { /** @@ -383,7 +386,7 @@ $cat_names = array(); $filter = 'rss'; - if ( 'atom' == $type ) { + if ( 'atom' === $type ) { $filter = 'raw'; } @@ -402,12 +405,12 @@ $cat_names = array_unique( $cat_names ); foreach ( $cat_names as $cat_name ) { - if ( 'rdf' == $type ) { + if ( 'rdf' === $type ) { $the_list .= "\t\t\n"; - } elseif ( 'atom' == $type ) { + } elseif ( 'atom' === $type ) { $the_list .= sprintf( '', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) ); } else { - $the_list .= "\t\t\n"; + $the_list .= "\t\t\n"; } } @@ -427,6 +430,7 @@ * Display the post categories in the feed. * * @since 0.71 + * * @see get_the_category_rss() For better explanation. * * @param string $type Optional, default is the type returned by get_default_feed(). @@ -472,11 +476,11 @@ } foreach ( (array) get_post_custom() as $key => $val ) { - if ( $key == 'enclosure' ) { + if ( 'enclosure' === $key ) { foreach ( (array) $val as $enc ) { $enclosure = explode( "\n", $enc ); - // only get the first element, e.g. audio/mpeg from 'audio/mpeg mpga mp2 mp3' + // Only get the first element, e.g. 'audio/mpeg' from 'audio/mpeg mpga mp2 mp3'. $t = preg_split( '/[ \t]/', trim( $enclosure[2] ) ); $type = $t[0]; @@ -512,9 +516,39 @@ } foreach ( (array) get_post_custom() as $key => $val ) { - if ( $key == 'enclosure' ) { + if ( 'enclosure' === $key ) { foreach ( (array) $val as $enc ) { $enclosure = explode( "\n", $enc ); + + $url = ''; + $type = ''; + $length = 0; + + $mimes = get_allowed_mime_types(); + + // Parse URL. + if ( isset( $enclosure[0] ) && is_string( $enclosure[0] ) ) { + $url = trim( $enclosure[0] ); + } + + // Parse length and type. + for ( $i = 1; $i <= 2; $i++ ) { + if ( isset( $enclosure[ $i ] ) ) { + if ( is_numeric( $enclosure[ $i ] ) ) { + $length = trim( $enclosure[ $i ] ); + } elseif ( in_array( $enclosure[ $i ], $mimes, true ) ) { + $type = trim( $enclosure[ $i ] ); + } + } + } + + $html_link_tag = sprintf( + "\n", + esc_url( $url ), + esc_attr( $length ), + esc_attr( $type ) + ); + /** * Filters the atom enclosure HTML link tag for the current post. * @@ -522,7 +556,7 @@ * * @param string $html_link_tag The HTML link tag with a URI and other attributes. */ - echo apply_filters( 'atom_enclosure', '' . "\n" ); + echo apply_filters( 'atom_enclosure', $html_link_tag ); } } } @@ -531,12 +565,12 @@ /** * Determine the type of a string of data with the data formatted. * - * Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1. + * Tell whether the type is text, HTML, or XHTML, per RFC 4287 section 3.1. * * In the case of WordPress, text is defined as containing no markup, - * xhtml is defined as "well formed", and html as tag soup (i.e., the rest). + * XHTML is defined as "well formed", and HTML as tag soup (i.e., the rest). * - * Container div tags are added to xhtml values, per section 3.1.1.3. + * Container div tags are added to XHTML values, per section 3.1.1.3. * * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1 * @@ -560,6 +594,7 @@ xml_parse( $parser, '
' . $data . '
', true ); $code = xml_get_error_code( $parser ); xml_parser_free( $parser ); + unset( $parser ); if ( ! $code ) { if ( strpos( $data, '<' ) === false ) { @@ -587,7 +622,7 @@ function atom_site_icon() { $url = get_site_icon_url( 32 ); if ( $url ) { - echo "$url\n"; + echo '' . convert_chars( $url ) . "\n"; } } @@ -616,6 +651,18 @@ } /** + * Returns the link for the currently displayed feed. + * + * @since 5.3.0 + * + * @return string Correct link for the atom:self element. + */ +function get_self_link() { + $host = parse_url( home_url() ); + return set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ); +} + +/** * Display the link for the currently displayed feed in a XSS safe way. * * Generate a correct link for the atom:self element. @@ -623,7 +670,6 @@ * @since 2.5.0 */ function self_link() { - $host = @parse_url( home_url() ); /** * Filters the current feed URL. * @@ -634,53 +680,63 @@ * * @param string $feed_link The link for the feed with set URL scheme. */ - echo esc_url( apply_filters( 'self_link', set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); + echo esc_url( apply_filters( 'self_link', get_self_link() ) ); } -/* - * Get the timestamp of the most recently modified post from WP_Query. +/** + * Get the UTC time of the most recently modified post from WP_Query. * - * If viewing a comment feed, the timestamp of the most recently modified + * If viewing a comment feed, the time of the most recently modified * comment will be returned. * - * @global WP_Query $wp_query The global WP_Query object. + * @global WP_Query $wp_query WordPress Query object. * * @since 5.2.0 * - * @param string $format Format of the timestamp to return, passed to mysql2date. - * - * @return string The timestamp. + * @param string $format Date format string to return the time in. + * @return string|false The time in requested format, or false on failure. */ function get_feed_build_date( $format ) { global $wp_query; - if ( empty( $wp_query ) || ! $wp_query->have_posts() ) { - // Fallback to last time any post was modified or published. - return get_lastpostmodified( 'GMT' ); + $datetime = false; + $max_modified_time = false; + $utc = new DateTimeZone( 'UTC' ); + + if ( ! empty( $wp_query ) && $wp_query->have_posts() ) { + // Extract the post modified times from the posts. + $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); + + // If this is a comment feed, check those objects too. + if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { + // Extract the comment modified times from the comments. + $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); + + // Add the comment times to the post times for comparison. + $modified_times = array_merge( $modified_times, $comment_times ); + } + + // Determine the maximum modified time. + $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc ); } - // Extract the post modified times from the posts. - $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); - - // If this is a comment feed, check those objects too. - if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { - // Extract the comment modified times from the comments. - $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); - - // Add the comment times to the post times for comparison. - $modified_times = array_merge( $modified_times, $comment_times ); + if ( false === $datetime ) { + // Fall back to last time any post was modified or published. + $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc ); } - // Determine the maximum modified time. - $max_modified_time = mysql2date( $format, max( $modified_times ), false ); + if ( false !== $datetime ) { + $max_modified_time = $datetime->format( $format ); + } /** * Filters the date the last post or comment in the query was modified. * * @since 5.2.0 * - * @param string $max_modified_time Date the last post or comment was modified in the query. - * @param string $format The date format requested in get_feed_build_date. + * @param string|false $max_modified_time Date the last post or comment was modified in the query, in UTC. + * False on failure. + * @param string $format The date format requested in get_feed_build_date(). */ return apply_filters( 'get_feed_build_date', $max_modified_time, $format ); } @@ -723,27 +779,26 @@ * * @since 2.8.0 * - * @param mixed $url URL of feed to retrieve. If an array of URLs, the feeds are merged - * using SimplePie's multifeed feature. - * See also {@link http://simplepie.org/wiki/faq/typical_multifeed_gotchas} - * - * @return WP_Error|SimplePie WP_Error object on failure or SimplePie object on success + * @param string|string[] $url URL of feed to retrieve. If an array of URLs, the feeds are merged + * using SimplePie's multifeed feature. + * See also {@link http://simplepie.org/wiki/faq/typical_multifeed_gotchas} + * @return SimplePie|WP_Error SimplePie object on success or WP_Error object on failure. */ function fetch_feed( $url ) { if ( ! class_exists( 'SimplePie', false ) ) { - require_once( ABSPATH . WPINC . '/class-simplepie.php' ); + require_once ABSPATH . WPINC . '/class-simplepie.php'; } - require_once( ABSPATH . WPINC . '/class-wp-feed-cache.php' ); - require_once( ABSPATH . WPINC . '/class-wp-feed-cache-transient.php' ); - require_once( ABSPATH . WPINC . '/class-wp-simplepie-file.php' ); - require_once( ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php' ); + require_once ABSPATH . WPINC . '/class-wp-feed-cache.php'; + require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php'; + require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php'; + require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php'; $feed = new SimplePie(); $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' ); // We must manually overwrite $feed->sanitize because SimplePie's - // constructor sets it before we have a chance to set the sanitization class + // constructor sets it before we have a chance to set the sanitization class. $feed->sanitize = new WP_SimplePie_Sanitize_KSES(); $feed->set_cache_class( 'WP_Feed_Cache' ); @@ -752,15 +807,17 @@ $feed->set_feed_url( $url ); /** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */ $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) ); + /** * Fires just before processing the SimplePie feed object. * * @since 3.0.0 * - * @param object $feed SimplePie feed object (passed by reference). - * @param mixed $url URL of feed to retrieve. If an array of URLs, the feeds are merged. + * @param SimplePie $feed SimplePie feed object (passed by reference). + * @param string|string[] $url URL of feed or array of URLs of feeds to retrieve. */ do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) ); + $feed->init(); $feed->set_output_encoding( get_option( 'blog_charset' ) );