Custom function to rearrange attachments when creating posts – Almost there

I’m not entirely sure what your intentions are for the code, and unfortunately i didn’t find what you provided worked very well, so i rewrote parts of the code supplied to make it into a more workable solution.

This code will work for saving the attachment order in the metabox on save, not via ajax, but realistically there’s no reason to save those changes on every sort(is there?).

I refactored the code so you can adjust the post type at the top of the code. I’m not sure what you aiming for with the enqueue call, and pretty sure it can’t be called in the way you were doing, nor was it needed on the post editor page anyway(sortable and the necessary scripts are already available/loaded on the editor screen).

Give this a shot and see how you get on.. (note this is a working sample)..

// Not applicable to my testing, but left it in because i'm sure it's appropriate to your usage
add_theme_support( 'post-thumbnails' );
add_image_size( 'editor-thumb', 130, 72, true );

// Quicker to update one line than several, only reason it's defined here
$my_post_type="book";

// Add metabox on the proper metabox hook
add_action( 'add_meta_boxes_' . $my_post_type, 'add_image_sortable_box',   2000 );

// Fire jQuery only on the appliable pages
add_action( 'admin_footer-post.php',           'add_sortable_to_elements', 2000 );
add_action( 'admin_footer-post-new.php',       'add_sortable_to_elements', 2000 );

function add_image_sortable_box() {
    global $my_post_type;
    add_meta_box( 'test-image-thing', 'Sortable Attachments Test', 'do_image_metabox_thingy', $my_post_type, 'side', 'default' );
}

function add_sortable_to_elements() { 
    ?>
    <script type="text/javascript">
    //<![CDATA[
        jQuery(document).ready(function($) {
            $('#attachmentcontainer').sortable();   
        });
    //]]>
    </script>
    <?php
}

function do_image_metabox_thingy( $p ) { 

    // No global statement needed here, the hook this function is attached to gives you the post object

    $args = array(
        'order'          => 'asc',
        'orderby'        => 'menu_order',
        'post_type'      => 'attachment',
        'post_parent'    => $p->ID,
        'post_mime_type' => 'image',
        'post_status'    => null,
        'numberposts'    => -1,
    );

    $attachments = get_posts( $args );

    if( $attachments ) :

        // Only need 1 nonce to cover the lot
        wp_nonce_field( 'my_attachment_sort', 'attachment_sort_nonce' );
    ?>

    <div class="imageuploader">
        <div id="attachmentcontainer">

        <?php
        foreach( $attachments as $attachment ) :
            $attachmentid = $attachment->ID;
            $editorimage = wp_get_attachment_image_src( $attachment->ID, 'editor-thumb', false, false);
        ?>

            <div class="attachment" id="test-<?php echo $attachment->ID; ?>">
                <div class="image">
                    <img width="100" height="auto" src="https://wordpress.stackexchange.com/questions/23843/<?php echo $editorimage[0]; ?>" />
                    <input type="hidden" name="att_id[]" id="att_id" value="<?php echo $attachment->ID; ?>" />
                </div>
            </div>

        <?php 
        endforeach;
        ?>

        <div style="clear: both;"></div>
        </div>      
    </div>

    <?php
    endif;
}

// Updates the attachments when saving
add_filter( 'wp_insert_post_data', 'test_meta_save', 1000, 2 );

function test_meta_save( $data, $_post_vars ) {
    global $my_post_type;
    if( $my_post_type != $data['post_type'] || !isset( $_post_vars['attachment_sort_nonce'] ) )
        return $data;

    if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
        return $data;

    if( !wp_verify_nonce( $_post_vars['attachment_sort_nonce'], 'my_attachment_sort' ) )
        return $data;

    global $post_ID;

    if( !current_user_can( 'edit_post', $post_ID ) ) 
        return $data;

    if( isset( $_post_vars['att_id'] ) ) {
        foreach( $_post_vars['att_id'] as $img_index => $img_id ) {
            $a = array(
                'ID' => $img_id,
                'menu_order' => $img_index
            );
            wp_update_post( $a );
        }
    }
    return $data;
}

Of course make sure to switch the post type value, book is my testing post type.. 🙂

Any questions, add them to your original question, then drop a comment onto this answer to let me know..

Leave a Comment