1

I currently have a custom post type in a theme I'm developing which will be used for portfolio items. So far, I have implemented functionality that allows images to be attached to a portfolio post.

I now need the best way to go about detaching images from a post: My code currently is:

    $images =& get_children('post_type=attachment&post_mime_type=image&post_parent=$post->ID');
            $numberOfImages = count($images);
            if($numberOfImages == 1) {

            }
            else if($numberOfImages > 1)
            {
                foreach($images as $attachment_id => $attachment)
                {
                    $imageAttributes = wp_get_attachment_image_src($attachment_id);
                    ?>
                    <div class="element">
                        <img alt="" height="100" src="<?php echo $imageAttributes[0]; ?>" width="150" />
                        <a href="#" title="Unattach this media item.">Unattach</a>
                    </div>
                    <?php
                }
            }

This loops through the images that are attached and displays them in a meta box with an associated 'Unattach' button. I am at a loss as to what/where I need to link to to detach the images from the post. Any help appreciated.

1 Answer 1

6

This can be done using an Ajax call that will query the database and set the parent as "zero".

First, create a meta box, enqueue the Javascript that calls the unattach function and register this WP_Ajax function.

<?php
/*
Plugin Name: Unattach Meta Box
Version: 0.3
Author: brasofilo
Plugin URI: http://wordpress.stackexchange.com/q/54822
*/

add_action( 'add_meta_boxes', 'wpse_54822_add_custom_box' );
add_action( 'admin_head', 'wpse_54822_script_enqueuer' );
add_action( 'wp_ajax_wpse_54822_custom_query', 'wpse_54822_unattach' );
add_action( 'wp_ajax_nopriv_wpse_54822_custom_query', 'wpse_54822_unattach' );

function wpse_54822_add_custom_box() 
{
    add_meta_box(
        'wpse_54822_sectionid',
        __( 'Page Attachments' ), 
        'wpse_54822_inner_custom_box',
        'page'
    );
}

function wpse_54822_inner_custom_box() 
{
    global $post;
    $images = get_children( 'post_type=attachment&post_mime_type=image&post_parent=' . $post->ID );
    if( count($images) > 0 )
    {
        foreach( $images as $attachment_id => $attachment )
        {
            $imageAttributes = wp_get_attachment_image_src( $attachment_id );
            ?>
            <div class="element" id="container-<?php echo $attachment_id; ?>">
                <img alt="" height="100" src="<?php echo $imageAttributes[0]; ?>" width="150" />
                <a href="javascript:void(0);" id="dettach-<?php echo $attachment_id; ?>" class="dettach" title="Unattach this media item." >Unattach</a>
            </div>
            <?php
        }
    } 
    else
    {
        echo 'No images attached.';
    }
}

function wpse_54822_script_enqueuer() 
{
    global $current_screen;
    if( 'page' != $current_screen->id )
        return;
    wp_register_script( 'scripts.js', plugin_dir_url(__FILE__).'script.js' );
    wp_enqueue_script( 'scripts.js' );
    wp_localize_script( 'scripts.js', 'wp_ajax', array( 
        'url' => admin_url( 'admin-ajax.php' ),
        'nonce' => wp_create_nonce('nonce_wpse_54822')
    )); 
}

function wpse_54822_unattach()
{
    check_ajax_referer( 'nonce_wpse_54822' );
    global $post, $wpdb;
    if( !isset( $_POST['the_attach_id'] ) )
        wp_send_json_error( array( 'error' => 'ID not set' ) );

    $the_id = intval( $_POST['the_attach_id'] );
    $do_query = $wpdb->query( $wpdb->prepare( 
        "UPDATE $wpdb->posts SET post_parent = 0 WHERE ID = '%s'", 
        $the_id 
    ));

    if( !$do_query ) {
        wp_send_json_error( array( 'error' => 'Query error.' ) ); // Refine this to show proper wpdb error
    }
    else {
        wp_send_json_success();
    }
}

This is the enqueued Javascript file (script.js). It makes the Ajax call that will execute a MySql query to unattach and removes the thumbnail from the meta box.

jQuery(document).ready( function($) 
{       
    $('.dettach').each( function(i,e)
    {
        var id = $(this).attr('id').replace(/dettach-/, '');
        $(this).click( function(){
            $.post( 
                wp_ajax.url, 
                { 
                    action: 'wpse_54822_custom_query', 
                    _ajax_nonce: wp_ajax.nonce, 
                    the_attach_id: id
                }, 
                function( response ){
                    if( !response.success )
                        console.log( response.data.error );
                    else
                        remove_image( id );
                }
            );
        });
     });                 

    function remove_image( id )
    {
        $('#container-'+id).remove();
        return false;
    }
});  

Result:
unattach meta box

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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