Making WordPress.org


Ignore:
Timestamp:
07/12/2024 03:41:39 AM (17 months ago)
Author:
adamwood
Message:

Learn: Sync with git WordPress/learn@33af4b9

File:
1 edited

Legend:

Unmodified
Added
Removed
  • sites/trunk/wordpress.org/public_html/wp-content/plugins/wporg-learn/inc/locale.php

    r12299 r13901  
    1515add_filter( 'wporg_locale_switcher_options', __NAMESPACE__ . '\locale_switcher_options' );
    1616add_filter( 'wp_headers', __NAMESPACE__ . '\disable_caching' );
     17add_filter( 'posts_clauses', __NAMESPACE__ . '\wporg_archive_query_prioritize_locale', 10, 2 );
    1718
    1819if ( ! wp_next_scheduled( 'wporg_learn_update_locale_data' ) ) {
     
    157158    return $headers;
    158159}
     160
     161/**
     162 * Modify post type archive queries to prioritize content in the user's locale.
     163 *
     164 * @param array    $clauses
     165 * @param WP_Query $query
     166 *
     167 * @return array
     168 */
     169function wporg_archive_query_prioritize_locale( $clauses, $query ) {
     170    if ( is_admin() || is_feed() ) {
     171        return $clauses;
     172    }
     173
     174    $locale = get_locale();
     175
     176    if ( ! $locale ) {
     177        return $clauses;
     178    }
     179
     180    if ( $query->is_post_type_archive( 'wporg_workshop' ) ) {
     181        return wporg_tutorials_query_prioritize_locale( $clauses, $locale );
     182    }
     183
     184    $current_theme = wp_get_theme();
     185    $theme_slug = $current_theme->get_stylesheet();
     186
     187    if ( 'pub/wporg-learn-2020' === $theme_slug ) {
     188        return $clauses;
     189    }
     190
     191    if ( $query->is_post_type_archive( 'course' ) || $query->is_post_type_archive( 'lesson' ) || $query->is_post_type_archive( 'lesson-plan' ) ) {
     192        return wporg_query_prioritize_locale( $clauses, $locale );
     193    }
     194
     195    return $clauses;
     196}
     197
     198/**
     199 * Modify the workshop post type archive query to prioritize workshops in the user's locale.
     200 * DEPRECATED: this function has been superseded by wporg_query_prioritize_locale, which handles language post meta being empty or null.
     201 *
     202 * In order to show all workshops, but with the ones that are presented/captioned in the user's locale shown first, we
     203 * need to modify the posts query in ways that can't be done through the WP_Query or WP_Meta_Query APIs. Instead, here,
     204 * we're filtering the individual clauses of the query to add the pieces we need.
     205 *
     206 * Examples, slightly truncated for simplicity:
     207 *
     208 * Before:
     209 * SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
     210 * FROM wp_posts
     211 * WHERE 1=1
     212 * AND wp_posts.post_type = 'wporg_workshop'
     213 * ORDER BY wp_posts.post_date DESC
     214 *
     215 * After:
     216 * SELECT SQL_CALC_FOUND_ROWS wp_posts.*,
     217 *   MAX( IF( pmeta.meta_key = 'language' AND pmeta.meta_value LIKE 'art_%', 1, 0 ) ) AS has_language,
     218 *   MAX( IF( pmeta.meta_key = 'video_caption_language' AND pmeta.meta_value LIKE 'art_%', 1, 0 ) ) AS has_caption
     219 * FROM wp_posts
     220 * INNER JOIN wp_postmeta pmeta ON ( wp_posts.ID = pmeta.post_id )
     221 * WHERE 1=1
     222 * AND wp_posts.post_type = 'wporg_workshop'
     223 * GROUP BY wp_posts.ID
     224 * ORDER BY has_language DESC, has_caption DESC, wp_posts.post_date DESC
     225 *
     226 * @param array  $clauses
     227 * @param string $locale
     228 *
     229 * @return array
     230 */
     231function wporg_tutorials_query_prioritize_locale( $clauses, $locale ) {
     232    global $wpdb;
     233
     234    $locale_root = preg_replace( '#^([a-z]{2,3}_?)[a-zA-Z_-]*#', '$1', $locale, -1, $count );
     235
     236    if ( $count ) {
     237        /**
     238         * $clauses['fields'] contains the SELECT part of the query.
     239         *
     240         * The extra fields clauses are calculated fields that will contain a `1` if the workshop post row has a postmeta
     241         * value that matches the locale root. The MAX() and the groupby clause below ensure that all the rows for a
     242         * given workshop are consolidated into one with the highest value in the calculated column. Without the
     243         * grouping, there would be a separate row for each postmeta value for each workshop post.
     244         */
     245        $clauses['fields'] .= ",
     246            MAX( IF( pmeta.meta_key = 'language' AND pmeta.meta_value LIKE '{$locale_root}%', 1, 0 ) ) AS has_language
     247        ";
     248        $clauses['fields'] .= ",
     249            MAX( IF( pmeta.meta_key = 'video_caption_language' AND pmeta.meta_value LIKE '{$locale_root}%', 1, 0 ) ) AS has_caption
     250        ";
     251        $clauses['join']   .= " INNER JOIN {$wpdb->postmeta} pmeta ON ( {$wpdb->posts}.ID = pmeta.post_id )";
     252        // This orderby clause ensures that the workshops are sorted by the values in the calculated columns first.
     253        $clauses['orderby'] = 'has_language DESC, has_caption DESC, ' . $clauses['orderby'];
     254
     255        if ( false === strpos( $clauses['groupby'], "{$wpdb->posts}.ID" ) ) {
     256            $clauses['groupby'] = "{$wpdb->posts}.ID";
     257        }
     258    }
     259
     260    return $clauses;
     261}
     262
     263/**
     264 * Modify the post type archive query to prioritize posts in the user's locale.
     265 *
     266 * In order to show all posts, but with the ones that are presented in the user's locale shown first, we
     267 * need to modify the posts query in ways that can't be done through the WP_Query or WP_Meta_Query APIs. Instead, here,
     268 * we're filtering the individual clauses of the query to add the pieces we need.
     269 *
     270 * Handles cases where the language post meta is empty or null and treats them as being english, if the locale is english.
     271 * This matches the default value for the language post meta field.
     272 *
     273 * Examples, slightly truncated for simplicity:
     274 *
     275 * Before:
     276 * SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
     277 * FROM wp_posts
     278 * WHERE 1=1
     279 * AND wp_posts.post_type = 'lesson'
     280 * ORDER BY wp_posts.post_date DESC
     281 *
     282 * After:
     283 * SELECT SQL_CALC_FOUND_ROWS wp_posts.*,
     284 *   MAX(
     285 *     CASE
     286 *       WHEN pmeta.meta_key = 'language' AND pmeta.meta_value LIKE 'en_%' THEN 1
     287 *       WHEN (pmeta.meta_key = 'language' AND pmeta.meta_value = '') OR pmeta.meta_key IS NULL THEN 1
     288 *       ELSE 0
     289 *     END
     290 *   ) AS has_language,
     291 * FROM wp_posts
     292 * LEFT JOIN wp_postmeta pmeta ON ( wp_posts.ID = pmeta.post_id AND pmeta.meta_key = 'language' )
     293 * WHERE 1=1
     294 * AND wp_posts.post_type = 'lesson'
     295 * ORDER BY has_language DESC, wp_posts.post_date DESC
     296 * GROUP BY wp_posts.ID
     297 *
     298 * @param array  $clauses
     299 * @param string $locale
     300 *
     301 * @return array
     302 */
     303function wporg_query_prioritize_locale( $clauses, $locale ) {
     304    global $wpdb;
     305
     306    $locale_root = preg_replace( '#^([a-z]{2,3}_?)[a-zA-Z_-]*#', '$1', $locale, -1, $count );
     307
     308    if ( $count ) {
     309        /**
     310         * $clauses['fields'] contains the SELECT part of the query.
     311         *
     312         * The extra fields clause is calculated, and will contain a `1` if the post row has a postmeta
     313         * value that matches the locale root, or if the locale is english and the postmeta value is empty or null.
     314         * The MAX() and the groupby clause below ensure that all the rows for a given post are consolidated into
     315         * one, with the highest value in the calculated column.
     316         * Without the grouping, there would be a separate row for each postmeta value for each post.
     317         */
     318        $is_english = strpos( $locale_root, 'en_' ) === 0;
     319
     320        $clauses['fields'] .= ",
     321            MAX(
     322                CASE
     323                    WHEN pmeta.meta_key = 'language' AND pmeta.meta_value LIKE '{$locale_root}%' THEN 1
     324                    WHEN (pmeta.meta_key = 'language' AND pmeta.meta_value = '') OR pmeta.meta_key IS NULL THEN " . ( $is_english ? '1' : '0' ) . '
     325                    ELSE 0
     326                END
     327            ) AS has_language
     328        ';
     329        $clauses['join']   .= " LEFT JOIN {$wpdb->postmeta} pmeta ON ( {$wpdb->posts}.ID = pmeta.post_id AND pmeta.meta_key = 'language' )";
     330        $clauses['orderby'] = 'has_language DESC, ' . $clauses['orderby'];
     331        $clauses['groupby'] = "{$wpdb->posts}.ID";
     332    }
     333
     334    return $clauses;
     335}
Note: See TracChangeset for help on using the changeset viewer.