WordPress – Adding Page/Post Attachment Feature to the Media Edit Screen

Is there a way to add the page attachment feature to the edit media screen? So if I add/edit a media item, I can also attach/re-attach it to a page.

Here’s the code I have so far:

Read More
function my_post_submitbox_misc_actions( $id ){
    $post = get_post( $id );
   if( $post->post_parent > 0 ) {
        if( get_post( $post->post_parent ) ) {
            $title = _draft_or_post_title( $post->post_parent );
        }
   ?>
    <div class="misc-pub-section misc-pub-attachment">
      Attached to: <strong><a href="<?php echo get_edit_post_link( $post->post_parent ); ?>"><?php                  echo $title ?></a></strong>
    (<a class="hide-if-no-js" onclick="findPosts.open( ''media[]'', '<?php echo $post->ID ?>'     );return false;" href="#the-list"><?php _e( 'Re-Attach' ); ?></a>)
    </div>
   <?php
   } else { ?>
      <?php _e( '(Unattached)' ); ?><br />
      <a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>'  );return false;" href="#the-list"><?php _e( 'Attach' ); ?></a>
   <?php
   }
}
add_action( 'attachment_submitbox_misc_actions', 'my_post_submitbox_misc_actions' );

And here’s my call to the database:

global $wpdb;

$wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment'", $parent_id ) );

  if ( isset( $attached ) ) {
    $location = 'upload.php';
    if ( $referer = wp_get_referer() ) {
      if ( false !== strpos( $referer, 'upload.php' ) )
        $location = $referer;
    }

    $location = add_query_arg( array( 'attached' => $attached ) , $location );
    wp_redirect( $location );
  }

enter image description here

Related posts

Leave a Reply

2 comments

  1. I’ve use these combined functions, in my functions.php file, to add a link in the media library (upload.php in admin area) for each media item in the table to attach/re-attach that item to anything.

    // Functions to allow one to re-attach an image to a post
    function upload_columns( $columns ) {
        // Unset( $columns['parent'] );
        $columns['better_parent'] = 'Re-Attach';
        return $columns;
    }
    add_filter( 'manage_upload_columns', 'upload_columns' );
    function media_custom_columns( $column_name, $id ) {
        $post = get_post($id);
        if( $column_name != 'better_parent' )
            return;
        if( $post->post_parent > 0 ) {
            if( get_post( $post->post_parent ) ) {
                $title = _draft_or_post_title( $post->post_parent );
            }
            ?>
            <strong><a href="<?php echo get_edit_post_link( $post->post_parent ); ?>"><?php echo $title ?></a></strong>, <?php echo get_the_time( __( 'Y/m/d' )); ?>
            <br />
            <a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Re-Attach' ); ?></a>
            <?php
        }else {
            ?>
            <?php _e( '(Unattached)' ); ?><br />
            <a class="hide-if-no-js" onclick="findPosts.open( 'media[]', '<?php echo $post->ID ?>' );return false;" href="#the-list"><?php _e( 'Attach' ); ?></a>
            <?php
        }
    }
    add_action( 'manage_media_custom_column', 'media_custom_columns', 10, 2 );
    

    I know this doesn’t put the option where you are describing, but it’s a start in the right direction.

    UPDATE:

    Note that I’ll leave the above code in case someone wants to have the re-attach option in their library table.

    As for your question… Here is the code, explanation to follow:

    function my_post_submitbox_misc_actions( $id ) {
        global $pagenow, $typenow;
        // We only want to run the code on a specific page
        if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
            return;
        }
        $post = get_post( $id );
    
        if( $post->post_parent > 0 ) {
            if( get_post( $post->post_parent ) ) {
                $title = _draft_or_post_title( $post->post_parent );
            }
            ?>
            <div class="misc-pub-section misc-pub-attachment">
                Attached to: <strong><a href="<?php echo get_edit_post_link( $post->post_parent ); ?>"><?php echo $title ?></a></strong>
                ( <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Re-Attach' ); ?></a> )
            </div>
            <?php
        } else {
            _e( '(Unattached)' ); ?><br />
            <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Attach' ); ?></a>
            <?php
        }
    }
    add_action( 'attachment_submitbox_misc_actions', 'my_post_submitbox_misc_actions' );
    // Function to call the find_posts_div pop up OUTSIDE the post form
    function my_post_submitbox_misc_form() {
        global $pagenow, $typenow;
        // We only want to run the code on a specific page  
        if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
            return;
        }   
        // Enqueue our scripts
        wp_enqueue_style('thickbox');
        wp_enqueue_script('thickbox'); // needed for find posts div
        wp_enqueue_script('media');
        wp_enqueue_script('wp-ajax-response');
        ?>
        <form name="plugin_form" id="plugin_form" method="post" action="/wp-content/themes/<?php echo get_template() . '/test.php'; ?>">
            <?php
                wp_nonce_field('plugin_nonce');
                find_posts_div();
            ?>
        </form>
        <?php
    }
    add_filter('admin_footer','my_post_submitbox_misc_form');
    

    BREAKDOWN

    The first function is very similar to what you already have in your code above. I believe the only change I made was to add the check to make sure we only run this code on the edit attachment page. You might need to tweak this, as I tested it, but not fully.

    I also changed the way we call findPosts.open(). We now pass a variable called ‘action’ and set it’s value to ‘find_posts’ so we can check for it later…

    So the first function simply shows the post the attachment is already attached to, and lets you re-assign it if desired… or shows you an option to just attach it. The re-attach and attach are just links that, when clicked, launch findPosts.open() which looks for a hidden div/inputs on the page… we haven’t created those yet.

    The second function is the key… first, you do need to enqueue scripts and one style. The import piece of code here is the find_posts_div() call. This is what makes the magic happen, but all this does is creates hidden divs and form fields in a pop-up, just waiting to be called (our anchors in the first function). This NEEDS TO BE in a separate function so that we can use add_filter to call the function OUTSIDE OF the post form.

    At first I tried to have it all together in one function. The browser strips out our <form> tag because we are attempting to place a form inside another form (the post form), and that’s a no no. So by calling it in the admin_footer, we load the code outside the form.

    Wrapping the find_posts_div() in a form allows us to submit the results of that form to where ever we want, to do whatever we want with it. In our case, we create a new page (test.php) and submit the results there, so we can do what we need.

    So far, the test.php page is as follows:

    <?php 
        echo '<pre>';print_r($_POST);echo '</pre>';
        die();
    ?>
    

    This will show you all the values of $_POST… feel free to add more hidden values and what not, but the ‘found_post_id’ value is the post id from the selected value from the pop up. Then you can check out lines 103 – 141 of upload.php to find code to do the actual re-attach. There might be a hook or something better, but I didn’t have time to look.

    Hope this helps!

  2. So after a little help from Daniel and some research, I was finally able to make it work! Here’s how my code looks now:

    function spd_submitbox_misc_actions( $id ) {
        global $pagenow, $typenow;
        // We only want to run the code on a specific page
        if( $pagenow != 'post.php' || $typenow != 'attachment' ) {
            return;
        }
        $post = get_post( $id );
    
        if( $post->post_parent > 0 ) {
            if( get_post( $post->post_parent ) ) {
                $title = _draft_or_post_title( $post->post_parent );
            }
    
            ?>
            <div class="misc-pub-section misc-pub-attachment">
                Attached to: <strong><a href="<?php echo get_edit_post_link( $post->post_parent ); ?>"><?php echo $title ?></a></strong>
                <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( ' (Re-Attach) ' ); ?></a>
            </div>
        <?php
        } else { ?>
            <div class="misc-pub-section misc-pub-attachment">
                Attached to: (Unattached) <a class="hide-if-no-js" onclick="findPosts.open('action','find_posts');return false;" href="#"><?php _e( 'Attach' ); ?></a>
            </div>
        <?php
        }
    }
    add_action( 'attachment_submitbox_misc_actions', 'spd_submitbox_misc_actions' );
    // Function to call the find_posts_div pop up OUTSIDE the post form
    function spd_post_submitbox_misc_form() {
        global $pagenow, $typenow;
    
        // We only want to run on edit media page
        if( $pagenow != 'post.php' || $typenow != 'attachment' )
            return;
    
        // Enqueue our scripts
        wp_enqueue_style('thickbox');
        wp_enqueue_script('thickbox'); // needed for find posts div
        wp_enqueue_script('media');
        wp_enqueue_script('wp-ajax-response');
        $send_to = get_template_directory_uri() . '/inc/spdfunctions/spd_post_actions.php';
    
        ?>
        <form name="attach-to-post" method="post" action="<?php echo $send_to; ?>">
            <?php find_posts_div(); ?>
            <input type="hidden" name="attach-to-post" value="attach" />
            <input type="hidden" name="attachment-id" value="<?php the_ID(); ?>" />
        </form>
    <?php
    }
    add_filter('admin_footer','spd_post_submitbox_misc_form');
    

    Then to process the submission:

    if ( $_REQUEST['action'] && isset( $_POST['attach-to-post'] ) ) {
    
        $location = $_SERVER['DOCUMENT_ROOT'];
        include( $location . '/wp-load.php' );
    
        $parent_id = $_POST['found_post_id'];
        $attach_id = (int) $_POST['attachment-id'];
    
        $attached = $wpdb->query( $wpdb->prepare( "UPDATE $wpdb->posts SET post_parent = %d WHERE post_type = 'attachment' AND ID IN ( %d )", $parent_id, $attach_id ) );
    
        //redirect back to edit media screen
        if ( isset( $attached ) ) {
            $referer = wp_get_referer();
            $location = add_query_arg( array( 'attached' => $attached ) , $referer );
            wp_redirect( $location );
        }
    }
    

    Thanks again, Daniel, for all your help. It was very much appreciated!