diff --git a/includes/filters-wp_rest_workarounds.php b/includes/filters-wp_rest_workarounds.php new file mode 100644 index 00000000..cde9d1ff --- /dev/null +++ b/includes/filters-wp_rest_workarounds.php @@ -0,0 +1,146 @@ +getPostID())) { + return $wp_sitecaps; + } + + $type_obj = get_post_type_object($_post->post_type); + $status_obj = get_post_status_object($_post->post_status); + + if ($type_obj && !empty($type_obj->cap) + && !empty($type_obj->cap->publish_posts) && !empty($type_obj->cap->edit_published_posts) + && $type_obj->cap->publish_posts == $reqd_cap + && $status_obj && (!empty($status_obj->public) || 'future' == $_post->post_status) + ) { + if (!empty($wp_sitecaps[$type_obj->cap->edit_published_posts])) { + $wp_sitecaps[$reqd_cap] = true; + } + } + } + } + + return $wp_sitecaps; + } + + /** + * If the post is already published, prevent the workaround from allowing status to be changed via "Switch to Draft" (or by any other means). + * + * This will also prevent users with edit_published capability but not publish capability from unpublishing via Quick Edit. + * + * @param string $post_status New post status about to be saved + */ + function fltPostStatus($post_status) { + global $current_user; + + if ($_post = get_post($this->getPostID())) { + $type_obj = get_post_type_object($_post->post_type); + $status_obj = get_post_status_object($_post->post_status); + + if ($type_obj && $status_obj && (!empty($status_obj->public) || !empty($status_obj->private) || 'future' == $_post->post_status)) { + if (empty($current_user->allcaps[$type_obj->cap->publish_posts])) { + $post_status = $_post->post_status; + } + } + } + + return $post_status; + } + + private function getPostID() + { + global $post; + + if (defined('REST_REQUEST') && REST_REQUEST && $this->is_posts_request) { + return $this->post_id; + } + + if (!empty($post) && is_object($post)) { + return ('auto-draft' == $post->post_status) ? 0 : $post->ID; + } elseif (isset($_REQUEST['post'])) { + return (int)$_REQUEST['post']; + } elseif (isset($_REQUEST['post_ID'])) { + return (int)$_REQUEST['post_ID']; + } elseif (isset($_REQUEST['post_id'])) { + return (int)$_REQUEST['post_id']; + } + } + + public function fltRestPreDispatch($rest_response, $rest_server, $request) + { + $method = $request->get_method(); + $path = $request->get_route(); + + foreach ($rest_server->get_routes() as $route => $handlers) { + if (!$match = preg_match( '@^' . $route . '$@i', $path, $matches )) { + continue; + } + + $args = []; + foreach ($matches as $param => $value) { + if (!is_int($param)) { + $args[ $param ] = $value; + } + } + + foreach ($handlers as $handler) { + if (is_array($handler['callback']) && isset($handler['callback'][0]) && is_object($handler['callback'][0]) + && 'WP_REST_Posts_Controller' == get_class($handler['callback'][0]) + ) { + if ( ! $this->post_id = (!empty($args['id'])) ? $args['id'] : 0) { + $this->post_id = (!empty($this->params['id'])) ? $this->params['id'] : 0; + } + + $this->is_posts_request = true; + break 2; + } + } + } + + return $rest_response; + } +} diff --git a/includes/filters.php b/includes/filters.php index dc6e1042..c9401cdb 100644 --- a/includes/filters.php +++ b/includes/filters.php @@ -26,6 +26,11 @@ function add( $object ) { $cme_extensions->add( new CME_WooCommerce() ); } +if (!defined('CME_DISABLE_WP_EDIT_PUBLISHED_WORKAROUND')) { + require_once (dirname(__FILE__) . '/filters-wp_rest_workarounds.php'); + new PublishPress\Capabilities\WP_REST_Workarounds(); +} + if ( is_admin() ) { global $pagenow; if ( 'edit.php' == $pagenow ) {