web-dev-qa-db-fra.com

Erreur de base de données WordPress: [Table/alias non unique: 'wp_postmeta']

Quelqu'un m'a très gentiment aidé sur une autre question, qui a maintenant conduit à ce problème de deux fonctions provoquant une erreur de base de données. D'après ce que j'ai lu, cela pourrait avoir quelque chose à voir avec LEFT JOIN et/ou pas de wp_reset_query() ou wp_reset_postdata(). L'erreur que je reçois est:

WordPress database error: [Not unique table/alias: 'wp_postmeta']
SELECT SQL_CALC_FOUND_ROWS DISTINCT wp_posts.ID FROM wp_posts LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id ) LEFT JOIN wp_postmeta ON wp_posts.ID = wp_postmeta.post_id WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (567) ) AND ( wp_postmeta.meta_key = 'featured_listing' ) AND wp_posts.post_type = 'business' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled' OR wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_postmeta.meta_value DESC LIMIT 0, 10

Je l'ai réduit à deux fonctions, l'une étant:

// Order posts for featured posts first in search and categories

function custom_special_sort( $query ) {

    // if is this the main query and is this post type of business
    if ( ($query->is_main_query() && is_post_type_archive('business') ) || (is_main_query() && is_tax ('location') ) ) {

        // order results by the meta_key 'featured_listing'
       $query->set( 'meta_key', 'featured_listing' );
        $query->set( 'orderby', 'featured_listing' );
        $query->set( 'order', 'DESC' );

    }
}
add_action( 'pre_get_posts', 'custom_special_sort' );

et l'autre étant:

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

+

function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

+

function cf_search_distinct( $where ) {
    global $wpdb;

    if ( is_search() ) {
        return "DISTINCT";
    }

    return $where;
}
add_filter( 'posts_distinct', 'cf_search_distinct' );

La première fonction modifie l'ordre des publications dans un résultat de recherche, pour les classer avec un certain post_meta au-dessus des autres.

La deuxième fonction consiste à ajouter des champs personnalisés à la requête de recherche au lieu de wordpress, en recherchant simplement le contenu et les titres des publications.

Toute aide pour résoudre le conflit serait grandement appréciée. Si je supprime l’une des fonctions, l’autre fonctionne comme il se doit mais elles ne fonctionneront pas ensemble. De ce que j’ai lu, je suppose que c’est parce qu’elles essaient d’éditer la même requête?

3
Randomer11

Vous deux éléments JOIN tous les deux avec la même table. Lorsque vous devez joindre une table plus d'une fois, vous devez rendre chaque jointure unique en donnant l'alias de table. Lorsque WP crée la requête dans son ensemble, il en tient compte, mais vous devez ajouter votre propre code qui ne le fait pas.

Donc, première fonction:

function cf_search_join( $join ) {
    global $wpdb;

    if ( is_search() ) {    
        $join .=' LEFT JOIN '.$wpdb->postmeta. ' cfmeta ON '. $wpdb->posts . '.ID = cfmeta.post_id ';
    }

    return $join;
}
add_filter('posts_join', 'cf_search_join' );

Ceci définit l'alias de table postmeta 'cfmeta' et l'utilise dans ON.

Et le second:

function cf_search_where( $where ) {
    global $pagenow, $wpdb;

    if ( is_search() ) {
        $where = preg_replace(
            "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/",
            "(".$wpdb->posts.".post_title LIKE $1) OR (cfmeta.meta_value LIKE $1)", $where );
    }

    return $where;
}
add_filter( 'posts_where', 'cf_search_where' );

Utiliser 'cfmeta' au lieu de wp_postmeta.

Milan

3
Milan Petrovic