97 * @param string $deprecated Unused.. |
100 * @param string $deprecated Unused.. |
98 * @return string The document title. |
101 * @return string The document title. |
99 */ |
102 */ |
100 function get_wp_title_rss( $deprecated = '–' ) { |
103 function get_wp_title_rss( $deprecated = '–' ) { |
101 if ( '–' !== $deprecated ) { |
104 if ( '–' !== $deprecated ) { |
102 /* translators: %s: 'document_title_separator' filter name */ |
105 /* translators: %s: 'document_title_separator' filter name. */ |
103 _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) ); |
106 _deprecated_argument( __FUNCTION__, '4.4.0', sprintf( __( 'Use the %s filter instead.' ), '<code>document_title_separator</code>' ) ); |
104 } |
107 } |
105 |
108 |
106 /** |
109 /** |
107 * Filters the blog title for use as the feed title. |
110 * Filters the blog title for use as the feed title. |
267 /** |
270 /** |
268 * Display the feed GUID for the current comment. |
271 * Display the feed GUID for the current comment. |
269 * |
272 * |
270 * @since 2.5.0 |
273 * @since 2.5.0 |
271 * |
274 * |
272 * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object. |
275 * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object. |
273 */ |
276 */ |
274 function comment_guid( $comment_id = null ) { |
277 function comment_guid( $comment_id = null ) { |
275 echo esc_url( get_comment_guid( $comment_id ) ); |
278 echo esc_url( get_comment_guid( $comment_id ) ); |
276 } |
279 } |
277 |
280 |
278 /** |
281 /** |
279 * Retrieve the feed GUID for the current comment. |
282 * Retrieve the feed GUID for the current comment. |
280 * |
283 * |
281 * @since 2.5.0 |
284 * @since 2.5.0 |
282 * |
285 * |
283 * @param int|WP_Comment $comment_id Optional comment object or id. Defaults to global comment object. |
286 * @param int|WP_Comment $comment_id Optional comment object or ID. Defaults to global comment object. |
284 * @return false|string false on failure or guid for comment on success. |
287 * @return string|false GUID for comment on success, false on failure. |
285 */ |
288 */ |
286 function get_comment_guid( $comment_id = null ) { |
289 function get_comment_guid( $comment_id = null ) { |
287 $comment = get_comment( $comment_id ); |
290 $comment = get_comment( $comment_id ); |
288 |
291 |
289 if ( ! is_object( $comment ) ) { |
292 if ( ! is_object( $comment ) ) { |
400 } |
403 } |
401 |
404 |
402 $cat_names = array_unique( $cat_names ); |
405 $cat_names = array_unique( $cat_names ); |
403 |
406 |
404 foreach ( $cat_names as $cat_name ) { |
407 foreach ( $cat_names as $cat_name ) { |
405 if ( 'rdf' == $type ) { |
408 if ( 'rdf' === $type ) { |
406 $the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n"; |
409 $the_list .= "\t\t<dc:subject><![CDATA[$cat_name]]></dc:subject>\n"; |
407 } elseif ( 'atom' == $type ) { |
410 } elseif ( 'atom' === $type ) { |
408 $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) ); |
411 $the_list .= sprintf( '<category scheme="%1$s" term="%2$s" />', esc_attr( get_bloginfo_rss( 'url' ) ), esc_attr( $cat_name ) ); |
409 } else { |
412 } else { |
410 $the_list .= "\t\t<category><![CDATA[" . @html_entity_decode( $cat_name, ENT_COMPAT, get_option( 'blog_charset' ) ) . "]]></category>\n"; |
413 $the_list .= "\t\t<category><![CDATA[" . html_entity_decode( $cat_name, ENT_COMPAT, get_option( 'blog_charset' ) ) . "]]></category>\n"; |
411 } |
414 } |
412 } |
415 } |
413 |
416 |
414 /** |
417 /** |
415 * Filters all of the post categories for display in a feed. |
418 * Filters all of the post categories for display in a feed. |
470 if ( post_password_required() ) { |
474 if ( post_password_required() ) { |
471 return; |
475 return; |
472 } |
476 } |
473 |
477 |
474 foreach ( (array) get_post_custom() as $key => $val ) { |
478 foreach ( (array) get_post_custom() as $key => $val ) { |
475 if ( $key == 'enclosure' ) { |
479 if ( 'enclosure' === $key ) { |
476 foreach ( (array) $val as $enc ) { |
480 foreach ( (array) $val as $enc ) { |
477 $enclosure = explode( "\n", $enc ); |
481 $enclosure = explode( "\n", $enc ); |
478 |
482 |
479 // only get the first element, e.g. audio/mpeg from 'audio/mpeg mpga mp2 mp3' |
483 // Only get the first element, e.g. 'audio/mpeg' from 'audio/mpeg mpga mp2 mp3'. |
480 $t = preg_split( '/[ \t]/', trim( $enclosure[2] ) ); |
484 $t = preg_split( '/[ \t]/', trim( $enclosure[2] ) ); |
481 $type = $t[0]; |
485 $type = $t[0]; |
482 |
486 |
483 /** |
487 /** |
484 * Filters the RSS enclosure HTML link tag for the current post. |
488 * Filters the RSS enclosure HTML link tag for the current post. |
510 if ( post_password_required() ) { |
514 if ( post_password_required() ) { |
511 return; |
515 return; |
512 } |
516 } |
513 |
517 |
514 foreach ( (array) get_post_custom() as $key => $val ) { |
518 foreach ( (array) get_post_custom() as $key => $val ) { |
515 if ( $key == 'enclosure' ) { |
519 if ( 'enclosure' === $key ) { |
516 foreach ( (array) $val as $enc ) { |
520 foreach ( (array) $val as $enc ) { |
517 $enclosure = explode( "\n", $enc ); |
521 $enclosure = explode( "\n", $enc ); |
|
522 |
|
523 $url = ''; |
|
524 $type = ''; |
|
525 $length = 0; |
|
526 |
|
527 $mimes = get_allowed_mime_types(); |
|
528 |
|
529 // Parse URL. |
|
530 if ( isset( $enclosure[0] ) && is_string( $enclosure[0] ) ) { |
|
531 $url = trim( $enclosure[0] ); |
|
532 } |
|
533 |
|
534 // Parse length and type. |
|
535 for ( $i = 1; $i <= 2; $i++ ) { |
|
536 if ( isset( $enclosure[ $i ] ) ) { |
|
537 if ( is_numeric( $enclosure[ $i ] ) ) { |
|
538 $length = trim( $enclosure[ $i ] ); |
|
539 } elseif ( in_array( $enclosure[ $i ], $mimes, true ) ) { |
|
540 $type = trim( $enclosure[ $i ] ); |
|
541 } |
|
542 } |
|
543 } |
|
544 |
|
545 $html_link_tag = sprintf( |
|
546 "<link href=\"%s\" rel=\"enclosure\" length=\"%d\" type=\"%s\" />\n", |
|
547 esc_url( $url ), |
|
548 esc_attr( $length ), |
|
549 esc_attr( $type ) |
|
550 ); |
|
551 |
518 /** |
552 /** |
519 * Filters the atom enclosure HTML link tag for the current post. |
553 * Filters the atom enclosure HTML link tag for the current post. |
520 * |
554 * |
521 * @since 2.2.0 |
555 * @since 2.2.0 |
522 * |
556 * |
523 * @param string $html_link_tag The HTML link tag with a URI and other attributes. |
557 * @param string $html_link_tag The HTML link tag with a URI and other attributes. |
524 */ |
558 */ |
525 echo apply_filters( 'atom_enclosure', '<link href="' . esc_url( trim( $enclosure[0] ) ) . '" rel="enclosure" length="' . absint( trim( $enclosure[1] ) ) . '" type="' . esc_attr( trim( $enclosure[2] ) ) . '" />' . "\n" ); |
559 echo apply_filters( 'atom_enclosure', $html_link_tag ); |
526 } |
560 } |
527 } |
561 } |
528 } |
562 } |
529 } |
563 } |
530 |
564 |
531 /** |
565 /** |
532 * Determine the type of a string of data with the data formatted. |
566 * Determine the type of a string of data with the data formatted. |
533 * |
567 * |
534 * Tell whether the type is text, html, or xhtml, per RFC 4287 section 3.1. |
568 * Tell whether the type is text, HTML, or XHTML, per RFC 4287 section 3.1. |
535 * |
569 * |
536 * In the case of WordPress, text is defined as containing no markup, |
570 * In the case of WordPress, text is defined as containing no markup, |
537 * xhtml is defined as "well formed", and html as tag soup (i.e., the rest). |
571 * XHTML is defined as "well formed", and HTML as tag soup (i.e., the rest). |
538 * |
572 * |
539 * Container div tags are added to xhtml values, per section 3.1.1.3. |
573 * Container div tags are added to XHTML values, per section 3.1.1.3. |
540 * |
574 * |
541 * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1 |
575 * @link http://www.atomenabled.org/developers/syndication/atom-format-spec.php#rfc.section.3.1 |
542 * |
576 * |
543 * @since 2.5.0 |
577 * @since 2.5.0 |
544 * |
578 * |
614 </image> ' . "\n"; |
649 </image> ' . "\n"; |
615 } |
650 } |
616 } |
651 } |
617 |
652 |
618 /** |
653 /** |
|
654 * Returns the link for the currently displayed feed. |
|
655 * |
|
656 * @since 5.3.0 |
|
657 * |
|
658 * @return string Correct link for the atom:self element. |
|
659 */ |
|
660 function get_self_link() { |
|
661 $host = parse_url( home_url() ); |
|
662 return set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ); |
|
663 } |
|
664 |
|
665 /** |
619 * Display the link for the currently displayed feed in a XSS safe way. |
666 * Display the link for the currently displayed feed in a XSS safe way. |
620 * |
667 * |
621 * Generate a correct link for the atom:self element. |
668 * Generate a correct link for the atom:self element. |
622 * |
669 * |
623 * @since 2.5.0 |
670 * @since 2.5.0 |
624 */ |
671 */ |
625 function self_link() { |
672 function self_link() { |
626 $host = @parse_url( home_url() ); |
|
627 /** |
673 /** |
628 * Filters the current feed URL. |
674 * Filters the current feed URL. |
629 * |
675 * |
630 * @since 3.6.0 |
676 * @since 3.6.0 |
631 * |
677 * |
632 * @see set_url_scheme() |
678 * @see set_url_scheme() |
633 * @see wp_unslash() |
679 * @see wp_unslash() |
634 * |
680 * |
635 * @param string $feed_link The link for the feed with set URL scheme. |
681 * @param string $feed_link The link for the feed with set URL scheme. |
636 */ |
682 */ |
637 echo esc_url( apply_filters( 'self_link', set_url_scheme( 'http://' . $host['host'] . wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
683 echo esc_url( apply_filters( 'self_link', get_self_link() ) ); |
638 } |
684 } |
639 |
685 |
640 /* |
686 /** |
641 * Get the timestamp of the most recently modified post from WP_Query. |
687 * Get the UTC time of the most recently modified post from WP_Query. |
642 * |
688 * |
643 * If viewing a comment feed, the timestamp of the most recently modified |
689 * If viewing a comment feed, the time of the most recently modified |
644 * comment will be returned. |
690 * comment will be returned. |
645 * |
691 * |
646 * @global WP_Query $wp_query The global WP_Query object. |
692 * @global WP_Query $wp_query WordPress Query object. |
647 * |
693 * |
648 * @since 5.2.0 |
694 * @since 5.2.0 |
649 * |
695 * |
650 * @param string $format Format of the timestamp to return, passed to mysql2date. |
696 * @param string $format Date format string to return the time in. |
651 * |
697 * @return string|false The time in requested format, or false on failure. |
652 * @return string The timestamp. |
|
653 */ |
698 */ |
654 function get_feed_build_date( $format ) { |
699 function get_feed_build_date( $format ) { |
655 global $wp_query; |
700 global $wp_query; |
656 |
701 |
657 if ( empty( $wp_query ) || ! $wp_query->have_posts() ) { |
702 $datetime = false; |
658 // Fallback to last time any post was modified or published. |
703 $max_modified_time = false; |
659 return get_lastpostmodified( 'GMT' ); |
704 $utc = new DateTimeZone( 'UTC' ); |
660 } |
705 |
661 |
706 if ( ! empty( $wp_query ) && $wp_query->have_posts() ) { |
662 // Extract the post modified times from the posts. |
707 // Extract the post modified times from the posts. |
663 $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); |
708 $modified_times = wp_list_pluck( $wp_query->posts, 'post_modified_gmt' ); |
664 |
709 |
665 // If this is a comment feed, check those objects too. |
710 // If this is a comment feed, check those objects too. |
666 if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { |
711 if ( $wp_query->is_comment_feed() && $wp_query->comment_count ) { |
667 // Extract the comment modified times from the comments. |
712 // Extract the comment modified times from the comments. |
668 $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); |
713 $comment_times = wp_list_pluck( $wp_query->comments, 'comment_date_gmt' ); |
669 |
714 |
670 // Add the comment times to the post times for comparison. |
715 // Add the comment times to the post times for comparison. |
671 $modified_times = array_merge( $modified_times, $comment_times ); |
716 $modified_times = array_merge( $modified_times, $comment_times ); |
672 } |
717 } |
673 |
718 |
674 // Determine the maximum modified time. |
719 // Determine the maximum modified time. |
675 $max_modified_time = mysql2date( $format, max( $modified_times ), false ); |
720 $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', max( $modified_times ), $utc ); |
|
721 } |
|
722 |
|
723 if ( false === $datetime ) { |
|
724 // Fall back to last time any post was modified or published. |
|
725 $datetime = date_create_immutable_from_format( 'Y-m-d H:i:s', get_lastpostmodified( 'GMT' ), $utc ); |
|
726 } |
|
727 |
|
728 if ( false !== $datetime ) { |
|
729 $max_modified_time = $datetime->format( $format ); |
|
730 } |
676 |
731 |
677 /** |
732 /** |
678 * Filters the date the last post or comment in the query was modified. |
733 * Filters the date the last post or comment in the query was modified. |
679 * |
734 * |
680 * @since 5.2.0 |
735 * @since 5.2.0 |
681 * |
736 * |
682 * @param string $max_modified_time Date the last post or comment was modified in the query. |
737 * @param string|false $max_modified_time Date the last post or comment was modified in the query, in UTC. |
683 * @param string $format The date format requested in get_feed_build_date. |
738 * False on failure. |
|
739 * @param string $format The date format requested in get_feed_build_date(). |
684 */ |
740 */ |
685 return apply_filters( 'get_feed_build_date', $max_modified_time, $format ); |
741 return apply_filters( 'get_feed_build_date', $max_modified_time, $format ); |
686 } |
742 } |
687 |
743 |
688 /** |
744 /** |
721 /** |
777 /** |
722 * Build SimplePie object based on RSS or Atom feed from URL. |
778 * Build SimplePie object based on RSS or Atom feed from URL. |
723 * |
779 * |
724 * @since 2.8.0 |
780 * @since 2.8.0 |
725 * |
781 * |
726 * @param mixed $url URL of feed to retrieve. If an array of URLs, the feeds are merged |
782 * @param string|string[] $url URL of feed to retrieve. If an array of URLs, the feeds are merged |
727 * using SimplePie's multifeed feature. |
783 * using SimplePie's multifeed feature. |
728 * See also {@link http://simplepie.org/wiki/faq/typical_multifeed_gotchas} |
784 * See also {@link http://simplepie.org/wiki/faq/typical_multifeed_gotchas} |
729 * |
785 * @return SimplePie|WP_Error SimplePie object on success or WP_Error object on failure. |
730 * @return WP_Error|SimplePie WP_Error object on failure or SimplePie object on success |
|
731 */ |
786 */ |
732 function fetch_feed( $url ) { |
787 function fetch_feed( $url ) { |
733 if ( ! class_exists( 'SimplePie', false ) ) { |
788 if ( ! class_exists( 'SimplePie', false ) ) { |
734 require_once( ABSPATH . WPINC . '/class-simplepie.php' ); |
789 require_once ABSPATH . WPINC . '/class-simplepie.php'; |
735 } |
790 } |
736 |
791 |
737 require_once( ABSPATH . WPINC . '/class-wp-feed-cache.php' ); |
792 require_once ABSPATH . WPINC . '/class-wp-feed-cache.php'; |
738 require_once( ABSPATH . WPINC . '/class-wp-feed-cache-transient.php' ); |
793 require_once ABSPATH . WPINC . '/class-wp-feed-cache-transient.php'; |
739 require_once( ABSPATH . WPINC . '/class-wp-simplepie-file.php' ); |
794 require_once ABSPATH . WPINC . '/class-wp-simplepie-file.php'; |
740 require_once( ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php' ); |
795 require_once ABSPATH . WPINC . '/class-wp-simplepie-sanitize-kses.php'; |
741 |
796 |
742 $feed = new SimplePie(); |
797 $feed = new SimplePie(); |
743 |
798 |
744 $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' ); |
799 $feed->set_sanitize_class( 'WP_SimplePie_Sanitize_KSES' ); |
745 // We must manually overwrite $feed->sanitize because SimplePie's |
800 // We must manually overwrite $feed->sanitize because SimplePie's |
746 // constructor sets it before we have a chance to set the sanitization class |
801 // constructor sets it before we have a chance to set the sanitization class. |
747 $feed->sanitize = new WP_SimplePie_Sanitize_KSES(); |
802 $feed->sanitize = new WP_SimplePie_Sanitize_KSES(); |
748 |
803 |
749 $feed->set_cache_class( 'WP_Feed_Cache' ); |
804 $feed->set_cache_class( 'WP_Feed_Cache' ); |
750 $feed->set_file_class( 'WP_SimplePie_File' ); |
805 $feed->set_file_class( 'WP_SimplePie_File' ); |
751 |
806 |
752 $feed->set_feed_url( $url ); |
807 $feed->set_feed_url( $url ); |
753 /** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */ |
808 /** This filter is documented in wp-includes/class-wp-feed-cache-transient.php */ |
754 $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) ); |
809 $feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) ); |
|
810 |
755 /** |
811 /** |
756 * Fires just before processing the SimplePie feed object. |
812 * Fires just before processing the SimplePie feed object. |
757 * |
813 * |
758 * @since 3.0.0 |
814 * @since 3.0.0 |
759 * |
815 * |
760 * @param object $feed SimplePie feed object (passed by reference). |
816 * @param SimplePie $feed SimplePie feed object (passed by reference). |
761 * @param mixed $url URL of feed to retrieve. If an array of URLs, the feeds are merged. |
817 * @param string|string[] $url URL of feed or array of URLs of feeds to retrieve. |
762 */ |
818 */ |
763 do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) ); |
819 do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) ); |
|
820 |
764 $feed->init(); |
821 $feed->init(); |
765 $feed->set_output_encoding( get_option( 'blog_charset' ) ); |
822 $feed->set_output_encoding( get_option( 'blog_charset' ) ); |
766 |
823 |
767 if ( $feed->error() ) { |
824 if ( $feed->error() ) { |
768 return new WP_Error( 'simplepie-error', $feed->error() ); |
825 return new WP_Error( 'simplepie-error', $feed->error() ); |