Make WordPress Core


Ignore:
Timestamp:
03/11/2022 11:05:02 AM (3 years ago)
Author:
spacedmonkey
Message:

Taxonomy: Use get_terms instead of a database lookup in term_exists().

Replace raw SQL queries to the terms table, with a call to the get_terms function. Using get_terms means that term_exists is now cached. For developers using term_exists where cache invalidation is disabled, such as importing, a workaround was added to ensure that queries are uncached.

Props Spacedmonkey, boonebgorges, flixos90, peterwilsoncc.
Fixes #36949.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/taxonomy.php

    r52830 r52921  
    15201520 *
    15211521 * @since 3.0.0
    1522  *
    1523  * @global wpdb $wpdb WordPress database abstraction object.
     1522 * @since 6.0.0 Converted to use `get_terms()`.
     1523 *
     1524 * @global bool $_wp_suspend_cache_invalidation
    15241525 *
    15251526 * @param int|string $term     The term to check. Accepts term ID, slug, or name.
     
    15321533 */
    15331534function term_exists( $term, $taxonomy = '', $parent = null ) {
    1534     global $wpdb;
     1535    global $_wp_suspend_cache_invalidation;
    15351536
    15361537    if ( null === $term ) {
     
    15381539    }
    15391540
    1540     $select     = "SELECT term_id FROM $wpdb->terms as t WHERE ";
    1541     $tax_select = "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE ";
     1541    $defaults = array(
     1542        'get'                    => 'all',
     1543        'fields'                 => 'ids',
     1544        'number'                 => 1,
     1545        'update_term_meta_cache' => false,
     1546        'order'                  => 'ASC',
     1547        'orderby'                => 'term_id',
     1548        'suppress_filter'        => true,
     1549    );
     1550
     1551    // Ensure that while importing, queries are not cached.
     1552    if ( ! empty( $_wp_suspend_cache_invalidation ) ) {
     1553        // @todo Disable caching once #52710 is merged.
     1554        $defaults['cache_domain'] = microtime();
     1555    }
     1556
     1557    if ( ! empty( $taxonomy ) ) {
     1558        $defaults['taxonomy'] = $taxonomy;
     1559        $defaults['fields']   = 'all';
     1560    }
    15421561
    15431562    if ( is_int( $term ) ) {
     
    15451564            return 0;
    15461565        }
    1547         $where = 't.term_id = %d';
    1548         if ( ! empty( $taxonomy ) ) {
    1549             // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
    1550             return $wpdb->get_row( $wpdb->prepare( $tax_select . $where . ' AND tt.taxonomy = %s', $term, $taxonomy ), ARRAY_A );
    1551         } else {
    1552             return $wpdb->get_var( $wpdb->prepare( $select . $where, $term ) );
    1553         }
    1554     }
    1555 
    1556     $term = trim( wp_unslash( $term ) );
    1557     $slug = sanitize_title( $term );
    1558 
    1559     $where             = 't.slug = %s';
    1560     $else_where        = 't.name = %s';
    1561     $where_fields      = array( $slug );
    1562     $else_where_fields = array( $term );
    1563     $orderby           = 'ORDER BY t.term_id ASC';
    1564     $limit             = 'LIMIT 1';
     1566        $args  = wp_parse_args( array( 'include' => array( $term ) ), $defaults );
     1567        $terms = get_terms( $args );
     1568    } else {
     1569        $term = trim( wp_unslash( $term ) );
     1570        if ( '' === $term ) {
     1571            return null;
     1572        }
     1573
     1574        if ( ! empty( $taxonomy ) && is_numeric( $parent ) ) {
     1575            $defaults['parent'] = (int) $parent;
     1576        }
     1577
     1578        $args  = wp_parse_args( array( 'slug' => sanitize_title( $term ) ), $defaults );
     1579        $terms = get_terms( $args );
     1580        if ( empty( $terms ) || is_wp_error( $terms ) ) {
     1581            $args  = wp_parse_args( array( 'name' => $term ), $defaults );
     1582            $terms = get_terms( $args );
     1583        }
     1584    }
     1585
     1586    if ( empty( $terms ) || is_wp_error( $terms ) ) {
     1587        return null;
     1588    }
     1589
     1590    $_term = array_shift( $terms );
     1591
    15651592    if ( ! empty( $taxonomy ) ) {
    1566         if ( is_numeric( $parent ) ) {
    1567             $parent              = (int) $parent;
    1568             $where_fields[]      = $parent;
    1569             $else_where_fields[] = $parent;
    1570             $where              .= ' AND tt.parent = %d';
    1571             $else_where         .= ' AND tt.parent = %d';
    1572         }
    1573 
    1574         $where_fields[]      = $taxonomy;
    1575         $else_where_fields[] = $taxonomy;
    1576 
    1577         $result = $wpdb->get_row( $wpdb->prepare( "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $where AND tt.taxonomy = %s $orderby $limit", $where_fields ), ARRAY_A );
    1578         if ( $result ) {
    1579             return $result;
    1580         }
    1581 
    1582         return $wpdb->get_row( $wpdb->prepare( "SELECT tt.term_id, tt.term_taxonomy_id FROM $wpdb->terms AS t INNER JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id WHERE $else_where AND tt.taxonomy = %s $orderby $limit", $else_where_fields ), ARRAY_A );
    1583     }
    1584 
    1585     // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
    1586     $result = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms as t WHERE $where $orderby $limit", $where_fields ) );
    1587     if ( $result ) {
    1588         return $result;
    1589     }
    1590 
    1591     // phpcs:ignore WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
    1592     return $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM $wpdb->terms as t WHERE $else_where $orderby $limit", $else_where_fields ) );
     1593        return array(
     1594            'term_id'          => (string) $_term->term_id,
     1595            'term_taxonomy_id' => (string) $_term->term_taxonomy_id,
     1596        );
     1597    }
     1598
     1599    return (string) $_term;
    15931600}
    15941601
Note: See TracChangeset for help on using the changeset viewer.