diff --git a/phpcs.xml.dist b/phpcs.xml.dist index 586d3c7ea..11a5b927b 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -123,6 +123,8 @@ + + diff --git a/public_html/wp-content/themes/wporg-events-2023/inc/events-query.php b/public_html/wp-content/themes/wporg-events-2023/inc/events-query.php index c1e1102ae..e6d388be0 100644 --- a/public_html/wp-content/themes/wporg-events-2023/inc/events-query.php +++ b/public_html/wp-content/themes/wporg-events-2023/inc/events-query.php @@ -10,6 +10,7 @@ // This intentionally doesn't have the starting/ending delimiters and flags, so that it can be used with // `add_rewrite_rule()`. const FILTERED_URL_PATTERN = '([\w-]+)/filtered/(.+)'; +const FILTERED_URL_PATTERN_FEED = FILTERED_URL_PATTERN . '/feed/?'; const PRETTY_URL_VALUE_DELIMITER = '-'; // Misc. @@ -21,6 +22,7 @@ add_filter( 'query_vars', __NAMESPACE__ . '\add_query_vars' ); add_action( 'parse_request', __NAMESPACE__ . '\set_query_vars_from_pretty_url' ); add_action( 'wp', __NAMESPACE__ . '\redirect_to_pretty_query_vars' ); +add_action( 'parse_query', __NAMESPACE__ . '\feed_parse_query' ); add_action( 'wporg_query_filter_in_form', __NAMESPACE__ . '\inject_other_filters' ); add_filter( 'document_title_parts', __NAMESPACE__ . '\add_filters_to_page_title' ); add_filter( 'wporg_query_total_label', __NAMESPACE__ . '\update_query_total_label', 10, 3 ); @@ -62,8 +64,13 @@ function inject_events_into_query( $posts, WP_Query $query ) { global $wp; - $posts = array(); - $facets = get_query_var_facets(); + $posts = array(); + $facets = get_query_var_facets(); + $facets['limit'] = $query->get( 'posts_per_page' ); + if ( is_feed() ) { + $facets['include_description'] = true; + } + $events = Google_Map\get_events( 'all-upcoming', 0, 0, $facets ); // Simulate an ID that won't collide with a real post. @@ -88,6 +95,13 @@ function inject_events_into_query( $posts, WP_Query $query ) { 'guid' => $event->url, 'post_type' => 'wporg_event', + // For feeds. + 'post_date' => gmdate( 'Y-m-d H:i:s', $event->timestamp + $event->tz_offset ), + 'post_date_gmt' => gmdate( 'Y-m-d H:i:s', $event->timestamp ), + 'post_content' => wp_kses_post( $event->description ?? '' ), + 'comment_status' => 'closed', + 'comment_count' => 0, + // This makes Core create a new post object, rather than trying to get an instance. // See https://github.com/WordPress/WordPress/blob/7926dbb4d5392c870ccbc3ec6019c002feed904c/wp-includes/post.php#L1030-L1033. 'filter' => 'raw', @@ -193,6 +207,7 @@ function add_rewrite_rules(): void { // predictable. Instead, this just matches all the facets into a single var, and they'll be parsed out of that // into individual facets later. // @see set_query_vars_from_pretty_url(). + add_rewrite_rule( FILTERED_URL_PATTERN_FEED, 'index.php?pagename=$matches[1]&event_facets=$matches[2]&feed=feed', 'top' ); add_rewrite_rule( FILTERED_URL_PATTERN, 'index.php?pagename=$matches[1]&event_facets=$matches[2]', 'top' ); } @@ -220,7 +235,7 @@ function add_query_vars( array $query_vars ): array { * @see add_rewrite_rules() * @see add_query_vars() */ -function set_query_vars_from_pretty_url( WP $wp ): void { +function set_query_vars_from_pretty_url( WP|WP_Query $wp ): void { $facets = get_query_var_facets(); foreach ( $facets as $key => $value ) { @@ -293,6 +308,72 @@ function ( &$facet ) { return $facets; } +/** + * Adjust the query for feeds on the upcoming-events page. + * + * @param WP_Query $wp_query The WP_Query instance. + */ +function feed_parse_query( $wp_query ) { + global $wp; + + if ( + 'upcoming-events' !== $wp_query->get( 'pagename' ) || + ! $wp_query->is_feed() + ) { + return; + } + + // Fix the feed link to use the correct URL. + $pagelink = home_url( preg_replace( '#/feed/?$#i', '/', $wp->request ) ); + add_filter( 'bloginfo_rss', function( $value, $show ) use ( $pagelink ) { + if ( 'url' === $show ) { + return $pagelink; + } + + return $value; + }, 10, 2 ); + + // The feed is built now. + add_filter( 'get_feed_build_date', function() { + return gmdate( 'r' ); + } ); + + // Query for events. + $wp_query->parse_query( [ + 'post_type' => 'wporg_events', + 'feed' => $wp_query->get( 'feed' ), + 'posts_per_page' => 50, + 'posts_per_rss' => 50, + ] ); + + // Permalinks should use the Guid. + add_filter( 'the_permalink_rss', function () { + return get_post()->guid; + } ); + + // Set the author to the meetup group. + add_filter( 'the_author', function () { + return get_post()->meetup; + } ); + + // Body should be prefixed with Location & Time. RSS Dates can't be in the future. + add_filter( 'the_content_feed', function ( $content ) { + $event = get_post(); + $time = gmdate( 'F j, Y g:ia', strtotime( $event->post_date ) ); // This is not in UTC, but the timestamps is. + + $prefix = sprintf( + '

Location: %s
Time: %s

', + $event->location, + $time + ); + + return $prefix . $content; + } ); + + // Body doesn't need to staticize the emojis. + remove_filter( 'the_content_feed', 'wp_staticize_emoji' ); +} + /** * Add in the other existing filters as hidden inputs in the filter form. *