web-dev-qa-db-ja.com

phpの投稿からタグを削除する

これは単純な質問であるべきだと私は思いますが、私はそれを理解することができません。

私がpost_idを持っている場合、どのように私はphpでその記事から特定のタグを削除することができますか?メタ情報を更新する方法は知っていますが、タグ情報は異なります。

4
Alexander Bird

以下はうまくいくコードです:

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 );
}

以下は動作する代替コードです。

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);
    }
}

下記は、機能をテストするためにWordPressテスト環境(http://codex.wordpress.org/Automated_Testing)内で使用したテストデータです。

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);
} 

編集:以下(私の前の答えだった) IS間違って

私の以前の答えが許すことはすべて、すべての投稿タグを削除する方法です。しかし、私は特定の投稿タグのみを削除する方法を探しています。


関数wp_delete_object_term_relationshipswp-includes/taxonomy.php line 1662)はこれを行う低レベルの関数です。しかしながら...

  1. 必要に応じて、何かを自動的に分類されていないと見なすことはありません(これは問題にならないかもしれません)。

  2. 私はこれをテストしていません

  3. 私は、ワードプレスのドキュメントWebサイトで公用には意図されていない低レベルの機能を使用することに少し不快を感じます。

だからより良い方法があるかもしれません。

4
Alexander Bird

何らかの理由で、アレクサンダーバードのルーチンは私にとってはあまりうまくいきませんでした。 wp_set_object_termsの代わりにwp_set_post_tagsを使うように少し修正しました。

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