web-dev-qa-db-fra.com

Fonction personnalisée pour réorganiser les pièces jointes lors de la création de messages - Vous y êtes presque

J'ai des problèmes avec une chose personnalisée que je fais.

J'ai implémenté un téléchargeur d'image personnalisé dans une metabox dans un type de publication personnalisé. Maintenant, j'essaie de trouver un moyen de me permettre de réorganiser les images téléchargées. J'ai trouvé que jQuery Sortable serait un moyen pratique pour l'utilisateur de pouvoir simplement glisser-déposer dans l'ordre d'affichage des images (dans l'interface, j'utilise un curseur d'image jQuery pour afficher les images et l'ordre des images. sont décidés par les données de pièce jointe "menu_order", il me faut donc une sorte de fonctionnalité qui enregistre le menu_order que je crée avec jQuery Sortable.

Maintenant, ceci est un exemple simplifié de ce que j'ai: http://jsfiddle.net/LN4sA/

Avec chaque pièce jointe, j'ai ajouté des champs de saisie masqués avec l'identifiant de la pièce jointe et un champ qui hébergera la position actuelle de la pièce jointe dans l'ordre du menu.

L'identifiant de la pièce jointe est facilement récupérable avec la base WP PHP ($ pièce jointe-> ID). Cependant, je n'ai pas encore trouvé de moyen facile de remplir le #att_order avec le bon menu_order. Donc, ici, j'aimerais avoir de l'aide/de la contribution si quelqu'un était si gentil.

Pour enregistrer les informations réelles, j'utilise ajax pour extraire les valeurs des champs de saisie:

add_action('save_post', 'save_attachment_position');
function save_attachment_position(){
    global $post;
    if ($post->post_type == 'work') { ?>
        <script type="text/javascript">
        //<![CDATA[
            jQuery.ajax({
                type: 'post',
                url: ajaxurl,
                data: {
                    action: 'order_attachment',
                    att_ID: jQuery(this).parents('.attachment').find('#att_id').val(),
                    att_order: jQuery(this).parents('.attachment').find('#att_order').val(),
                    _ajax_nonce: jQuery('#ordernonce').val(),
                    post_type: 'attachment'
                }
            });
        //]]>
    </script><?php 
    }
}

Et utilisez ensuite wp_update_post pour mettre à jour les données de pièce jointe:

add_action('wp_ajax_order_attachment', 'order_attachment');
function order_attachment($post) {
    $attachmentdata = array();
    $attachmentdata['ID'] = $_POST['att_ID'];
    $attachmentdata['menu_order'] = $_POST['att_order'];
    wp_update_post($attachmentdata);    
}

Je suis conscient que j'ai besoin d'une sorte de boucle ici mais je vais y arriver.

Des idées?

Merci

4
INT

Je ne suis pas tout à fait sûr de vos intentions concernant le code et, malheureusement, je n'ai pas trouvé ce que vous fournissiez fonctionnait très bien. J'ai donc récrit certaines parties du code fourni pour en faire une solution plus pratique.

Ce code fonctionnera pour sauvegarder l'ordre des pièces jointes dans la métaboxe sur save, pas via ajax, mais de manière réaliste, il n'y a aucune raison de sauvegarder ces modifications de toutes les sortes (y a-t-il?).

J'ai refactored le code afin que vous puissiez ajuster le type de message en haut du code. Je ne suis pas sûr de ce que vous visez avec l'appel de mise en file d'attente, et je suis presque sûr qu'il ne peut pas être appelé comme vous le faisiez, et il n'était de toute façon pas nécessaire sur la page de l'éditeur de publication (triable et les scripts nécessaires sont déjà disponibles/chargé sur l'écran de l'éditeur).

Donnez un coup de feu et voyez comment vous vous en sortez .. (notez que ceci est un exemple de travail) ..

// 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="<?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;
}

Bien sûr, assurez-vous de changer la valeur du type de post, book est mon type de post de test .. :)

Si vous avez des questions, ajoutez-les à votre question initiale, puis ajoutez un commentaire sur cette réponse afin de me le faire savoir ..

5
t31os