Nous avons créé un CPT qui permet à notre client de télécharger des fichiers de la page d’administration dans un dossier situé en dehors du dossier wp-content/uploads. Les fichiers sont téléchargés et manipulés à l'aide de wp_handle_upload et wp_insert_attachment.
Comment empêcher ces fichiers de s'afficher dans la médiathèque? Peut-on filtrer par type de message?
Merci d'avance pour votre aide!
UPDATE: voici le code que nous avons mis en place jusqu'à présent. Les nouveaux téléchargements ne sont toujours pas affichés dans la médiathèque.
/*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);
Les éléments multimédias ressemblent aux publications avecpost_type = attachment
etpost_status = inherit
.
lorsque nous sommes sur la page upload.php
, nous avons deux vues:
La vue en grille est renseignée via JavaScript et la vue en liste est normaleWP_List_Table
.
Étant donné que la vue liste utilise des requêtes post normales, nous pouvons utiliserpre_get_posts
pour modifier la requête afin de masquer les éléments multimédias requis.
Comment empêcher ces fichiers de s'afficher dans la médiathèque?
Peut-on filtrer par type de message?
Nous ne pouvons pas simplement filtrer les éléments multimédias par post_type
puisque les éléments multimédias post_type sont attachment
. Ce que vous voulez, c'est filtrer les éléments multimédias par leurs identificateurspost_parent's
post.
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;
}
Vérifiez cette question pour obtenir les identifiants d'un type de message donné.
Comme @tomjnowell l'a fait remarquer, cela fonctionne pour l'affichage en liste mais c'est une requête coûteuse.
Une chose que vous pouvez faire est d’ajouter une méta-valeur lors du téléchargement et d’interroger cette méta-valeur.
Lorsque vous créez une pièce jointe, procédez comme suit:
par exemple.
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 );
Maintenant, prenez le code dans la réponse de bravokeyls et au lieu d'utiliser post_parent__not_in
, recherchez le tag dans la taxonomie personnalisée masquée:
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;
}
Cela devrait avoir une amélioration significative des performances et une évolutivité supérieure à celle utilisée avec post_parent__not_in
, et fournit une taxonomie que vous pouvez utiliser pour filtrer d'autres éléments.
Cela vous laisse avec un dernier problème. Les pièces jointes ne montreront que si elles ont ce terme, mais qu'en est-il de toutes les pièces jointes que vous avez déjà téléchargées? Nous devons revenir en arrière et ajouter le terme à ceux-là. Pour ce faire, vous exécuterez un morceau de code tel que celui-ci une fois:
$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";
}
Je vous recommande d'exécuter cette commande en tant que commande CLI WP, en particulier si vous avez beaucoup de pièces jointes à traiter.
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;
}