これは単純な質問であるべきだと私は思いますが、私はそれを理解することができません。
私がpost_idを持っている場合、どのように私はphpでその記事から特定のタグを削除することができますか?メタ情報を更新する方法は知っていますが、タグ情報は異なります。
以下はうまくいくコードです:
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_relationships
(wp-includes/taxonomy.php
line 1662)はこれを行う低レベルの関数です。しかしながら...
必要に応じて、何かを自動的に分類されていないと見なすことはありません(これは問題にならないかもしれません)。
私はこれをテストしていません
私は、ワードプレスのドキュメントWebサイトで公用には意図されていない低レベルの機能を使用することに少し不快を感じます。
だからより良い方法があるかもしれません。
何らかの理由で、アレクサンダーバードのルーチンは私にとってはあまりうまくいきませんでした。 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 );
}
}