3

On the admin add/edit post page, I have a new meta box with submit button. I want to submit them separately. For example if some one click on Publish / update button then it save all post content and when some one click on meta box submit button then it should save meta box fields in a new DB table. Code is attached.

add_action( 'add_meta_boxes', 'cd_meta_box_add' );
function cd_meta_box_add()
{
add_meta_box( 'my-meta-box-id', 'Copy', 'cd_meta_box_cb', 'post', 'side', 'high', $post->ID);
}

function cd_meta_box_cb( $post )
{

wp_nonce_field( 'my_meta_box_nonce', 'meta_box_nonce' );

global $wpdb, $wp_query;
$wpdb->show_errors();
$table = $wpdb->base_prefix . 'post_copy';
$parent_post_id = $post->ID;
$parent_blog_id = get_current_blog_id();
$query= "SELECT * 
        FROM {$table}
        WHERE  child_post_id= '".$parent_post_id."'
        AND child_blog_id = '".$parent_blog_id."' 
         ";
    $resultset = $wpdb->get_results($query);
    if(!empty ($resultset)){
        foreach ( $resultset as $result ) 
        {
             $copy_type = $result->copy_type;
        }
    }
$if_post_child = $wpdb->get_var( "SELECT COUNT(*) FROM {$table} where  child_post_id = '".$post->ID."' and child_blog_id ='".$parent_blog_id."' and copy_type = '".$copy_type."'");
if( $if_post_child == 0 ){
?>
    <div id="scrollbox">
        <input type="hidden" value="<?php echo $parent_blog_id ?>" name= "parent_blog_id">
    <ul>
    <?php   $user_id = get_current_user_id();
        $user_blogs = get_blogs_of_user( $user_id );
        //echo "<pre>"; print_r($user_blogs); echo "</pre>";

        foreach ($user_blogs as $user_blog) {
                $child_blog_id = $user_blog ->userblog_id;
                $if_child = $wpdb->get_var( "SELECT COUNT(*) FROM {$table} where  parent_post_id = '".$parent_post_id."' and child_blog_id ='".$child_blog_id."'");
                $querystr = "SELECT * 
                        FROM {$table}
                        WHERE  parent_blog_id= '".$parent_blog_id."'
                        AND parent_post_id = '".$parent_post_id."' 
                        AND child_blog_id = '".$child_blog_id."' 
                         ";
                    $result = $wpdb->get_results($querystr);
                    if(!empty ($result)){
                        foreach ( $result as $res ) 
                        {
                            $sel_child_blog_id = $res->child_blog_id;
                            $set_post_type = $res->copy_type;
                        }
                    }

                        //print_r($result);
                if($if_child == 0){
        ?>
                    <li style="margin-bottom:10px;"><label for="all_blog_name">
                    <input type="hidden" name="blog_check_name[]" id="blog_check_name_<?php echo $user_blog ->userblog_id ?>" value="<?php echo $user_blog ->blogname; ?>"/>
                        <input class="chk-copy" type="checkbox" name="blog_check[]" id="blog_check_<?php echo $user_blog ->userblog_id ?>" value="<?php echo $user_blog ->userblog_id; ?>" />
                        <span>
                        <?php
                            echo $user_blog->blogname;
                        ?>
                        </span>
                        <br>&nbsp;&nbsp;<input type="radio" name="child_post_<?php echo $user_blog ->userblog_id; ?>" id="child_post_<?php echo $user_blog ->userblog_id; ?>"checked value="draft"  /> Draft
                        <input type="radio" name="child_post_<?php echo $user_blog ->userblog_id; ?>" id="child_post_<?php echo $user_blog ->userblog_id; ?>" value="publish" /> Published
                        <input type="radio" name="child_post_<?php echo $user_blog ->userblog_id; ?>" id="child_post_<?php echo $user_blog ->userblog_id; ?>"  value="future" /> Scheduled
                        <br>
                    </li>
            <?php
                } else { ?>
                <input type="hidden" name="blog_check_name[]" id="blog_check_name_<?php echo $user_blog ->userblog_id ?>" value="<?php echo $user_blog ->blogname; ?>"/>
                    <li style="margin-bottom:10px;"><label for="all_blog_name">
                    <?php
                        if($sel_child_blog_id == $user_blog ->userblog_id){
                            $chked = "checked";
                        }
                    ?>
                        <input class="chk-copy" type="checkbox" name="blog_check[]" id="blog_check_<?php echo $user_blog ->userblog_id ?>" value="<?php echo $user_blog ->userblog_id; ?>" <?php echo $chked ?>/>
                        <span>
                        <?php
                            echo $user_blog->blogname;

                        ?>
                        </span>
                        <br>&nbsp;&nbsp;<input type="radio" name="child_post_<?php echo $user_blog ->userblog_id; ?>" id="child_post_<?php echo $user_blog ->userblog_id; ?>" value="update" checked /> Update
                        <input type="radio" name="child_post_<?php echo $user_blog ->userblog_id; ?>" id="child_post_<?php echo $user_blog ->userblog_id; ?>" value="no_update" /> No Update
                        <br>
                    </li>
            <?php   } // End If

            }   // End For
            ?>
        </label>



    </ul>
    </div>
    <div class="btncopy">  
         <?php
        $if_not_parent = $wpdb->get_var( "SELECT COUNT(*) FROM {$table} where  parent_post_id = '".$parent_post_id."'");
        if($if_not_parent == 0){
            submit_button( __( 'Copy', 'Copy-post' ), 'button button-primary button-large', 'copy-post', false );
        }else{

         ?>
          <input type="button" name="copy-post" id="copy-post" class="button button-primary button-large" value="Copy" onClick ="openbox_parent('Copy Confirm', 1)" />
         <?php } ?> 
    </div>
    <input type="hidden" name="copy-post" id="copy-post" class="button button-primary button-large" value="Copy"  />
    <div id="shadowing-parent"></div>

    <div id="box-parent">
      <span id="boxtitle-parent"></span>

        <label for="confirmation_copy">
        <p> Update the following child posts : </p>

        <div id="checkboxContainer"></div>  
        <p> 
          <input type="submit" name="Copy" value="Copy">
          <input type="button" name="cancel" value="Cancel" onClick="closebox_parent()">
        </p>
        </label>
      <!--/form-->
    </div>
<?php
} // End of $if_post_child
else if ($if_post_child > 0 && $copy_type == 'child_linked'){
    echo "This is a child post of CEBBlogs. Any edits made here will break the link with the parent post and will disable it from being updated in future by the parent.
    To maintain the link with the Parent post please make all edits at the Parent post and copy them down.<br><br>";
    echo "<a href='#'>View Parent Post</a>";

}else if ($if_post_child > 0 && $copy_type == 'child_unlinked'){
    echo "This is a child post of CEBBlogs. It has been updated and is no longer linked to the parent post.<br><br>";
    echo "<a href='#'>View Parent Post</a>";

}
}

Now I called the save_post

add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $post_id )
{


// Bail if we're doing an auto save
//if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;

// if our nonce isn't there, or we can't verify it, bail
if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;


// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) ) return;

$registerFormParameterHandler = new FormParameterHandler($_POST);

if($_POST['copy-post'] == 'Copy'){
    echo 'here';

    global $wpdb, $wp_query;

    $wpdb->show_errors();

    $id = $wp_query->post->ID; // get post ID
    $table = $wpdb->base_prefix . 'post_copy';

    // update popularpostsdata table

    $blog_checked = $_POST[blog_check];
    for ($i =0; $i < count($blog_checked); $i++){
        $child_blog_id =  $blog_checked[$i];
        // $child_blog_type = Published, Draft, Schedule, update, No Update
        $child_blog_type = $_POST['child_post_'.$child_blog_id];
        $parent_blog_id = $_POST['parent_blog_id'];
        $parent_post_id = $_POST['post_ID'];

        // Date time for New Inserted post
        $post_date = date("Y-m-d h:m:s");
        $post_date_gmt = gmdate("Y-m-d h:m:s");

        // If the post is Published, Draft, zzzzzz,--- Copy content



        if($child_blog_type =='publish' || $child_blog_type =='draft' || $child_blog_type =='future')
        {

        $vals = sprintf("'%s', '%s', '%s', '%s', '%s', '%s',
            '%s', '%s', '%s', '%s','%s', '%s', '%s',
            '%s', '%s', '%s',
            '%s', '%s', '%s', '%s','%s', '%s'",
            mysql_real_escape_string($registerFormParameterHandler->post_author), mysql_real_escape_string($post_date), mysql_real_escape_string($post_date_gmt), mysql_real_escape_string($registerFormParameterHandler->post_content), mysql_real_escape_string($registerFormParameterHandler->post_title), mysql_real_escape_string($registerFormParameterHandler->post_excerpt),
            mysql_real_escape_string($child_blog_type), mysql_real_escape_string($registerFormParameterHandler->comment_status), mysql_real_escape_string($registerFormParameterHandler->ping_status), mysql_real_escape_string($registerFormParameterHandler->post_password), mysql_real_escape_string($registerFormParameterHandler->post_name), mysql_real_escape_string($registerFormParameterHandler->to_ping), mysql_real_escape_string($registerFormParameterHandler->pinged), 
            mysql_real_escape_string($registerFormParameterHandler->post_modified), mysql_real_escape_string($registerFormParameterHandler->post_modified_gmt), mysql_real_escape_string($registerFormParameterHandler->post_content_filtered), 
            mysql_real_escape_string($registerFormParameterHandler->post_parent), mysql_real_escape_string($registerFormParameterHandler->guid), mysql_real_escape_string($registerFormParameterHandler->menu_order), mysql_real_escape_string($registerFormParameterHandler->post_type), mysql_real_escape_string($registerFormParameterHandler->post_mime_type), mysql_real_escape_string($registerFormParameterHandler->comment_count)
        );
        $cols = "post_author, post_date, post_date_gmt, post_content, post_title, post_excerpt,
            post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged,
            post_modified, post_modified_gmt, post_content_filtered,
            post_parent, guid, menu_order, post_type, post_mime_type, comment_count";


                echo $sql = "insert into cebblogs_".$child_blog_id."_posts (".$cols.") values(".$vals.")";
                $wpdb->query ($sql);
                $new_post_id = mysql_insert_id();

        }else if($child_blog_type =='update'){
            // Code will go here
            $get_child_post_id = "Select child_post_id from {$table} where parent_post_id = {$parent_post_id} and child_blog_id = {$child_blog_id} and copy_type= 'child_linked'";
            $result = $wpdb->get_results($get_child_post_id);
            if(!empty ($result)){
                foreach ( $result as $res ) 
                {
                    $child_post_id = $res->child_post_id;
                }
            }
            $vals = sprintf("'%s','%s', '%s', '%s', '%s', '%s', '%s',
            '%s', '%s', '%s', '%s','%s', '%s', '%s',
            '%s', '%s', '%s',
            '%s', '%s', '%s', '%s','%s', '%s'",
            mysql_real_escape_string($child_post_id), mysql_real_escape_string($registerFormParameterHandler->post_author), mysql_real_escape_string($post_date), mysql_real_escape_string($post_date_gmt), mysql_real_escape_string($registerFormParameterHandler->post_content), mysql_real_escape_string($registerFormParameterHandler->post_title), mysql_real_escape_string($registerFormParameterHandler->post_excerpt),
            mysql_real_escape_string($child_blog_type), mysql_real_escape_string($registerFormParameterHandler->comment_status), mysql_real_escape_string($registerFormParameterHandler->ping_status), mysql_real_escape_string($registerFormParameterHandler->post_password), mysql_real_escape_string($registerFormParameterHandler->post_name), mysql_real_escape_string($registerFormParameterHandler->to_ping), mysql_real_escape_string($registerFormParameterHandler->pinged), 
            mysql_real_escape_string($registerFormParameterHandler->post_modified), mysql_real_escape_string($registerFormParameterHandler->post_modified_gmt), mysql_real_escape_string($registerFormParameterHandler->post_content_filtered), 
            mysql_real_escape_string($registerFormParameterHandler->post_parent), mysql_real_escape_string($registerFormParameterHandler->guid), mysql_real_escape_string($registerFormParameterHandler->menu_order), mysql_real_escape_string($registerFormParameterHandler->post_type), mysql_real_escape_string($registerFormParameterHandler->post_mime_type), mysql_real_escape_string($registerFormParameterHandler->comment_count)
        );
        $cols = "ID, post_author, post_date, post_date_gmt, post_content, post_title, post_excerpt,
            post_status, comment_status, ping_status, post_password, post_name, to_ping, pinged,
            post_modified, post_modified_gmt, post_content_filtered,
            post_parent, guid, menu_order, post_type, post_mime_type, comment_count";
            //echo "<pre>";print_r($child_post_id   ); echo "</pre>";
            $sql = "REPLACE INTO cebblogs_".$child_blog_id."_posts   (".$cols.") values(".$vals.")";
            $wpdb->query ($sql);
        }


        $numberofpost = $wpdb->get_var( "SELECT COUNT(*) FROM {$table} where parent_blog_id = '".$parent_blog_id."' and parent_post_id = '".$parent_post_id."' and child_blog_id ='".$child_blog_id."'");
        if($numberofpost == 0) {
            $result = $wpdb->query("INSERT INTO {$table}  VALUES ('' , '".$parent_blog_id."', '".$parent_post_id."', '".$child_blog_id."', '".$new_post_id."', 'child_linked', '2013-04-09 07:00:00', '2013-04-17 06:00:00')");

        }

    }

}
exit;
}

This all code fine except two things: 1. It execute query two times in save_post. 2. All code execute either you press publish button or you press meta box submit button

1 Answer 1

2

IMO, it's much better to solve this with Ajax. Maybe it's possible the way you're proposing, but it seems a bit confusing from an User Experience perspective: two similar buttons that do different things.
What if the user modifies the content and the custom fields, updates one and loses the other? Maybe the save_post action hook should be just a backup function.

It can be implemented with the following steps covering just the Ajax side. You'll find a full Ajaxified meta box here: Unattaching images from a post

1) Enqueue and localize the Javascript
We can pass any value to JS in the array, like 'custom_value' = $something and retrieve it in JS with wp_ajax.custom_value. The second parameter of wp_localize_script, wp_ajax, is the object name to be referenced in JS.

add_action( "admin_print_scripts-post.php", 'enqueue_ajax_wpse_97845' );

function enqueue_ajax_wpse_97845()
{
    // Check post type
    global $typenow;
    if( 'post' != $typenow )
        return;

    wp_enqueue_script( 'wpse_97845_js', plugins_url( '/', __FILE__ ) . 'wpse_97845.js' );

    wp_localize_script( 
            'wpse_97845_js', 
            'wp_ajax', 
            array( 
                'ajaxurl' => admin_url( 'admin-ajax.php' ),
                'ajaxnonce' => wp_create_nonce( 'wpse_97845_validation' )
            ) 
    ); 
}

2) Add the Ajax function that will be called by JS
Here we'll save our data based on the data sent by the Ajax call in the Javascript file. First, we do a security check. Then check if the correct $_POST data was sent. And finally do our stuff.
I'm not sure if global $post; $post->ID is available at this point. If not, it has to be grabbed and sent with jQuery/JS.

add_action( 'wp_ajax_update_metabox_wpse_97845', 'update_metabox_wpse_97845' );

function update_metabox_wpse_97845()
{
    check_ajax_referer( 'wpse_97845_validation', 'ajaxnonce' );

    if( !isset( $_POST['wpse_97845_custom_field'] ) ) {
        wp_send_json_error( array(
            'error' => __( 'Post ID not set' ) 
        ));
    }

    wp_send_json_success( 'Success' );
}

3) Javascript/jQuery file
Here, we detect that our custom Update button was pressed. Grab the information from the input fields and send it to the previous Ajax function.
This is the file wpse_97845.js that's alongside the plugin file.

jQuery(document).ready(function($)
{
    /**
     * Handle error messages
     */
    function wpse_97845_handle_error( error )
    {
        // Do something
    }

    /**
     * Process Ajax response
     */
    function wpse_97845_do_response( response )
    {
        // Error
        if( !response.success )
        {
            wpse_97845_handle_error( response.data.error );
            return;
        }

        // do something
    }

    /**
     * Ajax button call
     */
    $('#wpse_97845_update_button').click(function()
    {
        origin_value = $('#input_field_id').val();

        /* Prepare data */
        var data = {
            action: 'query_external_site',
            ajaxnonce: wp_ajax.ajaxnonce,
            wpse_97845_custom_field: origin_value
        };

        $.post( wp_ajax.ajaxurl, data, wpse_97845_do_response );
    }); 

});

[Update]

Working example

Check code comments.

publish to other blog meta box

mu-copy-post.php

<?php
/**
 * Plugin Name: Multisite - Copy Post to Other Site
 * Plugin URI: https://wordpress.stackexchange.com/q/97845/12615
 * Version: 1.0
 * Author: brasofilo
 * Author URI: https://wordpress.stackexchange.com/users/12615/brasofilo
 */

add_action( 'add_meta_boxes', 'add_custom_box_wpse_94701' );
add_action( "admin_print_scripts-post.php", 'enqueue_ajax_wpse_97845' );
add_action( 'wp_ajax_update_metabox_wpse_97845', 'update_metabox_wpse_97845' );

function add_custom_box_wpse_94701() 
{
    add_meta_box(
        'sectionid_wpse_94701',
        __( 'Copy Post' ), 
        'copy_post_box_wpse_94701',
        'post',
        'side'
    );
}

function copy_post_box_wpse_94701() 
{
    global $wpdb,$post;
    $blogs = $wpdb->get_results("
        SELECT blog_id
        FROM {$wpdb->blogs}
        WHERE site_id = '{$wpdb->siteid}'
        AND spam = '0'
        AND deleted = '0'
        AND archived = '0'
        AND mature = '0' 
        AND public = '1'
    ");

    $original_blog_id = get_current_blog_id();

    // Dropdown
    echo '<select name="other-blog-id" id="other-blog-id">
        <option value="">- Select -</option>';
    foreach ( $blogs as $blog ) 
    {
        // Don't display current blog
        if( $original_blog_id == $blog->blog_id )
            continue;

        switch_to_blog($blog->blog_id);

        printf(
            '<option value="%d"> %s</option>',
            $blog->blog_id,
            get_option('blogname')
        );
    }
    echo '</select>';

    // Publish button
    echo "<a class='button-secondary' href='#' title='Publish to other blog' id='publish-to-other-blog' name='$post->ID'>Publish</a>";

    // Error and success messages
    echo '<div class="updated below-h2" id="ajax-success" style="display:none">updated</div>';
    echo '<div class="form-invalid" id="ajax-error" style="display:none">form-invalid</div>';

    switch_to_blog( $original_blog_id );
}

function enqueue_ajax_wpse_97845()
{
    // Check post type
    global $typenow;
    if( 'post' != $typenow )
        return;

    wp_enqueue_script( 'wpse_97845_js', plugins_url( '/', __FILE__ ) . 'mu-copy-post.js' );

    wp_localize_script( 
            'wpse_97845_js', 
            'wp_ajax', 
            array( 
                'ajaxurl' => admin_url( 'admin-ajax.php' ),
                'ajaxnonce' => wp_create_nonce( 'wpse_97845_validation' )
            ) 
    ); 
}

function update_metabox_wpse_97845()
{
    check_ajax_referer( 'wpse_97845_validation', 'ajaxnonce' );

    if( empty( $_POST['wpse_97845_blog_id'] ) || empty( $_POST['wpse_97845_post_id'] ) ) {
        wp_send_json_error( array(
            'error' => __( 'Blog ID not set' ) 
        ));
    }

    // Grac actual post data and current blog ID
    $actual_post = get_post( $_POST['wpse_97845_post_id'] );
    $original_blog_id = get_current_blog_id();

    // Prepare cloned post
    $copy_post = array(
      'post_title' => $actual_post->post_title,
      'post_content' => $actual_post->post_content,
      'post_status' => $actual_post->post_status,
      'post_type' => $actual_post->post_type
    );

    // Switch to destination blog, grab its name and insert cloned post
    switch_to_blog($_POST['wpse_97845_blog_id']);
    $blog_name = get_option( 'blogname' );
    $result = wp_insert_post($copy_post);

    // Restore current blog and return response
    switch_to_blog( $original_blog_id );
    wp_send_json_success( "Post added to $blog_name with the ID of $result" );
}

mu-copy-post.js

jQuery(document).ready(function($)
{
    /**
     * Handle error messages
     */
    function wpse_97845_handle_error( error )
    {
        $('#ajax-error').html(error).show();
    }

    /**
     * Process Ajax response
     */
    function wpse_97845_do_response( response )
    {
        // Error
        if( !response.success )
        {
            wpse_97845_handle_error( response.data.error );
            return;
        }

        // Display success response
        $('#ajax-success').html(response.data).show();
    }

    /**
     * Ajax button call
     */
    $('#publish-to-other-blog').click( function(event)
    {
        // Block button default
        event.preventDefault();

        // Clear previous messages
        $('#ajax-success').hide();
        $('#ajax-error').hide();

        // Grab info
        blog_id = $('#other-blog-id').val();
        post_id = $('#publish-to-other-blog').attr('name');

        // Prepare data
        var data = {
            action: 'update_metabox_wpse_97845',
            ajaxnonce: wp_ajax.ajaxnonce,
            wpse_97845_blog_id: blog_id,
            wpse_97845_post_id: post_id
        };

        // Send Ajax request
        $.post( wp_ajax.ajaxurl, data, wpse_97845_do_response );
    }); 
});
2
  • Actually I need to Copy one blog content into another blog in multisite environment. So when some one click on custom submit button which is 'copy', whole content of current post will be copied into selected blogs in our plugin.
    – Xing Lee
    Commented May 1, 2013 at 7:12
  • @Sumit, I played with the idea and updated the Answer with a working example.
    – brasofilo
    Commented May 1, 2013 at 13:44

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.