Cómo ocultar los archivos CPT de la biblioteca de medios mediante programación

2

Hemos creado un CPT que permite a nuestros clientes cargar archivos desde la página de administración a una carpeta fuera de la carpeta wp-content / uploads. Los archivos se cargan y manipulan utilizando wp_handle_upload y wp_insert_attachment.

¿Cómo evitamos que estos archivos se muestren en la biblioteca de medios? ¿Podemos filtrar por tipo de publicación?

¡Gracias de antemano por cualquier ayuda!

ACTUALIZACIÓN: aquí está el código que hemos implementado hasta ahora. Las nuevas cargas aún no se muestran en la biblioteca de medios.

/*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);
    
pregunta Richard Tinkler 01.07.2016 - 10:30

3 respuestas

3

Los elementos de medios son como publicaciones con post_type = attachment y post_status = inherit .

cuando estamos en la página upload.php , tenemos dos vistas:

  • Vista de lista
  • Vista de cuadrícula

La vista de cuadrícula se rellena a través de JavaScript y la vista de lista se está extendiendo normalmente WP_List_Table .

Dado que (vista de lista) utiliza una consulta de publicación normal, podemos usar pre_get_posts para modificar la consulta y ocultar los elementos multimedia necesarios.

  

¿Cómo evitamos que estos archivos se muestren en la biblioteca de medios?
Puede   filtramos por tipo de publicación?

No podemos simplemente filtrar los elementos multimedia por post_type , ya que los elementos multimedia post_type son attachment . Lo que quieres es filtrar los elementos de medios por sus post_parent's ID de publicación.

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

Marque esta pregunta para obtener ID de un determinado tipo de publicación.

Como señaló @tomjnowell, funciona para la vista de lista pero es una consulta costosa.

Una cosa que puedes hacer es agregar algo de valor meta al cargar y consultar ese valor meta

    
respondido por el bravokeyl 01.07.2016 - 16:07
4

Cuando cree un archivo adjunto, haga lo siguiente:

  • Si la ID de los padres adjuntos es para una publicación con un tipo de publicación excluida, no haga nada
  • Si no está en la lista de tipos de publicaciones excluidas, asígnele una etiqueta en una taxonomía personalizada oculta

por ejemplo

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

Ahora, tome el código en la respuesta de bravokeyls y en lugar de usar post_parent__not_in , busque la etiqueta en la taxonomía personalizada oculta:

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

Esto debería tener un aumento de rendimiento significativo y una mejor escala que el uso de post_parent__not_in , y proporciona una taxonomía que puedes usar para filtrar otras cosas

Esto te deja con un problema final. Los archivos adjuntos solo se mostrarán si tienen este término, pero ¿qué pasa con todos los archivos adjuntos que ya ha subido? Necesitamos regresar y agregar el término a esos. Para hacer esto, ejecutaría un fragmento de código como este una vez:

$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";
}

Recomendaría ejecutar esto como un comando de WP CLI, especialmente si tiene muchos archivos adjuntos que necesitan procesamiento

    
respondido por el Tom J Nowell 01.07.2016 - 17:03
0
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;

}
    
respondido por el EndyVelvet 21.12.2017 - 11:10

Lea otras preguntas en las etiquetas