/** * Edit a post for any registered post type. * * The $data parameter only needs to contain fields that should be changed. * All other fields will retain their existing values. * * @since 3.4.0 * @internal 'data' is used here rather than 'content', as get_default_post_to_edit uses $_REQUEST['content'] * * @param int $id Post ID to edit * @param array $data Data construct, see {@see WP_JSON_Posts::create_post} * @param array $_headers Header data * @return true on success */ public function edit_post($id, $data, $_headers = array()) { $id = (int) $id; $post = get_post($id, ARRAY_A); if (empty($id) || empty($post['ID'])) { return new WP_Error('json_post_invalid_id', __('Invalid post ID.'), array('status' => 404)); } if (isset($_headers['IF_UNMODIFIED_SINCE'])) { // As mandated by RFC2616, we have to check all of RFC1123, RFC1036 // and C's asctime() format (and ignore invalid headers) $formats = array(DateTime::RFC1123, DateTime::RFC1036, 'D M j H:i:s Y'); foreach ($formats as $format) { $check = WP_JSON_DateTime::createFromFormat($format, $_headers['IF_UNMODIFIED_SINCE']); if ($check !== false) { break; } } // If the post has been modified since the date provided, return an error. if ($check && mysql2date('U', $post['post_modified_gmt']) > $check->format('U')) { return new WP_Error('json_old_revision', __('There is a revision of this post that is more recent.'), array('status' => 412)); } } $data['ID'] = $id; $retval = $this->insert_post($data); if (is_wp_error($retval)) { return $retval; } return $this->get_post($id); }
/** * Prepares post data for return in an XML-RPC object. * * @access protected * * @param array $post The unprepared post data * @param string $context The context for the prepared post. (view|view-revision|edit|embed|single-parent) * @return array The prepared post data */ protected function prepare_post($post, $context = 'view') { // Holds the data for this post. $_post = array('ID' => (int) $post['ID']); $post_type = get_post_type_object($post['post_type']); if (!json_check_post_permission($post, 'read')) { return new WP_Error('json_user_cannot_read', __('Sorry, you cannot read this post.'), array('status' => 401)); } $previous_post = null; if (!empty($GLOBALS['post'])) { $previous_post = $GLOBALS['post']; } $post_obj = get_post($post['ID']); // Don't allow unauthenticated users to read password-protected posts if (!empty($post['post_password'])) { if (!json_check_post_permission($post, 'edit')) { return new WP_Error('json_user_cannot_read', __('Sorry, you cannot read this post.'), array('status' => 403)); } // Fake the correct cookie to fool post_password_required(). // Without this, get_the_content() will give a password form. require_once ABSPATH . 'wp-includes/class-phpass.php'; $hasher = new PasswordHash(8, true); $value = $hasher->HashPassword($post['post_password']); $_COOKIE['wp-postpass_' . COOKIEHASH] = wp_slash($value); } $GLOBALS['post'] = $post_obj; setup_postdata($post_obj); // prepare common post fields $post_fields = array('title' => get_the_title($post['ID']), 'status' => $post['post_status'], 'type' => $post['post_type'], 'author' => (int) $post['post_author'], 'content' => apply_filters('the_content', $post['post_content']), 'parent' => (int) $post['post_parent'], 'link' => get_permalink($post['ID'])); $post_fields_extended = array('slug' => $post['post_name'], 'guid' => apply_filters('get_the_guid', $post['guid']), 'excerpt' => $this->prepare_excerpt($post['post_excerpt']), 'menu_order' => (int) $post['menu_order'], 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'], 'sticky' => $post['post_type'] === 'post' && is_sticky($post['ID'])); $post_fields_raw = array('title_raw' => $post['post_title'], 'content_raw' => $post['post_content'], 'excerpt_raw' => $post['post_excerpt'], 'guid_raw' => $post['guid'], 'post_meta' => $this->handle_get_post_meta($post['ID'])); // Dates $timezone = json_get_timezone(); if ($post['post_date_gmt'] === '0000-00-00 00:00:00') { $post_fields['date'] = null; $post_fields_extended['date_tz'] = null; $post_fields_extended['date_gmt'] = null; } else { $post_date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_date'], $timezone); $post_fields['date'] = json_mysql_to_rfc3339($post['post_date']); $post_fields_extended['date_tz'] = $post_date->format('e'); $post_fields_extended['date_gmt'] = json_mysql_to_rfc3339($post['post_date_gmt']); } if ($post['post_modified_gmt'] === '0000-00-00 00:00:00') { $post_fields['modified'] = null; $post_fields_extended['modified_tz'] = null; $post_fields_extended['modified_gmt'] = null; } else { $modified_date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_modified'], $timezone); $post_fields['modified'] = json_mysql_to_rfc3339($post['post_modified']); $post_fields_extended['modified_tz'] = $modified_date->format('e'); $post_fields_extended['modified_gmt'] = json_mysql_to_rfc3339($post['post_modified_gmt']); } // Authorized fields // TODO: Send `Vary: Authorization` to clarify that the data can be // changed by the user's auth status if (json_check_post_permission($post, 'edit')) { $post_fields_extended['password'] = $post['post_password']; } // Consider future posts as published if ($post_fields['status'] === 'future') { $post_fields['status'] = 'publish'; } // Fill in blank post format $post_fields['format'] = get_post_format($post['ID']); if (empty($post_fields['format'])) { $post_fields['format'] = 'standard'; } if (0 === $post['post_parent']) { $post_fields['parent'] = null; } if (('view' === $context || 'view-revision' == $context) && 0 !== $post['post_parent']) { // Avoid nesting too deeply // This gives post + post-extended + meta for the main post, // post + meta for the parent and just meta for the grandparent $parent = get_post($post['post_parent'], ARRAY_A); $post_fields['parent'] = $this->prepare_post($parent, 'embed'); } // Merge requested $post_fields fields into $_post $_post = array_merge($_post, $post_fields); // Include extended fields. We might come back to this. $_post = array_merge($_post, $post_fields_extended); if ('edit' === $context) { if (json_check_post_permission($post, 'edit')) { $_post = array_merge($_post, $post_fields_raw); } else { $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } return new WP_Error('json_cannot_edit', __('Sorry, you cannot edit this post'), array('status' => 403)); } } elseif ('view-revision' == $context) { if (json_check_post_permission($post, 'edit')) { $_post = array_merge($_post, $post_fields_raw); } else { $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } return new WP_Error('json_cannot_view', __('Sorry, you cannot view this revision'), array('status' => 403)); } } // Entity meta $links = array('self' => json_url('/posts/' . $post['ID']), 'author' => json_url('/users/' . $post['post_author']), 'collection' => json_url('/posts')); if ('view-revision' != $context) { $links['replies'] = json_url('/posts/' . $post['ID'] . '/comments'); $links['version-history'] = json_url('/posts/' . $post['ID'] . '/revisions'); } $_post['meta'] = array('links' => $links); if (!empty($post['post_parent'])) { $_post['meta']['links']['up'] = json_url('/posts/' . (int) $post['post_parent']); } $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } return apply_filters('json_prepare_post', $_post, $post, $context); }
/** * Prepares comment data for returning as a JSON response. * * @param stdClass $comment Comment object * @param array $requested_fields Fields to retrieve from the comment * @param string $context Where is the comment being loaded? * @return array Comment data for JSON serialization */ protected function prepare_comment($comment, $requested_fields = array('comment', 'meta'), $context = 'single') { $fields = array('ID' => (int) $comment->comment_ID, 'post' => (int) $comment->comment_post_ID); $post = (array) get_post($fields['post']); // Content $fields['content'] = apply_filters('comment_text', $comment->comment_content, $comment); // $fields['content_raw'] = $comment->comment_content; // Status switch ($comment->comment_approved) { case 'hold': case '0': $fields['status'] = 'hold'; break; case 'approve': case '1': $fields['status'] = 'approved'; break; case 'spam': case 'trash': default: $fields['status'] = $comment->comment_approved; break; } // Type $fields['type'] = apply_filters('get_comment_type', $comment->comment_type); if (empty($fields['type'])) { $fields['type'] = 'comment'; } // Post if ('single' === $context) { $parent = get_post($post['post_parent'], ARRAY_A); $fields['parent'] = $this->prepare_post($parent, 'single-parent'); } // Parent if (('single' === $context || 'single-parent' === $context) && (int) $comment->comment_parent) { $parent_fields = array('meta'); if ($context === 'single') { $parent_fields[] = 'comment'; } $parent = get_comment($post['post_parent']); $fields['parent'] = $this->prepare_comment($parent, $parent_fields, 'single-parent'); } // Parent $fields['parent'] = (int) $comment->comment_parent; // Author if ((int) $comment->user_id !== 0) { $fields['author'] = (int) $comment->user_id; } else { $fields['author'] = array('ID' => 0, 'name' => $comment->comment_author, 'URL' => $comment->comment_author_url, 'avatar' => json_get_avatar_url($comment->comment_author_email)); } // Date $timezone = json_get_timezone(); $date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $comment->comment_date, $timezone); $fields['date'] = $date->format('c'); $fields['date_tz'] = $date->format('e'); $fields['date_gmt'] = date('c', strtotime($comment->comment_date_gmt)); // Meta $meta = array('links' => array('up' => json_url(sprintf('/posts/%d', (int) $comment->comment_post_ID)))); if (0 !== (int) $comment->comment_parent) { $meta['links']['in-reply-to'] = json_url(sprintf('/posts/%d/comments/%d', (int) $comment->comment_post_ID, (int) $comment->comment_parent)); } if ('single' !== $context) { $meta['links']['self'] = json_url(sprintf('/posts/%d/comments/%d', (int) $comment->comment_post_ID, (int) $comment->comment_ID)); } // Remove unneeded fields $data = array(); if (in_array('comment', $requested_fields)) { $data = array_merge($data, $fields); } if (in_array('meta', $requested_fields)) { $data['meta'] = $meta; } return apply_filters('json_prepare_comment', $data, $comment, $context); }
/** * Prepares post data for return in an XML-RPC object. * * @access protected * * @param array $post The unprepared post data * @param string $context The context for the prepared post. (view|view-revision|edit|embed|single-parent) * @return array The prepared post data */ protected function prepare_post($post, $context = 'view', $show_type = 'row') { // Holds the data for this post. $_post = array('ID' => (int) $post['ID']); $post_type = get_post_type_object($post['post_type']); if (!json_check_post_permission($post, 'read')) { return false; } $previous_post = null; if (!empty($GLOBALS['post'])) { $previous_post = $GLOBALS['post']; } $post_obj = get_post($post['ID']); // Don't allow unauthenticated users to read password-protected posts if (!empty($post['post_password'])) { if (!json_check_post_permission($post, 'edit')) { return false; } // Fake the correct cookie to fool post_password_required(). // Without this, get_the_content() will give a password form. require_once ABSPATH . 'wp-includes/class-phpass.php'; $hasher = new PasswordHash(8, true); $value = $hasher->HashPassword($post['post_password']); $_COOKIE['wp-postpass_' . COOKIEHASH] = wp_slash($value); } $GLOBALS['post'] = $post_obj; setup_postdata($post_obj); //comment num $comment_num = $this->comments->get_comments_num_by_post_id($_post['ID']); // prepare common post fields $post_content = ''; if ($show_type == 'row') { $post_content = $post['post_content']; } $post_fields = array('title' => get_the_title($post['ID']), 'status' => $post['post_status'], 'type' => $post['post_type'], 'author' => (int) $post['post_author'], 'content' => apply_filters('the_content', $post_content), 'parent' => (int) $post['post_parent'], 'link' => get_json_url_posts_list($post['ID'])); $post_fields_extended = array('excerpt' => $this->prepare_excerpt($post['post_excerpt']), 'comment_status' => $post['comment_status'], 'comment_num' => (int) $comment_num); $post_fields_raw = array(); if ($show_type == 'row') { $post_fields_raw = array('title_raw' => $post['post_title'], 'content_raw' => $post['post_content'], 'excerpt_raw' => $post['post_excerpt'], 'guid_raw' => $post['guid']); } // Dates $timezone = json_get_timezone(); if ($post['post_date_gmt'] === '0000-00-00 00:00:00') { $post_fields['date'] = null; $post_fields_extended['date_tz'] = null; $post_fields_extended['date_gmt'] = null; } else { $post_date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_date'], $timezone); $post_fields['date'] = json_mysql_to_rfc3339($post['post_date']); $post_fields_extended['date_tz'] = $post_date->format('e'); $post_fields_extended['date_gmt'] = json_mysql_to_rfc3339($post['post_date_gmt']); } if ($post['post_modified_gmt'] === '0000-00-00 00:00:00') { $post_fields['modified'] = null; $post_fields_extended['modified_tz'] = null; $post_fields_extended['modified_gmt'] = null; } else { $modified_date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_modified'], $timezone); $post_fields['modified'] = json_mysql_to_rfc3339($post['post_modified']); $post_fields_extended['modified_tz'] = $modified_date->format('e'); $post_fields_extended['modified_gmt'] = json_mysql_to_rfc3339($post['post_modified_gmt']); } // Authorized fields // TODO: Send `Vary: Authorization` to clarify that the data can be // changed by the user's auth status if (json_check_post_permission($post, 'edit')) { $post_fields_extended['password'] = $post['post_password']; } // Consider future posts as published if ($post_fields['status'] === 'future') { $post_fields['status'] = 'publish'; } // Fill in blank post format $post_fields['format'] = get_post_format($post['ID']); if (empty($post_fields['format'])) { $post_fields['format'] = 'standard'; } if (0 === $post['post_parent']) { $post_fields['parent'] = null; } if (('view' === $context || 'view-revision' == $context) && 0 !== $post['post_parent']) { // Avoid nesting too deeply // This gives post + post-extended + meta for the main post, // post + meta for the parent and just meta for the grandparent $parent = get_post($post['post_parent'], ARRAY_A); $post_fields['parent'] = $this->prepare_post($parent, 'embed'); } // Merge requested $post_fields fields into $_post $_post = array_merge($_post, $post_fields); // Include extended fields. We might come back to this. $_post = array_merge($_post, $post_fields_extended); if ('edit' === $context) { if (json_check_post_permission($post, 'edit')) { $_post = array_merge($_post, $post_fields_raw); } else { $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } json_error(BigAppErr::$post['code'], "post id is not valid", $id); } } elseif ('view-revision' == $context) { if (json_check_post_permission($post, 'edit')) { $_post = array_merge($_post, $post_fields_raw); } else { $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } return false; } } // Entity meta $links = array('self' => get_json_url_posts_list($post['ID']), 'author' => get_json_url_users_get_user($post['post_author']), 'collection' => get_json_url_posts_list()); if ('view-revision' != $context) { $links['replies'] = get_json_url_comments_get_comments($post['ID']); $links['version-history'] = get_json_url_post_get_revisions($post['ID']); } #$_post['meta'] = array( 'links' => $links ); if (!empty($post['post_parent'])) { $_post['meta']['links']['up'] = get_json_url_posts_list((int) $post['post_parent']); } $GLOBALS['post'] = $previous_post; if ($previous_post) { setup_postdata($previous_post); } //控制发表评论状态 if ($_post['comment_status'] == 'closed') { $comment_type = 0; } else { $comment_type = bigapp_core::check_comment_status(); if ($comment_type == 0 && $_post['comment_status'] == 'open') { $comment_type = 1; } } $_post['comment_type'] = $comment_type; //浏览量次数 $post_views = new WP_JSON_PostViews($this->server); $_post['views'] = $post_views->get_views_by_id($post['ID']); return apply_filters('json_prepare_post', $_post, $post, $context); }
/** * Parse an RFC3339 timestamp into a DateTime * * @param string $date RFC3339 timestamp * @param boolean $force_utc Force UTC timezone instead of using the timestamp's TZ? * @return DateTime */ function json_parse_date($date, $force_utc = false) { // Default timezone to the server's current one $timezone = json_get_timezone(); if ($force_utc) { $date = preg_replace('/[+-]\\d+:?\\d+$/', '+00:00', $date); $timezone = new DateTimeZone('UTC'); } // Strip millisecond precision (a full stop followed by one or more digits) if (strpos($date, '.') !== false) { $date = preg_replace('/\\.\\d+/', '', $date); } $datetime = WP_JSON_DateTime::createFromFormat(DateTime::RFC3339, $date, $timezone); return $datetime; }
protected function check_get_post_response($response, $post_obj, $context = 'view') { $response = json_ensure_response($response); $response_data = $response->get_data(); $this->assertEquals($post_obj->ID, $response_data['ID']); $this->assertEquals($post_obj->post_name, $response_data['slug']); $this->assertEquals($post_obj->post_status, $response_data['status']); $this->assertEquals($post_obj->post_author, $response_data['author']); $this->assertArrayHasKey('parent', $response_data); $this->assertEquals(get_permalink($post_obj->ID), $response_data['link']); $this->assertEquals($post_obj->menu_order, $response_data['menu_order']); $this->assertEquals($post_obj->comment_status, $response_data['comment_status']); $this->assertEquals($post_obj->ping_status, $response_data['ping_status']); $this->assertEquals($post_obj->post_password, $response_data['password']); $this->assertEquals(is_sticky($post_obj->ID), $response_data['sticky']); // Check post parent. if ($post_obj->post_parent) { if (is_int($response_data['parent'])) { $this->assertEquals($post_obj->post_parent, $response_data['parent']); } else { $this->assertEquals($post_obj->post_parent, $response_data['parent']['ID']); $this->check_get_post_response($response_data['parent'], get_post($response_data['parent']['ID']), 'view-parent'); } } else { $this->assertEmpty($response_data['parent']); } // Check post format. $post_format = get_post_format($post_obj->ID); if (empty($post_format)) { $this->assertEquals('standard', $response_data['format']); } else { $this->assertEquals(get_post_format($post_obj->ID), $response_data['format']); } // Check post dates. $timezone = json_get_timezone(); if ($post_obj->post_date_gmt === '0000-00-00 00:00:00') { $this->assertNull($response_data['date']); $this->assertNull($response_data['date_gmt']); } else { $post_date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post_obj->post_date, $timezone); $post_date_gmt = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post_obj->post_date_gmt); $this->assertEquals($post_date->format('c'), $response_data['date']); $this->assertEquals($post_date_gmt->format('c'), $response_data['date_gmt']); } if ($post_obj->post_modified_gmt === '0000-00-00 00:00:00') { $this->assertNull($response_data['modified']); $this->assertNull($response_data['modified_gmt']); } else { $post_modified = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post_obj->post_modified, $timezone); $post_modified_gmt = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post_obj->post_modified_gmt); $this->assertEquals($post_modified_gmt->format('c'), $response_data['modified_gmt']); $this->assertEquals($post_modified->format('c'), $response_data['modified']); } // Check filtered values. $this->assertEquals(get_the_title($post_obj->ID), $response_data['title']); // TODO: apply content filter for more accurate testing. $this->assertEquals(wpautop($post_obj->post_content), $response_data['content']); // TODO: apply excerpt filter for more accurate testing. $this->assertEquals(wpautop($post_obj->post_excerpt), $response_data['excerpt']); $this->assertEquals($post_obj->guid, $response_data['guid']); if ($context === 'edit') { $this->assertEquals($post_obj->post_content, $response_data['content_raw']); $this->assertEquals($post_obj->post_excerpt, $response_data['excerpt_raw']); } }
protected function prepare_post($post, $context = 'view') { // holds the data for this post. built up based on $fields $_post = array('ID' => (int) $post['ID']); $post_type = get_post_type_object($post['post_type']); //if ( ! $this->check_read_permission( $post ) ) //return new WP_Error( 'json_user_cannot_read', __( 'Sorry, you cannot read this post.' ), array( 'status' => 401 ) ); // prepare common post fields $post_fields = array('title' => get_the_title($post['ID']), 'status' => $post['post_status'], 'type' => $post['post_type'], 'author' => (int) $post['post_author'], 'content' => apply_filters('the_content', $post['post_content']), 'parent' => (int) $post['post_parent'], 'link' => get_permalink($post['ID'])); $post_fields_extended = array('slug' => $post['post_name'], 'guid' => apply_filters('get_the_guid', $post['guid']), 'excerpt' => $this->prepare_excerpt($post['post_excerpt']), 'menu_order' => (int) $post['menu_order'], 'comment_status' => $post['comment_status'], 'ping_status' => $post['ping_status'], 'sticky' => $post['post_type'] === 'post' && is_sticky($post['ID'])); $post_fields_raw = array('title_raw' => $post['post_title'], 'content_raw' => $post['post_content'], 'guid_raw' => $post['guid'], 'post_meta' => $this->get_all_meta($post['ID'])); // Dates $timezone = $this->server->get_timezone(); $date = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_date'], $timezone); $post_fields['date'] = $date->format('c'); $post_fields_extended['date_tz'] = $date->format('e'); $post_fields_extended['date_gmt'] = date('c', strtotime($post['post_date_gmt'])); $modified = WP_JSON_DateTime::createFromFormat('Y-m-d H:i:s', $post['post_modified'], $timezone); $post_fields['modified'] = $modified->format('c'); $post_fields_extended['modified_tz'] = $modified->format('e'); $post_fields_extended['modified_gmt'] = date('c', strtotime($post['post_modified_gmt'])); // Authorized fields // TODO: Send `Vary: Authorization` to clarify that the data can be // changed by the user's auth status //if ( current_user_can( $post_type->cap->edit_post, $post['ID'] ) ) { // $post_fields_extended['password'] = $post['post_password']; //} // Consider future posts as published if ($post_fields['status'] === 'future') { $post_fields['status'] = 'publish'; } // Fill in blank post format $post_fields['format'] = get_post_format($post['ID']); if (empty($post_fields['format'])) { $post_fields['format'] = 'standard'; } if (('view' === $context || 'view-revision' == $context) && 0 !== $post['post_parent']) { // Avoid nesting too deeply // This gives post + post-extended + meta for the main post, // post + meta for the parent and just meta for the grandparent $parent = get_post($post['post_parent'], ARRAY_A); $post_fields['parent'] = $this->prepare_post($parent, 'embed'); } // Merge requested $post_fields fields into $_post $_post = array_merge($_post, $post_fields); // Include extended fields. We might come back to this. $_post = array_merge($_post, $post_fields_extended); if ('edit' === $context) { //if ( current_user_can( $post_type->cap->edit_post, $post['ID'] ) ) { if (is_wp_error($post_fields_raw['post_meta'])) { return $post_fields_raw['post_meta']; } $_post = array_merge($_post, $post_fields_raw); //} else { // return new WP_Error( 'json_cannot_edit', __( 'Sorry, you cannot edit this post' ), array( 'status' => 403 ) ); //} } elseif ('view-revision' == $context) { //if ( current_user_can( $post_type->cap->edit_post, $post['ID'] ) ) { $_post = array_merge($_post, $post_fields_raw); //} else { // return new WP_Error( 'json_cannot_view', __( 'Sorry, you cannot view this revision' ), array( 'status' => 403 ) ); //} } // Entity meta $links = array('self' => json_url('/posts/' . $post['ID']), 'author' => json_url('/users/' . $post['post_author']), 'collection' => json_url('/posts')); if ('view-revision' != $context) { $links['replies'] = json_url('/posts/' . $post['ID'] . '/comments'); $links['version-history'] = json_url('/posts/' . $post['ID'] . '/revisions'); } $_post['meta'] = array('links' => $links); if (!empty($post['post_parent'])) { $_post['meta']['links']['up'] = json_url('/posts/' . (int) $post['post_parent']); } return apply_filters('json_prepare_post', $_post, $post, $context); }