Skip to content

Instantly share code, notes, and snippets.

@brandonjp
Last active January 31, 2026 14:26
Show Gist options
  • Select an option

  • Save brandonjp/bf8a2ef3cab014b5ae3dba3e510bca2d to your computer and use it in GitHub Desktop.

Select an option

Save brandonjp/bf8a2ef3cab014b5ae3dba3e510bca2d to your computer and use it in GitHub Desktop.
Allow non-Author to edit & save a published wordpress post. This works around issues with `_wp_translate_postdata` & `user_has_cap` - Fixes "Sorry, you are not allowed to edit posts as this user."
<?php
/*
*
* ALLOW USER TO EDIT POST IF THEY ARE SELECTED AS THE PM
* Preferred way would be to use `user_has_cap` - see:
* - https://wordpress.stackexchange.com/a/360990/5380
* - https://developer.wordpress.org/reference/hooks/user_has_cap/
* However, WordPress has a nasty long standing issue with this line:
* - https://bit.ly/3I72jOn
* Where it forces a check to make sure the author is current user, which prevents any efforts to customize capabilities by using a `user_has_cap` filter. The bug is documented here:
* - https://core.trac.wordpress.org/ticket/30452
* - https://wordpress.stackexchange.com/a/186280/5380
* So instead we're getting very hacky and maniuplating how WP checks capabilites:
* - https://core.trac.wordpress.org/ticket/30452#comment:3
* By modifiying code from @danielbachhuber:
* - https://gist.github.com/danielbachhuber/18850d571c5dce419f8b
* Which he created for his plugin, Co-Authors Plus (which might be the better option than the code below)
* - https://wordpress.org/plugins/co-authors-plus/
*
*/
function filter_map_meta_cap_allow_nonauthor_to_save_post( $caps, $cap, $user_id, $args ) {
// Adapted from @danielbachhuber : https://gist.github.com/danielbachhuber/18850d571c5dce419f8b
// To solve issue with `_wp_translate_postdata` : https://core.trac.wordpress.org/ticket/30452#comment:4
global $pagenow;
switch ( $cap ) {
case 'edit_post':
case 'edit_others_posts':
$post_obj = false;
if ( 'edit_post' === $cap ) {
$post_obj = get_post( (int) $args[0] );
/* Allow original authors to 'edit_others_posts' when updating
* Addresses core bug in _wp_translate_postdata()
*
* @see https://core.trac.wordpress.org/ticket/30452
*/
} else if ( 'edit_others_posts' === $cap
&& 'post.php' === $pagenow
&& ! empty( $_POST['post_ID'] ) ) {
$post_obj = get_post( (int) $_POST['post_ID'] );
}
if ( ! $post_obj ) {
break;
}
$post_type = get_post_type($post_obj);
$post_author = $post_obj->post_author;
$post_ID = $post_obj->ID;
// Allow user to edit the post based on custom meta
if ( 'custom-job' == $post_type ) {
// My custom meta is saved on a MetaBox.io custom taxonomy field
// you'll want to replace all the code below to check if your user should have access
// retrieve the term object from the job/post
$jobsTable = ['storage_type' => 'custom_table', 'table' => 'custom_jobs'];
$pm_term_obj = rwmb_get_value('job_pm_taxonomy', $jobsTable, $post_ID);
$pm_term_id = $pm_term_obj->term_id;
// retrieve the user id from the related term meta
$pm_user_id = get_term_meta( $pm_term_id, 'pm_related_user', true );
// check if the pm user account id matches the current logged in user id
$currentUserID = wp_get_current_user()->ID;
if ($pm_user_id == $currentUserID) {
// Don't require editing others' posts
if ( false !== ( $key = array_search( 'edit_others_posts', $caps ) ) ) {
unset( $caps[ $key ] );
}
// If the post is published...
if ( 'publish' == get_post_status($post_obj)) {
$caps[] = 'edit_published_posts';
} elseif ( 'trash' == get_post_status($post_obj)) {
if ( 'publish' == get_post_meta( $post_ID, '_wp_trash_meta_status', true ) ) {
$caps[] = 'edit_published_posts';
}
} else {
// If the post is draft...
$caps[] = 'edit_posts';
}
}
break;
}
}
return $caps;
}
add_filter( 'map_meta_cap', 'filter_map_meta_cap_allow_nonauthor_to_save_post', 10, 4 );
@majick777
Copy link
Copy Markdown

@brandonjp You saved my day, thankyou!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment