Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

trying to make a custom column sortable in the media library. Found lots of examples for posts, and users but can't get them to work on the media library page.

function wpse_hook_isv_columns() {
    add_action('manage_media_custom_column', 'isv_custom_media_column_content',10,2);
    add_filter('manage_media_columns', 'isv_custom_media_column_headings');
    add_filter('manage_media_imwidth_sortable_columns', 'imwidth_column_register_sortable' );
}
add_action( 'admin_init', 'wpse_hook_isv_columns' );


function isv_custom_media_column_headings($defaults) {
   $defaults['isv_width'] = __( 'Width', 'imwidth' );
   $defaults['isv_height']    = 'Height';
   return $defaults;
}

function isv_custom_media_column_content($column_name,$id) {
   $meta = wp_get_attachment_metadata($id);
   switch ($column_name) {         
      case 'isv_width':
         $imWidth = get_post_meta($id, "_im_width", true);
         if(  $imWidth ) : 

            echo $imWidth .' ('.$meta['width'].')';
         else : //  add meta value if not there...

            update_post_meta($id, '_im_width', $meta['width']);
            echo $meta['width'].' (updated)';
         endif;          
         break;

      case 'isv_height':
         $desc = get_the_content();
         echo $meta['height'] ? $meta['height'] : $none;
         break;
   }
}

// Register the column as sortable ???
function imwidth_column_register_sortable( $columns ) {
    $custom = array(
          // meta column id => sortby value used in query
          'imwidth'    => 'Width',
    );
    return wp_parse_args($custom, $columns);
}

// This example i found works!

function registerdate($columns) {
    $columns['registerdate'] = __('Registered', 'registerdate');
    return $columns;
}
add_filter('manage_users_columns', 'registerdate');

function registerdate_columns( $value, $column_name, $user_id ) {
    if ( 'registerdate' != $column_name )
       return $value;
    $user = get_userdata( $user_id );
    $registerdate = $user->user_registered;
    return $registerdate;
}
add_action('manage_users_custom_column',  'registerdate_columns', 10, 3);

function registerdate_column_sortable($columns) {
      $custom = array(
      // meta column id => sortby value used in query
      'registerdate'    => 'registered',
      );
  return wp_parse_args($custom, $columns);
}
add_filter( 'manage_users_sortable_columns', 'registerdate_column_sortable' );

how can i make isv_width sortable? Any help appreciated!

share|improve this question
    
thumbs up on the admin users custom registerdate column code, exactly what i was looking for –  lkraav Feb 19 '12 at 16:40

3 Answers 3

up vote 1 down vote accepted

You cannot do a sort on the attachment meta data specifically because it's stored in a serialized string.

Whilst WP_Query can sort on meta values it can't sort on data that's serialized. For example wp_get_attachment_metadata fetches and unserializes that for you inside the column callback, but MySQL queries can't sort on that type of data.

Short answer: Not possible due to how the width and height are stored.


Follow-up:

Of course, if you setup the image height or width as seperate meta values you can then query on that, or should be able to at least, using a couple more hook(in addition to what you have).. manage_upload_sortable_columns and request.

// These would go inside your admin_init hook
add_filter( 'manage_upload_sortable_columns', 'isv_column_register_sortable' );
add_filter( 'request', 'isv_column_orderby' );

function isv_column_orderby( $vars ) {
    if ( isset( $vars['orderby'] ) && 'Width' == $vars['orderby'] ) {
        $vars = array_merge( $vars, array(
            'meta_key' => '_im_width',
            'orderby' => 'meta_value_num'
        ) );
    }
    return $vars;
}
function isv_column_register_sortable( $columns ) {
    $columns['isv_width'] = 'Width';
    return $columns;
}

If it helps more, Scribu gave an example of creating new sortable columns here. Note, the hook for the media listing is upload and not media for the sortable columns(because the hook is the screen id).

I tested this alongside your code and it did work, minus the sort order being off, because i don't have the _im_width key associated with media in my install.

I hope that's enough info to work from, and be sure to check the link to Scribu's page if you want to see a more complete example of sortable columns.

share|improve this answer
    
ok - now storing width as a meta value '_im_width'. Any idea how can i get the column to worth now? I just can't get the header of the column to be a link... –  daniel Crabbe Dec 7 '11 at 10:09
    
Added the necessary info to my answer for you, check it out.. ;) –  t31os Dec 7 '11 at 11:07
    
you're ace! All works. Had to make one tweak, && '_im_width' == $vars['orderly'] needed to be && 'Width' == $vars['orderly']. thanks all. D. –  daniel Crabbe Dec 7 '11 at 11:17
    
Happy to help.. :) –  t31os Dec 7 '11 at 11:23

First: If you're adding stuff to hooks or filters, you should allways wrap the action calls in a separate function and hook it (in your case:) to admin_init:

function wpse_hook_isv_columns()
{
    add_action('manage_media_custom_column', 'isv_custom_media_column_content',10,2);
    add_filter('manage_media_columns', 'isv_custom_media_column_headings');
}
add_action( 'admin_init', 'wpse_hook_isv_columns' );
// or:
if ( is_admin() )
    add_action( 'init', 'wpse_hook_isv_columns' );

Else you can't be shure they load early enough.

Also: Why are you calling $desc = get_the_content(); and not using it?

You should also use a string instead of None that is sortable and sort before the number "0" or after the letter "Z". Else it would be - in case of sorting - right in the middle of the sorting results...

Sidenote: If you check the Codex about translation, then you'll see all gettext functions having a second Parameter. That's the textdomain, nothing else. So your __('Width','domain'); will probably have your themes/plugins textdomain, hm? :)

share|improve this answer
    
Thanks Kaiser - updated according to your suggestions but still no joy. Underneath updated code is an example that works on the users page... The column and its values work. I just can't get the width header to be clickable! –  daniel Crabbe Dec 7 '11 at 10:25

Full Working Code

/*
 * Add Sortable Width and Height Columns to the Media Library
 *
 */

if( is_admin() )
{
    add_filter( 'manage_upload_columns', 'wpse_35680_size_columns_register' );
    add_action( 'manage_media_custom_column', 'wpse_35680_size_columns_display', 10, 2 );
    add_filter( 'manage_upload_sortable_columns', 'wpse_35680_size_columns_sortable' );
    add_filter( 'wp_generate_attachment_metadata', 'wpse_35680_update_imagesize_meta_data', 10, 2);
    add_action( 'pre_get_posts', 'wpse_35680_size_columns_do_sort' );
}


/*
 * Adding Width and Height columns
 *
 */

function wpse_35680_size_columns_register( $columns ) 
{
    $columns['_width'] = 'Width';
    $columns['_height'] = 'Height';

    return $columns;
}


/*
 * Display the columns
 *
 */

function wpse_35680_size_columns_display( $column_name, $post_id ) 
{
    if( '_width' != $column_name && '_height' != $column_name || !wp_attachment_is_image( $post_id ) )
        return;

    list( $url, $width, $height ) = wp_get_attachment_image_src( $post_id, 'full' );

    if( '_width' == $column_name )
        echo get_post_meta($post_id, '_width', true);

    if( '_height' == $column_name )
        echo get_post_meta($post_id, '_height', true);
}


/*
 * Registering columns as sortable
 *
 */

function wpse_35680_size_columns_sortable( $columns ) 
{
    $columns['_width'] = '_width';
    $columns['_height'] = '_height';

    return $columns;
}


/*
 * Save Image Attachments meta data on save
 *
 */

function wpse_35680_update_image_meta_data( $image_data, $att_id ) 
{
    $width  = $image_data['width'];
    $height = $image_data['height'];

    update_post_meta( $att_id, '_width', $width );
    update_post_meta( $att_id, '_height', $height );

    return $image_data;
}


/*
 * Sort the columns
 *
 */

function wpse_35680_size_columns_do_sort(&$query)
{
    global $current_screen;
    if( 'upload' != $current_screen->id )
        return;

    $is_width = (isset( $_GET['orderby'] ) && '_width' == $_GET['orderby']);
    $is_height = (isset( $_GET['orderby'] ) && '_height' == $_GET['orderby']);
    if( !$is_width && !$is_height )
        return;

    if ( '_width' == $_GET['orderby'] ) 
    {
        $query->set('meta_key', '_width');
        $query->set('orderby', 'meta_value_num');
    }

    if ( '_height' == $_GET['orderby'] ) 
    {
        $query->set('meta_key', '_height');
        $query->set('orderby', 'meta_value_num');
    }   
}

Workaround for Updating All Images in the Posts Table

/*
 * Update ALL attachments metada with Width and Height
 *
 * Important: Run Only Once
 * 
 */
//add_action('admin_init','wpse_35680_run_only_once');
function wpse_35680_run_only_once()
{   
    global $wpdb;
    $attachments = $wpdb->get_results( "SELECT ID FROM $wpdb->posts WHERE post_mime_type LIKE '%image%'" );
    foreach( $attachments as $att )
    {
        list( $url, $width, $height ) = wp_get_attachment_image_src( $att->ID, 'full' );
        update_post_meta( $att->ID, '_width', $width );
        update_post_meta( $att->ID, '_height', $height );
    }
}

Assembled with the invaluable input from Rarst, Bainternet, kaiser, t31os and scribu throughout this Stack

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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