web-dev-qa-db-fra.com

enlever les tags des posts en php

Je pense que cela devrait être une question simple, mais je ne peux pas le comprendre.

Si j'ai un post_id, comment puis-je supprimer une étiquette particulière de cette publication en php? Je sais comment mettre à jour les méta-informations, mais les informations sur les balises sont différentes.

4
Alexander Bird

Voici le code qui fonctionne:

function untag_posts($post_ids, $tags) {
    global $wpdb;
    if(! is_array($post_ids) ) { 
        $post_ids = array($post_ids);
    }   
    $in_post_ids = implode("','", $post_ids);

    if(! is_array($tags) ) { 
        $tags = array($tags);
    }   
    $in_tag_names = "'" . implode("','", $tags) . "'";

    $query = "SELECT tt.term_taxonomy_id " . 
        " from $wpdb->terms as t " . 
            " JOIN $wpdb->term_taxonomy as tt ON tt.term_id = t.term_id " . 
            " JOIN $wpdb->term_relationships as tr on tr.term_taxonomy_id = tt.term_taxonomy_id " . 
        " where t.name in ($in_tag_names) " . 
            " AND (tr.object_id in ($in_post_ids)) ";
    $tt_ids = $wpdb->get_col($query); // TODO: correct function?
    $in_tt_ids = implode("','", $tt_ids);

    $delete_query = "DELETE FROM $wpdb->term_relationships where object_id in ($in_post_ids) and term_taxonomy_id in ($in_tt_ids)";
    $myrows = $wpdb->get_results( $delete_query );
}

Vous trouverez ci-dessous un code alternatif qui fonctionne:

function untag_post($post_ids, $tags) {
    global $wpdb;
    if(! is_array($post_ids) ) {
        $post_ids = array($post_ids);
    }
    if(! is_array($tags) ) {
        $tags = array($tags);
    }

    foreach($post_ids as $post_id) {
        $terms = wp_get_object_terms($post_id, 'post_tag');
        $newterms = array();
        foreach($terms as $term) {
            if ( !in_array($term->name,$tags) ) { //$term will be a wordpress Term object.
                $newterms[] = $term;
            }
        }
        wp_set_object_terms($post_id, $newterms, 'post_tag', FALSE);
    }
}

Vous trouverez ci-dessous les données de test que j'ai utilisées dans l'environnement de test wordpress (http://codex.wordpress.org/Automated_Testing) pour tester les fonctions:

function test_untag_post() {
    function untag_post($post_ids, $tags) {
        global $wpdb;
        if(! is_array($post_ids) ) { 
            $post_ids = array($post_ids);
        }   
        if(! is_array($tags) ) { 
            $tags = array($tags);
        }   

        foreach($post_ids as $post_id) {
            $terms = wp_get_object_terms($post_id, 'post_tag');
            $newterms = array();
            foreach($terms as $term) {
                if ( !in_array($term->name,$tags) ) { //$term will be a wordpress Term object.
                    $newterms[] = $term;
                }   
            }   
            wp_set_object_terms($post_id, $newterms, 'post_tag', FALSE);
        }   
    }   
    $post = array();
    $post['post_content'] = "Here is some content.";
    $post['post_excert'] = "Quick excerpt.";
    $post['post_title'] = "Test Post";
    $post['post_name'] = "test-post";
    $post['post_type'] = "post";
    $post_id = wp_insert_post($post);

    wp_add_post_tags($post_id, 'test-tag');
    $terms = wp_get_object_terms($post_id, 'post_tag');
    $this->assertEquals('test-tag', $terms[0]->name);

    untag_post($post_id, 'test-tag');

    $terms = wp_get_object_terms($post_id, 'post_tag');
    $this->assertEmpty($terms);
} 

EDIT: Le ci-dessous (qui était ma réponse précédente) IS WRONG

Tout ce que ma réponse précédente permettait, c’est un moyen de supprimer toutes les balises de publication. Mais je cherche un moyen de supprimer uniquement les balises post spécifiques.


La fonction wp_delete_object_term_relationships (wp-includes/taxonomy.php ligne 1662) est une fonction de bas niveau qui le fera. Toutefois...

  1. il ne met pas automatiquement quelque chose comme non classé si nécessaire (ce qui peut ne pas être un problème)

  2. Je n'ai pas testé cela

  3. Je me sens un peu mal à l'aise d'utiliser des fonctions de bas niveau qui ne sont pas mentionnées sur le site web wordpress doc comme étant destinées à un usage public.

Alors peut-être il y a une meilleure façon.

4
Alexander Bird

Pour une raison quelconque, la routine d'Alexander Bird ne me convenait pas vraiment. Je l'ai un peu modifié pour utiliser wp_set_post_tags au lieu de wp_set_object_terms:

function untag_post($post_ids, $tags) {
    global $wpdb;
    if(! is_array($post_ids) ) {
        $post_ids = array($post_ids);
    }
    if(! is_array($tags) ) {
        $tags = array($tags);
    }

    foreach($post_ids as $post_id) {
        $curtags = wp_get_post_tags($post_id, 'post_tag');
        $newtags = array();
        foreach($tags as $tag) {
            foreach($curtags as $id=>$curtag) {
                if ( $curtag->name == $tag ) {
                    unset($curtags[$id]);
                }
            }
        }

        foreach ($curtags as $curtag) {
            $newtags[] = $curtag->name;
        }

        wp_set_post_tags( $post_id, $newtags, false );
    }
}
1
Chris Rae