diff --git a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/events-landing-page.php b/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/events-landing-page.php
deleted file mode 100644
index 3878b30f57..0000000000
--- a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/events-landing-page.php
+++ /dev/null
@@ -1,54 +0,0 @@
- __NAMESPACE__ . '\render_events_landing_page',
- )
- );
-}
-
-/**
- * Render the output of the Events Landing Page block.
- */
-function render_events_landing_page( array $block_attributes, string $content ): string {
- switch ( $block_attributes['events'] ) {
- case 'all-upcoming':
- $map_options = array(
- 'id' => 'all-upcoming-events',
- 'markers' => get_all_upcoming_events(),
- );
- break;
-
- case 'city':
- // Can't use `$wp->request` because Gutenberg calls this on `init`, before `parse_request`.
- // @todo That was true when this was part of a pattern, but it isn't now that this is a block. We can
- // maybe pass `$wp->request` to `normalize_request_uri()` now, or maybe remove that function entirely.
- $request_uri = normalize_request_uri( $_SERVER['REQUEST_URI'], $_SERVER['QUERY_STRING'] );
-
- $map_options = array(
- 'id' => 'city-landing-page',
- 'markers' => get_city_landing_page_events( $request_uri ),
- );
- break;
-
- default:
- return 'No events available';
- }
-
- $map_options['apiKey'] = 'production' === wp_get_environment_type() ? 'WORDCAMP_PROD_GOOGLE_MAPS_API_KEY' : 'WORDCAMP_DEV_GOOGLE_MAPS_API_KEY';
-
- return do_blocks( '' );
-}
diff --git a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/package.json b/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/package.json
deleted file mode 100644
index cd3ed74644..0000000000
--- a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/package.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "events-landing-page",
- "version": "0.0.1",
- "description": "Gather events for the different landing pages, and pass them to the Google Map block to be displayed.",
- "main": "index.js",
- "scripts": {
- "start": "wp-scripts start",
- "build": "wp-scripts build"
- },
- "devDependencies": {
- "@wordpress/scripts": "^26.13.0"
- }
-}
diff --git a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/block.json b/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/block.json
deleted file mode 100644
index 40e0db2136..0000000000
--- a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/block.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "$schema": "https://schemas.wp.org/trunk/block.json",
- "apiVersion": 2,
- "name": "wporg/events-landing-page",
- "title": "Events Landing Page",
- "icon": "admin-site-alt",
- "category": "widgets",
- "description": "Gather events for the different landing pages, and pass them to the Google Map block to be displayed.",
- "textdomain": "wporg",
- "attributes": {
- "events": {
- "type": "string",
- "default": ""
- }
- },
- "editorScript": "file:./index.js"
-}
diff --git a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/index.js b/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/index.js
deleted file mode 100644
index 57bc371958..0000000000
--- a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/src/index.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * WordPress dependencies
- */
-import { __ } from '@wordpress/i18n';
-import { registerBlockType } from '@wordpress/blocks';
-import { Placeholder } from '@wordpress/components';
-
-/**
- * Internal dependencies
- */
-import metadata from './block.json';
-
-function Edit() {
- return (
-
- );
-}
-
-registerBlockType( metadata.name, {
- edit: Edit,
-} );
diff --git a/public_html/wp-content/themes/wporg-events-2023/functions.php b/public_html/wp-content/themes/wporg-events-2023/functions.php
index cd747030ad..18187354bd 100644
--- a/public_html/wp-content/themes/wporg-events-2023/functions.php
+++ b/public_html/wp-content/themes/wporg-events-2023/functions.php
@@ -1,59 +1,13 @@
set_query_var( 'page', '' );
- $wp->set_query_var( 'pagename', 'city-landing-page' );
-}
-
-/**
- * Determine if the current request is for a city landing page.
- *
- * See `get_city_landing_sites()` for examples of request URIs.
- */
-function is_city_landing_page() {
- global $wp, $wpdb;
-
- // The landing page formats will always match the rewrite rule for pages, which sets `page` and `pagename`.
- if ( empty( $wp->query_vars['page'] ) && empty( $wp->query_vars['pagename'] ) ) {
- return false;
- }
-
- $city = explode( '/', $wp->request );
- $city = $city[0] ?? false;
-
- // Using this instead of `get_sites()` so that the search doesn't match false positives.
- $sites = $wpdb->get_results( $wpdb->prepare( "
- SELECT blog_id
- FROM {$wpdb->blogs}
- WHERE
- site_id = %d AND
- path REGEXP %s
- LIMIT 1",
- EVENTS_NETWORK_ID,
- "^/$city/\d{4}/[a-z-]+/$"
- ) );
-
- return ! empty( $sites );
-}
/**
* Enqueue scripts and styles.
diff --git a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/event-getters.php b/public_html/wp-content/themes/wporg-events-2023/inc/city-landing-pages.php
similarity index 56%
rename from public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/event-getters.php
rename to public_html/wp-content/themes/wporg-events-2023/inc/city-landing-pages.php
index 0e9240cfa3..7dabc38cf3 100644
--- a/public_html/wp-content/themes/wporg-events-2023/blocks/events-landing-page/event-getters.php
+++ b/public_html/wp-content/themes/wporg-events-2023/inc/city-landing-pages.php
@@ -1,14 +1,65 @@
set_query_var( 'page', '' );
+ $wp->set_query_var( 'pagename', 'city-landing-page' );
+}
+
+/**
+ * Determine if the current request is for a city landing page.
+ *
+ * See `get_city_landing_sites()` for examples of request URIs.
+ */
+function is_city_landing_page(): bool {
+ global $wp, $wpdb;
+
+ // The landing page formats will always match the rewrite rule for pages, which sets `page` and `pagename`.
+ if ( empty( $wp->query_vars['page'] ) && empty( $wp->query_vars['pagename'] ) ) {
+ return false;
+ }
+
+ $city = explode( '/', $wp->request );
+ $city = $city[0] ?? false;
+
+ // Using this instead of `get_sites()` so that the search doesn't match false positives.
+ $sites = $wpdb->get_results( $wpdb->prepare( "
+ SELECT blog_id
+ FROM {$wpdb->blogs}
+ WHERE
+ site_id = %d AND
+ path REGEXP %s
+ LIMIT 1",
+ EVENTS_NETWORK_ID,
+ "^/$city/\d{4}/[a-z-]+/$"
+ ) );
+
+ return ! empty( $sites );
+}
+
/**
* Schedule cron jobs.
*/
@@ -24,14 +75,30 @@ function schedule_cron_jobs(): void {
* Without this, users would have to wait for new results to be generated every time the cache expires. That could
* make the front end very slow. This will refresh the cache before it expires, so that the front end can always
* load cached results.
+ *
+ * These pages can't use the cache-priming cron provided by the Event Filters plugin, because it doesn't know how
+ * to handle them.
*/
function prime_query_cache(): void {
- get_all_upcoming_events( true );
-
$city_landing_uris = get_known_city_landing_request_uris();
+ // It won't know the "current" page in a cron context, so we'll pass it directly to `get_cache_key()` in the loop below.
+ remove_action( 'google_map_event_filters_cache_key_parts', __NAMESPACE__ .'\add_landing_page_to_cache_key' );
+
foreach ( $city_landing_uris as $request_uri ) {
- get_city_landing_page_events( $request_uri, true );
+ // Must match the return value of the cache key that `Google_Map_Event_Filters\get_events()` generates during block rendering,
+ // including the `landing_page` item added by `add_landing_page_to_cache_key()`.
+ $parts = array(
+ 'filter_slug' => FILTER_SLUG,
+ 'start_timestamp' => 0,
+ 'end_timestamp' => 0,
+ 'landing_page' => $request_uri
+ );
+
+ $cache_key = Google_Map_Event_Filters\get_cache_key( $parts );
+ $events = get_city_landing_page_events( $request_uri, true );
+
+ set_transient( $cache_key, $events, DAY_IN_SECONDS );
}
}
@@ -71,100 +138,19 @@ function get_known_city_landing_request_uris(): array {
return array_keys( $city_landing_pages );
}
-/**
- * Query a table that's encoded with the `latin1` charset.
- *
- * Unlike wordpress.org, wordcamp.org has a `DB_CHARSET` of `utf8mb4`, so that's what WPDB uses when querying
- * tables. w.org tables use `latin1`, so we need to switch to that when pulling from them. If you query it with
- * `utf8mb4`, you'll get Mojibake.
- *
- * @param string $prepared_query ⚠️ This must have already be ran through `$wpdb->prepare()` if needed.
- *
- * @return object|null
- */
-function get_latin1_results_with_prepared_query( string $prepared_query ) {
- global $wpdb;
-
- // Local environments don't always use HyperDB, but production does.
- $db_handle = $wpdb instanceof hyperdb ? $wpdb->db_connect( $prepared_query ) : $wpdb->dbh;
- $wpdb->set_charset( $db_handle, 'latin1', 'latin1_swedish_ci' );
-
- // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- This function doesn't have the context to prepare it, the caller must.
- $results = $wpdb->get_results( $prepared_query );
-
- // Revert to the default charset to avoid affecting other queries.
- $wpdb->set_charset( $db_handle, DB_CHARSET, DB_COLLATE );
-
- return $results;
-}
-
-/**
- * Get a list of all upcoming events across all sites.
- */
-function get_all_upcoming_events( bool $force_refresh = false ): array {
- $cache_key = 'event_landing_all_upcoming_events';
-
- if ( ! $force_refresh ) {
- $cached_events = get_transient( $cache_key );
-
- if ( $cached_events ) {
- return $cached_events;
- }
- }
-
- $events = get_latin1_results_with_prepared_query( '
- SELECT
- id, `type`, title, url, meetup, location, latitude, longitude, date_utc,
- date_utc_offset AS tz_offset
- FROM `wporg_events`
- WHERE
- status = "scheduled" AND
- (
- ( "wordcamp" = type AND date_utc BETWEEN NOW() AND ADDDATE( NOW(), 180 ) ) OR
- ( "meetup" = type AND date_utc BETWEEN NOW() AND ADDDATE( NOW(), 30 ) )
- )
- ORDER BY date_utc ASC
- LIMIT 400'
- );
-
- foreach ( $events as $event ) {
- // `capital_P_dangit()` won't work here because the current filter isn't `the_title` and there isn't a safelisted prefix before `$text`.
- $event->title = str_replace( 'Wordpress', 'WordPress', $event->title );
-
- // `date_utc` is a misnomer, the value is actually in the local timezone of the event. So, convert to a true Unix timestamp (UTC).
- // Can't do this reliably in the query because MySQL converts it to the server timezone.
- $event->timestamp = strtotime( $event->date_utc ) - $event->tz_offset;
-
- unset( $event->date_utc );
- }
-
- // `prime_query_cache()` should update this hourly, but expire after a day just in case it doesn't.
- set_transient( $cache_key, $events, DAY_IN_SECONDS );
-
- return $events;
-}
/**
* Get events based on the given request URI.
*
* See `get_city_landing_sites()` for how request URIs map to events.
*/
-function get_city_landing_page_events( string $request_uri, bool $force_refresh = false ): array {
- $limit = 300;
- $cache_key = 'event_landing_city_events_' . md5( $request_uri );
+function get_city_landing_page_events( string $request_uri ): array {
+ $limit = 300;
if ( empty( $request_uri ) || '/' === $request_uri ) {
return array();
}
- if ( ! $force_refresh ) {
- $cached_events = get_transient( $cache_key );
-
- if ( $cached_events ) {
- return $cached_events;
- }
- }
-
$sites = get_city_landing_sites( $request_uri, $limit );
switch_to_blog( WORDCAMP_ROOT_BLOG_ID );
@@ -202,26 +188,9 @@ function get_city_landing_page_events( string $request_uri, bool $force_refresh
restore_current_blog();
- // `prime_query_cache()` should update this hourly, but expire after a day just in case it doesn't find all the
- // valid request URIs.
- set_transient( $cache_key, $events, DAY_IN_SECONDS );
-
return $events;
}
-/**
- * Standardize request URIs so they can be reliably used as cache keys.
- *
- * For example, `/rome`, `/rome/` and `/rome/?foo=bar` should all be `/rome/`.
- */
-function normalize_request_uri( $raw_uri, $query_string ) {
- $clean_uri = str_replace( '?' . $query_string, '', $raw_uri );
- $clean_uri = trailingslashit( $clean_uri );
- $clean_uri = '/' . ltrim( $clean_uri, '/' );
-
- return $clean_uri;
-}
-
/**
* Get sites that match the given request URI.
*
@@ -297,3 +266,51 @@ function get_wordcamp_offset( WP_Post $wordcamp ): int {
return $wordcamp_timezone->getOffset( $wordcamp_datetime );
}
+
+/**
+ * Disable the cron job that Google Map Event Filters registers.
+ *
+ * This plugin needs to run its own cron to prime the events cache, because the upstream one doesn't know how to handle city pages.
+ */
+function disable_event_filters_cron( bool $enabled, string $filter_slug ): bool {
+ if ( FILTER_SLUG === $filter_slug ) {
+ $enabled = false;
+ }
+
+ return $enabled;
+}
+
+/**
+ * Get the events for the current city landing page.
+ */
+function get_events( array $events ): array {
+ if ( is_city_landing_page() ) {
+ $events = get_city_landing_page_events( get_current_landing_page() );
+ }
+
+ return $events;
+}
+
+/**
+ * Get the path to the current landing page, with surrounding slashes.
+ */
+function get_current_landing_page(): string {
+ global $wp;
+
+ $page = '/' . $wp->request . '/';
+
+ return $page;
+}
+
+/**
+ * Adds the current landing page to the Event Filters cache key.
+ *
+ * Without this, all city pages would share the same cache key, and the wrong events would show up on most pages.
+ */
+function add_landing_page_to_cache_key( array $items ) : array {
+ if ( is_city_landing_page() && FILTER_SLUG === $items['filter_slug'] ) {
+ $items['landing_page'] = get_current_landing_page();
+ }
+
+ return $items;
+}
diff --git a/public_html/wp-content/themes/wporg-events-2023/parts/front-page/cover.html b/public_html/wp-content/themes/wporg-events-2023/parts/front-page/cover.html
index 8751867bb1..f6a24c4635 100644
--- a/public_html/wp-content/themes/wporg-events-2023/parts/front-page/cover.html
+++ b/public_html/wp-content/themes/wporg-events-2023/parts/front-page/cover.html
@@ -25,8 +25,6 @@
Meet the community behind WordPress
-
- map goes here when block updated
-
+
\ No newline at end of file
diff --git a/public_html/wp-content/themes/wporg-events-2023/parts/front-page/events.html b/public_html/wp-content/themes/wporg-events-2023/parts/front-page/events.html
index 42e642fff0..3f19ef8d45 100644
--- a/public_html/wp-content/themes/wporg-events-2023/parts/front-page/events.html
+++ b/public_html/wp-content/themes/wporg-events-2023/parts/front-page/events.html
@@ -5,7 +5,7 @@
Upcoming Events
-
+
diff --git a/public_html/wp-content/themes/wporg-events-2023/templates/page-city-landing-page.html b/public_html/wp-content/themes/wporg-events-2023/templates/page-city-landing-page.html
index c4f989270e..463e87579b 100644
--- a/public_html/wp-content/themes/wporg-events-2023/templates/page-city-landing-page.html
+++ b/public_html/wp-content/themes/wporg-events-2023/templates/page-city-landing-page.html
@@ -2,7 +2,7 @@
-
+