web-dev-qa-db-ja.com

プログラムでメディアライブラリからCPTファイルを隠す方法

お客様が管理者ページからwp-content/uploadsフォルダ以外のフォルダにファイルをアップロードできるようにするCPTを作成しました。ファイルは、wp_handle_uploadおよびwp_insert_attachmentを使用してアップロードおよび操作されます。

これらのファイルがメディアライブラリに表示されないようにするにはどうすればよいですか。投稿タイプでフィルタリングできますか?

ご協力ありがとうございます。

更新: これまでに実装したコードです。新しいアップロードはまだメディアライブラリに表示されません。

/*FORCE LIST VIEW IN MEDIA LIBRARY*/
add_action('admin_init', function() {
    $_GET['mode'] = 'list';
}, 100);

/*HIDE GRID BUTTON IN MEDIA LIBRARY*/
add_action('admin_head', function() {
    $css = '<style type="text/css">
        .view-switch .view-grid {
            display: none;
        }
    <style>';
    echo $css;
});

/*REGISTER CUSTOM TAXONOMY*/
function create_hidden_taxonomy() {
    register_taxonomy(
        'hidden_taxonomy',
        'attachment',
        array(
            'label' => __( 'Hidden Taxonomy' ),
            'public' => false,
            'rewrite' => false,
            'hierarchical' => false,
        )
    );
}
add_action( 'init', 'create_hidden_taxonomy' );

/*CHECK IF PARENT POST TYPE IS ASSET. IF NOT ADD 'show_in_media_library' TERM*/
function assets_add_term( $post_id, \WP_Post $p, $update ) {

    if ( 'attachment' !== $p->post_type ) {
        error_log("fail1");            
        return;
    }
    if ( wp_is_post_revision( $post_id ) ) {
        error_log("fail2");            
        return;
    }
    if ( $post->post_parent ) {
        $excluded_types = array( 'assets' );
        if ( in_array( get_post_type( $p->post_parent ), $excluded_types ) ) {
        error_log("fail3");                
        return;
        }
    }
    $result = wp_set_object_terms( $post_id, 'show_in_media_library', 'hidden_taxonomy', false );
    if ( !is_array( $result ) || is_wp_error( $result ) ) {
        error_log("fail4");
    }else{
        error_log("it worked!");
    }
}
add_action( 'save_post', 'assets_add_term', 10, 2 );

/*HIDE MEDIA WITH CPT ASSETS FROM MEDIA LIBRARY*/
function assets_load_media() {
   add_action('pre_get_posts','assets_hide_media',10,1);
}
add_action( 'load-upload.php' , 'assets_load_media' );

function assets_hide_media($query){
    global $pagenow;

// there is no need to check for update.php as we are already hooking to it, but anyway
    if( 'upload.php' != $pagenow  || !is_admin())
        return;

    if(is_main_query()){
        $excluded_cpt_ids = get_posts('post_type=assets&posts_per_page=-1&fields=ids');
        $query->set('post_parent__not_in', $excluded_cpt_ids);
        //$query->set('hidden_taxonomy', 'show_in_media_library' );
    }

    return $query;
}

/*HIDE MEDIA WITH CPT ASSETS FROM MEDIA LIBRARY MODAL*/
function assets_hide_media_modal( $query = array() ){
    $query['post_parent__not_in'] = $excluded_cpt_ids;
    return $query;
}
add_action('ajax_query_attachments_args','assets_hide_media_modal',10,1);
3
Richard Tinkler

メディア項目は、post_type = attachmentおよびpost_status = inheritの投稿とまったく同じです。

upload.phpページにいるときには、2つのビューがあります。

  • リストビュー
  • グリッドビュー

グリッドビューはJavaScriptで生成され、リストビューは通常のWP_List_Tableを拡張しています。

リストビューでは通常の投稿クエリを使用しているため、pre_get_postsを使用して、必要なメディアアイテムを非表示にするようにクエリを変更できます。

これらのファイルがメディアライブラリに表示されないようにするにはどうすればよいですか。
投稿タイプでフィルタできますか?

メディアアイテムpost_typeはattachmentなので、メディアアイテムをpost_typeだけでフィルタリングすることはできません。あなたが欲しいのは、メディアアイテムをpost_parent'spost idでフィルターすることです。

add_action( 'load-upload.php' , 'wp_231165_load_media' );
function wp_231165_load_media() {
   add_action('pre_get_posts','wp_231165_hide_media',10,1);
}

function wp_231165_hide_media($query){
    global $pagenow;

// there is no need to check for update.php as we are already hooking to it, but anyway
    if( 'upload.php' != $pagenow  || !is_admin())
        return;

    if(is_main_query()){
        $excluded_cpt_ids = array();//find a way to get all cpt post ids
        $query->set('post_parent__not_in', $excluded_cpt_ids);
    }

    return $query;
}

この質問 をチェックして、特定の投稿タイプのIDを取得してください。

@tomjnowellが指摘したように、それはリストビューのために働きますが、それは高価な問い合わせです。

できることの1つは、アップロード中にメタ値を追加し、そのメタ値に対してクエリを実行することです。

4
bravokeyl

添付ファイルを作成するときは、次の操作を行います。

  • 添付ファイルの親IDが除外された投稿タイプの投稿用である場合、何もしません。
  • 除外された投稿タイプのリストにない場合は、非表示のカスタム分類法でタグを割り当てます。

例えば.

function create_hidden_taxonomy() {
    register_taxonomy(
        'hidden_taxonomy',
        'attachment',
        array(
            'label' => __( 'Hidden Attachment Taxonomy' ),
            'public' => false, // it's hidden!
            'rewrite' => false,
            'hierarchical' => false,
        )
    );
}
add_action( 'init', 'create_hidden_taxonomy' );

function tomjn_add_term( $post_id, \WP_Post $p, $update ) {

    if ( 'attachment' !== $p->post_type ) {
        return;
    }
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    if ( $post->post_parent ) {
        $excluded_types = array( 'example_post_type', 'other_post_type' );
        if ( in_array( get_post_type( $p->post_parent ), $excluded_types ) ) {
            return;
        }
    }
    $result = wp_set_object_terms( $post_id, 'show_in_media_library', 'hidden_taxonomy', false );
    if ( !is_array( $result ) || is_wp_error( $result ) ) {
        wp_die( "Error setting up terms") ;
    }
}
add_action( 'save_post', 'tomjn_add_term', 10, 2 );

それでは、bravokeyls answerのコードを取り、post_parent__not_inを使用する代わりに、隠されたカスタム分類法でタグを検索してください。

add_action( 'pre_get_posts' , 'assets_hide_media' );
/**
 * Only show attachments tagged as show_in_media_library
 **/
function assets_hide_media( \WP_Query $query ){
    if ( !is_admin() ) {
        return;
    }
    global $pagenow;
    if ( 'upload.php' != $pagenow && 'media-upload.php' != $pagenow ) {
        return;
    }

    if ( $query->is_main_query() ) {
        $query->set('hidden_taxonomy', 'show_in_media_library' );
    }

    return $query;
}

これはpost_parent__not_inを使用するよりもパフォーマンスを大幅に向上させ、拡張する必要があります。また、他のものをフィルタリングするために使用できる分類法を提供します。

これはあなたに1つの最後の問題を残します。添付ファイルにはこの用語がある場合にのみ表示されますが、既にアップロードしたすべての添付ファイルについてはどうですか。戻って、それらに用語を追加する必要があります。これを行うには、このようなコードを1回実行します。

$q = new WP_Query( array(
    'post_type' => 'attachment',
    'post_status' => 'any',
    'nopaging' => true,
) );

if ( $q->have_posts() ) {
    global $post;
    while ( $q->have_posts() ) {
        $q->the_post();

        $excluded_types = array( 'example_post_type', 'other_post_type' );
        if ( $post->post_parent ) {
            if ( in_array( get_post_type( $post->post_parent ), $excluded_types ) ) {
                echo "Skipping ".intval( $post_id )." ".esc_html( get_the_title() )."\n";
                continue;
            }
        }
        echo "Setting term for ".intval( $post_id )." ".esc_html( get_the_title() )."\n";
        $result = wp_set_object_terms( $post_id, 'show_in_media_library', 'hidden_taxonomy', false );
        if ( !is_array( $result ) || is_wp_error( $result ) ) {
            echo "Error setting up terms";
        }
    }
    wp_reset_postdata();
} else {
    echo "No attachments found!\n";
}

特に処理が必要な添付ファイルが多数ある場合は、WP CLIコマンドとして実行することをお勧めします。

4
Tom J Nowell
add_action( 'ajax_query_attachments_args' , 'custom_ajax_query_attachments_args' );

function custom_ajax_query_attachments_args( $query ) {

    if( $query['post_type'] != 'attachment' ) {

        return $query;

    }


    $posts = get_posts([
      'post_type' => 'YOUR_CUSTOM_POST_TYPE',
      'post_status' => 'publish',
      'numberposts' => -1
    ]);

    foreach($posts as $post){

        $excluded_cpt_ids[] = $post->ID;
    }  

    $query['post_parent__not_in'] = $excluded_cpt_ids;

    return $query;

}
0
EndyVelvet