Initial commit

This commit is contained in:
Dan Phiffer committed 2011-03-25 12:22:44 -04:00
commit 86c1e5f82b
40 files changed
+4362

No files matched your search

+371
View File
@@ -0,0 +1,371 @@
<?php
class JSON_API {
function __construct() {
$this->query = new JSON_API_Query();
$this->introspector = new JSON_API_Introspector();
$this->response = new JSON_API_Response();
add_action('template_redirect', array(&$this, 'template_redirect'));
add_action('admin_menu', array(&$this, 'admin_menu'));
add_action('update_option_json_api_base', array(&$this, 'flush_rewrite_rules'));
add_action('pre_update_option_json_api_controllers', array(&$this, 'update_controllers'));
}
function template_redirect() {
// Check to see if there's an appropriate API controller + method
$controller = strtolower($this->query->get_controller());
$available_controllers = $this->get_controllers();
$enabled_controllers = explode(',', get_option('json_api_controllers', 'core'));
$active_controllers = array_intersect($available_controllers, $enabled_controllers);
if ($controller) {
if (!in_array($controller, $active_controllers)) {
$this->error("Unknown controller '$controller'.");
}
$controller_path = $this->controller_path($controller);
if (file_exists($controller_path)) {
require_once $controller_path;
}
$controller_class = $this->controller_class($controller);
if (!class_exists($controller_class)) {
$this->error("Unknown controller '$controller_class'.");
}
$this->controller = new $controller_class();
$method = $this->query->get_method($controller);
if ($method) {
$this->response->setup();
// Run action hooks for method
do_action("json_api-{$controller}-$method");
// Error out if nothing is found
if ($method == '404') {
$this->error('Not found');
}
// Run the method
$result = $this->controller->$method();
// Handle the result
$this->response->respond($result);
// Done!
exit;
}
}
}
function admin_menu() {
add_options_page('JSON API Settings', 'JSON API', 'manage_options', 'json-api', array(&$this, 'admin_options'));
}
function admin_options() {
if (!current_user_can('manage_options')) {
wp_die( __('You do not have sufficient permissions to access this page.') );
}
$available_controllers = $this->get_controllers();
$active_controllers = explode(',', get_option('json_api_controllers', 'core'));
if (count($active_controllers) == 1 && empty($active_controllers[0])) {
$active_controllers = array();
}
if (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], "update-options")) {
if ((!empty($_REQUEST['action']) || !empty($_REQUEST['action2'])) &&
(!empty($_REQUEST['controller']) || !empty($_REQUEST['controllers']))) {
if (!empty($_REQUEST['action'])) {
$action = $_REQUEST['action'];
} else {
$action = $_REQUEST['action2'];
}
if (!empty($_REQUEST['controllers'])) {
$controllers = $_REQUEST['controllers'];
} else {
$controllers = array($_REQUEST['controller']);
}
foreach ($controllers as $controller) {
if (in_array($controller, $available_controllers)) {
if ($action == 'activate' && !in_array($controller, $active_controllers)) {
$active_controllers[] = $controller;
} else if ($action == 'deactivate') {
$index = array_search($controller, $active_controllers);
if ($index !== false) {
unset($active_controllers[$index]);
}
}
}
}
$this->save_option('json_api_controllers', implode(',', $active_controllers));
}
if (isset($_REQUEST['json_api_base'])) {
$this->save_option('json_api_base', $_REQUEST['json_api_base']);
}
}
?>
<div class="wrap">
<div id="icon-options-general" class="icon32"><br /></div>
<h2>JSON API Settings</h2>
<form action="options-general.php?page=json-api" method="post">
<?php wp_nonce_field('update-options'); ?>
<h3>Controllers</h3>
<?php $this->print_controller_actions(); ?>
<table id="all-plugins-table" class="widefat">
<thead>
<tr>
<th class="manage-column check-column" scope="col"><input type="checkbox" /></th>
<th class="manage-column" scope="col">Controller</th>
<th class="manage-column" scope="col">Description</th>
</tr>
</thead>
<tfoot>
<tr>
<th class="manage-column check-column" scope="col"><input type="checkbox" /></th>
<th class="manage-column" scope="col">Controller</th>
<th class="manage-column" scope="col">Description</th>
</tr>
</tfoot>
<tbody class="plugins">
<?php
foreach ($available_controllers as $controller) {
$error = false;
$active = in_array($controller, $active_controllers);
$info = $this->controller_info($controller);
if (is_string($info)) {
$active = false;
$error = true;
$info = array(
'name' => $controller,
'description' => "<p><strong>Error</strong>: $info</p>",
'methods' => array(),
'url' => null
);
}
?>
<tr class="<?php echo ($active ? 'active' : 'inactive'); ?>">
<th class="check-column" scope="row">
<input type="checkbox" name="controllers[]" value="<?php echo $controller; ?>" />
</th>
<td class="plugin-title">
<strong><?php echo $info['name']; ?></strong>
<div class="row-actions-visible">
<?php
if ($active) {
echo '<a href="' . wp_nonce_url('options-general.php?page=json-api&amp;action=deactivate&amp;controller=' . $controller, 'update-options') . '" title="' . __('Deactivate this controller') . '" class="edit">' . __('Deactivate') . '</a>';
} else if (!$error) {
echo '<a href="' . wp_nonce_url('options-general.php?page=json-api&amp;action=activate&amp;controller=' . $controller, 'update-options') . '" title="' . __('Activate this controller') . '" class="edit">' . __('Activate') . '</a>';
}
if ($info['url']) {
echo ' | ';
echo '<a href="' . $info['url'] . '" target="_blank">Docs</a></div>';
}
?>
</td>
<td class="desc">
<p><?php echo $info['description']; ?></p>
<p>
<?php
foreach($info['methods'] as $method) {
$url = $this->get_method_url($controller, $method, array('dev' => 1));
if ($active) {
echo "<code><a href=\"$url\">$method</a></code> ";
} else {
echo "<code>$method</code> ";
}
}
?>
</p>
</td>
</tr>
<?php } ?>
</tbody>
</table>
<?php $this->print_controller_actions('action2'); ?>
<h3>Address</h3>
<p>Specify a base URL for JSON API. For example, using <code>api</code> as your API base URL would enable the following <code><?php bloginfo('url'); ?>/api/get_recent_posts/</code>. If you assign a blank value the API will only be available by setting a <code>json</code> query variable.</p>
<table class="form-table">
<tr valign="top">
<th scope="row">API base</th>
<td><code><?php bloginfo('url'); ?>/</code><input type="text" name="json_api_base" value="<?php echo get_option('json_api_base', 'api'); ?>" size="15" /></td>
</tr>
</table>
<?php if (!get_option('permalink_structure', '')) { ?>
<br />
<p><strong>Note:</strong> User-friendly permalinks are not currently enabled. <a target="_blank" class="button" href="options-permalink.php">Change Permalinks</a>
<?php } ?>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
</p>
</form>
</div>
<?php
}
function print_controller_actions($name = 'action') {
?>
<div class="tablenav">
<div class="alignleft actions">
<select name="<?php echo $name; ?>">
<option selected="selected" value="-1">Bulk Actions</option>
<option value="activate">Activate</option>
<option value="deactivate">Deactivate</option>
</select>
<input type="submit" class="button-secondary action" id="doaction" name="doaction" value="Apply">
</div>
<div class="clear"></div>
</div>
<div class="clear"></div>
<?php
}
function get_method_url($controller, $method, $options = '') {
$url = get_bloginfo('url');
$base = get_option('json_api_base', 'api');
$permalink_structure = get_option('permalink_structure', '');
if (!empty($options) && is_array($options)) {
$args = array();
foreach ($options as $key => $value) {
$args[] = urlencode($key) . '=' . urlencode($value);
}
$args = implode('&', $args);
} else {
$args = $options;
}
if ($controller != 'core') {
$method = "$controller/$method";
}
if (!empty($base) && !empty($permalink_structure)) {
if (!empty($args)) {
$args = "?$args";
}
return "$url/$base/$method/$args";
} else {
return "$url?json=$method&$args";
}
}
function save_option($id, $value) {
$option_exists = (get_option($id, null) !== null);
if ($option_exists) {
update_option($id, $value);
} else {
add_option($id, $value);
}
}
function get_controllers() {
$controllers = array();
$dir = json_api_dir();
$dh = opendir("$dir/controllers");
while ($file = readdir($dh)) {
if (preg_match('/(.+)\.php$/', $file, $matches)) {
$controllers[] = $matches[1];
}
}
$controllers = apply_filters('json_api_controllers', $controllers);
return array_map('strtolower', $controllers);
}
function controller_is_active($controller) {
if (defined('JSON_API_CONTROLLERS')) {
$default = JSON_API_CONTROLLERS;
} else {
$default = 'core';
}
$active_controllers = explode(',', get_option('json_api_controllers', $default));
return (in_array($controller, $active_controllers));
}
function update_controllers($controllers) {
if (is_array($controllers)) {
return implode(',', $controllers);
} else {
return $controllers;
}
}
function controller_info($controller) {
$path = $this->controller_path($controller);
$class = $this->controller_class($controller);
$response = array(
'name' => $controller,
'description' => '(No description available)',
'methods' => array()
);
if (file_exists($path)) {
$source = file_get_contents($path);
if (preg_match('/^\s*Controller name:(.+)$/im', $source, $matches)) {
$response['name'] = trim($matches[1]);
}
if (preg_match('/^\s*Controller description:(.+)$/im', $source, $matches)) {
$response['description'] = trim($matches[1]);
}
if (preg_match('/^\s*Controller URI:(.+)$/im', $source, $matches)) {
$response['docs'] = trim($matches[1]);
}
if (!class_exists($class)) {
require_once($path);
}
$response['methods'] = get_class_methods($class);
return $response;
} else if (is_admin()) {
return "Cannot find controller class '$class' (filtered path: $path).";
} else {
$this->error("Unknown controller '$controller'.");
}
return $response;
}
function controller_class($controller) {
return "json_api_{$controller}_controller";
}
function controller_path($controller) {
$dir = json_api_dir();
$controller_class = $this->controller_class($controller);
return apply_filters("{$controller_class}_path", "$dir/controllers/$controller.php");
}
function get_nonce_id($controller, $method) {
$controller = strtolower($controller);
$method = strtolower($method);
return "json_api-$controller-$method";
}
function flush_rewrite_rules() {
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
function error($message = 'Unknown error', $status = 'error') {
$this->response->respond(array(
'error' => $message
), $status);
}
function include_value($key) {
return $this->response->is_value_included($key);
}
}
?>
+299
View File
@@ -0,0 +1,299 @@
<?php
class JSON_API_Introspector {
public function get_posts($query = false, $wp_posts = false) {
global $post;
$this->set_posts_query($query);
$output = array();
while (have_posts()) {
the_post();
if ($wp_posts) {
$output[] = $post;
} else {
$output[] = new JSON_API_Post($post);
}
}
return $output;
}
public function get_date_archive_permalinks() {
$archives = wp_get_archives('echo=0');
preg_match_all("/href='([^']+)'/", $archives, $matches);
return $matches[1];
}
public function get_date_archive_tree($permalinks) {
$tree = array();
foreach ($permalinks as $url) {
if (preg_match('#(\d{4})/(\d{2})#', $url, $date)) {
$year = $date[1];
$month = $date[2];
} else if (preg_match('/(\d{4})(\d{2})/', $url, $date)) {
$year = $date[1];
$month = $date[2];
} else {
continue;
}
$count = $this->get_date_archive_count($year, $month);
if (empty($tree[$year])) {
$tree[$year] = array(
$month => $count
);
} else {
$tree[$year][$month] = $count;
}
}
return $tree;
}
public function get_date_archive_count($year, $month) {
if (!isset($this->month_archives)) {
global $wpdb;
$post_counts = $wpdb->get_results("
SELECT DATE_FORMAT(post_date, '%Y%m') AS month,
COUNT(ID) AS post_count
FROM $wpdb->posts
WHERE post_status = 'publish'
AND post_type = 'post'
GROUP BY month
");
$this->month_archives = array();
foreach ($post_counts as $post_count) {
$this->month_archives[$post_count->month] = $post_count->post_count;
}
}
return $this->month_archives["$year$month"];
}
public function get_categories() {
$wp_categories = get_categories();
$categories = array();
foreach ($wp_categories as $wp_category) {
if ($wp_category->term_id == 1 && $wp_category->slug == 'uncategorized') {
continue;
}
$categories[] = $this->get_category_object($wp_category);
}
return $categories;
}
public function get_current_category() {
global $json_api;
extract($json_api->query->get(array('id', 'slug', 'category_id', 'category_slug')));
if ($id || $category_id) {
if (!$id) {
$id = $category_id;
}
return $this->get_category_by_id($id);
} else if ($slug || $category_slug) {
if (!$slug) {
$slug = $category_slug;
}
return $this->get_category_by_slug($slug);
} else {
$json_api->error("Include 'id' or 'slug' var in your request.");
}
return null;
}
public function get_category_by_id($category_id) {
$wp_category = get_term_by('id', $category_id, 'category');
return $this->get_category_object($wp_category);
}
public function get_category_by_slug($category_slug) {
$wp_category = get_term_by('slug', $category_slug, 'category');
return $this->get_category_object($wp_category);
}
public function get_tags() {
$wp_tags = get_tags();
return array_map(array(&$this, 'get_tag_object'), $wp_tags);
}
public function get_current_tag() {
global $json_api;
extract($json_api->query->get(array('id', 'slug', 'tag_id', 'tag_slug')));
if ($id || $tag_id) {
if (!$id) {
$id = $tag_id;
}
return $this->get_tag_by_id($id);
} else if ($slug || $tag_slug) {
if (!$slug) {
$slug = $tag_slug;
}
return $this->get_tag_by_slug($slug);
} else {
$json_api->error("Include 'id' or 'slug' var in your request.");
}
return null;
}
public function get_tag_by_id($tag_id) {
$wp_tag = get_term_by('id', $tag_id, 'post_tag');
return $this->get_tag_object($wp_tag);
}
public function get_tag_by_slug($tag_slug) {
$wp_tag = get_term_by('slug', $tag_slug, 'post_tag');
return $this->get_tag_object($wp_tag);
}
public function get_authors() {
global $wpdb;
$author_ids = $wpdb->get_col($wpdb->prepare("
SELECT u.ID, m.meta_value AS last_name
FROM $wpdb->users AS u,
$wpdb->usermeta AS m
WHERE m.user_id = u.ID
AND m.meta_key = 'last_name'
ORDER BY last_name
"));
$all_authors = array_map(array(&$this, 'get_author_by_id'), $author_ids);
$active_authors = array_filter($all_authors, array(&$this, 'is_active_author'));
return $active_authors;
}
public function get_current_author() {
global $json_api;
extract($json_api->query->get(array('id', 'slug', 'author_id', 'author_slug')));
if ($id || $author_id) {
if (!$id) {
$id = $author_id;
}
return $this->get_author_by_id($id);
} else if ($slug || $author_slug) {
if (!$slug) {
$slug = $author_slug;
}
return $this->get_author_by_login($slug);
} else {
$json_api->error("Include 'id' or 'slug' var in your request.");
}
return null;
}
public function get_author_by_id($id) {
$id = get_the_author_meta('ID', $id);
if (!$id) {
return null;
}
return new JSON_API_Author($id);
}
public function get_author_by_login($login) {
global $wpdb;
$id = $wpdb->get_var($wpdb->prepare("
SELECT ID
FROM $wpdb->users
WHERE user_nicename = %s
", $login));
return $this->get_author_by_id($id);
}
public function get_comments($post_id) {
global $wpdb;
$wp_comments = $wpdb->get_results($wpdb->prepare("
SELECT *
FROM $wpdb->comments
WHERE comment_post_ID = %d
AND comment_approved = 1
AND comment_type = ''
ORDER BY comment_date
", $post_id));
$comments = array();
foreach ($wp_comments as $wp_comment) {
$comments[] = new JSON_API_Comment($wp_comment);
}
return $comments;
}
public function get_attachments($post_id) {
$wp_attachments = get_children(array(
'post_type' => 'attachment',
'post_parent' => $post_id,
'orderby' => 'menu_order',
'order' => 'ASC'
));
$attachments = array();
if (!empty($wp_attachments)) {
foreach ($wp_attachments as $wp_attachment) {
$attachments[] = new JSON_API_Attachment($wp_attachment);
}
}
return $attachments;
}
public function attach_child_posts(&$post) {
$post->children = array();
$wp_children = get_posts(array(
'post_type' => $post->type,
'post_parent' => $post->id,
'order' => 'ASC',
'orderby' => 'menu_order'
));
foreach ($wp_children as $wp_post) {
$post->children[] = new JSON_API_Post($wp_post);
}
foreach ($post->children as $child) {
$this->attach_child_posts($child);
}
}
protected function get_category_object($wp_category) {
if (!$wp_category) {
return null;
}
return new JSON_API_Category($wp_category);
}
protected function get_tag_object($wp_tag) {
if (!$wp_tag) {
return null;
}
return new JSON_API_Tag($wp_tag);
}
protected function is_active_author($author) {
if (!isset($this->active_authors)) {
$this->active_authors = explode(',', wp_list_authors(array(
'html' => false,
'echo' => false,
'exclude_admin' => false
)));
$this->active_authors = array_map('trim', $this->active_authors);
}
return in_array($author->name, $this->active_authors);
}
protected function set_posts_query($query = false) {
global $json_api, $wp_query;
if (!$query) {
$query = array();
}
$query = array_merge($query, $wp_query->query);
if ($json_api->query->page) {
$query['paged'] = $json_api->query->page;
}
if ($json_api->query->count) {
$query['posts_per_page'] = $json_api->query->count;
}
if ($json_api->query->post_type) {
$query['post_type'] = $json_api->query->post_type;
}
if (!empty($query)) {
query_posts($query);
}
}
}
?>
+194
View File
@@ -0,0 +1,194 @@
<?php
class JSON_API_Query {
// Default values
protected $defaults = array(
'date_format' => 'Y-m-d H:i:s',
'read_more' => 'Read more'
);
function __construct() {
// Register JSON API query vars
add_filter('query_vars', array(&$this, 'query_vars'));
}
function get($key) {
if (is_array($key)) {
$result = array();
foreach ($key as $k) {
$result[$k] = $this->get($k);
}
return $result;
}
$query_var = (isset($_REQUEST[$key])) ? $_REQUEST[$key] : null;
$wp_query_var = $this->wp_query_var($key);
if ($wp_query_var) {
return $wp_query_var;
} else if ($query_var) {
return $this->strip_magic_quotes($query_var);
} else if (isset($this->defaults[$key])) {
return $this->defaults[$key];
} else {
return null;
}
}
function __get($key) {
return $this->get($key);
}
function __isset($key) {
return ($this->get($key) !== null);
}
function wp_query_var($key) {
$wp_translation = array(
'json' => 'json',
'post_id' => 'p',
'post_slug' => 'name',
'page_id' => 'page_id',
'page_slug' => 'name',
'category_id' => 'cat',
'category_slug' => 'category_name',
'tag_id' => 'tag_id',
'tag_slug' => 'tag',
'author_id' => 'author',
'author_slug' => 'author_name',
'search' => 's',
'order' => 'order',
'order_by' => 'orderby'
);
if ($key == 'date') {
$date = null;
if (get_query_var('year')) {
$date = get_query_var('year');
}
if (get_query_var('monthnum')) {
$month = get_query_var('monthnum');
if ($month < 10) {
$month = "0$month";
}
$date .= $month;
}
if (get_query_var('day')) {
$day = get_query_var('day');
if ($day < 10) {
$day = "0$day";
}
$date .= $day;
}
return $date;
} else if (isset($wp_translation[$key])) {
return get_query_var($wp_translation[$key]);
} else {
return null;
}
}
function strip_magic_quotes($value) {
if (get_magic_quotes_gpc()) {
return stripslashes($value);
} else {
return $value;
}
}
function query_vars($wp_vars) {
$wp_vars[] = 'json';
return $wp_vars;
}
function get_controller() {
$json = $this->get('json');
if (empty($json)) {
return false;
}
if (preg_match('/^[a-zA-Z_]+$/', $json)) {
return $this->get_legacy_controller($json);
} else if (preg_match('/^([a-zA-Z_]+)(\/|\.)[a-zA-Z_]+$/', $json, $matches)) {
return $matches[1];
} else {
return 'core';
}
}
function get_legacy_controller($json) {
global $json_api;
if ($json == 'submit_comment') {
if ($json_api->controller_is_active('respond')) {
return 'respond';
} else {
$json_api->error("The 'submit_comment' method has been removed from the Core controller. To use this method you must enable the Respond controller from WP Admin > Settings > JSON API.");
}
} else if ($json == 'create_post') {
if ($json_api->controller_is_active('posts')) {
return 'posts';
} else {
$json_api->error("The 'create_post' method has been removed from the Core controller. To use this method you must enable the Posts controller from WP Admin > Settings > JSON API.");
}
} else {
return 'core';
}
}
function get_method($controller) {
global $json_api;
// Returns an appropriate API method name or false. Four possible outcomes:
// 1. API isn't being invoked at all (return false)
// 2. A specific API method was requested (return method name)
// 3. A method is chosen implicitly on a given WordPress page
// 4. API invoked incorrectly (return "error" method)
//
// Note:
// The implicit outcome (3) is invoked by setting the json query var to a
// non-empty value on any WordPress page:
// * http://example.org/2009/11/10/hello-world/?json=1 (get_post)
// * http://example.org/2009/11/?json=1 (get_date_posts)
// * http://example.org/category/foo?json=1 (get_category_posts)
$method = $this->get('json');
if (strpos($method, '/') !== false) {
$method = substr($method, strpos($method, '/') + 1);
} else if (strpos($method, '.') !== false) {
$method = substr($method, strpos($method, '.') + 1);
}
if (empty($method)) {
// Case 1: we're not being invoked (done!)
return false;
} else if (method_exists("JSON_API_{$controller}_Controller", $method)) {
// Case 2: an explicit method was specified
return $method;
} else if ($controller == 'core') {
// Case 3: choose the method implicitly based on which page we're on...
if (is_search()) {
return 'get_search_results';
} else if (is_home()) {
if (empty($_GET['json'])) {
$json_api->error("Uknown method '$method'.");
}
return 'get_recent_posts';
} else if (is_page()) {
return 'get_page';
} else if (is_single()) {
return 'get_post';
} else if (is_category()) {
return 'get_category_posts';
} else if (is_tag()) {
return 'get_tag_posts';
} else if (is_author()) {
return 'get_author_posts';
} else if (is_date()) {
return 'get_date_posts';
} else if (is_404()) {
return '404';
}
}
// Case 4: either the method doesn't exist or we don't support the page implicitly
return 'error';
}
}
+184
View File
@@ -0,0 +1,184 @@
<?php
class JSON_API_Response {
function setup() {
global $json_api;
$this->include_values = array();
$this->exclude_values = array();
if ($json_api->query->include) {
$this->include_values = explode(',', $json_api->query->include);
}
// Props to ikesyo for submitting a fix!
if ($json_api->query->exclude) {
$this->exclude_values = explode(',', $json_api->query->exclude);
$this->include_values = array_diff($this->include_values, $this->exclude_values);
}
// Compatibility with Disqus plugin
remove_action('loop_end', 'dsq_loop_end');
}
function get_json($data, $status = 'ok') {
// Include a status value with the response
if (is_array($data)) {
$data = array_merge(array('status' => $status), $data);
} else if (is_object($data)) {
$data = get_object_vars($data);
$data = array_merge(array('status' => $status), $data);
}
$data = apply_filters('json_api_encode', $data);
if (function_exists('json_encode')) {
// Use the built-in json_encode function if it's available
return json_encode($data);
} else {
// Use PEAR's Services_JSON encoder otherwise
if (!class_exists('Services_JSON')) {
$dir = json_api_dir();
require_once "$dir/library/JSON.php";
}
$json = new Services_JSON();
return $json->encode($data);
}
}
function is_value_included($key) {
// Props to ikesyo for submitting a fix!
if (empty($this->include_values) && empty($this->exclude_values)) {
return true;
} else {
if (empty($this->exclude_values)) {
return in_array($key, $this->include_values);
} else {
return !in_array($key, $this->exclude_values);
}
}
}
function respond($result, $status = 'ok') {
global $json_api;
$json = $this->get_json($result, $status);
$status_redirect = "redirect_$status";
if ($json_api->query->dev || !empty($_REQUEST['dev'])) {
// Output the result in a human-redable format
if (!headers_sent()) {
header('HTTP/1.1 200 OK');
header('Content-Type: text/plain; charset: UTF-8', true);
} else {
echo '<pre>';
}
echo $this->prettify($json);
} else if (!empty($_REQUEST[$status_redirect])) {
wp_redirect($_REQUEST[$status_redirect]);
} else if ($json_api->query->redirect) {
$url = $this->add_status_query_var($json_api->query->redirect, $status);
wp_redirect($url);
} else if ($json_api->query->callback) {
// Run a JSONP-style callback with the result
$this->callback($json_api->query->callback, $json);
} else {
// Output the result
$this->output($json);
}
exit;
}
function output($result) {
$charset = get_option('blog_charset');
if (!headers_sent()) {
header('HTTP/1.1 200 OK', true);
header("Content-Type: application/json; charset=$charset", true);
}
echo $result;
}
function callback($callback, $result) {
$charset = get_option('blog_charset');
if (!headers_sent()) {
header('HTTP/1.1 200 OK', true);
header("Content-Type: application/javascript; charset=$charset", true);
}
echo "$callback($result)";
}
function add_status_query_var($url, $status) {
if (strpos($url, '#')) {
// Remove the anchor hash for now
$pos = strpos($url, '#');
$anchor = substr($url, $pos);
$url = substr($url, 0, $pos);
}
if (strpos($url, '?')) {
$url .= "&status=$status";
} else {
$url .= "?status=$status";
}
if (!empty($anchor)) {
// Add the anchor hash back in
$url .= $anchor;
}
return $url;
}
function prettify($ugly) {
$pretty = "";
$indent = "";
$last = '';
$pos = 0;
$level = 0;
$string = false;
while ($pos < strlen($ugly)) {
$char = substr($ugly, $pos++, 1);
if (!$string) {
if ($char == '{' || $char == '[') {
if ($char == '[' && substr($ugly, $pos, 1) == ']') {
$pretty .= "[]";
$pos++;
} else if ($char == '{' && substr($ugly, $pos, 1) == '}') {
$pretty .= "{}";
$pos++;
} else {
$pretty .= "$char\n";
$indent = str_repeat(' ', ++$level);
$pretty .= "$indent";
}
} else if ($char == '}' || $char == ']') {
$indent = str_repeat(' ', --$level);
if ($last != '}' && $last != ']') {
$pretty .= "\n$indent";
} else if (substr($pretty, -2, 2) == ' ') {
$pretty = substr($pretty, 0, -2);
}
$pretty .= $char;
if (substr($ugly, $pos, 1) == ',') {
$pretty .= ",";
$last = ',';
$pos++;
}
$pretty .= "\n$indent";
} else if ($char == ':') {
$pretty .= ": ";
} else if ($char == ',') {
$pretty .= ",\n$indent";
} else if ($char == '"') {
$pretty .= '"';
$string = true;
} else {
$pretty .= $char;
}
} else {
if ($last != '\\' && $char == '"') {
$string = false;
}
$pretty .= $char;
}
$last = $char;
}
return $pretty;
}
}
?>