/** * Validate current user can access the post * * @return WP_Error or post */ private function validate_access($post) { $context = $post->context; if (!$this->is_post_type_allowed($post->post_type) && (!function_exists('is_post_freshly_pressed') || !is_post_freshly_pressed($post->ID))) { return new WP_Error('unknown_post', 'Unknown post', 404); } switch ($context) { case 'edit': if (!current_user_can('edit_post', $post)) { return new WP_Error('unauthorized', 'User cannot edit post', 403); } break; case 'display': $can_view = $this->user_can_view_post($post); if (is_wp_error($can_view)) { return $can_view; } break; default: return new WP_Error('invalid_context', 'Invalid API CONTEXT', 400); } return $post; }
/** * Get a post by a specified field and value * * @param string $field * @param string $field_value * @param string $context Post use context (e.g. 'display') * @return array Post **/ function get_post_by($field, $field_value, $context = 'display') { global $blog_id; /** This filter is documented in class.json-api-endpoints.php */ $is_jetpack = true === apply_filters('is_jetpack_site', false, $blog_id); if (defined('GEO_LOCATION__CLASS') && class_exists(GEO_LOCATION__CLASS)) { $geo = call_user_func(array(GEO_LOCATION__CLASS, 'init')); } else { $geo = false; } if ('display' === $context) { $args = $this->query_args(); if (isset($args['content_width']) && $args['content_width']) { $GLOBALS['content_width'] = (int) $args['content_width']; } } if (strpos($_SERVER['HTTP_USER_AGENT'], 'wp-windows8')) { remove_shortcode('gallery', 'gallery_shortcode'); add_shortcode('gallery', array(&$this, 'win8_gallery_shortcode')); } switch ($field) { case 'name': $post_id = $this->get_post_id_by_name($field_value); if (is_wp_error($post_id)) { return $post_id; } break; default: $post_id = (int) $field_value; break; } $post = get_post($post_id, OBJECT, $context); if (!$post || is_wp_error($post)) { return new WP_Error('unknown_post', 'Unknown post', 404); } if (!$this->is_post_type_allowed($post->post_type) && (!function_exists('is_post_freshly_pressed') || !is_post_freshly_pressed($post->ID))) { return new WP_Error('unknown_post', 'Unknown post', 404); } // Permissions $capabilities = $this->get_current_user_capabilities($post); switch ($context) { case 'edit': if (!$capabilities['edit_post']) { return new WP_Error('unauthorized', 'User cannot edit post', 403); } break; case 'display': break; default: return new WP_Error('invalid_context', 'Invalid API CONTEXT', 400); } $can_view = $this->user_can_view_post($post->ID); if (!$can_view || is_wp_error($can_view)) { return $can_view; } $GLOBALS['post'] = $post; if ('display' === $context) { setup_postdata($post); } $response = array(); foreach (array_keys($this->post_object_format) as $key) { switch ($key) { case 'ID': // explicitly cast all output $response[$key] = (int) $post->ID; break; case 'site_ID': $response[$key] = (int) $this->api->get_blog_id_for_output(); break; case 'author': $response[$key] = (object) $this->get_author($post, 'edit' === $context && $capabilities['edit_post']); break; case 'date': $response[$key] = (string) $this->format_date($post->post_date_gmt, $post->post_date); break; case 'modified': $response[$key] = (string) $this->format_date($post->post_modified_gmt, $post->post_modified); break; case 'title': if ('display' === $context) { $response[$key] = (string) get_the_title($post->ID); } else { $response[$key] = (string) htmlspecialchars_decode($post->post_title, ENT_QUOTES); } break; case 'URL': if ('revision' === $post->post_type) { $response[$key] = (string) esc_url_raw(get_permalink($post->post_parent)); } else { $response[$key] = (string) esc_url_raw(get_permalink($post->ID)); } break; case 'short_URL': $response[$key] = (string) esc_url_raw(wp_get_shortlink($post->ID)); break; case 'content': if ('display' === $context) { add_filter('the_password_form', array($this, 'the_password_form')); $response[$key] = (string) $this->get_the_post_content_for_display(); remove_filter('the_password_form', array($this, 'the_password_form')); } else { $response[$key] = (string) $post->post_content; } break; case 'excerpt': if ('display' === $context) { add_filter('the_password_form', array($this, 'the_password_form')); ob_start(); the_excerpt(); $response[$key] = (string) ob_get_clean(); remove_filter('the_password_form', array($this, 'the_password_form')); } else { $response[$key] = htmlspecialchars_decode((string) $post->post_excerpt, ENT_QUOTES); } break; case 'status': $response[$key] = (string) get_post_status($post->ID); break; case 'sticky': $response[$key] = (bool) is_sticky($post->ID); break; case 'slug': $response[$key] = (string) $post->post_name; break; case 'guid': $response[$key] = (string) $post->guid; break; case 'password': $response[$key] = (string) $post->post_password; if ('edit' === $context) { $response[$key] = htmlspecialchars_decode((string) $response[$key], ENT_QUOTES); } break; case 'parent': // (object|false) if ($post->post_parent) { $parent = get_post($post->post_parent); if ('display' === $context) { $parent_title = (string) get_the_title($parent->ID); } else { $parent_title = (string) htmlspecialchars_decode($post->post_title, ENT_QUOTES); } $response[$key] = (object) array('ID' => (int) $parent->ID, 'type' => (string) $parent->post_type, 'link' => (string) $this->get_post_link($this->api->get_blog_id_for_output(), $parent->ID), 'title' => $parent_title); } else { $response[$key] = false; } break; case 'type': $response[$key] = (string) $post->post_type; break; case 'discussion': $response[$key] = array('comments_open' => (bool) comments_open($post->ID), 'comment_status' => (string) $post->comment_status, 'pings_open' => (bool) pings_open($post->ID), 'ping_status' => (string) $post->ping_status, 'comment_count' => (int) $post->comment_count); break; case 'likes_enabled': /** This filter is documented in modules/likes.php */ $sitewide_likes_enabled = (bool) apply_filters('wpl_is_enabled_sitewide', !get_option('disabled_likes')); $post_likes_switched = (bool) get_post_meta($post->ID, 'switch_like_status', true); $post_likes_enabled = $sitewide_likes_enabled; if ($post_likes_switched) { $post_likes_enabled = !$post_likes_enabled; } $response[$key] = (bool) $post_likes_enabled; break; case 'sharing_enabled': $show = true; /** This filter is documented in modules/sharedaddy/sharing-service.php */ $show = apply_filters('sharing_show', $show, $post); $switched_status = get_post_meta($post->ID, 'sharing_disabled', false); if (!empty($switched_status)) { $show = false; } $response[$key] = (bool) $show; break; case 'like_count': $response[$key] = (int) $this->api->post_like_count($blog_id, $post->ID); break; case 'i_like': $response[$key] = (int) $this->api->is_liked($blog_id, $post->ID); break; case 'is_reblogged': $response[$key] = (int) $this->api->is_reblogged($blog_id, $post->ID); break; case 'is_following': $response[$key] = (int) $this->api->is_following($blog_id); break; case 'global_ID': $response[$key] = (string) $this->api->add_global_ID($blog_id, $post->ID); break; case 'featured_image': if ($is_jetpack && (defined('IS_WPCOM') && IS_WPCOM)) { $response[$key] = get_post_meta($post->ID, '_jetpack_featured_image', true); } else { $image_attributes = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full'); if (is_array($image_attributes) && isset($image_attributes[0])) { $response[$key] = (string) $image_attributes[0]; } else { $response[$key] = ''; } } break; case 'post_thumbnail': $response[$key] = null; $thumb_id = get_post_thumbnail_id($post->ID); if (!empty($thumb_id)) { $attachment = get_post($thumb_id); if (!empty($attachment)) { $featured_image_object = $this->get_attachment($attachment); } if (!empty($featured_image_object)) { $response[$key] = (object) $featured_image_object; } } break; case 'format': $response[$key] = (string) get_post_format($post->ID); if (!$response[$key]) { $response[$key] = 'standard'; } break; case 'geo': // (object|false) if (!$geo) { $response[$key] = false; } else { $geo_data = $geo->get_geo('post', $post->ID); $response[$key] = false; if ($geo_data) { $geo_data = array_intersect_key($geo_data, array('latitude' => true, 'longitude' => true, 'address' => true, 'public' => true)); if ($geo_data) { $response[$key] = (object) array('latitude' => isset($geo_data['latitude']) ? (double) $geo_data['latitude'] : 0, 'longitude' => isset($geo_data['longitude']) ? (double) $geo_data['longitude'] : 0, 'address' => isset($geo_data['address']) ? (string) $geo_data['address'] : ''); } else { $response[$key] = false; } // Private if (!isset($geo_data['public']) || !$geo_data['public']) { if ('edit' !== $context || !$capabilities['edit_post']) { // user can't access $response[$key] = false; } } } } break; case 'menu_order': $response[$key] = (int) $post->menu_order; break; case 'page_template': $response[$key] = (string) get_post_meta($post->ID, '_wp_page_template', true); break; case 'publicize_URLs': $publicize_URLs = array(); $publicize = get_post_meta($post->ID, 'publicize_results', true); if ($publicize) { foreach ($publicize as $service => $data) { switch ($service) { case 'twitter': foreach ($data as $datum) { $publicize_URLs[] = esc_url_raw("https://twitter.com/{$datum['user_id']}/status/{$datum['post_id']}"); } break; case 'fb': foreach ($data as $datum) { $publicize_URLs[] = esc_url_raw("https://www.facebook.com/permalink.php?story_fbid={$datum['post_id']}&id={$datum['user_id']}"); } break; } } } $response[$key] = (array) $publicize_URLs; break; case 'tags': $response[$key] = array(); $terms = wp_get_post_tags($post->ID); foreach ($terms as $term) { if (!empty($term->name)) { $response[$key][$term->name] = $this->format_taxonomy($term, 'post_tag', 'display'); } } $response[$key] = (object) $response[$key]; break; case 'categories': $response[$key] = array(); $terms = wp_get_object_terms($post->ID, 'category', array('fields' => 'all')); foreach ($terms as $term) { if (!empty($term->name)) { $response[$key][$term->name] = $this->format_taxonomy($term, 'category', 'display'); } } $response[$key] = (object) $response[$key]; break; case 'attachments': $response[$key] = array(); $_attachments = new WP_Query(array('post_parent' => $post->ID, 'post_status' => 'inherit', 'post_type' => 'attachment', 'posts_per_page' => '20')); foreach ($_attachments->posts as $attachment) { $response[$key][$attachment->ID] = $this->get_media_item_v1_1($attachment->ID); } $response['attachment_count'] = $_attachments->found_posts; $response[$key] = (object) $response[$key]; break; case 'metadata': // (array|false) $metadata = array(); foreach ((array) has_meta($post_id) as $meta) { // Don't expose protected fields. $show = false; if ($this->is_metadata_public($meta['meta_key'])) { $show = true; } if (current_user_can('edit_post_meta', $post_id, $meta['meta_key'])) { $show = true; } if (!$show) { continue; } $metadata[] = array('id' => $meta['meta_id'], 'key' => $meta['meta_key'], 'value' => maybe_unserialize($meta['meta_value'])); } if (!empty($metadata)) { $response[$key] = $metadata; } else { $response[$key] = false; } break; case 'meta': $response[$key] = (object) array('links' => (object) array('self' => (string) $this->get_post_link($this->api->get_blog_id_for_output(), $post->ID), 'help' => (string) $this->get_post_link($this->api->get_blog_id_for_output(), $post->ID, 'help'), 'site' => (string) $this->get_site_link($this->api->get_blog_id_for_output()), 'replies' => (string) $this->get_post_link($this->api->get_blog_id_for_output(), $post->ID, 'replies/'), 'likes' => (string) $this->get_post_link($this->api->get_blog_id_for_output(), $post->ID, 'likes/'))); break; case 'capabilities': $response[$key] = $capabilities; break; } } // WPCOM_JSON_API_Post_Endpoint::find_featured_worthy_media( $post ); // $response['featured_media'] = self::find_featured_media( $response ); unset($GLOBALS['post']); return $response; }