So I finally decided to tackle this one today. Here is my solution:
Looks like when hitting ‘update’ on the edit media attachment page ‘wp_insert_post’ does not fire. So the ‘save_postdata’ method in the class WPSEO_Metabox (located in wordpress-seo\admin\class-metabox.php) never gets executed.
What I have done is added a new function that is a copy of the ‘save_postdata’ and I named it ‘save_attachmentpostdata’.
I then added the filter ‘attachment_fields_to_save’ to execute it.
The only issue is that this filter catches a lot more than just the post id so we needed to change the receiving argument to ‘stuff’ and extract the post id.
The code:
add_filter('attachment_fields_to_save', array( $this, 'save_attachmentpostdata' ) );
added to the __construct function
/**
* Save the WP SEO metadata for attachment posts.
*
* @param array $stuff
* @return mixed
*/
function save_attachmentpostdata( $stuff ) {
$post_id = $stuff['post_ID'];
if ( $post_id == null )
return false;
if ( wp_is_post_revision( $post_id ) )
$post_id = wp_is_post_revision( $post_id );
clean_post_cache( $post_id );
$post = get_post( $post_id );
$metaboxes = array_merge( $this->get_meta_boxes( $post->post_type ), $this->get_advanced_meta_boxes() );
$metaboxes = apply_filters( 'wpseo_save_metaboxes', $metaboxes );
foreach ( $metaboxes as $meta_box ) {
if ( !isset( $meta_box['name'] ) )
continue;
if ( 'checkbox' == $meta_box['type'] ) {
if ( isset( $_POST['yoast_wpseo_' . $meta_box['name']] ) )
$data = 'on';
else
$data = 'off';
} else if ( 'multiselect' == $meta_box['type'] ) {
if ( isset( $_POST['yoast_wpseo_' . $meta_box['name']] ) ) {
if ( is_array( $_POST['yoast_wpseo_' . $meta_box['name']] ) )
$data = implode( ",", $_POST['yoast_wpseo_' . $meta_box['name']] );
else
$data = $_POST['yoast_wpseo_' . $meta_box['name']];
} else {
continue;
}
} else {
if ( isset( $_POST['yoast_wpseo_' . $meta_box['name']] ) )
$data = $_POST['yoast_wpseo_' . $meta_box['name']];
else
continue;
}
wpseo_set_value( $meta_box['name'], sanitize_text_field( $data ), $post_id );
}
$this->calculate_results( $post );
do_action( 'wpseo_saved_postdata' );
}
added after function save_postdata
This is obviously altering the plugin’s core files and so generally I am opposed to doing that but maybe Yoast will implement something similar as a change?
Any thoughts anyone?