2

I have some section where user can upload CV and profile images,

I'm using the native attachment functions,

$attachment_cv_id = media_handle_upload( 'candidate_cv', 0 );
if ( ! is_wp_error( $attachment_cv_id ) ) {
    // We link this file to the post 
    // add_post_meta( $result , 'wpcf-cv-file', wp_get_attachment_url($attachment_cv_id));
} else {
    $submit_candidate_errors[] = lang("Hubo error subiendo la CV");
}

Is there any way I can hide this files from the media section in the wp-admin? ( perhaps changing its folder )

Thanks

-EDIT-

i'm trying like Dave suggested, adding a meta: 'rrhh-file'

$attachment_id = media_handle_upload( 'apply_file', 0 );

if ( ! is_wp_error( $attachment_id ) ) {
    // The image was uploaded successfully!
    add_post_meta($attachment_id, 'rrhh-file', true);
}

And even that it has the attribute:

var_dump(get_post_meta(1200)); // last id I uploaded
die();

Prints out:

array(4) {
  ["_wp_attached_file"]=>
  array(1) {
    [0]=>
    string(20) "2017/06/image001.jpg"
  }
  ["_wp_attachment_metadata"]=>
  array(1) {
    [0]=>
    string(666) "a:5:{s:5:"width";i:523;s:6:"height";i:122;s:4:"file";s:20:"2017/06/image001.jpg";s:5:"sizes";a:2:{s:9:"thumbnail";a:4:{s:4:"file";s:20:"image001-150x122.jpg";s:5:"width";i:150;s:6:"height";i:122;s:9:"mime-type";s:10:"image/jpeg";}s:6:"medium";a:4:{s:4:"file";s:19:"image001-300x70.jpg";s:5:"width";i:300;s:6:"height";i:70;s:9:"mime-type";s:10:"image/jpeg";}}s:10:"image_meta";a:12:{s:8:"aperture";s:1:"0";s:6:"credit";s:0:"";s:6:"camera";s:0:"";s:7:"caption";s:0:"";s:17:"created_timestamp";s:1:"0";s:9:"copyright";s:0:"";s:12:"focal_length";s:1:"0";s:3:"iso";s:1:"0";s:13:"shutter_speed";s:1:"0";s:5:"title";s:0:"";s:11:"orientation";s:1:"1";s:8:"keywords";a:0:{}}}"
  }
  ["rrhh-file"]=> // <-- here
  array(1) {
    [0]=>
    string(1) "1"
  }
  ["_edit_lock"]=>
  array(1) {
    [0]=>
    string(12) "1498731595:1"
  }
}

With this action this attachment still shows up in the media library

add_action( 'pre_get_posts', 'wpse_hide_cv_media_list_view' );
function wpse_hide_cv_media_list_view( $query ) {
    // Bail if this is not the admin area.
    if ( ! is_admin() ) {
        return;
    }

    // Bail if this is not the main query.
    if ( ! $query->is_main_query() ) {
        return;
    }

    // Only proceed if this the attachment upload screen.
    $screen = get_current_screen();
    if ( ! $screen || 'upload' !== $screen->id || 'attachment' !== $screen->post_type ) {
        return;
    }

    // Modify the query.
    $query->set( 'meta_query', [
        [
            'key'     => 'rrhh-file',
            'compare' => 'NOT EXISTS',
        ]
    ]);

    return;
}

Any idea what i'm missing?

4

WordPress has two different ways of displaying media. There's the media overlay/modal view and also the list view, which is triggered by navigating to Admin > Media > Library then by clicking the list view icon next to the filter select box. To filter attachments in both locations, we will need to use two separate hooks.

Filtering attachments in the Media Library (modal view)

The ajax_query_attachments_args filter can be used to adjust the query used for getting attachments on the media overlay screens. (Adapted from this answer from birgire.)

/**
 * Hide attachment files from the Media Library's overlay (modal) view
 * if they have a certain meta key set.
 * 
 * @param array $args An array of query variables.
 */
add_filter( 'ajax_query_attachments_args', 'wpse_hide_cv_media_overlay_view' );
function wpse_hide_cv_media_overlay_view( $args ) {
    // Bail if this is not the admin area.
    if ( ! is_admin() ) {
        return;
    }

    // Modify the query.
    $args['meta_query'] = [
        [
            'key'     => 'rrhh-file',
            'compare' => 'NOT EXISTS',
        ]
    ];

    return $args;
}

Filtering attachments in the Media Library (list view)

We need an additional, separate approach for modifying the attachment query on the Media Library screen in list view (older list mode, non-modal view). The pre_get_posts hook will do the trick:

/**
 * Hide attachment files from the Media Library's list view
 * if they have a certain meta key set.
 * 
 * @param WP_Query $query The WP_Query instance (passed by reference).
 */
add_action( 'pre_get_posts', 'wpse_hide_cv_media_list_view' );
function wpse_hide_cv_media_list_view( $query ) {
    // Bail if this is not the admin area.
    if ( ! is_admin() ) {
        return;
    }

    // Bail if this is not the main query.
    if ( ! $query->is_main_query() ) {
        return;
    }

    // Only proceed if this the attachment upload screen.
    $screen = get_current_screen();
    if ( ! $screen || 'upload' !== $screen->id || 'attachment' !== $screen->post_type ) {
        return;
    }

    // Modify the query.
    $query->set( 'meta_query', [
        [
            'key'     => 'rrhh-file',
            'compare' => 'NOT EXISTS',
        ]
    ]   );

    return;
}

In both cases, we're setting up a meta query to exclude any attachments that have the meta key rrhh-file set. You can change the meta query or conditions to suit your needs.

Note that meta queries are slow. One alternative approach would be to assign these special media items to a custom taxonomy when they are uploaded/created, then alter the query to exclude these items using a tax query.

Edit: Debugging info

I'm using the following functions to allow me to more easily edit our custom attachment field:

/**
 * Add custom field to media
 */
add_filter( 'attachment_fields_to_edit', 'wpse_cv_attachment_fields', 10, 2 );
function wpse_cv_attachment_fields( $fields, $post ) {
    $meta = get_post_meta( $post->ID, 'rrhh-file', true );

    $fields['rrhh-file'] = array(
            'label' =>  __( 'RRHH File', 'text-domain' ),
            'input' => 'text',
            'value' => $meta,
            'show_in_edit' => true,
    );

    return $fields;
}

/**
 * Update custom field within media overlay (via ajax)
 */
add_action( 'wp_ajax_save-attachment-compat', 'wpse_cv_media_fields', 0, 1 );
function wpse_cv_media_fields() {
    $post_id = $_POST['id'];
    $value = isset( $_POST['attachments'][ $post_id ]['rrhh-file'] ) ? $_POST['attachments'][ $post_id ]['rrhh-file'] : false;

    if ( '1' === $value ) {
        update_post_meta( $post_id, 'rrhh-file', $value );
    } else {
        delete_post_meta( $post_id, 'rrhh-file' );
    }

    clean_post_cache( $post_id );
}

/**
 * Update media custom field from edit media page (non ajax).
 */
add_action( 'edit_attachment', 'wpse_cv_update_attachment_meta', 1 );
function wpse_cv_update_attachment_meta( $post_id ) {
    $value = isset( $_POST['attachments'][ $post_id ]['rrhh-file'] ) ? $_POST['attachments'][ $post_id ]['rrhh-file'] : false;
    //exit ( var_dump( $value ) );
    if ( '1' === $value ) {
        update_post_meta( $post_id, 'rrhh-file', $value );
    } else {
        delete_post_meta( $post_id, 'rrhh-file' );
    }

    return;
}

I use the following SQL to check if the rrhh-file field is set:

SELECT * FROM wp_postmeta w where meta_key = 'rrhh-file';

When viewing the media library in list mode, which should be affected by our pre_get_posts hook, $query->is_main_query() is returning true and $screen, the WP_Screen object, looks like this:

WP_Screen Object
(
    [action] => 
    [base] => upload
    [columns:WP_Screen:private] => 0
    [id] => upload
    [in_admin:protected] => site
    [is_network] => 
    [is_user] => 
    [parent_base] => 
    [parent_file] => 
    [post_type] => attachment
    [taxonomy] => 
    [_help_tabs:WP_Screen:private] => Array
        (
        )

    [_help_sidebar:WP_Screen:private] => 
    [_screen_reader_content:WP_Screen:private] => Array
        (
        )

    [_options:WP_Screen:private] => Array
        (
        )

    [_show_screen_options:WP_Screen:private] => 
    [_screen_settings:WP_Screen:private] => 
)

and the $query, the WP_Query object looks like this:

WP_Query Object
(
    [query] => Array
        (
            [m] => 0
            [cat] => 0
            [post_type] => attachment
            [posts_per_page] => 20
            [post_status] => inherit,private
        )

    [query_vars] => Array
        (
            [m] => 0
            [cat] => 0
            [post_type] => attachment
            [posts_per_page] => 20
            [post_status] => inherit,private
            [error] => 
            [p] => 0
            [post_parent] => 
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [name] => 
            [static] => 
            [pagename] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [tag_id] => 
            [author] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [meta_key] => 
            [meta_value] => 
            [preview] => 
            [s] => 
            [sentence] => 
            [title] => 
            [fields] => 
            [menu_order] => 
            [embed] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__in] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [post_name__in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

            [post_parent__in] => Array
                (
                )

            [post_parent__not_in] => Array
                (
                )

            [author__in] => Array
                (
                )

            [author__not_in] => Array
                (
                )

        )

    [tax_query] => WP_Tax_Query Object
        (
            [queries] => Array
                (
                )

            [relation] => AND
            [table_aliases:protected] => Array
                (
                )

            [queried_terms] => Array
                (
                )

            [primary_table] => 
            [primary_id_column] => 
        )

    [meta_query] => 
    [date_query] => 
    [post_count] => 0
    [current_post] => -1
    [in_the_loop] => 
    [comment_count] => 0
    [current_comment] => -1
    [found_posts] => 0
    [max_num_pages] => 0
    [max_num_comment_pages] => 0
    [is_single] => 
    [is_preview] => 
    [is_page] => 
    [is_archive] => 
    [is_date] => 
    [is_year] => 
    [is_month] => 
    [is_day] => 
    [is_time] => 
    [is_author] => 
    [is_category] => 
    [is_tag] => 
    [is_tax] => 
    [is_search] => 
    [is_feed] => 
    [is_comment_feed] => 
    [is_trackback] => 
    [is_home] => 
    [is_404] => 
    [is_embed] => 
    [is_paged] => 
    [is_admin] => 1
    [is_attachment] => 
    [is_singular] => 
    [is_robots] => 
    [is_posts_page] => 
    [is_post_type_archive] => 
    [query_vars_hash:WP_Query:private] => b01f0d78a3a985d46374d4384bba30b7
    [query_vars_changed:WP_Query:private] => 
    [thumbnails_cached] => 
    [stopwords:WP_Query:private] => 
    [compat_fields:WP_Query:private] => Array
        (
            [0] => query_vars_hash
            [1] => query_vars_changed
        )

    [compat_methods:WP_Query:private] => Array
        (
            [0] => init_query_flags
            [1] => parse_tax_query
        )

)
  • oh, now that I realise, the add_post_meta is applied to another entity.. ( the cv_submission, not the cv_file ), i'll remove it from the question. that changes everyting, right? Thanks for your input :) – Toni Michel Caubet Jun 28 '17 at 10:24
  • Yes, but the overall concept still applies. We'll need to set some meta data or assign a custom taxonomy term or use some other way to identify these attachments and then exclude them. – Dave Romsey Jun 28 '17 at 10:27
  • 1
    Ok, I think I understand; I'll give it a shot and let you know. Thanks! – Toni Michel Caubet Jun 28 '17 at 13:07
  • I had some tests ( and made sure that the postmeta was saved ), but it shows up in the media library ( updating the question with details ), any idea? – Toni Michel Caubet Jun 29 '17 at 10:34
  • You'll need to use both functions I posted. I'll edit the wording on my answer to make it more clear. The ajax_query_attachments_args hook handles the media overlay view. The pre_get_posts hook is used more for an edge case. (When viewing Admin > Media and using the icon to select the list view.) ajax_query_attachments_args is used for everything else. Your meta data looks good though. And just for some reassurance, I have tested the code. – Dave Romsey Jun 29 '17 at 19:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.