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( "https://wordpress.stackexchange.com/", __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.
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( "https://wordpress.stackexchange.com/", __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 );
});
});