web-dev-qa-db-ja.com

メディアライブラリのソート可能なカスタム列

カスタムライブラリをメディアライブラリでソート可能にしようとしています。投稿用の例やユーザーがたくさん見つかりましたが、メディアライブラリページでそれらを使用することはできません。

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

どのようにしてisv_widthをソート可能にすることができますか?どんな助けにも感謝します!

6
v3nt

添付ファイルのメタデータは、シリアル化された文字列に保存されているため、並べ替えることはできません。

WP_Queryはメタ値でソートできますが、シリアル化されたデータではソートできません。たとえば、wp_get_attachment_metadataはカラムコールバック内でそれを取得して非シリアル化しますが、MySQLクエリはそのタイプのデータでソートできません。

簡単な答え:幅と高さがどのように格納されているかによって不可能です。


ファローアップ:

もちろん、画像の高さまたは幅を個別のメタ値として設定する場合、その上でクエリを実行できます。または、少なくとも2つ以上のフック(使用しているものに加えて)を使用できます。manage_upload_sortable_columnsおよび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;
}

さらに役立つ場合、Scribuは新しい並べ替え可能な列 here を作成する例を示しました。メディアリストのフックは、ソート可能な列のuploadではなくmediaであることに注意してください(フックは画面IDであるため)。

私はこれをあなたのコードと一緒にテストしましたが、ソート順を除いて動作しました。インストール中にメディアに関連付けられた_im_widthキーがないためです。

これで十分な情報が得られることを願っています。ソート可能な列のより完全な例をご覧になりたい場合は、Scribuのページへのリンクを確認してください。

1
t31os

まず、フックやフィルタに何かを追加しているのであれば、アクション呼び出しを別の関数でラップして(あなたの場合は)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' );

そうでなければ、あなたは彼らが十分に早くロードすると確信することはできません。

また、$desc = get_the_content();を呼び出していて、使用していないのはなぜですか。

Noneの代わりにソート可能で文字列 "0"の前または文字 "Z"の後にソートする文字列も使用する必要があります。そうでなければそれは - ソートの場合 - ソート結果の真ん中にあるでしょう...

サイドノート:翻訳についてコーデックスをチェックすると、すべてのgettext関数が2番目のパラメータを持つことがわかります。それが textdomain です。それであなたの__('Width','domain');はおそらくあなたのテーマ/プラグインtextdomainを持っているでしょうね? :)

2
kaiser

フルワーキングコード

/*
 * 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');
    }   
}

投稿テーブルのすべての画像を更新するための回避策

/*
 * 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 );
    }
}

このスタック全体を通して、Rarst、Bainternet、kaiser、t31os、およびscribuからの貴重な入力を使って組み立てられました

2
brasofilo