Unattaching images from a post

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="https://wordpress.stackexchange.com/questions/54822/<?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

Leave a Comment