如何以编程方式从媒体库中隐藏CPT文件

时间:2016-07-01 作者:Richard Tinkler

我们创建了一个CPT,允许我们的客户将文件从管理页面上载到wp content/uploads文件夹之外的文件夹。使用wp\\u handle\\u upload和wp\\u insert\\u attachment上载和操作文件。

如何防止这些文件显示在媒体库中?我们可以按帖子类型过滤吗?

提前感谢您的帮助!

UPDATE: 这是我们迄今为止已经实现的代码。媒体库中仍没有显示新上载的内容。

/*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 个回复
最合适的回答,由SO网友:bravokeyl 整理而成

媒体项目就像帖子一样post_type = attachmentpost_status = inherit.

当我们开始时upload.php 第页,我们有两个视图:

列表视图通过JavaScript填充网格视图,列表视图扩展正常WP_List_Table.

由于它(列表视图)使用的是普通的post查询,因此我们可以使用pre_get_posts 更改查询以隐藏所需的媒体项。

如何防止这些文件显示在媒体库中
我们可以按帖子类型过滤吗?

我们不能只按以下方式筛选媒体项post_type 由于媒体项目post\\U类型为attachment. 您需要的是按其post_parent\'s post 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;
}
检查this question 获取特定帖子类型的id。

正如@tomjnowell指出的,它适用于列表视图,但这是一个昂贵的查询。

您可以做的一件事是在上载和查询元数据时添加一些元数据

SO网友:Tom J Nowell

创建附件时,请执行以下操作:

如果附件父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 ( $p->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, 3 );
现在,使用bravokeyls答案中的代码,而不是使用post_parent__not_in, 在隐藏的自定义分类中搜索标记:

/**
 * 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;
}
add_action( \'pre_get_posts\' , \'assets_hide_media\' );
这应该比使用post_parent__not_in, 并提供了一种分类法,可用于筛选其他内容

这给你留下了最后一个问题。附件只有在有此术语时才会显示,但是您已经上传的所有附件呢?我们需要回到过去,把这个词加上去。要做到这一点,您需要运行这样一段代码:

$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();

        $post_id = get_the_ID();

        $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命令运行,尤其是当您有许多附件需要处理时

SO网友:EndyVelvet
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;

}