Last active
January 31, 2026 14:26
-
-
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."
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?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 ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@brandonjp You saved my day, thankyou!