From 66fe29e404b0707fda5f24302df5c6381973b780 Mon Sep 17 00:00:00 2001 From: Adam Wood <1017872+adamwoodnz@users.noreply.github.com> Date: Thu, 27 Jun 2024 10:55:24 +1200 Subject: [PATCH] Switch to archive based search (#2574) * Refactor query filter options Rename keys and functions * Pass search query with filter params * Add filters to search template * Add filter info to search results context * Get all available languages for search language filter * Add a post type filter to the search template Enables clearing the post type if set from searching on an archive * Use native labels for language options * Show a header for Course and Lesson searches * Fix post type filtering for 'all' * Switch to archive based search * Allow lesson plans to be searched * Set the title of the Lesson plan archive * Remove search post type limits * Update filter option docs * Fix archive language fetching --- .../plugins/wporg-learn/inc/post-meta.php | 24 +- .../pub/wporg-learn-2024/inc/block-config.php | 97 ++++++-- .../themes/pub/wporg-learn-2024/inc/query.php | 30 --- .../patterns/archive-content.php | 6 +- .../patterns/archive-courses-content.php | 11 +- .../patterns/archive-lesson-plan-content.php | 10 +- .../patterns/archive-lessons-content.php | 12 +- .../patterns/page-my-courses-content.php | 2 +- .../patterns/taxonomy-content.php | 4 +- ...-learning-pathway-content-search-grid.php} | 28 +-- ...nomy-learning-pathway-content-sections.php | 227 ++++++++++++++++++ .../taxonomy-learning-pathway-content.php | 211 +--------------- .../src/learning-pathway-header/index.php | 4 +- .../src/search-results-context/index.php | 69 +++++- .../wporg-learn-2024/templates/search.html | 17 -- 15 files changed, 419 insertions(+), 333 deletions(-) rename wp-content/themes/pub/wporg-learn-2024/patterns/{search-content.php => taxonomy-learning-pathway-content-search-grid.php} (68%) create mode 100644 wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-sections.php delete mode 100644 wp-content/themes/pub/wporg-learn-2024/templates/search.html diff --git a/wp-content/plugins/wporg-learn/inc/post-meta.php b/wp-content/plugins/wporg-learn/inc/post-meta.php index 97e966a55..2421c75a0 100644 --- a/wp-content/plugins/wporg-learn/inc/post-meta.php +++ b/wp-content/plugins/wporg-learn/inc/post-meta.php @@ -296,15 +296,23 @@ function get_available_post_type_locales( $meta_key, $post_type, $post_status, $ $and_post_status = "AND posts.post_status = '$post_status'"; } + $and_post_type = ''; + if ( isset( $post_type ) ) { + $public_post_types = get_post_types( array( 'public' => true ), 'names' ); + + if ( in_array( $post_type, $public_post_types ) ) { + $and_post_type = "AND posts.post_type = '$post_type'"; + } + } + $results = $wpdb->get_col( $wpdb->prepare( - // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $and_post_status only includes $post_status if it matches an allowed string. - " - SELECT DISTINCT postmeta.meta_value - FROM {$wpdb->postmeta} postmeta - JOIN {$wpdb->posts} posts ON posts.ID = postmeta.post_id AND posts.post_type = %s $and_post_status - WHERE postmeta.meta_key = %s - ", - $post_type, + // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $and_post_status and $and_post_type only include $post_status and $post_type if they match an allowed string. + "SELECT DISTINCT postmeta.meta_value + FROM {$wpdb->postmeta} postmeta + JOIN {$wpdb->posts} posts ON posts.ID = postmeta.post_id + $and_post_type + $and_post_status + WHERE postmeta.meta_key = %s", $meta_key // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared ) ); diff --git a/wp-content/themes/pub/wporg-learn-2024/inc/block-config.php b/wp-content/themes/pub/wporg-learn-2024/inc/block-config.php index 33be79680..340abda0e 100644 --- a/wp-content/themes/pub/wporg-learn-2024/inc/block-config.php +++ b/wp-content/themes/pub/wporg-learn-2024/inc/block-config.php @@ -8,14 +8,18 @@ use function WPOrg_Learn\Post_Meta\{get_available_post_type_locales}; add_filter( 'wporg_query_filter_options_language', __NAMESPACE__ . '\get_language_options' ); +add_filter( 'wporg_query_filter_options_archive_language', __NAMESPACE__ . '\get_language_options_by_post_type' ); + add_filter( 'wporg_query_filter_options_level', __NAMESPACE__ . '\get_level_options' ); -add_filter( 'wporg_query_filter_options_taxonomy-level', __NAMESPACE__ . '\get_taxonomy_level_options' ); -add_filter( 'wporg_query_filter_options_learning-pathway-level', __NAMESPACE__ . '\get_learning_pathway_level_options' ); +add_filter( 'wporg_query_filter_options_archive_level', __NAMESPACE__ . '\get_level_options_by_post_type' ); +add_filter( 'wporg_query_filter_options_learning_pathway_level', __NAMESPACE__ . '\get_learning_pathway_level_options' ); + add_filter( 'wporg_query_filter_options_topic', __NAMESPACE__ . '\get_topic_options' ); -add_filter( 'wporg_query_filter_options_taxonomy-topic', __NAMESPACE__ . '\get_taxonomy_topic_options' ); -add_filter( 'wporg_query_filter_options_learning-pathway-topic', __NAMESPACE__ . '\get_learning_pathway_topic_options' ); +add_filter( 'wporg_query_filter_options_archive_topic', __NAMESPACE__ . '\get_topic_options_by_post_type' ); +add_filter( 'wporg_query_filter_options_learning_pathway_topic', __NAMESPACE__ . '\get_learning_pathway_topic_options' ); + add_filter( 'query_vars', __NAMESPACE__ . '\add_student_course_filter_query_vars' ); -add_filter( 'wporg_query_filter_options_student-course', __NAMESPACE__ . '\get_student_course_options' ); +add_filter( 'wporg_query_filter_options_student_course', __NAMESPACE__ . '\get_student_course_options' ); add_action( 'wporg_query_filter_in_form', __NAMESPACE__ . '\inject_other_filters' ); /** @@ -29,7 +33,7 @@ function get_current_url() { } /** - * Create level options. + * Create the options for a level filter. * * @param array $levels The filtered levels for a view. * @return array The options for a level filter. @@ -92,12 +96,13 @@ function ( $level ) use ( $selected_slug ) { } /** - * Get the list of levels for the course and lesson filters. + * Get the top 10 level options for a post type. + * Used for the archive filters. * * @param array $options The options for this filter. * @return array New list of level options. */ -function get_level_options( $options ) { +function get_level_options_by_post_type( $options ) { global $wp_query; if ( ! isset( $wp_query->query_vars['post_type'] ) ) { @@ -128,12 +133,13 @@ function get_level_options( $options ) { } /** - * Get the list of levels for the taxonomy filters. + * Get the top 10 level options. + * Used for the taxonomy and search filters. * * @param array $options The options for this filter. * @return array New list of level options. */ -function get_taxonomy_level_options( $options ) { +function get_level_options( $options ) { // Get top 10 levels ordered by count, not empty. $levels = get_terms( array( @@ -149,7 +155,7 @@ function get_taxonomy_level_options( $options ) { } /** - * Get the list of levels for the learning pathway filters. + * Get the top 10 level options for a learning pathway. * * @param array $options The options for this filter. * @return array New list of level options. @@ -192,7 +198,7 @@ function get_learning_pathway_level_options( $options ) { } /** - * Create topic options. + * Create the options for a topic filter. * * @param array $topics The filtered topics for a view. * @return array The options for a topic filter. @@ -232,12 +238,13 @@ function ( $a, $b ) { } /** - * Get the list of topics for the course and lesson filters. + * Get the top 20 topic options for a post type. + * Used for the archive filters. * * @param array $options The options for this filter. * @return array New list of topic options. */ -function get_topic_options( $options ) { +function get_topic_options_by_post_type( $options ) { global $wp_query; if ( ! isset( $wp_query->query_vars['post_type'] ) ) { @@ -266,12 +273,13 @@ function get_topic_options( $options ) { } /** - * Get the list of topics for the taxonomy filters. + * Get the top 20 topic options. + * Used for the taxonomy and search filters. * * @param array $options The options for this filter. * @return array New list of topic options. */ -function get_taxonomy_topic_options( $options ) { +function get_topic_options( $options ) { // Get top 20 topics ordered by count, not empty. $topics = get_terms( array( @@ -287,7 +295,7 @@ function get_taxonomy_topic_options( $options ) { } /** - * Get the list of topics for the learning pathway filters. + * Get the top 20 topic options for a learning pathway. * * @param array $options The options for this filter. * @return array New list of topic options. @@ -351,15 +359,14 @@ function get_meta_query_values_by_key( $query, $key ) { } /** - * Get the list of languages for the course and lesson filters. + * Create the options for a language filter. * - * @param array $options The options for this filter. - * @return array New list of language options. + * @param array $languages The filtered languages for a view. + * @return array The options for a language filter. */ -function get_language_options( $options ) { +function create_language_options( $languages ) { global $wp_query; - $post_type = $wp_query->query_vars['post_type']; - $languages = get_available_post_type_locales( 'language', $post_type, 'publish' ); + // If there are no languages, or the only language is en_US, don't show the filter. if ( empty( $languages ) || ( 1 === count( $languages ) && isset( $languages['en_US'] ) ) ) { return array(); @@ -388,6 +395,43 @@ function get_language_options( $options ) { ); } +/** + * Get the full list of available languages that have content. + * Used for the taxonomy filters. + * + * @param array $options The options for this filter. + * @return array New list of language options. + */ +function get_language_options( $options ) { + $languages = get_available_post_type_locales( 'language', null, 'publish', 'native' ); + + return create_language_options( $languages ); +} + +/** + * Get the list of languages for a post_type. + * Used for the archive filters. + * + * @param array $options The options for this filter. + * @return array New list of language options. + */ +function get_language_options_by_post_type( $options ) { + global $wp_query; + $post_type = $wp_query->get( 'post_type' ); + // Convert post type from array to string if possible. + if ( is_array( $post_type ) && count( $post_type ) === 1 ) { + $post_type = reset( $post_type ); + } + + if ( ! is_string( $post_type ) ) { + return array(); + } + + $languages = get_available_post_type_locales( 'language', $post_type, 'publish', 'native' ); + + return create_language_options( $languages ); +} + /** * Get the query variable name for the student course filter, used by Sensei to filter the My Courses page. * This is the PARAM_KEY defined in the Sensei plugin + the query id on the query loop in my-courses-content.php @@ -468,7 +512,7 @@ function ( $option, $slug ) use ( $selected_slug ) { function inject_other_filters( $key ) { global $wp_query; - $single_query_vars = array( 'wporg_lesson_level' ); + $single_query_vars = array( 'wporg_lesson_level', 'wporg_learning_pathway', 'post_type' ); foreach ( $single_query_vars as $single_query_var ) { if ( ! isset( $wp_query->query[ $single_query_var ] ) ) { continue; @@ -507,4 +551,9 @@ function inject_other_filters( $key ) { printf( '', esc_attr( $meta_query_var ), esc_attr( $value ) ); } } + + // Pass through search query. + if ( isset( $wp_query->query['s'] ) ) { + printf( '', esc_attr( $wp_query->query['s'] ) ); + } } diff --git a/wp-content/themes/pub/wporg-learn-2024/inc/query.php b/wp-content/themes/pub/wporg-learn-2024/inc/query.php index 0e5523107..d28ae030b 100644 --- a/wp-content/themes/pub/wporg-learn-2024/inc/query.php +++ b/wp-content/themes/pub/wporg-learn-2024/inc/query.php @@ -7,8 +7,6 @@ add_action( 'pre_get_posts', __NAMESPACE__ . '\modify_archive_queries' ); add_action( 'pre_get_posts', __NAMESPACE__ . '\modify_level_query' ); -add_action( 'pre_get_posts', __NAMESPACE__ . '\modify_search_query' ); - /** * Modify the query by adding meta query for language if set. @@ -63,31 +61,3 @@ function modify_level_query( $query ) { return $query; } - -/** - * Get a list of the searchable Learn post types. - * - * @return array The searchable post types. - */ -function get_searchable_post_types() { - return array( 'course', 'lesson', 'quiz', 'meeting', 'page', 'post', 'wporg_workshop' ); -} - -/** - * Modify the search query to filter to only Learn post types if no post type is set. - * - * @param WP_Query $query The search query. - */ -function modify_search_query( $query ) { - if ( is_admin() || ! $query->is_search() ) { - return; - } - - if ( isset( $query->query_vars['post_type'] ) ) { - return $query; - } - - $query->set( 'post_type', get_searchable_post_types() ); - - return $query; -} diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-content.php index 084eda5e6..97158e32a 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-content.php @@ -22,9 +22,9 @@
- - - + + +
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-courses-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-courses-content.php index 6a168ed56..e28fe39ea 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-courses-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-courses-content.php @@ -10,7 +10,9 @@
- + +

+

@@ -26,15 +28,16 @@
- - - + + +
+
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lesson-plan-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lesson-plan-content.php index e934a0cf2..ac8bdcdae 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lesson-plan-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lesson-plan-content.php @@ -10,7 +10,9 @@
- + +

+

@@ -26,9 +28,9 @@
- - - + + +
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lessons-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lessons-content.php index 4f6850e71..513cf8f8e 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lessons-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/archive-lessons-content.php @@ -10,7 +10,9 @@
- + +

+

@@ -26,15 +28,17 @@
- - - + + +
+ +
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/page-my-courses-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/page-my-courses-content.php index 9c5b2a27e..df8414fec 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/page-my-courses-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/page-my-courses-content.php @@ -22,7 +22,7 @@
- +
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-content.php index 4779135b2..42a776d57 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-content.php @@ -41,7 +41,7 @@
- +
@@ -50,6 +50,8 @@ + +
diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/search-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-search-grid.php similarity index 68% rename from wp-content/themes/pub/wporg-learn-2024/patterns/search-content.php rename to wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-search-grid.php index 4080dbf72..9ae51c051 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/search-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-search-grid.php @@ -1,30 +1,12 @@ - -
- - -

- - -
- - - -
- - - -
- - @@ -66,12 +48,8 @@ - -

- - -

+

diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-sections.php b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-sections.php new file mode 100644 index 000000000..a553d7554 --- /dev/null +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content-sections.php @@ -0,0 +1,227 @@ +term_id; +$learning_pathway_slug = $learning_pathway_object->slug; +$learning_pathway_url = get_term_link( $learning_pathway_object ); + +$beginner_level_id = get_term_by( 'slug', 'beginner', 'level' )->term_id; +$intermediate_level_id = get_term_by( 'slug', 'intermediate', 'level' )->term_id; +$advanced_level_id = get_term_by( 'slug', 'advanced', 'level' )->term_id; + +$content = get_learning_pathway_level_content( $learning_pathway_slug ); +?> + + +

+ + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + + + + +
+ + +
+ + +
+ + + + + + + +

+ + + + +
+ + + +

+ + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + + + + +
+ + +
+ + +
+ + + + + + + +

+ + + + +
+ + + +

+ + + +
+ + + + + + + + + +
+ + + +
+ + + + +
+ + + + +
+ + + + + + +
+ + + + + + + +
+ + +
+ + +
+ + + + + + + +

+ + + + +
+ diff --git a/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content.php b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content.php index bf6596ee8..c1e136cdb 100644 --- a/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content.php +++ b/wp-content/themes/pub/wporg-learn-2024/patterns/taxonomy-learning-pathway-content.php @@ -17,219 +17,24 @@ return; } -$learning_pathway_id = $learning_pathway_object->term_id; -$learning_pathway_slug = $learning_pathway_object->slug; -$learning_pathway_url = get_term_link( $learning_pathway_object ); - -$beginner_level_id = get_term_by( 'slug', 'beginner', 'level' )->term_id; -$intermediate_level_id = get_term_by( 'slug', 'intermediate', 'level' )->term_id; -$advanced_level_id = get_term_by( 'slug', 'advanced', 'level' )->term_id; - -$content = get_learning_pathway_level_content( $learning_pathway_slug ); +global $wp_query; +$search_term = $wp_query->get( 's' ); ?> - +
- -

- - - -
- - - - - - - - - -
- - - -
- - - - -
- - - - -
- - - - - - -
- - - - - - - -
- - -
- - -
- - - - - - - -

- - - - -
- - - -

- - - -
- - - - - - - - - -
- - - -
- - - - -
- - - - -
- - - - - - -
- - - - - - - -
- - -
- - -
- - - - - - - -

- - - - -
- - - -

- - - -
- - - - - - - - - -
- - - -
- - - - -
- - - - -
- - - - - - -
- - - - - - - -
- - -
- - -
- - - + - + - -

- + - + -
- +
diff --git a/wp-content/themes/pub/wporg-learn-2024/src/learning-pathway-header/index.php b/wp-content/themes/pub/wporg-learn-2024/src/learning-pathway-header/index.php index 364c8e887..75cd70173 100644 --- a/wp-content/themes/pub/wporg-learn-2024/src/learning-pathway-header/index.php +++ b/wp-content/themes/pub/wporg-learn-2024/src/learning-pathway-header/index.php @@ -92,8 +92,8 @@ function render( $attributes, $content, $block ) {
- - + +
diff --git a/wp-content/themes/pub/wporg-learn-2024/src/search-results-context/index.php b/wp-content/themes/pub/wporg-learn-2024/src/search-results-context/index.php index 1cf37cd6d..afd260a52 100644 --- a/wp-content/themes/pub/wporg-learn-2024/src/search-results-context/index.php +++ b/wp-content/themes/pub/wporg-learn-2024/src/search-results-context/index.php @@ -45,24 +45,79 @@ function render( $attributes ) { esc_html( $wp_query->query['s'] ), ); - $showing = sprintf( - /* translators: %1$s number of first displayed result, %2$s number of last displayed result. */ - 'Showing results %1$s to %2$s.', - number_format_i18n( $first_result ), - number_format_i18n( $last_result ), - ); + $filters = get_applied_filter_info( $wp_query ); + + $showing = $results_count > 1 + ? sprintf( + /* translators: %1$s number of first displayed result, %2$s number of last displayed result. */ + 'Showing results %1$s to %2$s.', + number_format_i18n( $first_result ), + number_format_i18n( $last_result ), + ) + : ''; $wrapper_attributes = get_block_wrapper_attributes(); return sprintf( - '<%1$s %2$s>%3$s %4$s', + '<%1$s %2$s>%3$s %4$s %5$s', esc_attr( $attributes['tagName'] ), $wrapper_attributes, $content, + $filters, $showing, ); } +/** + * Get a description of the number of filters applied. + * + * @param WP_Query $query The WP_Query object. + * @return string Returns the filter information. + */ +function get_applied_filter_info( $query ) { + $filters_count = 0; + + // Add the level filter count + if ( + isset( $query->query_vars['wporg_lesson_level'] ) + && ! empty( $query->query_vars['wporg_lesson_level'] + && 'all' !== $query->query_vars['wporg_lesson_level'] ) + ) { + // Level is a single value filter + $filters_count++; + } + + // Add the topic filter count + if ( isset( $query->query_vars['wporg_workshop_topic'] ) && ! empty( $query->query_vars['wporg_workshop_topic'] ) ) { + // Topic is a multiple value filter + $filters_count += count( $query->query_vars['wporg_workshop_topic'] ); + } + + // Add the language filter count + if ( isset( $query->query_vars['meta_query'] ) && is_array( $query->query_vars['meta_query'] ) ) { + foreach ( $query->query_vars['meta_query'] as $meta_query ) { + if ( + isset( $meta_query['key'] ) && 'language' === $meta_query['key'] + && isset( $meta_query['value'] ) && is_array( $meta_query['value'] ) + ) { + // Language is a multiple value filter + $filters_count += count( $meta_query['value'] ); + } + } + } + + return $filters_count > 0 ? sprintf( + /* translators: %s number of filters. */ + _n( + '%s filter applied.', + '%s filters applied.', + $filters_count, + 'wporg-learn' + ), + number_format_i18n( $filters_count ) + ) : ''; +} + /** * Registers the block using the metadata loaded from the `block.json` file. * Behind the scenes, it registers also all assets so they can be enqueued diff --git a/wp-content/themes/pub/wporg-learn-2024/templates/search.html b/wp-content/themes/pub/wporg-learn-2024/templates/search.html deleted file mode 100644 index 9c8c0df1a..000000000 --- a/wp-content/themes/pub/wporg-learn-2024/templates/search.html +++ /dev/null @@ -1,17 +0,0 @@ - - - -
- - -
- - - -
- - -
- - -