Version Description
Major release, see changelog for details.
Download this release
Release Info
Developer | dphiffer |
Plugin | JSON API |
Version | 1.0 |
Comparing to | |
See all releases |
Code changes from version 0.9.6 to 1.0
- controllers/core.php +311 -0
- controllers/posts.php +35 -0
- controllers/respond.php +28 -0
- json-api.php +374 -12
- models/attachment.php +3 -0
- models/post.php +38 -10
- readme.txt +442 -171
- singletons/controller.php +0 -253
- singletons/introspector.php +130 -65
- singletons/query.php +156 -119
- singletons/response.php +76 -43
controllers/core.php
ADDED
@@ -0,0 +1,311 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Name: Core
|
4 |
+
Description: Basic introspection methods
|
5 |
+
*/
|
6 |
+
|
7 |
+
class JSON_API_Core_Controller {
|
8 |
+
|
9 |
+
public function info() {
|
10 |
+
global $json_api;
|
11 |
+
if (!empty($json_api->query->controller)) {
|
12 |
+
return $json_api->controller_info($json_api->query->controller);
|
13 |
+
} else {
|
14 |
+
$dir = dirname(dirname(__FILE__));
|
15 |
+
$php = file_get_contents("$dir/json-api.php");
|
16 |
+
if (preg_match('/^\s*Version:\s*(.+)$/m', $php, $matches)) {
|
17 |
+
$version = $matches[1];
|
18 |
+
} else {
|
19 |
+
$version = '(Unknown)';
|
20 |
+
}
|
21 |
+
$active_controllers = explode(',', get_option('json_api_controllers', 'core'));
|
22 |
+
$controllers = array_intersect($json_api->get_controllers(), $active_controllers);
|
23 |
+
return array(
|
24 |
+
'json_api_version' => $version,
|
25 |
+
'controllers' => $controllers
|
26 |
+
);
|
27 |
+
}
|
28 |
+
}
|
29 |
+
|
30 |
+
public function get_recent_posts() {
|
31 |
+
global $json_api;
|
32 |
+
$posts = $json_api->introspector->get_posts();
|
33 |
+
return $this->posts_result($posts);
|
34 |
+
}
|
35 |
+
|
36 |
+
public function get_post() {
|
37 |
+
global $json_api;
|
38 |
+
extract($json_api->query->get(array('id', 'slug', 'post_id', 'post_slug')));
|
39 |
+
if ($id || $post_id) {
|
40 |
+
if (!$id) {
|
41 |
+
$id = $post_id;
|
42 |
+
}
|
43 |
+
$posts = $json_api->introspector->get_posts(array(
|
44 |
+
'p' => $id
|
45 |
+
));
|
46 |
+
} else if ($slug || $post_slug) {
|
47 |
+
if (!$slug) {
|
48 |
+
$slug = $post_slug;
|
49 |
+
}
|
50 |
+
$posts = $json_api->introspector->get_posts(array(
|
51 |
+
'name' => $slug
|
52 |
+
));
|
53 |
+
} else {
|
54 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
55 |
+
}
|
56 |
+
if (count($posts) == 1) {
|
57 |
+
return array(
|
58 |
+
'post' => $posts[0]
|
59 |
+
);
|
60 |
+
} else {
|
61 |
+
$json_api->error("Not found.");
|
62 |
+
}
|
63 |
+
}
|
64 |
+
|
65 |
+
public function get_page() {
|
66 |
+
global $json_api;
|
67 |
+
extract($json_api->query->get(array('id', 'slug', 'page_id', 'page_slug', 'children')));
|
68 |
+
if ($id || $page_id) {
|
69 |
+
if (!$id) {
|
70 |
+
$id = $page_id;
|
71 |
+
}
|
72 |
+
$posts = $json_api->introspector->get_posts(array(
|
73 |
+
'page_id' => $id
|
74 |
+
));
|
75 |
+
} else if ($slug || $page_slug) {
|
76 |
+
if (!$slug) {
|
77 |
+
$slug = $page_slug;
|
78 |
+
}
|
79 |
+
$posts = $json_api->introspector->get_posts(array(
|
80 |
+
'pagename' => $slug
|
81 |
+
));
|
82 |
+
} else {
|
83 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
84 |
+
}
|
85 |
+
|
86 |
+
// Workaround for https://core.trac.wordpress.org/ticket/12647
|
87 |
+
if (empty($posts)) {
|
88 |
+
$url = $_SERVER['REQUEST_URI'];
|
89 |
+
$parsed_url = parse_url($url);
|
90 |
+
$path = $parsed_url['path'];
|
91 |
+
if (preg_match('#^http://[^/]+(/.+)$#', get_bloginfo('url'), $matches)) {
|
92 |
+
$blog_root = $matches[1];
|
93 |
+
$path = preg_replace("#^$blog_root#", '', $path);
|
94 |
+
}
|
95 |
+
if (substr($path, 0, 1) == '/') {
|
96 |
+
$path = substr($path, 1);
|
97 |
+
}
|
98 |
+
$posts = $json_api->introspector->get_posts(array('pagename' => $path));
|
99 |
+
}
|
100 |
+
|
101 |
+
if (count($posts) == 1) {
|
102 |
+
if (!empty($children)) {
|
103 |
+
$json_api->introspector->attach_child_posts($posts[0]);
|
104 |
+
}
|
105 |
+
return array(
|
106 |
+
'page' => $posts[0]
|
107 |
+
);
|
108 |
+
} else {
|
109 |
+
$json_api->error("Not found.");
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
public function get_date_posts() {
|
114 |
+
global $json_api;
|
115 |
+
if ($json_api->query->date) {
|
116 |
+
$date = preg_replace('/\D/', '', $json_api->query->date);
|
117 |
+
if (!preg_match('/^\d{4}(\d{2})?(\d{2})?$/', $date)) {
|
118 |
+
$json_api->error("Specify a date var in one of 'YYYY' or 'YYYY-MM' or 'YYYY-MM-DD' formats.");
|
119 |
+
}
|
120 |
+
$request = array('year' => substr($date, 0, 4));
|
121 |
+
if (strlen($date) > 4) {
|
122 |
+
$request['monthnum'] = (int) substr($date, 4, 2);
|
123 |
+
}
|
124 |
+
if (strlen($date) > 6) {
|
125 |
+
$request['day'] = (int) substr($date, 6, 2);
|
126 |
+
}
|
127 |
+
$posts = $json_api->introspector->get_posts($request);
|
128 |
+
} else {
|
129 |
+
$json_api->error("Include 'date' var in your request.");
|
130 |
+
}
|
131 |
+
return $this->posts_result($posts);
|
132 |
+
}
|
133 |
+
|
134 |
+
public function get_category_posts() {
|
135 |
+
global $json_api;
|
136 |
+
$category = $json_api->introspector->get_current_category();
|
137 |
+
if (!$category) {
|
138 |
+
$json_api->error("Not found.");
|
139 |
+
}
|
140 |
+
$posts = $json_api->introspector->get_posts(array(
|
141 |
+
'cat' => $category->id
|
142 |
+
));
|
143 |
+
return $this->posts_object_result($posts, $category);
|
144 |
+
}
|
145 |
+
|
146 |
+
public function get_tag_posts() {
|
147 |
+
global $json_api;
|
148 |
+
$tag = $json_api->introspector->get_current_tag();
|
149 |
+
if (!$tag) {
|
150 |
+
$json_api->error("Not found.");
|
151 |
+
}
|
152 |
+
$posts = $json_api->introspector->get_posts(array(
|
153 |
+
'tag_id' => $tag->id
|
154 |
+
));
|
155 |
+
return $this->posts_object_result($posts, $tag);
|
156 |
+
}
|
157 |
+
|
158 |
+
public function get_author_posts() {
|
159 |
+
global $json_api;
|
160 |
+
$author = $json_api->introspector->get_current_author();
|
161 |
+
if (!$author) {
|
162 |
+
$json_api->error("Not found.");
|
163 |
+
}
|
164 |
+
$posts = $json_api->introspector->get_posts(array(
|
165 |
+
'author' => $author->id
|
166 |
+
));
|
167 |
+
return $this->posts_object_result($posts, $author);
|
168 |
+
}
|
169 |
+
|
170 |
+
public function get_search_results() {
|
171 |
+
global $json_api;
|
172 |
+
if ($json_api->query->search) {
|
173 |
+
$posts = $json_api->introspector->get_posts(array(
|
174 |
+
's' => $json_api->query->search
|
175 |
+
));
|
176 |
+
} else {
|
177 |
+
$json_api->error("Include 'search' var in your request.");
|
178 |
+
}
|
179 |
+
return $this->posts_result($posts);
|
180 |
+
}
|
181 |
+
|
182 |
+
public function get_date_index() {
|
183 |
+
global $json_api;
|
184 |
+
$permalinks = $json_api->introspector->get_date_archive_permalinks();
|
185 |
+
$tree = $json_api->introspector->get_date_archive_tree($permalinks);
|
186 |
+
return array(
|
187 |
+
'permalinks' => $permalinks,
|
188 |
+
'tree' => $tree
|
189 |
+
);
|
190 |
+
}
|
191 |
+
|
192 |
+
public function get_category_index() {
|
193 |
+
global $json_api;
|
194 |
+
$categories = $json_api->introspector->get_categories();
|
195 |
+
return array(
|
196 |
+
'count' => count($categories),
|
197 |
+
'categories' => $categories
|
198 |
+
);
|
199 |
+
}
|
200 |
+
|
201 |
+
public function get_tag_index() {
|
202 |
+
global $json_api;
|
203 |
+
$tags = $json_api->introspector->get_tags();
|
204 |
+
return array(
|
205 |
+
'count' => count($tags),
|
206 |
+
'tags' => $tags
|
207 |
+
);
|
208 |
+
}
|
209 |
+
|
210 |
+
public function get_author_index() {
|
211 |
+
global $json_api;
|
212 |
+
$authors = $json_api->introspector->get_authors();
|
213 |
+
return array(
|
214 |
+
'count' => count($authors),
|
215 |
+
'authors' => array_values($authors)
|
216 |
+
);
|
217 |
+
}
|
218 |
+
|
219 |
+
public function get_page_index() {
|
220 |
+
global $json_api;
|
221 |
+
$pages = array();
|
222 |
+
$wp_posts = get_posts(array(
|
223 |
+
'post_type' => 'page',
|
224 |
+
'post_parent' => 0,
|
225 |
+
'order' => 'ASC',
|
226 |
+
'orderby' => 'menu_order'
|
227 |
+
));
|
228 |
+
foreach ($wp_posts as $wp_post) {
|
229 |
+
$pages[] = new JSON_API_Post($wp_post);
|
230 |
+
}
|
231 |
+
foreach ($pages as $page) {
|
232 |
+
$json_api->introspector->attach_child_posts($page);
|
233 |
+
}
|
234 |
+
return array(
|
235 |
+
'pages' => $pages
|
236 |
+
);
|
237 |
+
}
|
238 |
+
|
239 |
+
public function get_nonce() {
|
240 |
+
global $json_api;
|
241 |
+
extract($json_api->query->get(array('controller', 'method')));
|
242 |
+
if ($controller && $method) {
|
243 |
+
$controller = strtolower($controller);
|
244 |
+
if (!in_array($controller, $json_api->get_controllers())) {
|
245 |
+
$json_api->error("Unknown controller '$controller'.");
|
246 |
+
}
|
247 |
+
require_once $json_api->controller_path($controller);
|
248 |
+
if (!method_exists($json_api->controller_class($controller), $method)) {
|
249 |
+
$json_api->error("Unknown method '$method'.");
|
250 |
+
}
|
251 |
+
$nonce_id = $json_api->get_nonce_id($controller, $method);
|
252 |
+
return array(
|
253 |
+
'controller' => $controller,
|
254 |
+
'method' => $method,
|
255 |
+
'nonce' => wp_create_nonce($nonce_id)
|
256 |
+
);
|
257 |
+
} else {
|
258 |
+
$json_api->error("Include 'controller' and 'method' vars in your request.");
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
protected function get_object_posts($object, $id_var, $slug_var) {
|
263 |
+
global $json_api;
|
264 |
+
$object_id = "{$type}_id";
|
265 |
+
$object_slug = "{$type}_slug";
|
266 |
+
extract($json_api->query->get(array('id', 'slug', $object_id, $object_slug)));
|
267 |
+
if ($id || $$object_id) {
|
268 |
+
if (!$id) {
|
269 |
+
$id = $$object_id;
|
270 |
+
}
|
271 |
+
$posts = $json_api->introspector->get_posts(array(
|
272 |
+
$id_var => $id
|
273 |
+
));
|
274 |
+
} else if ($slug || $$object_slug) {
|
275 |
+
if (!$slug) {
|
276 |
+
$slug = $$object_slug;
|
277 |
+
}
|
278 |
+
$posts = $json_api->introspector->get_posts(array(
|
279 |
+
$slug_var => $slug
|
280 |
+
));
|
281 |
+
} else {
|
282 |
+
$json_api->error("No $type specified. Include 'id' or 'slug' var in your request.");
|
283 |
+
}
|
284 |
+
return $posts;
|
285 |
+
}
|
286 |
+
|
287 |
+
protected function posts_result($posts) {
|
288 |
+
global $wp_query;
|
289 |
+
return array(
|
290 |
+
'count' => count($posts),
|
291 |
+
'count_total' => (int) $wp_query->found_posts,
|
292 |
+
'pages' => $wp_query->max_num_pages,
|
293 |
+
'posts' => $posts
|
294 |
+
);
|
295 |
+
}
|
296 |
+
|
297 |
+
protected function posts_object_result($posts, $object) {
|
298 |
+
global $wp_query;
|
299 |
+
// Convert something like "JSON_API_Category" into "category"
|
300 |
+
$object_key = strtolower(substr(get_class($object), 9));
|
301 |
+
return array(
|
302 |
+
'count' => count($posts),
|
303 |
+
'pages' => (int) $wp_query->max_num_pages,
|
304 |
+
$object_key => $object,
|
305 |
+
'posts' => $posts
|
306 |
+
);
|
307 |
+
}
|
308 |
+
|
309 |
+
}
|
310 |
+
|
311 |
+
?>
|
controllers/posts.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Name: Posts
|
4 |
+
Description: Data manipulation methods for posts
|
5 |
+
URL:
|
6 |
+
*/
|
7 |
+
|
8 |
+
class JSON_API_Posts_Controller {
|
9 |
+
|
10 |
+
public function create_post() {
|
11 |
+
global $json_api;
|
12 |
+
if (!current_user_can('edit_posts')) {
|
13 |
+
$json_api->error("You need to login with a user capable of creating posts.");
|
14 |
+
}
|
15 |
+
if (!$json_api->query->nonce) {
|
16 |
+
$json_api->error("You must include a 'nonce' value to create posts. Use the `get_nonce` Core API method.");
|
17 |
+
}
|
18 |
+
$nonce_id = $json_api->get_nonce_id('posts', 'create_post');
|
19 |
+
if (!wp_verify_nonce($json_api->query->nonce, $nonce_id)) {
|
20 |
+
$json_api->error("Your 'nonce' value was incorrect. Use the 'get_nonce' API method.");
|
21 |
+
}
|
22 |
+
nocache_headers();
|
23 |
+
$post = new JSON_API_Post();
|
24 |
+
$id = $post->create($_REQUEST);
|
25 |
+
if (empty($id)) {
|
26 |
+
$json_api->error("Could not create post.");
|
27 |
+
}
|
28 |
+
return array(
|
29 |
+
'post' => $post
|
30 |
+
);
|
31 |
+
}
|
32 |
+
|
33 |
+
}
|
34 |
+
|
35 |
+
?>
|
controllers/respond.php
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*
|
3 |
+
Name: Respond
|
4 |
+
Description: Comment/trackback submission methods
|
5 |
+
URL:
|
6 |
+
*/
|
7 |
+
|
8 |
+
class JSON_API_Respond_Controller {
|
9 |
+
|
10 |
+
function submit_comment() {
|
11 |
+
global $json_api;
|
12 |
+
nocache_headers();
|
13 |
+
if (empty($_REQUEST['post_id'])) {
|
14 |
+
$json_api->error("No post specified. Include 'post_id' var in your request.");
|
15 |
+
} else if (empty($_REQUEST['name']) ||
|
16 |
+
empty($_REQUEST['email']) ||
|
17 |
+
empty($_REQUEST['content'])) {
|
18 |
+
$json_api->error("Please include all required arguments (name, email, content).");
|
19 |
+
} else if (!is_email($_REQUEST['email'])) {
|
20 |
+
$json_api->error("Please enter a valid email address.");
|
21 |
+
}
|
22 |
+
$pending = new JSON_API_Comment();
|
23 |
+
return $pending->handle_submission();
|
24 |
+
}
|
25 |
+
|
26 |
+
}
|
27 |
+
|
28 |
+
?>
|
json-api.php
CHANGED
@@ -3,21 +3,34 @@
|
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/json-api/
|
5 |
Description: A RESTful API for WordPress
|
6 |
-
Version: 0
|
7 |
Author: Dan Phiffer
|
8 |
Author URI: http://phiffer.org/
|
9 |
*/
|
10 |
|
11 |
-
|
12 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
function json_api_init() {
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
19 |
add_filter('rewrite_rules_array', 'json_api_rewrites');
|
20 |
-
$json_api = new
|
|
|
|
|
|
|
|
|
21 |
}
|
22 |
|
23 |
function json_api_activation() {
|
@@ -34,16 +47,365 @@ function json_api_deactivation() {
|
|
34 |
}
|
35 |
|
36 |
function json_api_rewrites($wp_rules) {
|
37 |
-
|
|
|
|
|
|
|
38 |
$json_api_rules = array(
|
39 |
-
|
|
|
40 |
);
|
41 |
return array_merge($json_api_rules, $wp_rules);
|
42 |
}
|
43 |
|
44 |
// Add initialization and activation hooks
|
45 |
add_action('init', 'json_api_init');
|
46 |
-
register_activation_hook("$
|
47 |
-
register_deactivation_hook("$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
?>
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/extend/plugins/json-api/
|
5 |
Description: A RESTful API for WordPress
|
6 |
+
Version: 1.0
|
7 |
Author: Dan Phiffer
|
8 |
Author URI: http://phiffer.org/
|
9 |
*/
|
10 |
|
11 |
+
$dir = dirname(__FILE__);
|
12 |
+
require_once "$dir/singletons/query.php";
|
13 |
+
require_once "$dir/singletons/introspector.php";
|
14 |
+
require_once "$dir/singletons/response.php";
|
15 |
+
require_once "$dir/models/post.php";
|
16 |
+
require_once "$dir/models/comment.php";
|
17 |
+
require_once "$dir/models/category.php";
|
18 |
+
require_once "$dir/models/tag.php";
|
19 |
+
require_once "$dir/models/author.php";
|
20 |
+
require_once "$dir/models/attachment.php";
|
21 |
|
22 |
function json_api_init() {
|
23 |
+
global $json_api;
|
24 |
+
if (phpversion() < 5) {
|
25 |
+
add_action('admin_notices', 'json_api_php_version_warning');
|
26 |
+
return;
|
27 |
+
}
|
28 |
add_filter('rewrite_rules_array', 'json_api_rewrites');
|
29 |
+
$json_api = new JSON_API();
|
30 |
+
}
|
31 |
+
|
32 |
+
function json_api_php_version_warning() {
|
33 |
+
echo "<div id=\"json-api-warning\" class=\"updated fade\"><p>Sorry, JSON API requires PHP version 5.0 or greater.</p></div>";
|
34 |
}
|
35 |
|
36 |
function json_api_activation() {
|
47 |
}
|
48 |
|
49 |
function json_api_rewrites($wp_rules) {
|
50 |
+
$base = get_option('json_api_base', 'api');
|
51 |
+
if (empty($base)) {
|
52 |
+
return $wp_rules;
|
53 |
+
}
|
54 |
$json_api_rules = array(
|
55 |
+
"$base\$" => 'index.php?json=info',
|
56 |
+
"$base/(.+)\$" => 'index.php?json=$matches[1]'
|
57 |
);
|
58 |
return array_merge($json_api_rules, $wp_rules);
|
59 |
}
|
60 |
|
61 |
// Add initialization and activation hooks
|
62 |
add_action('init', 'json_api_init');
|
63 |
+
register_activation_hook("$dir/json-api.php", 'json_api_activation');
|
64 |
+
register_deactivation_hook("$dir/json-api.php", 'json_api_deactivation');
|
65 |
+
|
66 |
+
|
67 |
+
class JSON_API {
|
68 |
+
|
69 |
+
function __construct() {
|
70 |
+
$this->query = new JSON_API_Query();
|
71 |
+
$this->introspector = new JSON_API_Introspector();
|
72 |
+
$this->response = new JSON_API_Response();
|
73 |
+
add_action('template_redirect', array(&$this, 'template_redirect'));
|
74 |
+
add_action('admin_menu', array(&$this, 'admin_menu'));
|
75 |
+
add_action('update_option_json_api_base', array(&$this, 'flush_rewrite_rules'));
|
76 |
+
add_action('pre_update_option_json_api_controllers', array(&$this, 'update_controllers'));
|
77 |
+
}
|
78 |
+
|
79 |
+
function template_redirect() {
|
80 |
+
// Check to see if there's an appropriate API controller + method
|
81 |
+
$controller = strtolower($this->query->get_controller());
|
82 |
+
$available_controllers = $this->get_controllers();
|
83 |
+
$enabled_controllers = explode(',', get_option('json_api_controllers', 'core'));
|
84 |
+
$active_controllers = array_intersect($available_controllers, $enabled_controllers);
|
85 |
+
|
86 |
+
if ($controller) {
|
87 |
+
|
88 |
+
if (!in_array($controller, $active_controllers)) {
|
89 |
+
$this->error("Unknown controller '$controller'.");
|
90 |
+
}
|
91 |
+
|
92 |
+
$controller_path = $this->controller_path($controller);
|
93 |
+
if (file_exists($controller_path)) {
|
94 |
+
require_once $controller_path;
|
95 |
+
}
|
96 |
+
$controller_class = $this->controller_class($controller);
|
97 |
+
|
98 |
+
if (!class_exists($controller_class)) {
|
99 |
+
$this->error("Unknown controller '$controller_class'.");
|
100 |
+
}
|
101 |
+
|
102 |
+
$this->controller = new $controller_class();
|
103 |
+
$method = $this->query->get_method($controller);
|
104 |
+
|
105 |
+
if ($method) {
|
106 |
+
|
107 |
+
$this->response->setup();
|
108 |
+
|
109 |
+
// Run action hooks for method
|
110 |
+
do_action("json_api-{$controller}-$method");
|
111 |
+
|
112 |
+
// Error out if nothing is found
|
113 |
+
if ($method == '404') {
|
114 |
+
$this->error('Not found');
|
115 |
+
}
|
116 |
+
|
117 |
+
// Run the method
|
118 |
+
$result = $this->controller->$method();
|
119 |
+
|
120 |
+
// Handle the result
|
121 |
+
$this->response->respond($result);
|
122 |
+
|
123 |
+
// Done!
|
124 |
+
exit;
|
125 |
+
}
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
function admin_menu() {
|
130 |
+
add_options_page('JSON API Settings', 'JSON API', 'manage_options', 'json-api', array(&$this, 'admin_options'));
|
131 |
+
}
|
132 |
+
|
133 |
+
function admin_options() {
|
134 |
+
if (!current_user_can('manage_options')) {
|
135 |
+
wp_die( __('You do not have sufficient permissions to access this page.') );
|
136 |
+
}
|
137 |
+
|
138 |
+
$available_controllers = $this->get_controllers();
|
139 |
+
$active_controllers = explode(',', get_option('json_api_controllers', 'core'));
|
140 |
+
|
141 |
+
if (count($active_controllers) == 1 && empty($active_controllers[0])) {
|
142 |
+
$active_controllers = array();
|
143 |
+
}
|
144 |
+
|
145 |
+
if (!empty($_REQUEST['_wpnonce']) && wp_verify_nonce($_REQUEST['_wpnonce'], "update-options")) {
|
146 |
+
if ((!empty($_REQUEST['action']) || !empty($_REQUEST['action2'])) &&
|
147 |
+
(!empty($_REQUEST['controller']) || !empty($_REQUEST['controllers']))) {
|
148 |
+
if (!empty($_REQUEST['action'])) {
|
149 |
+
$action = $_REQUEST['action'];
|
150 |
+
} else {
|
151 |
+
$action = $_REQUEST['action2'];
|
152 |
+
}
|
153 |
+
|
154 |
+
if (!empty($_REQUEST['controllers'])) {
|
155 |
+
$controllers = $_REQUEST['controllers'];
|
156 |
+
} else {
|
157 |
+
$controllers = array($_REQUEST['controller']);
|
158 |
+
}
|
159 |
+
|
160 |
+
foreach ($controllers as $controller) {
|
161 |
+
if (in_array($controller, $available_controllers)) {
|
162 |
+
if ($action == 'activate' && !in_array($controller, $active_controllers)) {
|
163 |
+
$active_controllers[] = $controller;
|
164 |
+
} else if ($action == 'deactivate') {
|
165 |
+
$index = array_search($controller, $active_controllers);
|
166 |
+
if ($index !== false) {
|
167 |
+
unset($active_controllers[$index]);
|
168 |
+
}
|
169 |
+
}
|
170 |
+
}
|
171 |
+
}
|
172 |
+
$this->save_option('json_api_controllers', implode(',', $active_controllers));
|
173 |
+
}
|
174 |
+
if (isset($_REQUEST['json_api_base'])) {
|
175 |
+
$this->save_option('json_api_base', $_REQUEST['json_api_base']);
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
?>
|
180 |
+
<div class="wrap">
|
181 |
+
<div id="icon-options-general" class="icon32"><br /></div>
|
182 |
+
<h2>JSON API Settings</h2>
|
183 |
+
<form action="options-general.php?page=json-api" method="post">
|
184 |
+
<?php wp_nonce_field('update-options'); ?>
|
185 |
+
<h3>Controllers</h3>
|
186 |
+
<?php $this->print_controller_actions(); ?>
|
187 |
+
<table id="all-plugins-table" class="widefat">
|
188 |
+
<thead>
|
189 |
+
<tr>
|
190 |
+
<th class="manage-column check-column" scope="col"><input type="checkbox" /></th>
|
191 |
+
<th class="manage-column" scope="col">Controller</th>
|
192 |
+
<th class="manage-column" scope="col">Description</th>
|
193 |
+
</tr>
|
194 |
+
</thead>
|
195 |
+
<tfoot>
|
196 |
+
<tr>
|
197 |
+
<th class="manage-column check-column" scope="col"><input type="checkbox" /></th>
|
198 |
+
<th class="manage-column" scope="col">Controller</th>
|
199 |
+
<th class="manage-column" scope="col">Description</th>
|
200 |
+
</tr>
|
201 |
+
</tfoot>
|
202 |
+
<tbody class="plugins">
|
203 |
+
<?php
|
204 |
+
|
205 |
+
foreach ($available_controllers as $controller) {
|
206 |
+
|
207 |
+
$active = in_array($controller, $active_controllers);
|
208 |
+
$info = $this->controller_info($controller);
|
209 |
+
|
210 |
+
?>
|
211 |
+
<tr class="<?php echo ($active ? 'active' : 'inactive'); ?>">
|
212 |
+
<th class="check-column" scope="row">
|
213 |
+
<input type="checkbox" name="controllers[]" value="<?php echo $controller; ?>" />
|
214 |
+
</th>
|
215 |
+
<td class="plugin-title">
|
216 |
+
<strong><?php echo $info['name']; ?></strong>
|
217 |
+
<div class="row-actions-visible">
|
218 |
+
<?php
|
219 |
+
|
220 |
+
if ($active) {
|
221 |
+
echo '<a href="' . wp_nonce_url('options-general.php?page=json-api&action=deactivate&controller=' . $controller, 'update-options') . '" title="' . __('Deactivate this controller') . '" class="edit">' . __('Deactivate') . '</a>';
|
222 |
+
} else {
|
223 |
+
echo '<a href="' . wp_nonce_url('options-general.php?page=json-api&action=activate&controller=' . $controller, 'update-options') . '" title="' . __('Activate this controller') . '" class="edit">' . __('Activate') . '</a>';
|
224 |
+
}
|
225 |
+
|
226 |
+
if ($info['url']) {
|
227 |
+
echo ' | ';
|
228 |
+
echo '<a href="' . $info['url'] . '" target="_blank">Docs</a></div>';
|
229 |
+
}
|
230 |
+
|
231 |
+
?>
|
232 |
+
</td>
|
233 |
+
<td class="desc">
|
234 |
+
<p><?php echo $info['description']; ?></p>
|
235 |
+
<p>
|
236 |
+
<?php
|
237 |
+
|
238 |
+
foreach($info['methods'] as $method) {
|
239 |
+
$url = $this->get_method_url($controller, $method, array('dev' => 1));
|
240 |
+
if ($active) {
|
241 |
+
echo "<code><a href=\"$url\">$method</a></code> ";
|
242 |
+
} else {
|
243 |
+
echo "<code>$method</code> ";
|
244 |
+
}
|
245 |
+
}
|
246 |
+
|
247 |
+
?>
|
248 |
+
</p>
|
249 |
+
</td>
|
250 |
+
</tr>
|
251 |
+
<?php } ?>
|
252 |
+
</tbody>
|
253 |
+
</table>
|
254 |
+
<?php $this->print_controller_actions('action2'); ?>
|
255 |
+
<h3>Address</h3>
|
256 |
+
<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>
|
257 |
+
<table class="form-table">
|
258 |
+
<tr valign="top">
|
259 |
+
<th scope="row">API base</th>
|
260 |
+
<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>
|
261 |
+
</tr>
|
262 |
+
</table>
|
263 |
+
<?php if (!get_option('permalink_structure', '')) { ?>
|
264 |
+
<br />
|
265 |
+
<p><strong>Note:</strong> User-friendly permalinks are not currently enabled. <a target="_blank" class="button" href="options-permalink.php">Change Permalinks</a>
|
266 |
+
<?php } ?>
|
267 |
+
<p class="submit">
|
268 |
+
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
|
269 |
+
</p>
|
270 |
+
</form>
|
271 |
+
</div>
|
272 |
+
<?php
|
273 |
+
}
|
274 |
+
|
275 |
+
function print_controller_actions($name = 'action') {
|
276 |
+
?>
|
277 |
+
<div class="tablenav">
|
278 |
+
<div class="alignleft actions">
|
279 |
+
<select name="<?php echo $name; ?>">
|
280 |
+
<option selected="selected" value="-1">Bulk Actions</option>
|
281 |
+
<option value="activate">Activate</option>
|
282 |
+
<option value="deactivate">Deactivate</option>
|
283 |
+
</select>
|
284 |
+
<input type="submit" class="button-secondary action" id="doaction" name="doaction" value="Apply">
|
285 |
+
</div>
|
286 |
+
<div class="clear"></div>
|
287 |
+
</div>
|
288 |
+
<div class="clear"></div>
|
289 |
+
<?php
|
290 |
+
}
|
291 |
+
|
292 |
+
function get_method_url($controller, $method, $options = '') {
|
293 |
+
$url = get_bloginfo('url');
|
294 |
+
$base = get_option('json_api_base', 'api');
|
295 |
+
$permalink_structure = get_option('permalink_structure', '');
|
296 |
+
if (!empty($options) && is_array($options)) {
|
297 |
+
$args = array();
|
298 |
+
foreach ($options as $key => $value) {
|
299 |
+
$args[] = urlencode($key) . '=' . urlencode($value);
|
300 |
+
}
|
301 |
+
$args = implode('&', $args);
|
302 |
+
} else {
|
303 |
+
$args = $options;
|
304 |
+
}
|
305 |
+
if ($controller != 'core') {
|
306 |
+
$method = "$controller/$method";
|
307 |
+
}
|
308 |
+
if (!empty($base) && !empty($permalink_structure)) {
|
309 |
+
if (!empty($args)) {
|
310 |
+
$args = "?$args";
|
311 |
+
}
|
312 |
+
return "$url/$base/$method/$args";
|
313 |
+
} else {
|
314 |
+
return "$url?json=$method&$args";
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
function save_option($id, $value) {
|
319 |
+
$option_exists = (get_option($id, null) !== null);
|
320 |
+
if ($option_exists) {
|
321 |
+
update_option($id, $value);
|
322 |
+
} else {
|
323 |
+
add_option($id, $value);
|
324 |
+
}
|
325 |
+
}
|
326 |
+
|
327 |
+
function get_controllers() {
|
328 |
+
$controllers = array();
|
329 |
+
$dh = opendir(dirname(__FILE__) . '/controllers');
|
330 |
+
while ($file = readdir($dh)) {
|
331 |
+
if (preg_match('/(.+)\.php$/', $file, $matches)) {
|
332 |
+
$controllers[] = $matches[1];
|
333 |
+
}
|
334 |
+
}
|
335 |
+
return apply_filters('json_api_controllers', $controllers);
|
336 |
+
}
|
337 |
+
|
338 |
+
function controller_is_active($controller) {
|
339 |
+
$active_controllers = explode(',', get_option('json_api_controllers', 'core'));
|
340 |
+
return (in_array($controller, $active_controllers));
|
341 |
+
}
|
342 |
+
|
343 |
+
function update_controllers($controllers) {
|
344 |
+
if (is_array($controllers)) {
|
345 |
+
return implode(',', $controllers);
|
346 |
+
} else {
|
347 |
+
return $controllers;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
function controller_info($controller) {
|
352 |
+
$path = $this->controller_path($controller);
|
353 |
+
$class = $this->controller_class($controller);
|
354 |
+
$response = array(
|
355 |
+
'name' => $controller,
|
356 |
+
'description' => '(No description available)',
|
357 |
+
'methods' => array()
|
358 |
+
);
|
359 |
+
if (file_exists($path)) {
|
360 |
+
$source = file_get_contents($path);
|
361 |
+
if (preg_match('/^\s*Name:(.+)$/im', $source, $matches)) {
|
362 |
+
$response['name'] = trim($matches[1]);
|
363 |
+
}
|
364 |
+
if (preg_match('/^\s*Description:(.+)$/im', $source, $matches)) {
|
365 |
+
$response['description'] = trim($matches[1]);
|
366 |
+
}
|
367 |
+
if (preg_match('/^\s*Docs:(.+)$/im', $source, $matches)) {
|
368 |
+
$response['docs'] = trim($matches[1]);
|
369 |
+
}
|
370 |
+
require_once($path);
|
371 |
+
$response['methods'] = get_class_methods($class);
|
372 |
+
return $response;
|
373 |
+
} else {
|
374 |
+
$this->error("Unknown controller '$controller'.");
|
375 |
+
}
|
376 |
+
}
|
377 |
+
|
378 |
+
function controller_class($controller) {
|
379 |
+
return "json_api_{$controller}_controller";
|
380 |
+
}
|
381 |
+
|
382 |
+
function controller_path($controller) {
|
383 |
+
$dir = dirname(__FILE__);
|
384 |
+
$controller_class = $this->controller_class($controller);
|
385 |
+
return apply_filters("{$controller_class}_path", "$dir/controllers/$controller.php");
|
386 |
+
}
|
387 |
+
|
388 |
+
function get_nonce_id($controller, $method) {
|
389 |
+
$controller = strtolower($controller);
|
390 |
+
$method = strtolower($method);
|
391 |
+
return "json_api-$controller-$method";
|
392 |
+
}
|
393 |
+
|
394 |
+
function flush_rewrite_rules() {
|
395 |
+
global $wp_rewrite;
|
396 |
+
$wp_rewrite->flush_rules();
|
397 |
+
}
|
398 |
+
|
399 |
+
function error($message = 'Unknown error', $status = 'error') {
|
400 |
+
$this->response->respond(array(
|
401 |
+
'error' => $message
|
402 |
+
), $status);
|
403 |
+
}
|
404 |
+
|
405 |
+
function include_value($key) {
|
406 |
+
return $this->response->is_value_included($key);
|
407 |
+
}
|
408 |
+
|
409 |
+
}
|
410 |
|
411 |
?>
|
models/attachment.php
CHANGED
@@ -37,6 +37,9 @@ class JSON_API_Attachment {
|
|
37 |
|
38 |
function query_images() {
|
39 |
$sizes = array('thumbnail', 'medium', 'large', 'full');
|
|
|
|
|
|
|
40 |
$this->images = array();
|
41 |
foreach ($sizes as $size) {
|
42 |
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
|
37 |
|
38 |
function query_images() {
|
39 |
$sizes = array('thumbnail', 'medium', 'large', 'full');
|
40 |
+
if (function_exists('get_intermediate_image_sizes')) {
|
41 |
+
$sizes = array_merge(array('full'), get_intermediate_image_sizes());
|
42 |
+
}
|
43 |
$this->images = array();
|
44 |
foreach ($sizes as $size) {
|
45 |
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
|
models/post.php
CHANGED
@@ -6,6 +6,7 @@ class JSON_API_Post {
|
|
6 |
// JSON_API_Post objects must be instantiated within The Loop.
|
7 |
|
8 |
var $id; // Integer
|
|
|
9 |
var $slug; // String
|
10 |
var $url; // String
|
11 |
var $status; // String ("draft", "published", or "pending")
|
@@ -56,6 +57,10 @@ class JSON_API_Post {
|
|
56 |
$wp_values['ID'] = $values['id'];
|
57 |
}
|
58 |
|
|
|
|
|
|
|
|
|
59 |
if (!empty($values['status'])) {
|
60 |
$wp_values['post_status'] = $values['status'];
|
61 |
}
|
@@ -124,11 +129,12 @@ class JSON_API_Post {
|
|
124 |
$date_format = $json_api->query->date_format;
|
125 |
$this->id = (int) $wp_post->ID;
|
126 |
setup_postdata($wp_post);
|
|
|
127 |
$this->set_value('slug', $wp_post->post_name);
|
128 |
$this->set_value('url', get_permalink($this->id));
|
129 |
$this->set_value('status', $wp_post->post_status);
|
130 |
$this->set_value('title', get_the_title($this->id));
|
131 |
-
$this->set_value('title_plain', strip_tags(
|
132 |
$this->set_content_value();
|
133 |
$this->set_value('excerpt', get_the_excerpt());
|
134 |
$this->set_value('date', get_the_time($date_format));
|
@@ -160,6 +166,8 @@ class JSON_API_Post {
|
|
160 |
$content = apply_filters('the_content', $content);
|
161 |
$content = str_replace(']]>', ']]>', $content);
|
162 |
$this->content = $content;
|
|
|
|
|
163 |
}
|
164 |
}
|
165 |
|
@@ -177,6 +185,8 @@ class JSON_API_Post {
|
|
177 |
$this->categories[] = $category;
|
178 |
}
|
179 |
}
|
|
|
|
|
180 |
}
|
181 |
}
|
182 |
|
@@ -189,6 +199,8 @@ class JSON_API_Post {
|
|
189 |
$this->tags[] = new JSON_API_Tag($wp_tag);
|
190 |
}
|
191 |
}
|
|
|
|
|
192 |
}
|
193 |
}
|
194 |
|
@@ -196,6 +208,8 @@ class JSON_API_Post {
|
|
196 |
global $json_api;
|
197 |
if ($json_api->include_value('author')) {
|
198 |
$this->author = new JSON_API_Author($author_id);
|
|
|
|
|
199 |
}
|
200 |
}
|
201 |
|
@@ -203,6 +217,8 @@ class JSON_API_Post {
|
|
203 |
global $json_api;
|
204 |
if ($json_api->include_value('comments')) {
|
205 |
$this->comments = $json_api->introspector->get_comments($this->id);
|
|
|
|
|
206 |
}
|
207 |
}
|
208 |
|
@@ -210,24 +226,26 @@ class JSON_API_Post {
|
|
210 |
global $json_api;
|
211 |
if ($json_api->include_value('attachments')) {
|
212 |
$this->attachments = $json_api->introspector->get_attachments($this->id);
|
|
|
|
|
213 |
}
|
214 |
}
|
215 |
|
216 |
function set_thumbnail_value() {
|
217 |
global $json_api;
|
218 |
-
|
219 |
-
|
220 |
unset($this->thumbnail);
|
221 |
return;
|
222 |
}
|
223 |
-
$
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
$this->thumbnail = $image->url;
|
228 |
-
break;
|
229 |
-
}
|
230 |
}
|
|
|
|
|
|
|
231 |
}
|
232 |
|
233 |
function set_custom_fields_value() {
|
@@ -247,6 +265,16 @@ class JSON_API_Post {
|
|
247 |
}
|
248 |
}
|
249 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
250 |
}
|
251 |
|
252 |
?>
|
6 |
// JSON_API_Post objects must be instantiated within The Loop.
|
7 |
|
8 |
var $id; // Integer
|
9 |
+
var $type; // String
|
10 |
var $slug; // String
|
11 |
var $url; // String
|
12 |
var $status; // String ("draft", "published", or "pending")
|
57 |
$wp_values['ID'] = $values['id'];
|
58 |
}
|
59 |
|
60 |
+
if (!empty($values['type'])) {
|
61 |
+
$wp_values['post_type'] = $values['type'];
|
62 |
+
}
|
63 |
+
|
64 |
if (!empty($values['status'])) {
|
65 |
$wp_values['post_status'] = $values['status'];
|
66 |
}
|
129 |
$date_format = $json_api->query->date_format;
|
130 |
$this->id = (int) $wp_post->ID;
|
131 |
setup_postdata($wp_post);
|
132 |
+
$this->set_value('type', $wp_post->post_type);
|
133 |
$this->set_value('slug', $wp_post->post_name);
|
134 |
$this->set_value('url', get_permalink($this->id));
|
135 |
$this->set_value('status', $wp_post->post_status);
|
136 |
$this->set_value('title', get_the_title($this->id));
|
137 |
+
$this->set_value('title_plain', strip_tags(@$this->title));
|
138 |
$this->set_content_value();
|
139 |
$this->set_value('excerpt', get_the_excerpt());
|
140 |
$this->set_value('date', get_the_time($date_format));
|
166 |
$content = apply_filters('the_content', $content);
|
167 |
$content = str_replace(']]>', ']]>', $content);
|
168 |
$this->content = $content;
|
169 |
+
} else {
|
170 |
+
unset($this->content);
|
171 |
}
|
172 |
}
|
173 |
|
185 |
$this->categories[] = $category;
|
186 |
}
|
187 |
}
|
188 |
+
} else {
|
189 |
+
unset($this->categories);
|
190 |
}
|
191 |
}
|
192 |
|
199 |
$this->tags[] = new JSON_API_Tag($wp_tag);
|
200 |
}
|
201 |
}
|
202 |
+
} else {
|
203 |
+
unset($this->tags);
|
204 |
}
|
205 |
}
|
206 |
|
208 |
global $json_api;
|
209 |
if ($json_api->include_value('author')) {
|
210 |
$this->author = new JSON_API_Author($author_id);
|
211 |
+
} else {
|
212 |
+
unset($this->author);
|
213 |
}
|
214 |
}
|
215 |
|
217 |
global $json_api;
|
218 |
if ($json_api->include_value('comments')) {
|
219 |
$this->comments = $json_api->introspector->get_comments($this->id);
|
220 |
+
} else {
|
221 |
+
unset($this->comments);
|
222 |
}
|
223 |
}
|
224 |
|
226 |
global $json_api;
|
227 |
if ($json_api->include_value('attachments')) {
|
228 |
$this->attachments = $json_api->introspector->get_attachments($this->id);
|
229 |
+
} else {
|
230 |
+
unset($this->attachments);
|
231 |
}
|
232 |
}
|
233 |
|
234 |
function set_thumbnail_value() {
|
235 |
global $json_api;
|
236 |
+
if (!$json_api->include_value('thumbnail') ||
|
237 |
+
!function_exists('get_post_thumbnail_id')) {
|
238 |
unset($this->thumbnail);
|
239 |
return;
|
240 |
}
|
241 |
+
$attachment_id = get_post_thumbnail_id($this->id);
|
242 |
+
if (!$attachment_id) {
|
243 |
+
unset($this->thumbnail);
|
244 |
+
return;
|
|
|
|
|
|
|
245 |
}
|
246 |
+
$thumbnail_size = $this->get_thumbnail_size();
|
247 |
+
list($thumbnail) = wp_get_attachment_image_src($attachment_id, $thumbnail_size);
|
248 |
+
$this->thumbnail = $thumbnail;
|
249 |
}
|
250 |
|
251 |
function set_custom_fields_value() {
|
265 |
}
|
266 |
}
|
267 |
|
268 |
+
function get_thumbnail_size() {
|
269 |
+
if (function_exists('get_intermediate_image_sizes')) {
|
270 |
+
$sizes = get_intermediate_image_sizes();
|
271 |
+
if (in_array('post-thumbnail', $sizes)) {
|
272 |
+
return 'post-thumbnail';
|
273 |
+
}
|
274 |
+
}
|
275 |
+
return 'thumbnail';
|
276 |
+
}
|
277 |
+
|
278 |
}
|
279 |
|
280 |
?>
|
readme.txt
CHANGED
@@ -1,44 +1,76 @@
|
|
1 |
=== JSON API ===
|
2 |
Contributors: dphiffer
|
|
|
3 |
Tags: json, api, ajax, cms, admin, integration, moma
|
4 |
Requires at least: 2.8
|
5 |
-
Tested up to:
|
6 |
-
Stable tag: 0
|
7 |
|
8 |
A RESTful API for WordPress
|
9 |
|
10 |
== Description ==
|
11 |
|
12 |
-
|
13 |
|
14 |
-
|
|
|
|
|
15 |
|
16 |
-
|
|
|
|
|
17 |
|
18 |
== Installation ==
|
19 |
|
20 |
1. Upload the `json-api` folder to the `/wp-content/plugins/` directory or install directly through the plugin installer.
|
21 |
-
|
22 |
|
23 |
== Screenshots ==
|
24 |
|
25 |
1. Our old friend, in JSON format
|
26 |
|
27 |
-
==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
Requests use a simple REST-style HTTP GET or POST. To invoke the API, include a non-empty query value for `json` in the URL.
|
30 |
|
31 |
JSON API operates in two modes:
|
32 |
|
33 |
1. *Implicit mode* is triggered by setting the `json` query var to a non-empty value on any WordPress page. The content that would normally appear on that page is returned in JSON format.
|
34 |
-
|
35 |
|
36 |
= Implicit mode examples: =
|
37 |
|
38 |
* `http://www.example.org/?json=1`
|
39 |
* `http://www.example.org/?p=47&json=1`
|
40 |
* `http://www.example.org/tag/banana/?json=1`
|
41 |
-
|
42 |
= Explicit mode examples: =
|
43 |
|
44 |
* `http://www.example.org/?json=get_recent_posts`
|
@@ -51,7 +83,37 @@ JSON API operates in two modes:
|
|
51 |
* `http://www.example.org/api/get_post/?post_id=47`
|
52 |
* `http://www.example.org/api/get_tag_posts/?tag_slug=banana`
|
53 |
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
The standard response format for JSON API is (as you may have guessed) [JSON](http://json.org/).
|
57 |
|
@@ -65,6 +127,7 @@ Here is an example response from `http://localhost/wordpress/?json=1` called on
|
|
65 |
"posts": [
|
66 |
{
|
67 |
"id": 1,
|
|
|
68 |
"slug": "hello-world",
|
69 |
"url": "http:\/\/localhost\/wordpress\/?p=1",
|
70 |
"title": "Hello world!",
|
@@ -101,166 +164,44 @@ Here is an example response from `http://localhost/wordpress/?json=1` called on
|
|
101 |
]
|
102 |
}
|
103 |
|
104 |
-
==
|
105 |
-
|
106 |
-
The JSON API reference is split into four sections:
|
107 |
-
|
108 |
-
1. Request arguments
|
109 |
-
1. Response objects
|
110 |
-
1. Plugin hooks
|
111 |
-
1. Introspection methods
|
112 |
-
1. Data manipulation methods
|
113 |
-
|
114 |
-
__About API changes__
|
115 |
-
All methods are currently subject to change until the plugin reaches maturity. Please read the the changelog carefully before updating to subsequent releases.
|
116 |
-
|
117 |
-
== 1. Request arguments ==
|
118 |
-
|
119 |
-
The following arguments modify how you get results back from the API. The redirect response styles are intended for use with the data manipulation methods.
|
120 |
-
|
121 |
-
* Setting `callback` to a JavaScript function name will trigger a JSONP-style callback.
|
122 |
-
* Setting `redirect` to a URL will cause the user's browser to redirect to the specified URL with a `status` value appended to the query vars (see the *Response objects* section below for an explanation of status values).
|
123 |
-
* Setting `redirect_[status]` allows you to control the resulting browser redirection depending on the `status` value.
|
124 |
-
* Setting `dev` to a non-empty value formats a plain text response using PHP's `print_r()` function.
|
125 |
-
* Not setting any of the above argument values will result in a standard JSON response.
|
126 |
-
|
127 |
-
These arguments are available to modify all introspection methods:
|
128 |
-
|
129 |
-
* `date_format` - Changes the format of date values. Uses the same syntax as PHP's date() function. Default value is `Y-m-d H:i:s`.
|
130 |
-
* `read_more` - Changes the 'read more' link text in post content.
|
131 |
-
* `include` - Specifies which post data fields to include. Expects a comma-separated list of post fields. Leaving this empty includes *all* fields.
|
132 |
-
* `exclude` - Specifies which post data fields to exclude. Expects a comma-separated list of post fields.
|
133 |
-
* `custom_fields` - Includes values from posts' Custom Fields. Expects a comma-separated list of custom field keys.
|
134 |
-
* `author_meta` - Includes additional author metadata. Should be a comma-separated list of metadata fields.
|
135 |
-
* `count` - Controls the number of posts to include (defaults to the number specified by WordPress)
|
136 |
-
|
137 |
-
__About `include`/`exclude` arguments__
|
138 |
-
By default you get all values included with each post object. Specify a list of `include` values will cause the post object to filter out the values absent from the list. Specifying `exclude` causes post objects to include all values except the fields you list. For example, the query `exclude=comments` includes everything *except* the comments.
|
139 |
-
|
140 |
-
== 2. Response objects ==
|
141 |
-
|
142 |
-
This section describes data objects you can retrieve from WordPress and the optional URL redirects.
|
143 |
-
|
144 |
-
__Status values__
|
145 |
-
All JSON API requests result in a status value. The two basic status values are `ok` and `error`. Additional status values are available for certain methods (such as `pending` in the case of the `submit_comment` method). API methods that result in custom status values include a *custom status values* section in their documentation.
|
146 |
-
|
147 |
-
__Naming compatibility__
|
148 |
-
Developers familiar with WordPress may notice that many names for properties and arguments have been changed. This was a stylistic choice that intends to provide more clarity and consistency in the interface.
|
149 |
-
|
150 |
-
= Post response object =
|
151 |
-
|
152 |
-
* `id` - Integer
|
153 |
-
* `slug` - String
|
154 |
-
* `url` - String
|
155 |
-
* `title` - String
|
156 |
-
* `title_plain` - String
|
157 |
-
* `content` - String (modified by the `read_more` argument)
|
158 |
-
* `excerpt` - String
|
159 |
-
* `date` - String (modified by the `date_format` argument)
|
160 |
-
* `modified` - String (modified by the `date_format` argument)
|
161 |
-
* `categories` - Array of category objects
|
162 |
-
* `tags` - Array of tag objects
|
163 |
-
* `author` Author object
|
164 |
-
* `comments` - Array of comment objects
|
165 |
-
* `attachments` - Array of attachment objects
|
166 |
-
* `comment_count` - Integer
|
167 |
-
* `comment_status` - String (`"open"` or `"closed"`)
|
168 |
-
* `thumbnail` - String (only included if a post thumbnail has been specified)
|
169 |
-
* `custom_fields` - Object (included by setting the `custom_fields` argument to a comma-separated list of custom field names)
|
170 |
|
171 |
-
|
172 |
|
173 |
-
|
174 |
-
* `slug` - String
|
175 |
-
* `title` - String
|
176 |
-
* `description` - String
|
177 |
-
* `parent` - Integer
|
178 |
-
* `post_count` - Integer
|
179 |
|
180 |
-
|
181 |
-
|
182 |
-
* `id` - Integer
|
183 |
-
* `slug` - String
|
184 |
-
* `title` - String
|
185 |
-
* `description` - String
|
186 |
-
* `post_count` - Integer
|
187 |
|
188 |
-
= Author response object =
|
189 |
|
190 |
-
|
191 |
-
* `slug` - String
|
192 |
-
* `name` - String
|
193 |
-
* `first_name` - String
|
194 |
-
* `last_name` - String
|
195 |
-
* `nickname` - String
|
196 |
-
* `url` - String
|
197 |
-
* `description` - String
|
198 |
-
|
199 |
-
Note: You can include additional values by setting the `author_meta` argument to a comma-separated list of metadata fields.
|
200 |
|
201 |
-
|
202 |
|
203 |
-
|
204 |
-
* `name` - String
|
205 |
-
* `url` - String
|
206 |
-
* `date` - String
|
207 |
-
* `content` - String
|
208 |
-
* `parent` - Integer
|
209 |
-
* `author` - Object (only set if the comment author was registered & logged in)
|
210 |
-
|
211 |
-
= Attachment response object =
|
212 |
-
|
213 |
-
* `id` - Integer
|
214 |
-
* `url` - String
|
215 |
-
* `slug` - String
|
216 |
-
* `title` - String
|
217 |
-
* `description` - String
|
218 |
-
* `caption` - String
|
219 |
-
* `parent` - Integer
|
220 |
-
* `mime_type` - String
|
221 |
-
* `images` - Object with values `thumbnail`, `medium`, `large`, `full`, each of which are objects with values `url`, `width` and `height` (only set if the attachment is an image)
|
222 |
-
|
223 |
-
== Redirects ==
|
224 |
-
|
225 |
-
The `redirect` response style is useful for when you need the user's browser to make a request directly rather than making proxy requests using a tool like cURL. Setting a `redirect` argument causes the user's browser to redirect back to the specified URL instead of returning a JSON object. The resulting `status` value is included as an extra query variable.
|
226 |
-
|
227 |
-
For example calling an API method with `redirect` set to `http://www.example.com/foo` will result in a redirection to one of the following:
|
228 |
-
|
229 |
-
* `http://www.example.com/foo?status=ok`
|
230 |
-
* `http://www.example.com/foo?status=error`
|
231 |
-
|
232 |
-
You can also set separate URLs to handle status values differently. You could set `redirect_ok` to `http://www.example.com/handle_ok` and `redirect_error` to `http://www.example.com/handle_error` in order to have more fine-tuned control over the method result.
|
233 |
-
|
234 |
-
== 3. Plugin hooks ==
|
235 |
|
236 |
-
|
237 |
|
238 |
-
|
239 |
|
240 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
241 |
|
242 |
-
=
|
243 |
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
}
|
252 |
-
return $response;
|
253 |
}
|
254 |
|
255 |
-
add_kittens_field(&$post) {
|
256 |
-
$post->kittens = 'Kittens!';
|
257 |
-
}
|
258 |
-
|
259 |
-
|
260 |
-
== 4. Introspection methods ==
|
261 |
-
|
262 |
-
Introspection methods are used to retrieve data from WordPress.
|
263 |
-
|
264 |
|
265 |
== Method: get_recent_posts ==
|
266 |
|
@@ -292,8 +233,8 @@ Returns a single post object.
|
|
292 |
= One of the following is required =
|
293 |
|
294 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a post URL
|
295 |
-
* `post_id` - set to the post's ID
|
296 |
-
* `post_slug` - set to the post's URL slug
|
297 |
|
298 |
= Response =
|
299 |
|
@@ -310,8 +251,12 @@ Returns a single page object.
|
|
310 |
= One of the following is required =
|
311 |
|
312 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a page URL
|
313 |
-
* `page_id` - set to the page's ID
|
314 |
-
* `page_slug` - set to the page's URL slug
|
|
|
|
|
|
|
|
|
315 |
|
316 |
= Response =
|
317 |
|
@@ -327,7 +272,7 @@ Returns an array of posts/pages in a specific category.
|
|
327 |
= One of the following is required =
|
328 |
|
329 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a date archive page
|
330 |
-
* `date` - set to a date in the format `YYYY` or `
|
331 |
|
332 |
= Optional arguments =
|
333 |
|
@@ -354,8 +299,8 @@ Returns an array of posts/pages in a specific category.
|
|
354 |
= One of the following is required =
|
355 |
|
356 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a category archive page
|
357 |
-
* `category_id` - set to the category's ID
|
358 |
-
* `category_slug` - set to the category's URL slug
|
359 |
|
360 |
= Optional arguments =
|
361 |
|
@@ -384,8 +329,8 @@ Returns an array of posts/pages with a specific tag.
|
|
384 |
= One of the following is required =
|
385 |
|
386 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a tag archive page
|
387 |
-
* `tag_id` - set to the tag's ID
|
388 |
-
* `tag_slug` - set to the tag's URL slug
|
389 |
|
390 |
= Optional arguments =
|
391 |
|
@@ -414,8 +359,8 @@ Returns an array of posts/pages written by a specific author.
|
|
414 |
= One of the following is required =
|
415 |
|
416 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on an author archive page
|
417 |
-
* `author_id` - set to the author's ID
|
418 |
-
* `author_slug` - set to the author's URL slug
|
419 |
|
420 |
= Optional arguments =
|
421 |
|
@@ -540,18 +485,50 @@ Returns an array of active blog authors.
|
|
540 |
}
|
541 |
|
542 |
|
543 |
-
==
|
|
|
|
|
|
|
|
|
544 |
|
545 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
546 |
|
547 |
-
|
548 |
-
The data manipulation methods are still very incomplete.
|
549 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
550 |
|
551 |
== Method: create_post ==
|
552 |
|
553 |
Creates a new post.
|
554 |
|
|
|
|
|
|
|
|
|
555 |
= Optional arguments =
|
556 |
|
557 |
* `status` - sets the post status ("draft" or "publish"), default is "draft"
|
@@ -563,6 +540,9 @@ Creates a new post.
|
|
563 |
|
564 |
Note: including a file upload field called `attachment` will cause an attachment to be stored with your new post.
|
565 |
|
|
|
|
|
|
|
566 |
== Method: submit_comment ==
|
567 |
|
568 |
Submits a comment to a WordPress post.
|
@@ -586,8 +566,296 @@ Submits a comment to a WordPress post.
|
|
586 |
* `pending` - assigned if the comment submission is pending moderation
|
587 |
|
588 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
589 |
== Changelog ==
|
590 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
591 |
= 0.9.6 (2010-05-27): =
|
592 |
* Fixed a bug introduced in 0.9.5
|
593 |
|
@@ -641,6 +909,9 @@ Submits a comment to a WordPress post.
|
|
641 |
|
642 |
== Upgrade Notice ==
|
643 |
|
|
|
|
|
|
|
644 |
= 0.9.6 =
|
645 |
Bugfix release for something added in 0.9.5.
|
646 |
|
1 |
=== JSON API ===
|
2 |
Contributors: dphiffer
|
3 |
+
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=DH4MEG99JR2WE
|
4 |
Tags: json, api, ajax, cms, admin, integration, moma
|
5 |
Requires at least: 2.8
|
6 |
+
Tested up to: 3.0
|
7 |
+
Stable tag: 1.0
|
8 |
|
9 |
A RESTful API for WordPress
|
10 |
|
11 |
== Description ==
|
12 |
|
13 |
+
JSON API allows you to retrieve and manipulate WordPress content using HTTP requests. There are three main goals:
|
14 |
|
15 |
+
1. Provide a simple, consistent external interface
|
16 |
+
2. Create a stable, understandable internal implementation
|
17 |
+
3. Enable new types of extensions for WordPress
|
18 |
|
19 |
+
This plugin was created at [The Museum of Modern Art](http://moma.org/) for the weblog [Inside/Out](http://moma.org/explore/inside_out), which is served from Ruby on Rails. Instead of reimplementing the site templates as a WordPress theme, we opted for a Rails front-end that displays content served from a WordPress back-end. JSON API provides the necessary interface for retrieving content and accepting comment submissions.
|
20 |
+
|
21 |
+
See the [Other Notes](http://wordpress.org/extend/plugins/json-api/other_notes/) section for the complete documentation.
|
22 |
|
23 |
== Installation ==
|
24 |
|
25 |
1. Upload the `json-api` folder to the `/wp-content/plugins/` directory or install directly through the plugin installer.
|
26 |
+
2. Activate the plugin through the 'Plugins' menu in WordPress or by using the link provided by the plugin installer.
|
27 |
|
28 |
== Screenshots ==
|
29 |
|
30 |
1. Our old friend, in JSON format
|
31 |
|
32 |
+
== Documentation ==
|
33 |
+
|
34 |
+
1. General concepts
|
35 |
+
1.1. Requests
|
36 |
+
1.2. Controllers
|
37 |
+
1.3. Responses
|
38 |
+
2. Request methods
|
39 |
+
2.1. Core controller methods
|
40 |
+
2.2. Posts controller methods
|
41 |
+
2.3. Respond controller methods
|
42 |
+
3. Request arguments
|
43 |
+
3.1. Output-modifying arguments
|
44 |
+
3.2. Content-modifying arguments
|
45 |
+
3.3. Using query_posts, include/exclude, and redirects
|
46 |
+
4. Response objects
|
47 |
+
4.1. Post response object
|
48 |
+
4.2. Category response object
|
49 |
+
4.3. Tag response object
|
50 |
+
4.4. Author response object
|
51 |
+
4.4. Comment response object
|
52 |
+
4.5. Attachment response object
|
53 |
+
5. Extending JSON API
|
54 |
+
5.1. Plugin hooks
|
55 |
+
5.2. Developing JSON API controllers
|
56 |
+
|
57 |
+
== 1. General Concepts ==
|
58 |
+
|
59 |
+
== 1.1. Requests ==
|
60 |
|
61 |
Requests use a simple REST-style HTTP GET or POST. To invoke the API, include a non-empty query value for `json` in the URL.
|
62 |
|
63 |
JSON API operates in two modes:
|
64 |
|
65 |
1. *Implicit mode* is triggered by setting the `json` query var to a non-empty value on any WordPress page. The content that would normally appear on that page is returned in JSON format.
|
66 |
+
2. *Explicit mode* is triggered by setting `json` to a known method string. See the *API Reference* section below for a complete method listing.
|
67 |
|
68 |
= Implicit mode examples: =
|
69 |
|
70 |
* `http://www.example.org/?json=1`
|
71 |
* `http://www.example.org/?p=47&json=1`
|
72 |
* `http://www.example.org/tag/banana/?json=1`
|
73 |
+
|
74 |
= Explicit mode examples: =
|
75 |
|
76 |
* `http://www.example.org/?json=get_recent_posts`
|
83 |
* `http://www.example.org/api/get_post/?post_id=47`
|
84 |
* `http://www.example.org/api/get_tag_posts/?tag_slug=banana`
|
85 |
|
86 |
+
__Further reading__
|
87 |
+
See Section 3: Request arguments for more information about request arguments to modify the response.
|
88 |
+
|
89 |
+
== 1.2. Controllers ==
|
90 |
+
|
91 |
+
The 1.0 release of JSON API introduced a modular controller system. This allows developers to flexibly add features to the API and give users more control over which methods they have enabled.
|
92 |
+
|
93 |
+
= The Core controller =
|
94 |
+
|
95 |
+
Most of the methods available prior to version 1.0 have been moved to the Core controller. The two exceptions are `submit_comment` and `create_post` which are now available from the Respond and Posts controllers, respectively. The Core controller is the only one enabled by default. All other functionality must be enabled from the JSON API Settings page (under Settings in the WordPress admin menu).
|
96 |
+
|
97 |
+
= Specifying a controller =
|
98 |
+
|
99 |
+
There are a few ways of specifying a controller, depending on how you are calling the API:
|
100 |
+
|
101 |
+
* `http://www.example.org/?json=get_recent_posts` (`core` controller is implied, method is `get_recent_posts`)
|
102 |
+
* `http://www.example.org/api/info/` (`core` controller is implied)
|
103 |
+
* `http://www.example.org/api/core/get_category_posts/` (`core` controller can also be explicitly specified)
|
104 |
+
* `http://www.example.org/?json=respond.submit_comment` (`respond` controller, `submit_comment` method)
|
105 |
+
|
106 |
+
__Legacy compatibility__
|
107 |
+
JSON API retains support for its pre-1.0 methods. For example, if you invoke the method `create_post` without a controller specified, the Posts controller is chosen instead of Core.
|
108 |
+
|
109 |
+
= Available controllers =
|
110 |
+
|
111 |
+
The current release includes three controllers: Core, Posts, and Respond. Developers are encouraged to suggest or submit additional controllers.
|
112 |
+
|
113 |
+
__Further reading__
|
114 |
+
See Section 2: Request methods for a complete reference of available controllers and methods. For documentation on extending JSON API with new controllers see Section 5.2: Developing JSON API Controllers.
|
115 |
+
|
116 |
+
== 1.3. Responses ==
|
117 |
|
118 |
The standard response format for JSON API is (as you may have guessed) [JSON](http://json.org/).
|
119 |
|
127 |
"posts": [
|
128 |
{
|
129 |
"id": 1,
|
130 |
+
"type": "post",
|
131 |
"slug": "hello-world",
|
132 |
"url": "http:\/\/localhost\/wordpress\/?p=1",
|
133 |
"title": "Hello world!",
|
164 |
]
|
165 |
}
|
166 |
|
167 |
+
== 2. Request methods ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
+
The JSON API reference is split into the following sections:
|
170 |
|
171 |
+
== 2.1. Core controller methods ==
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
+
The Core controller offers a mostly-complete set of introspection methods for retrieving content from WordPress.
|
|
|
|
|
|
|
|
|
|
|
|
|
174 |
|
|
|
175 |
|
176 |
+
== Method: info ==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
|
178 |
+
Returns information about JSON API.
|
179 |
|
180 |
+
= Optional arguments =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
|
182 |
+
* `controller` - returns detailed information about a specific controller
|
183 |
|
184 |
+
= Response =
|
185 |
|
186 |
+
{
|
187 |
+
"status": "ok",
|
188 |
+
"json_api_version": "1.0",
|
189 |
+
"controllers": [
|
190 |
+
"core"
|
191 |
+
]
|
192 |
+
}
|
193 |
|
194 |
+
= Response =
|
195 |
|
196 |
+
{
|
197 |
+
"status": "ok",
|
198 |
+
"name": "Core",
|
199 |
+
"description": "Basic introspection methods",
|
200 |
+
"methods": [
|
201 |
+
...
|
202 |
+
]
|
|
|
|
|
203 |
}
|
204 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
== Method: get_recent_posts ==
|
207 |
|
233 |
= One of the following is required =
|
234 |
|
235 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a post URL
|
236 |
+
* `id` or `post_id` - set to the post's ID
|
237 |
+
* `slug` or `post_slug` - set to the post's URL slug
|
238 |
|
239 |
= Response =
|
240 |
|
251 |
= One of the following is required =
|
252 |
|
253 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a page URL
|
254 |
+
* `id` or `page_id` - set to the page's ID
|
255 |
+
* `slug` or `page_slug` - set to the page's URL slug
|
256 |
+
|
257 |
+
= Optional arguments =
|
258 |
+
|
259 |
+
* `children` - set to a non-empty value to include a recursive hierarchy of child pages
|
260 |
|
261 |
= Response =
|
262 |
|
272 |
= One of the following is required =
|
273 |
|
274 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a date archive page
|
275 |
+
* `date` - set to a date in the format `YYYY` or `YYYY-MM` or `YYYY-MM-DD` (non-numeric characters are stripped from the var, so `YYYYMMDD` or `YYYY/MM/DD` are also valid)
|
276 |
|
277 |
= Optional arguments =
|
278 |
|
299 |
= One of the following is required =
|
300 |
|
301 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a category archive page
|
302 |
+
* `id` or `category_id` - set to the category's ID
|
303 |
+
* `slug` or `category_slug` - set to the category's URL slug
|
304 |
|
305 |
= Optional arguments =
|
306 |
|
329 |
= One of the following is required =
|
330 |
|
331 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on a tag archive page
|
332 |
+
* `id` or `tag_id` - set to the tag's ID
|
333 |
+
* `slug` or `tag_slug` - set to the tag's URL slug
|
334 |
|
335 |
= Optional arguments =
|
336 |
|
359 |
= One of the following is required =
|
360 |
|
361 |
* Invoking the JSON API implicitly (i.e., `?json=1`) on an author archive page
|
362 |
+
* `id` or `author_id` - set to the author's ID
|
363 |
+
* `slug` or `author_slug` - set to the author's URL slug
|
364 |
|
365 |
= Optional arguments =
|
366 |
|
485 |
}
|
486 |
|
487 |
|
488 |
+
== Method: get_page_index ==
|
489 |
+
|
490 |
+
Returns a hierarchical tree of `page` posts.
|
491 |
+
|
492 |
+
= Response =
|
493 |
|
494 |
+
{
|
495 |
+
"status": "ok",
|
496 |
+
"pages": [
|
497 |
+
{ ... },
|
498 |
+
{ ... },
|
499 |
+
{ ... }
|
500 |
+
]
|
501 |
+
}
|
502 |
|
503 |
+
== Method: get_nonce ==
|
|
|
504 |
|
505 |
+
Returns a WordPress nonce value, required to call some data manipulation methods.
|
506 |
+
|
507 |
+
= Required arguments =
|
508 |
+
|
509 |
+
* `controller` - the JSON API controller
|
510 |
+
* `method` - the JSON API method
|
511 |
+
|
512 |
+
= Response =
|
513 |
+
|
514 |
+
{
|
515 |
+
"status": "ok",
|
516 |
+
"controller": "posts",
|
517 |
+
"method": "create_post",
|
518 |
+
"nonce": "cefe01efd4"
|
519 |
+
}
|
520 |
+
|
521 |
+
|
522 |
+
= 2.2. Pages controller methods =
|
523 |
|
524 |
== Method: create_post ==
|
525 |
|
526 |
Creates a new post.
|
527 |
|
528 |
+
= Required argument =
|
529 |
+
|
530 |
+
* `nonce` - a security check value, available from the `get_nonce` method
|
531 |
+
|
532 |
= Optional arguments =
|
533 |
|
534 |
* `status` - sets the post status ("draft" or "publish"), default is "draft"
|
540 |
|
541 |
Note: including a file upload field called `attachment` will cause an attachment to be stored with your new post.
|
542 |
|
543 |
+
|
544 |
+
= 2.3. Respond controller methods =
|
545 |
+
|
546 |
== Method: submit_comment ==
|
547 |
|
548 |
Submits a comment to a WordPress post.
|
566 |
* `pending` - assigned if the comment submission is pending moderation
|
567 |
|
568 |
|
569 |
+
== 3. Request arguments ==
|
570 |
+
|
571 |
+
API requests can be controlled by specifying one of the following arguments as URL query vars.
|
572 |
+
|
573 |
+
= Examples =
|
574 |
+
|
575 |
+
* Debug the response: `http://www.example.org/api/get_page_index/?dev=1`
|
576 |
+
* Widget-style JSONP output: `http://www.example.org/api/get_recent_posts/?callback=show_posts_widget&read_more=More&count=3`
|
577 |
+
* Redirect on error: `http://www.example.org/api/posts/create_post/?callback_error=http%3A%2F%2Fwww.example.org%2Fhelp.html`
|
578 |
+
|
579 |
+
== 3.1. Output-modifying arguments ==
|
580 |
+
|
581 |
+
The following arguments modify how you get results back from the API. The redirect response styles are intended for use with the data manipulation methods.
|
582 |
+
|
583 |
+
* Setting `callback` to a JavaScript function name will trigger a JSONP-style callback.
|
584 |
+
* Setting `redirect` to a URL will cause the user's browser to redirect to the specified URL with a `status` value appended to the query vars (see the *Response objects* section below for an explanation of status values).
|
585 |
+
* Setting `redirect_[status]` allows you to control the resulting browser redirection depending on the `status` value.
|
586 |
+
* Setting `dev` to a non-empty value adds whitespace for readability and responds with `text/plain`
|
587 |
+
* Omitting all of the above arguments will result in a standard JSON response.
|
588 |
+
|
589 |
+
== 3.2. Content-modifying arguments ==
|
590 |
+
|
591 |
+
These arguments are available to modify all introspection methods:
|
592 |
+
|
593 |
+
* `date_format` - Changes the format of date values. Uses the same syntax as PHP's date() function. Default value is `Y-m-d H:i:s`.
|
594 |
+
* `read_more` - Changes the 'read more' link text in post content.
|
595 |
+
* `include` - Specifies which post data fields to include. Expects a comma-separated list of post fields. Leaving this empty includes *all* fields.
|
596 |
+
* `exclude` - Specifies which post data fields to exclude. Expects a comma-separated list of post fields.
|
597 |
+
* `custom_fields` - Includes values from posts' Custom Fields. Expects a comma-separated list of custom field keys.
|
598 |
+
* `author_meta` - Includes additional author metadata. Should be a comma-separated list of metadata fields.
|
599 |
+
* `count` - Controls the number of posts to include (defaults to the number specified by WordPress)
|
600 |
+
* `order` - Controls the order of post results ('DESC' or 'ASC'). Default value is 'DESC'.
|
601 |
+
* `order_by` - Controls which field to order results by. Expects one of the following values:
|
602 |
+
* `author`
|
603 |
+
* `date` (default value)
|
604 |
+
* `title`
|
605 |
+
* `modified`
|
606 |
+
* `menu_order` (only works with Pages)
|
607 |
+
* `parent`
|
608 |
+
* `ID`
|
609 |
+
* `rand`
|
610 |
+
* `meta_value` (`meta_key` must also be set)
|
611 |
+
* `none`
|
612 |
+
* `comment_count`
|
613 |
+
* `meta_key`, `meta_value`, `meta_compare` - Retrieve posts (or Pages) based on a custom field key or value.
|
614 |
+
|
615 |
+
== 3.3. Using query_posts, include/exclude, and redirects ==
|
616 |
+
|
617 |
+
__Additional arguments__
|
618 |
+
JSON API is based on the same rules as the [`query_posts` template tag](http://codex.wordpress.org/Template_Tags/query_posts). Any query arguments that can be used to augment a call to `query_posts` can also be passed as a URL query variable to achieve the same results.
|
619 |
+
|
620 |
+
__About `include`/`exclude` arguments__
|
621 |
+
By default you get all values included with each post object. Specify a list of `include` values will cause the post object to filter out the values absent from the list. Specifying `exclude` causes post objects to include all values except the fields you list. For example, the query `exclude=comments` includes everything *except* the comments.
|
622 |
+
|
623 |
+
__About the `redirect` argument__
|
624 |
+
The `redirect` response style is useful for when you need the user's browser to make a request directly rather than making proxy requests using a tool like cURL. Setting a `redirect` argument causes the user's browser to redirect back to the specified URL instead of returning a JSON object. The resulting `status` value is included as an extra query variable.
|
625 |
+
|
626 |
+
For example calling an API method with `redirect` set to `http://www.example.com/foo` will result in a redirection to one of the following:
|
627 |
+
|
628 |
+
* `http://www.example.com/foo?status=ok`
|
629 |
+
* `http://www.example.com/foo?status=error`
|
630 |
+
|
631 |
+
You can also set separate URLs to handle status values differently. You could set `redirect_ok` to `http://www.example.com/handle_ok` and `redirect_error` to `http://www.example.com/handle_error` in order to have more fine-tuned control over the method result.
|
632 |
+
|
633 |
+
|
634 |
+
== 4. Response objects ==
|
635 |
+
|
636 |
+
This section describes data objects you can retrieve from WordPress and the optional URL redirects.
|
637 |
+
|
638 |
+
__Status values__
|
639 |
+
All JSON API requests result in a status value. The two basic status values are `ok` and `error`. Additional status values are available for certain methods (such as `pending` in the case of the `submit_comment` method). API methods that result in custom status values include a *custom status values* section in their documentation.
|
640 |
+
|
641 |
+
__Naming compatibility__
|
642 |
+
Developers familiar with WordPress may notice that many names for properties and arguments have been changed. This was a stylistic choice that intends to provide more clarity and consistency in the interface.
|
643 |
+
|
644 |
+
== 4.1. Post response object ==
|
645 |
+
|
646 |
+
* `id` - Integer
|
647 |
+
* `type` - String (e.g., `post` or `page`)
|
648 |
+
* `slug` - String
|
649 |
+
* `url` - String
|
650 |
+
* `title` - String
|
651 |
+
* `title_plain` - String
|
652 |
+
* `content` - String (modified by the `read_more` argument)
|
653 |
+
* `excerpt` - String
|
654 |
+
* `date` - String (modified by the `date_format` argument)
|
655 |
+
* `modified` - String (modified by the `date_format` argument)
|
656 |
+
* `categories` - Array of category objects
|
657 |
+
* `tags` - Array of tag objects
|
658 |
+
* `author` Author object
|
659 |
+
* `comments` - Array of comment objects
|
660 |
+
* `attachments` - Array of attachment objects
|
661 |
+
* `comment_count` - Integer
|
662 |
+
* `comment_status` - String (`"open"` or `"closed"`)
|
663 |
+
* `thumbnail` - String (only included if a post thumbnail has been specified)
|
664 |
+
* `custom_fields` - Object (included by setting the `custom_fields` argument to a comma-separated list of custom field names)
|
665 |
+
|
666 |
+
== 4.2. Category response object ==
|
667 |
+
|
668 |
+
* `id` - Integer
|
669 |
+
* `slug` - String
|
670 |
+
* `title` - String
|
671 |
+
* `description` - String
|
672 |
+
* `parent` - Integer
|
673 |
+
* `post_count` - Integer
|
674 |
+
|
675 |
+
== 4.3. Tag response object ==
|
676 |
+
|
677 |
+
* `id` - Integer
|
678 |
+
* `slug` - String
|
679 |
+
* `title` - String
|
680 |
+
* `description` - String
|
681 |
+
* `post_count` - Integer
|
682 |
+
|
683 |
+
== 4.4. Author response object ==
|
684 |
+
|
685 |
+
* `id` - Integer
|
686 |
+
* `slug` - String
|
687 |
+
* `name` - String
|
688 |
+
* `first_name` - String
|
689 |
+
* `last_name` - String
|
690 |
+
* `nickname` - String
|
691 |
+
* `url` - String
|
692 |
+
* `description` - String
|
693 |
+
|
694 |
+
Note: You can include additional values by setting the `author_meta` argument to a comma-separated list of metadata fields.
|
695 |
+
|
696 |
+
== 4.5. Comment response object ==
|
697 |
+
|
698 |
+
* `id` - Integer
|
699 |
+
* `name` - String
|
700 |
+
* `url` - String
|
701 |
+
* `date` - String
|
702 |
+
* `content` - String
|
703 |
+
* `parent` - Integer
|
704 |
+
* `author` - Object (only set if the comment author was registered & logged in)
|
705 |
+
|
706 |
+
== 4.6. Attachment response object ==
|
707 |
+
|
708 |
+
* `id` - Integer
|
709 |
+
* `url` - String
|
710 |
+
* `slug` - String
|
711 |
+
* `title` - String
|
712 |
+
* `description` - String
|
713 |
+
* `caption` - String
|
714 |
+
* `parent` - Integer
|
715 |
+
* `mime_type` - String
|
716 |
+
* `images` - Object with values including `thumbnail`, `medium`, `large`, `full`, each of which are objects with values `url`, `width` and `height` (only set if the attachment is an image)
|
717 |
+
|
718 |
+
|
719 |
+
== 5. Extending JSON API ==
|
720 |
+
|
721 |
+
JSON API exposes several WordPress action and filter hooks as well as a modular controller system for adding new API methods.
|
722 |
+
|
723 |
+
== 5.1. Plugin hooks ==
|
724 |
+
|
725 |
+
JSON API exposes several [action and filter hooks](http://codex.wordpress.org/Plugin_API#Hooks.2C_Actions_and_Filters) to augment its behavior.
|
726 |
+
|
727 |
+
== Filter: json_api_controllers ==
|
728 |
+
|
729 |
+
This filter controls the array of controllers available to JSON API. The callback function is passed a single argument, an array of strings.
|
730 |
+
|
731 |
+
= Example =
|
732 |
+
|
733 |
+
// Add a custom controller
|
734 |
+
add_filter('json_api_controllers', 'add_my_controller');
|
735 |
+
|
736 |
+
function add_my_controller($controllers) {
|
737 |
+
// Corresponds to the class JSON_API_MyController_Controller
|
738 |
+
$controllers[] = 'MyController';
|
739 |
+
return $controllers;
|
740 |
+
}
|
741 |
+
|
742 |
+
|
743 |
+
== Filter: json_api_[controller]_controller_path
|
744 |
+
|
745 |
+
Specifies the PHP source file for a given controller, overriding the default location `wp-content/plugins/json_api/controllers`.
|
746 |
+
|
747 |
+
__Note__
|
748 |
+
If you your controller file in the `json-api/controllers` folder JSON API will find it automatically.
|
749 |
+
|
750 |
+
= Example =
|
751 |
+
|
752 |
+
// Add a custom controller file for MyController
|
753 |
+
add_filter('json_api_mycontroller_controller', 'my_controller_path');
|
754 |
+
|
755 |
+
function my_controller_path($default_path) {
|
756 |
+
return '/path/to/mycontroller.php';
|
757 |
+
}
|
758 |
+
|
759 |
+
== Filter: json_api_encode ==
|
760 |
+
|
761 |
+
This is called just before the output is encoded into JSON format. The value passed will always be an associative array, according to the format described in each method's documentation. Those items described in the *Response objects* section are passed as PHP objects, not associative arrays.
|
762 |
+
|
763 |
+
= Example =
|
764 |
+
|
765 |
+
add_filter('json_api_encode', 'my_encode_kittens');
|
766 |
+
|
767 |
+
function my_encode_kittens($response) {
|
768 |
+
if (isset($response['posts'])) {
|
769 |
+
foreach ($response['posts'] as $post) {
|
770 |
+
my_add_kittens($post); // Add kittens to each post
|
771 |
+
}
|
772 |
+
} else if (isset($response['post'])) {
|
773 |
+
my_add_kittens($response['post']); // Add a kittens property
|
774 |
+
}
|
775 |
+
return $response;
|
776 |
+
}
|
777 |
+
|
778 |
+
function my_add_kittens(&$post) {
|
779 |
+
$post->kittens = 'Kittens!';
|
780 |
+
}
|
781 |
+
|
782 |
+
== Action: json_api-[controller]-[method] ==
|
783 |
+
|
784 |
+
Each JSON API method invokes an action when called.
|
785 |
+
|
786 |
+
= Example =
|
787 |
+
|
788 |
+
// Disable get_author_index method (e.g., for security reasons)
|
789 |
+
add_action('json_api-core-get_author_index', 'my_disable_author_index');
|
790 |
+
|
791 |
+
function my_disable_author_index() {
|
792 |
+
// Stop execution
|
793 |
+
exit;
|
794 |
+
}
|
795 |
+
|
796 |
+
== 5.2. Developing JSON API controllers ==
|
797 |
+
|
798 |
+
= Creating a controller =
|
799 |
+
|
800 |
+
To start a new JSON API controller, create a file called `hello.php` inside `wp-content/plugins/json-api/controllers`. Add the following class definition:
|
801 |
+
|
802 |
+
<?php
|
803 |
+
|
804 |
+
class JSON_API_Hello_Controller {
|
805 |
+
|
806 |
+
public function hello_world() {
|
807 |
+
return array(
|
808 |
+
"message" => "Hello, world"
|
809 |
+
);
|
810 |
+
}
|
811 |
+
|
812 |
+
}
|
813 |
+
|
814 |
+
?>
|
815 |
+
|
816 |
+
Your controller is now available as `hello`, and exposes one `hello_world` method.
|
817 |
+
|
818 |
+
Next, activate your controller from the WordPress admin interface, available from the menu under Settings > JSON API. You can either click on the link to your `hello_world` method from the admin interface or enter it manually. It should have the form: `http://www.example.org/api/hello/hello_world/?dev=1` or `http://www.example.org/?json=hello.hello_world&dev=1` (note the use of the `dev` argument to enable human-readable output). You should get the following output:
|
819 |
+
|
820 |
+
{
|
821 |
+
"status": "ok",
|
822 |
+
"message": "Hello, world"
|
823 |
+
}
|
824 |
+
|
825 |
+
= Using query vars =
|
826 |
+
|
827 |
+
To customize the behavior of your controller, you will want to make use of the global `$json_api->query` object. Add the following method to your controller:
|
828 |
+
|
829 |
+
public function hello_person() {
|
830 |
+
global $json_api;
|
831 |
+
$name = $json_api->query->name;
|
832 |
+
return array(
|
833 |
+
"message" => "Hello, $name."
|
834 |
+
);
|
835 |
+
}
|
836 |
+
|
837 |
+
Now append the `name` query var to the method call: `http://www.example.org/api/hello/hello_world/?dev=1&name=Alice` or `http://www.example.org/?json=hello.hello_world&dev=1&name=Alice`.
|
838 |
+
|
839 |
+
{
|
840 |
+
"status": "ok",
|
841 |
+
"message": "Hello, Alice"
|
842 |
+
}
|
843 |
+
|
844 |
+
|
845 |
== Changelog ==
|
846 |
|
847 |
+
= 1.0 (2010-06-29): =
|
848 |
+
* JSON API officially drops support for PHP 4 (it was already broken)
|
849 |
+
* Added JSON API Settings page to WP admin
|
850 |
+
* Broke apart `JSON_API_Controller` into a modular controller system
|
851 |
+
* Refactored `JSON_API_Query` to depend less on WordPress's `get_query_var` mechanism
|
852 |
+
* Developer mode now shows response in JSON format
|
853 |
+
* The `create_post` method now requires a nonce
|
854 |
+
* Improved support for complex post queries (props zibitt)
|
855 |
+
* Fixed a bug with `get_author_by_login` (props Krzysztof Sobolewski)
|
856 |
+
* Made image attachments more robust with `get_intermediate_image_sizes` (props mimecine)
|
857 |
+
* Improved post thumbnail support (props nyamsprod)
|
858 |
+
|
859 |
= 0.9.6 (2010-05-27): =
|
860 |
* Fixed a bug introduced in 0.9.5
|
861 |
|
909 |
|
910 |
== Upgrade Notice ==
|
911 |
|
912 |
+
= 1.0 =
|
913 |
+
Major release, see changelog for details.
|
914 |
+
|
915 |
= 0.9.6 =
|
916 |
Bugfix release for something added in 0.9.5.
|
917 |
|
singletons/controller.php
DELETED
@@ -1,253 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
class JSON_API_Controller {
|
4 |
-
|
5 |
-
function JSON_API_Controller() {
|
6 |
-
// The query object determines whether the current request is for the JSON API
|
7 |
-
$this->query = new JSON_API_Query();
|
8 |
-
|
9 |
-
// This action is called from wp-includes/template-loader.php
|
10 |
-
add_action('template_redirect', array(&$this, 'template_redirect'));
|
11 |
-
}
|
12 |
-
|
13 |
-
function template_redirect() {
|
14 |
-
// Check to see if there's an appropriate API method
|
15 |
-
$method = $this->query->get_method();
|
16 |
-
|
17 |
-
if ($method) {
|
18 |
-
// Looks like this is an API request
|
19 |
-
$this->setup();
|
20 |
-
$this->query->setup();
|
21 |
-
|
22 |
-
// Run Plugin hooks for method
|
23 |
-
do_action("json_api_$method");
|
24 |
-
|
25 |
-
// Run the method
|
26 |
-
$result = $this->$method();
|
27 |
-
|
28 |
-
// Handle the result
|
29 |
-
$this->response->respond($result);
|
30 |
-
|
31 |
-
// Done!
|
32 |
-
exit;
|
33 |
-
}
|
34 |
-
}
|
35 |
-
|
36 |
-
function setup() {
|
37 |
-
global $json_api_dir;
|
38 |
-
|
39 |
-
// Setup additional singletons
|
40 |
-
require_once "$json_api_dir/singletons/response.php";
|
41 |
-
require_once "$json_api_dir/singletons/introspector.php";
|
42 |
-
$this->response = new JSON_API_Response();
|
43 |
-
$this->introspector = new JSON_API_Introspector();
|
44 |
-
|
45 |
-
// Models used by introspection methods
|
46 |
-
require_once "$json_api_dir/models/post.php";
|
47 |
-
require_once "$json_api_dir/models/comment.php";
|
48 |
-
require_once "$json_api_dir/models/category.php";
|
49 |
-
require_once "$json_api_dir/models/tag.php";
|
50 |
-
require_once "$json_api_dir/models/author.php";
|
51 |
-
require_once "$json_api_dir/models/attachment.php";
|
52 |
-
}
|
53 |
-
|
54 |
-
function error($message, $status = 'error') {
|
55 |
-
$result = $this->response->get_json(array(
|
56 |
-
'error' => $message
|
57 |
-
), $status);
|
58 |
-
$this->response->respond($result);
|
59 |
-
}
|
60 |
-
|
61 |
-
function get_recent_posts() {
|
62 |
-
$posts = $this->introspector->get_posts('');
|
63 |
-
return $this->response->get_posts_json($posts);
|
64 |
-
}
|
65 |
-
|
66 |
-
function get_post() {
|
67 |
-
$query = '';
|
68 |
-
if ($this->query->post_id) {
|
69 |
-
$query = "p={$this->query->post_id}";
|
70 |
-
} else if ($this->query->post_slug) {
|
71 |
-
$query = "name={$this->query->post_slug}";
|
72 |
-
} else {
|
73 |
-
$this->error("No post specified. Include 'post_id' or 'post_slug' var in your request.");
|
74 |
-
}
|
75 |
-
$posts = $this->introspector->get_posts($query);
|
76 |
-
if (count($posts) == 1) {
|
77 |
-
return $this->response->get_json(array(
|
78 |
-
'post' => $posts[0]
|
79 |
-
));
|
80 |
-
} else {
|
81 |
-
$this->error("No post was found.");
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
function get_page() {
|
86 |
-
$query = '';
|
87 |
-
if ($this->query->page_id) {
|
88 |
-
$query = "page_id={$this->query->page_id}";
|
89 |
-
} else if ($this->query->page_slug) {
|
90 |
-
$query = "pagename={$this->query->page_slug}";
|
91 |
-
} else {
|
92 |
-
$this->error("No page specified. Include 'page_id' or 'page_slug' var in your request.");
|
93 |
-
}
|
94 |
-
$pages = $this->introspector->get_posts($query);
|
95 |
-
|
96 |
-
// Workaround for https://core.trac.wordpress.org/ticket/12647
|
97 |
-
if (empty($pages)) {
|
98 |
-
$url = $_SERVER['REQUEST_URI'];
|
99 |
-
$parsed_url = parse_url($url);
|
100 |
-
$path = $parsed_url['path'];
|
101 |
-
if (preg_match('#^http://[^/]+(/.+)$#', get_bloginfo('url'), $matches)) {
|
102 |
-
$blog_root = $matches[1];
|
103 |
-
$path = preg_replace("#^$blog_root#", '', $path);
|
104 |
-
}
|
105 |
-
if (substr($path, 0, 1) == '/') {
|
106 |
-
$path = substr($path, 1);
|
107 |
-
}
|
108 |
-
$pages = $this->introspector->get_posts("pagename=$path");
|
109 |
-
}
|
110 |
-
|
111 |
-
if (count($pages) == 1) {
|
112 |
-
return $this->response->get_json(array(
|
113 |
-
'page' => $pages[0]
|
114 |
-
));
|
115 |
-
} else {
|
116 |
-
$this->error("No page was found.");
|
117 |
-
}
|
118 |
-
}
|
119 |
-
|
120 |
-
function get_date_posts() {
|
121 |
-
$query = '';
|
122 |
-
if ($this->query->date) {
|
123 |
-
$query = "m={$this->query->date}";
|
124 |
-
} else {
|
125 |
-
$this->error("No date specified. Include 'date' var in your request.");
|
126 |
-
}
|
127 |
-
$posts = $this->introspector->get_posts($query);
|
128 |
-
return $this->response->get_posts_json($posts);
|
129 |
-
}
|
130 |
-
|
131 |
-
function get_category_posts() {
|
132 |
-
$query = '';
|
133 |
-
if ($this->query->category_id) {
|
134 |
-
$query = "cat={$this->query->category_id}";
|
135 |
-
} else if ($this->query->category_slug) {
|
136 |
-
$query = "category_name={$this->query->category_slug}";
|
137 |
-
} else {
|
138 |
-
$this->error("No category specified. Include 'category_id' or 'category_slug' var in your request.");
|
139 |
-
}
|
140 |
-
$posts = $this->introspector->get_posts($query);
|
141 |
-
$category = $this->introspector->get_current_category();
|
142 |
-
return $this->response->get_posts_object_json($posts, $category);
|
143 |
-
}
|
144 |
-
|
145 |
-
function get_tag_posts() {
|
146 |
-
$query = '';
|
147 |
-
if ($this->query->tag_slug) {
|
148 |
-
$query = "tag={$this->query->tag_slug}";
|
149 |
-
} else if ($this->query->tag_id) {
|
150 |
-
$query = "tag_id={$this->query->tag_id}";
|
151 |
-
} else {
|
152 |
-
$this->error("No tag specified. Include 'tag_id' or 'tag_slug' var in your request.");
|
153 |
-
}
|
154 |
-
$posts = $this->introspector->get_posts($query);
|
155 |
-
$tag = $this->introspector->get_current_tag();
|
156 |
-
return $this->response->get_posts_object_json($posts, $tag);
|
157 |
-
}
|
158 |
-
|
159 |
-
function get_author_posts() {
|
160 |
-
$query = '';
|
161 |
-
if ($this->query->author_id) {
|
162 |
-
$query = "author={$this->query->author_id}";
|
163 |
-
} else if ($this->query->author_slug) {
|
164 |
-
$query = "author_name={$this->query->author_slug}";
|
165 |
-
} else {
|
166 |
-
$this->error("No author specified. Include 'author_id' or 'author_slug' var in your request.");
|
167 |
-
}
|
168 |
-
$posts = $this->introspector->get_posts($query);
|
169 |
-
$author = $this->introspector->get_current_author();
|
170 |
-
return $this->response->get_posts_object_json($posts, $author);
|
171 |
-
}
|
172 |
-
|
173 |
-
function get_search_results() {
|
174 |
-
$query = '';
|
175 |
-
if ($this->query->search) {
|
176 |
-
$query = "s={$this->query->search}";
|
177 |
-
} else {
|
178 |
-
$this->error("No search query specified. Include 'search' var in your request.");
|
179 |
-
}
|
180 |
-
$posts = $this->introspector->get_posts($query);
|
181 |
-
return $this->response->get_posts_json($posts);
|
182 |
-
}
|
183 |
-
|
184 |
-
function get_date_index() {
|
185 |
-
$permalinks = $this->introspector->get_date_archive_permalinks();
|
186 |
-
$tree = $this->introspector->get_date_archive_tree($permalinks);
|
187 |
-
return $this->response->get_json(array(
|
188 |
-
'permalinks' => $permalinks,
|
189 |
-
'tree' => $tree
|
190 |
-
));
|
191 |
-
}
|
192 |
-
|
193 |
-
function get_category_index() {
|
194 |
-
$categories = $this->introspector->get_categories();
|
195 |
-
return $this->response->get_json(array(
|
196 |
-
'count' => count($categories),
|
197 |
-
'categories' => $categories
|
198 |
-
));
|
199 |
-
}
|
200 |
-
|
201 |
-
function get_tag_index() {
|
202 |
-
$tags = $this->introspector->get_tags();
|
203 |
-
return $this->response->get_json(array(
|
204 |
-
'count' => count($tags),
|
205 |
-
'tags' => $tags
|
206 |
-
));
|
207 |
-
}
|
208 |
-
|
209 |
-
function get_author_index() {
|
210 |
-
$authors = $this->introspector->get_authors();
|
211 |
-
return $this->response->get_json(array(
|
212 |
-
'count' => count($authors),
|
213 |
-
'authors' => array_values($authors)
|
214 |
-
));
|
215 |
-
}
|
216 |
-
|
217 |
-
function create_post() {
|
218 |
-
if (!current_user_can('edit_posts')) {
|
219 |
-
$this->error("You need to login with a user capable of creating posts.");
|
220 |
-
}
|
221 |
-
nocache_headers();
|
222 |
-
$post = new JSON_API_Post();
|
223 |
-
$id = $post->create($_REQUEST);
|
224 |
-
if (empty($id)) {
|
225 |
-
$this->error("Could not create post.");
|
226 |
-
}
|
227 |
-
return $this->response->get_json(array(
|
228 |
-
'post' => $post
|
229 |
-
));
|
230 |
-
}
|
231 |
-
|
232 |
-
function submit_comment() {
|
233 |
-
nocache_headers();
|
234 |
-
if (empty($_REQUEST['post_id'])) {
|
235 |
-
$this->error("No post specified. Include 'post_id' var in your request.");
|
236 |
-
} else if (empty($_REQUEST['name']) ||
|
237 |
-
empty($_REQUEST['email']) ||
|
238 |
-
empty($_REQUEST['content'])) {
|
239 |
-
$this->error("Please include all required arguments (name, email, content).");
|
240 |
-
} else if (!is_email($_REQUEST['email'])) {
|
241 |
-
$this->error("Please enter a valid email address.");
|
242 |
-
}
|
243 |
-
$pending = new JSON_API_Comment();
|
244 |
-
return $pending->handle_submission();
|
245 |
-
}
|
246 |
-
|
247 |
-
function include_value($key) {
|
248 |
-
return $this->response->is_value_included($key);
|
249 |
-
}
|
250 |
-
|
251 |
-
}
|
252 |
-
|
253 |
-
?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
singletons/introspector.php
CHANGED
@@ -2,9 +2,8 @@
|
|
2 |
|
3 |
class JSON_API_Introspector {
|
4 |
|
5 |
-
function get_posts($query =
|
6 |
global $post;
|
7 |
-
// Returns an array of JSON_API_Post objects
|
8 |
$this->set_posts_query($query);
|
9 |
$output = array();
|
10 |
while (have_posts()) {
|
@@ -14,13 +13,13 @@ class JSON_API_Introspector {
|
|
14 |
return $output;
|
15 |
}
|
16 |
|
17 |
-
function get_date_archive_permalinks() {
|
18 |
$archives = wp_get_archives('echo=0');
|
19 |
preg_match_all("/href='([^']+)'/", $archives, $matches);
|
20 |
return $matches[1];
|
21 |
}
|
22 |
|
23 |
-
function get_date_archive_tree($permalinks) {
|
24 |
$tree = array();
|
25 |
foreach ($permalinks as $url) {
|
26 |
if (preg_match('#(\d{4})/(\d{2})#', $url, $date)) {
|
@@ -44,7 +43,7 @@ class JSON_API_Introspector {
|
|
44 |
return $tree;
|
45 |
}
|
46 |
|
47 |
-
function get_date_archive_count($year, $month) {
|
48 |
if (!isset($this->month_archives)) {
|
49 |
global $wpdb;
|
50 |
$post_counts = $wpdb->get_results("
|
@@ -63,7 +62,7 @@ class JSON_API_Introspector {
|
|
63 |
return $this->month_archives["$year$month"];
|
64 |
}
|
65 |
|
66 |
-
function get_categories() {
|
67 |
$wp_categories = get_categories();
|
68 |
$categories = array();
|
69 |
foreach ($wp_categories as $wp_category) {
|
@@ -75,60 +74,70 @@ class JSON_API_Introspector {
|
|
75 |
return $categories;
|
76 |
}
|
77 |
|
78 |
-
function get_current_category() {
|
79 |
global $json_api;
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
}
|
85 |
return null;
|
86 |
}
|
87 |
|
88 |
-
function
|
89 |
-
return new JSON_API_Category($wp_category);
|
90 |
-
}
|
91 |
-
|
92 |
-
function get_category_by_id($category_id) {
|
93 |
$wp_category = get_term_by('id', $category_id, 'category');
|
94 |
return $this->get_category_object($wp_category);
|
95 |
}
|
96 |
|
97 |
-
function get_category_by_slug($category_slug) {
|
98 |
$wp_category = get_term_by('slug', $category_slug, 'category');
|
99 |
return $this->get_category_object($wp_category);
|
100 |
}
|
101 |
|
102 |
-
function get_tags() {
|
103 |
$wp_tags = get_tags();
|
104 |
return array_map(array(&$this, 'get_tag_object'), $wp_tags);
|
105 |
}
|
106 |
|
107 |
-
function get_current_tag() {
|
108 |
global $json_api;
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
return null;
|
115 |
}
|
116 |
|
117 |
-
function
|
118 |
-
return new JSON_API_Tag($wp_tag);
|
119 |
-
}
|
120 |
-
|
121 |
-
function get_tag_by_id($tag_id) {
|
122 |
$wp_tag = get_term_by('id', $tag_id, 'post_tag');
|
123 |
return $this->get_tag_object($wp_tag);
|
124 |
}
|
125 |
|
126 |
-
function get_tag_by_slug($tag_slug) {
|
127 |
$wp_tag = get_term_by('slug', $tag_slug, 'post_tag');
|
128 |
return $this->get_tag_object($wp_tag);
|
129 |
}
|
130 |
|
131 |
-
function get_authors() {
|
132 |
global $wpdb;
|
133 |
$author_ids = $wpdb->get_col($wpdb->prepare("
|
134 |
SELECT u.ID, m.meta_value AS last_name
|
@@ -138,20 +147,40 @@ class JSON_API_Introspector {
|
|
138 |
AND m.meta_key = 'last_name'
|
139 |
ORDER BY last_name
|
140 |
"));
|
141 |
-
$all_authors = array_map(array(&$this, '
|
142 |
$active_authors = array_filter($all_authors, array(&$this, 'is_active_author'));
|
143 |
return $active_authors;
|
144 |
}
|
145 |
|
146 |
-
function
|
147 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
}
|
149 |
|
150 |
-
function get_author_by_id($id) {
|
|
|
|
|
|
|
|
|
151 |
return new JSON_API_Author($id);
|
152 |
}
|
153 |
|
154 |
-
function get_author_by_login($login) {
|
|
|
155 |
$id = $wpdb->get_var($wpdb->prepare("
|
156 |
SELECT ID
|
157 |
FROM $wpdb->users
|
@@ -160,35 +189,7 @@ class JSON_API_Introspector {
|
|
160 |
return $this->get_author_by_id($id);
|
161 |
}
|
162 |
|
163 |
-
function
|
164 |
-
$author_id = get_query_var('author');
|
165 |
-
return $this->get_author($author_id);
|
166 |
-
}
|
167 |
-
|
168 |
-
function is_active_author($author) {
|
169 |
-
if (!isset($this->active_authors)) {
|
170 |
-
$this->active_authors = explode(',', wp_list_authors('html=0&echo=0'));
|
171 |
-
$this->active_authors = array_map('trim', $this->active_authors);
|
172 |
-
}
|
173 |
-
return in_array($author->name, $this->active_authors);
|
174 |
-
}
|
175 |
-
|
176 |
-
function set_posts_query($query = '') {
|
177 |
-
// Returns a query string to pass to WP's query_posts() function
|
178 |
-
if (get_query_var('page')) {
|
179 |
-
$amp = empty($query) ? '' : '&';
|
180 |
-
$query .= "{$amp}paged=" . get_query_var('page');
|
181 |
-
}
|
182 |
-
if (get_query_var('count')) {
|
183 |
-
$amp = empty($query) ? '' : '&';
|
184 |
-
$query .= "{$amp}posts_per_page=" . get_query_var('count');
|
185 |
-
}
|
186 |
-
if (!empty($query)) {
|
187 |
-
query_posts($query);
|
188 |
-
}
|
189 |
-
}
|
190 |
-
|
191 |
-
function get_comments($post_id) {
|
192 |
global $wpdb;
|
193 |
$wp_comments = $wpdb->get_results($wpdb->prepare("
|
194 |
SELECT *
|
@@ -205,7 +206,7 @@ class JSON_API_Introspector {
|
|
205 |
return $comments;
|
206 |
}
|
207 |
|
208 |
-
function get_attachments($post_id) {
|
209 |
$wp_attachments = get_children("post_type=attachment&post_parent=$post_id");
|
210 |
$attachments = array();
|
211 |
if (!empty($wp_attachments)) {
|
@@ -216,6 +217,70 @@ class JSON_API_Introspector {
|
|
216 |
return $attachments;
|
217 |
}
|
218 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
219 |
}
|
220 |
|
221 |
?>
|
2 |
|
3 |
class JSON_API_Introspector {
|
4 |
|
5 |
+
public function get_posts($query = false) {
|
6 |
global $post;
|
|
|
7 |
$this->set_posts_query($query);
|
8 |
$output = array();
|
9 |
while (have_posts()) {
|
13 |
return $output;
|
14 |
}
|
15 |
|
16 |
+
public function get_date_archive_permalinks() {
|
17 |
$archives = wp_get_archives('echo=0');
|
18 |
preg_match_all("/href='([^']+)'/", $archives, $matches);
|
19 |
return $matches[1];
|
20 |
}
|
21 |
|
22 |
+
public function get_date_archive_tree($permalinks) {
|
23 |
$tree = array();
|
24 |
foreach ($permalinks as $url) {
|
25 |
if (preg_match('#(\d{4})/(\d{2})#', $url, $date)) {
|
43 |
return $tree;
|
44 |
}
|
45 |
|
46 |
+
public function get_date_archive_count($year, $month) {
|
47 |
if (!isset($this->month_archives)) {
|
48 |
global $wpdb;
|
49 |
$post_counts = $wpdb->get_results("
|
62 |
return $this->month_archives["$year$month"];
|
63 |
}
|
64 |
|
65 |
+
public function get_categories() {
|
66 |
$wp_categories = get_categories();
|
67 |
$categories = array();
|
68 |
foreach ($wp_categories as $wp_category) {
|
74 |
return $categories;
|
75 |
}
|
76 |
|
77 |
+
public function get_current_category() {
|
78 |
global $json_api;
|
79 |
+
extract($json_api->query->get(array('id', 'slug', 'category_id', 'category_slug')));
|
80 |
+
if ($id || $category_id) {
|
81 |
+
if (!$id) {
|
82 |
+
$id = $category_id;
|
83 |
+
}
|
84 |
+
return $this->get_category_by_id($id);
|
85 |
+
} else if ($slug || $category_slug) {
|
86 |
+
if (!$slug) {
|
87 |
+
$slug = $category_slug;
|
88 |
+
}
|
89 |
+
return $this->get_category_by_slug($slug);
|
90 |
+
} else {
|
91 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
92 |
}
|
93 |
return null;
|
94 |
}
|
95 |
|
96 |
+
public function get_category_by_id($category_id) {
|
|
|
|
|
|
|
|
|
97 |
$wp_category = get_term_by('id', $category_id, 'category');
|
98 |
return $this->get_category_object($wp_category);
|
99 |
}
|
100 |
|
101 |
+
public function get_category_by_slug($category_slug) {
|
102 |
$wp_category = get_term_by('slug', $category_slug, 'category');
|
103 |
return $this->get_category_object($wp_category);
|
104 |
}
|
105 |
|
106 |
+
public function get_tags() {
|
107 |
$wp_tags = get_tags();
|
108 |
return array_map(array(&$this, 'get_tag_object'), $wp_tags);
|
109 |
}
|
110 |
|
111 |
+
public function get_current_tag() {
|
112 |
global $json_api;
|
113 |
+
extract($json_api->query->get(array('id', 'slug', 'tag_id', 'tag_slug')));
|
114 |
+
if ($id || $tag_id) {
|
115 |
+
if (!$id) {
|
116 |
+
$id = $tag_id;
|
117 |
+
}
|
118 |
+
return $this->get_tag_by_id($id);
|
119 |
+
} else if ($slug || $tag_slug) {
|
120 |
+
if (!$slug) {
|
121 |
+
$slug = $tag_slug;
|
122 |
+
}
|
123 |
+
return $this->get_tag_by_slug($slug);
|
124 |
+
} else {
|
125 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
126 |
}
|
127 |
return null;
|
128 |
}
|
129 |
|
130 |
+
public function get_tag_by_id($tag_id) {
|
|
|
|
|
|
|
|
|
131 |
$wp_tag = get_term_by('id', $tag_id, 'post_tag');
|
132 |
return $this->get_tag_object($wp_tag);
|
133 |
}
|
134 |
|
135 |
+
public function get_tag_by_slug($tag_slug) {
|
136 |
$wp_tag = get_term_by('slug', $tag_slug, 'post_tag');
|
137 |
return $this->get_tag_object($wp_tag);
|
138 |
}
|
139 |
|
140 |
+
public function get_authors() {
|
141 |
global $wpdb;
|
142 |
$author_ids = $wpdb->get_col($wpdb->prepare("
|
143 |
SELECT u.ID, m.meta_value AS last_name
|
147 |
AND m.meta_key = 'last_name'
|
148 |
ORDER BY last_name
|
149 |
"));
|
150 |
+
$all_authors = array_map(array(&$this, 'get_author_by_id'), $author_ids);
|
151 |
$active_authors = array_filter($all_authors, array(&$this, 'is_active_author'));
|
152 |
return $active_authors;
|
153 |
}
|
154 |
|
155 |
+
public function get_current_author() {
|
156 |
+
global $json_api;
|
157 |
+
extract($json_api->query->get(array('id', 'slug', 'author_id', 'author_slug')));
|
158 |
+
if ($id || $author_id) {
|
159 |
+
if (!$id) {
|
160 |
+
$id = $author_id;
|
161 |
+
}
|
162 |
+
return $this->get_author_by_id($id);
|
163 |
+
} else if ($slug || $author_slug) {
|
164 |
+
if (!$slug) {
|
165 |
+
$slug = $author_slug;
|
166 |
+
}
|
167 |
+
return $this->get_author_by_login($slug);
|
168 |
+
} else {
|
169 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
170 |
+
}
|
171 |
+
return null;
|
172 |
}
|
173 |
|
174 |
+
public function get_author_by_id($id) {
|
175 |
+
$id = get_the_author_meta('ID', $id);
|
176 |
+
if (!$id) {
|
177 |
+
return null;
|
178 |
+
}
|
179 |
return new JSON_API_Author($id);
|
180 |
}
|
181 |
|
182 |
+
public function get_author_by_login($login) {
|
183 |
+
global $wpdb;
|
184 |
$id = $wpdb->get_var($wpdb->prepare("
|
185 |
SELECT ID
|
186 |
FROM $wpdb->users
|
189 |
return $this->get_author_by_id($id);
|
190 |
}
|
191 |
|
192 |
+
public function get_comments($post_id) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
global $wpdb;
|
194 |
$wp_comments = $wpdb->get_results($wpdb->prepare("
|
195 |
SELECT *
|
206 |
return $comments;
|
207 |
}
|
208 |
|
209 |
+
public function get_attachments($post_id) {
|
210 |
$wp_attachments = get_children("post_type=attachment&post_parent=$post_id");
|
211 |
$attachments = array();
|
212 |
if (!empty($wp_attachments)) {
|
217 |
return $attachments;
|
218 |
}
|
219 |
|
220 |
+
public function attach_child_posts(&$post) {
|
221 |
+
$post->children = array();
|
222 |
+
$wp_children = get_posts(array(
|
223 |
+
'post_type' => $post->type,
|
224 |
+
'post_parent' => $post->id,
|
225 |
+
'order' => 'ASC',
|
226 |
+
'orderby' => 'menu_order'
|
227 |
+
));
|
228 |
+
foreach ($wp_children as $wp_post) {
|
229 |
+
$post->children[] = new JSON_API_Post($wp_post);
|
230 |
+
}
|
231 |
+
foreach ($post->children as $child) {
|
232 |
+
$this->attach_child_posts($child);
|
233 |
+
}
|
234 |
+
}
|
235 |
+
|
236 |
+
protected function get_category_object($wp_category) {
|
237 |
+
if (!$wp_category) {
|
238 |
+
return null;
|
239 |
+
}
|
240 |
+
return new JSON_API_Category($wp_category);
|
241 |
+
}
|
242 |
+
|
243 |
+
protected function get_tag_object($wp_tag) {
|
244 |
+
if (!$wp_tag) {
|
245 |
+
return null;
|
246 |
+
}
|
247 |
+
return new JSON_API_Tag($wp_tag);
|
248 |
+
}
|
249 |
+
|
250 |
+
protected function is_active_author($author) {
|
251 |
+
if (!isset($this->active_authors)) {
|
252 |
+
$this->active_authors = explode(',', wp_list_authors(array(
|
253 |
+
'html' => false,
|
254 |
+
'echo' => false,
|
255 |
+
'exclude_admin' => false
|
256 |
+
)));
|
257 |
+
$this->active_authors = array_map('trim', $this->active_authors);
|
258 |
+
}
|
259 |
+
return in_array($author->name, $this->active_authors);
|
260 |
+
}
|
261 |
+
|
262 |
+
protected function set_posts_query($query = false) {
|
263 |
+
global $json_api, $wp_query;
|
264 |
+
|
265 |
+
if (!$query) {
|
266 |
+
$query = array();
|
267 |
+
}
|
268 |
+
|
269 |
+
$query = array_merge($query, $wp_query->query);
|
270 |
+
|
271 |
+
if ($json_api->query->page) {
|
272 |
+
$query['paged'] = $json_api->query->page;
|
273 |
+
}
|
274 |
+
|
275 |
+
if ($json_api->query->count) {
|
276 |
+
$query['posts_per_page'] = $json_api->query->count;
|
277 |
+
}
|
278 |
+
|
279 |
+
if (!empty($query)) {
|
280 |
+
query_posts($query);
|
281 |
+
}
|
282 |
+
}
|
283 |
+
|
284 |
}
|
285 |
|
286 |
?>
|
singletons/query.php
CHANGED
@@ -2,112 +2,140 @@
|
|
2 |
|
3 |
class JSON_API_Query {
|
4 |
|
5 |
-
var $vars = array(
|
6 |
-
'json', // Determines which API controller method will be called
|
7 |
-
// Expects one of the following values:
|
8 |
-
// * 'get_recent_posts'
|
9 |
-
// * 'get_post'
|
10 |
-
// * 'get_page'
|
11 |
-
// * 'get_date_posts'
|
12 |
-
// * 'get_category_posts'
|
13 |
-
// * 'get_tag_posts'
|
14 |
-
// * 'get_author_posts'
|
15 |
-
// * 'get_date_index'
|
16 |
-
// * 'get_category_index'
|
17 |
-
// * 'get_tag_index'
|
18 |
-
// * 'get_author_index'
|
19 |
-
// * 'get_search_results'
|
20 |
-
// * 'submit_comment'
|
21 |
-
// * Any non-empty value to trigger the API implicitly
|
22 |
-
'callback', // Triggers a JSONP-style callback with the resulting data
|
23 |
-
'dev', // Triggers a developer-friendly print_r() output
|
24 |
-
'redirect', // Triggers a redirect response to the specified URL
|
25 |
-
'page', // Returns a specific page of results
|
26 |
-
'count', // Controls the number of posts returned
|
27 |
-
'post_id', // Used by the get_post API method
|
28 |
-
'post_slug', // Used by the get_post API method
|
29 |
-
'page_id', // Used by the get_page API method
|
30 |
-
'page_slug', // Used by the get_page API method
|
31 |
-
'search', // Used by the get_search_results API method
|
32 |
-
'category_id', // Used by get_category_posts API method
|
33 |
-
'category_slug', // Used by get_category_posts API method
|
34 |
-
'tag_id', // Used by get_tag_posts API method
|
35 |
-
'tag_slug', // Used by get_tag_posts API method
|
36 |
-
'author_id', // Used by get_author_posts API method
|
37 |
-
'author_slug', // Used by get_author_posts API method
|
38 |
-
'date', // Used by get_date_posts API method
|
39 |
-
// Expects 'YYYY', 'YYYYMM' or 'YYYYMMDD'
|
40 |
-
'date_format', // Changes the format of date values
|
41 |
-
// Uses the same syntax as PHP's date() function
|
42 |
-
// Default value is Y-m-d H:i:s
|
43 |
-
'read_more', // Changes the 'read more' link text in post content
|
44 |
-
'include', // Specifies which post data fields to include
|
45 |
-
// Expects a comma-separated list of post fields
|
46 |
-
// Leaving this empty includes *all* fields
|
47 |
-
'exclude', // Specifies which post data fields to exclude
|
48 |
-
// Expects a comma-separated list of post fields
|
49 |
-
'custom_fields', // Includes values from posts' Custom Fields
|
50 |
-
// Expects a comma-separated list of custom field keys
|
51 |
-
'author_meta' // Includes additional author metadata
|
52 |
-
// Should be a comma-separated list of metadata fields
|
53 |
-
|
54 |
-
// Note about include/exclude vars:
|
55 |
-
// The default behavior includes all post values. You only need to
|
56 |
-
// specify one of include or exclude -- the former will implicitly leave
|
57 |
-
// out those fields you haven't specified and the latter will implicitly
|
58 |
-
// include them. For example, a query that uses exclude=comments will
|
59 |
-
// include everything *except* the comments, so there's no need to also
|
60 |
-
// specify anything with the include argument.
|
61 |
-
|
62 |
-
);
|
63 |
-
|
64 |
// Default values
|
65 |
-
|
66 |
-
|
|
|
|
|
67 |
|
68 |
-
function
|
69 |
// Register JSON API query vars
|
70 |
add_filter('query_vars', array(&$this, 'query_vars'));
|
71 |
}
|
72 |
|
73 |
-
function
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
76 |
}
|
77 |
|
78 |
-
function
|
79 |
-
// Translation between WordPress vars and natively understood vars
|
80 |
$wp_translation = array(
|
81 |
-
'
|
82 |
-
'
|
|
|
83 |
'page_id' => 'page_id',
|
84 |
-
'
|
85 |
-
'
|
86 |
-
'
|
87 |
-
'
|
88 |
-
'
|
89 |
-
'
|
90 |
-
'
|
91 |
-
'
|
|
|
|
|
92 |
);
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
|
|
|
|
107 |
}
|
108 |
}
|
109 |
|
110 |
-
function get_method() {
|
|
|
|
|
|
|
111 |
// Returns an appropriate API method name or false. Four possible outcomes:
|
112 |
// 1. API isn't being invoked at all (return false)
|
113 |
// 2. A specific API method was requested (return method name)
|
@@ -117,41 +145,50 @@ class JSON_API_Query {
|
|
117 |
// Note:
|
118 |
// The implicit outcome (3) is invoked by setting the json query var to a
|
119 |
// non-empty value on any WordPress page:
|
120 |
-
// * http://example.org/2009/11/10/hello-world/?json=1
|
121 |
-
// * http://example.org/2009/11/?json=1
|
122 |
-
// * http://example.org/category/foo?json=1
|
123 |
|
124 |
-
$
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
-
if (empty($
|
127 |
// Case 1: we're not being invoked (done!)
|
128 |
return false;
|
129 |
-
} else if (method_exists(
|
130 |
// Case 2: an explicit method was specified
|
131 |
-
return $
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
|
|
|
|
154 |
}
|
|
|
|
|
155 |
}
|
156 |
|
157 |
}
|
2 |
|
3 |
class JSON_API_Query {
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
// Default values
|
6 |
+
protected $defaults = array(
|
7 |
+
'date_format' => 'Y-m-d H:i:s',
|
8 |
+
'read_more' => 'Read more'
|
9 |
+
);
|
10 |
|
11 |
+
function __construct() {
|
12 |
// Register JSON API query vars
|
13 |
add_filter('query_vars', array(&$this, 'query_vars'));
|
14 |
}
|
15 |
|
16 |
+
function get($key) {
|
17 |
+
if (is_array($key)) {
|
18 |
+
$result = array();
|
19 |
+
foreach ($key as $k) {
|
20 |
+
$result[$k] = $this->get($k);
|
21 |
+
}
|
22 |
+
return $result;
|
23 |
+
}
|
24 |
+
$query_var = (isset($_REQUEST[$key])) ? $_REQUEST[$key] : null;
|
25 |
+
$wp_query_var = $this->wp_query_var($key);
|
26 |
+
if ($wp_query_var) {
|
27 |
+
return $wp_query_var;
|
28 |
+
} else if ($query_var) {
|
29 |
+
return $this->strip_magic_quotes($query_var);
|
30 |
+
} else if (isset($this->defaults[$key])) {
|
31 |
+
return $this->defaults[$key];
|
32 |
+
} else {
|
33 |
+
return null;
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
function __get($key) {
|
38 |
+
return $this->get($key);
|
39 |
+
}
|
40 |
+
|
41 |
+
function __isset($key) {
|
42 |
+
return ($this->get($key) !== null);
|
43 |
}
|
44 |
|
45 |
+
function wp_query_var($key) {
|
|
|
46 |
$wp_translation = array(
|
47 |
+
'json' => 'json',
|
48 |
+
'post_id' => 'p',
|
49 |
+
'post_slug' => 'name',
|
50 |
'page_id' => 'page_id',
|
51 |
+
'page_slug' => 'name',
|
52 |
+
'category_id' => 'cat',
|
53 |
+
'category_slug' => 'category_name',
|
54 |
+
'tag_id' => 'tag_id',
|
55 |
+
'tag_slug' => 'tag',
|
56 |
+
'author_id' => 'author',
|
57 |
+
'author_slug' => 'author_name',
|
58 |
+
'search' => 's',
|
59 |
+
'order' => 'order',
|
60 |
+
'order_by' => 'orderby'
|
61 |
);
|
62 |
+
if ($key == 'date') {
|
63 |
+
$date = null;
|
64 |
+
if (get_query_var('year')) {
|
65 |
+
$date = get_query_var('year');
|
66 |
+
}
|
67 |
+
if (get_query_var('monthnum')) {
|
68 |
+
$month = get_query_var('monthnum');
|
69 |
+
if ($month < 10) {
|
70 |
+
$month = "0$month";
|
71 |
+
}
|
72 |
+
$date .= $month;
|
73 |
+
}
|
74 |
+
if (get_query_var('day')) {
|
75 |
+
$day = get_query_var('day');
|
76 |
+
if ($day < 10) {
|
77 |
+
$day = "0$day";
|
78 |
+
}
|
79 |
+
$date .= $day;
|
80 |
+
}
|
81 |
+
return $date;
|
82 |
+
} else if (isset($wp_translation[$key])) {
|
83 |
+
return get_query_var($wp_translation[$key]);
|
84 |
+
} else {
|
85 |
+
return null;
|
86 |
}
|
87 |
+
}
|
88 |
+
|
89 |
+
function strip_magic_quotes($value) {
|
90 |
+
if (get_magic_quotes_gpc()) {
|
91 |
+
return stripslashes($value);
|
92 |
+
} else {
|
93 |
+
return $value;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
function query_vars($wp_vars) {
|
98 |
+
$wp_vars[] = 'json';
|
99 |
+
return $wp_vars;
|
100 |
+
}
|
101 |
+
|
102 |
+
function get_controller() {
|
103 |
+
$json = $this->get('json');
|
104 |
+
if (empty($json)) {
|
105 |
+
return false;
|
106 |
+
}
|
107 |
+
if (preg_match('/^[a-zA-Z_]+$/', $json)) {
|
108 |
+
return $this->get_legacy_controller($json);
|
109 |
+
} else if (preg_match('/^([a-zA-Z_]+)(\/|\.)[a-zA-Z_]+$/', $json, $matches)) {
|
110 |
+
return $matches[1];
|
111 |
+
} else {
|
112 |
+
return 'core';
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
function get_legacy_controller($json) {
|
117 |
+
global $json_api;
|
118 |
+
if ($json == 'submit_comment') {
|
119 |
+
if ($json_api->controller_is_active('respond')) {
|
120 |
+
return 'respond';
|
121 |
+
} else {
|
122 |
+
$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.");
|
123 |
+
}
|
124 |
+
} else if ($json == 'create_post') {
|
125 |
+
if ($json_api->controller_is_active('posts')) {
|
126 |
+
return 'posts';
|
127 |
+
} else {
|
128 |
+
$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.");
|
129 |
}
|
130 |
+
} else {
|
131 |
+
return 'core';
|
132 |
}
|
133 |
}
|
134 |
|
135 |
+
function get_method($controller) {
|
136 |
+
|
137 |
+
global $json_api;
|
138 |
+
|
139 |
// Returns an appropriate API method name or false. Four possible outcomes:
|
140 |
// 1. API isn't being invoked at all (return false)
|
141 |
// 2. A specific API method was requested (return method name)
|
145 |
// Note:
|
146 |
// The implicit outcome (3) is invoked by setting the json query var to a
|
147 |
// non-empty value on any WordPress page:
|
148 |
+
// * http://example.org/2009/11/10/hello-world/?json=1 (get_post)
|
149 |
+
// * http://example.org/2009/11/?json=1 (get_date_posts)
|
150 |
+
// * http://example.org/category/foo?json=1 (get_category_posts)
|
151 |
|
152 |
+
$method = $this->get('json');
|
153 |
+
if (strpos($method, '/') !== false) {
|
154 |
+
$method = substr($method, strpos($method, '/') + 1);
|
155 |
+
} else if (strpos($method, '.') !== false) {
|
156 |
+
$method = substr($method, strpos($method, '.') + 1);
|
157 |
+
}
|
158 |
|
159 |
+
if (empty($method)) {
|
160 |
// Case 1: we're not being invoked (done!)
|
161 |
return false;
|
162 |
+
} else if (method_exists("JSON_API_{$controller}_Controller", $method)) {
|
163 |
// Case 2: an explicit method was specified
|
164 |
+
return $method;
|
165 |
+
} else if ($controller == 'core') {
|
166 |
+
// Case 3: choose the method implicitly based on which page we're on...
|
167 |
+
if (is_search()) {
|
168 |
+
return 'get_search_results';
|
169 |
+
} else if (is_home()) {
|
170 |
+
if (empty($_GET['json'])) {
|
171 |
+
$json_api->error("Uknown method '$method'.");
|
172 |
+
}
|
173 |
+
return 'get_recent_posts';
|
174 |
+
} else if (is_page()) {
|
175 |
+
return 'get_page';
|
176 |
+
} else if (is_single()) {
|
177 |
+
return 'get_post';
|
178 |
+
} else if (is_category()) {
|
179 |
+
return 'get_category_posts';
|
180 |
+
} else if (is_tag()) {
|
181 |
+
return 'get_tag_posts';
|
182 |
+
} else if (is_author()) {
|
183 |
+
return 'get_author_posts';
|
184 |
+
} else if (is_date()) {
|
185 |
+
return 'get_date_posts';
|
186 |
+
} else if (is_404()) {
|
187 |
+
return '404';
|
188 |
+
}
|
189 |
}
|
190 |
+
// Case 4: either the method doesn't exist or we don't support the page implicitly
|
191 |
+
return 'error';
|
192 |
}
|
193 |
|
194 |
}
|
singletons/response.php
CHANGED
@@ -2,42 +2,18 @@
|
|
2 |
|
3 |
class JSON_API_Response {
|
4 |
|
5 |
-
function
|
6 |
-
$
|
7 |
-
}
|
8 |
-
|
9 |
-
function setup_include_values() {
|
10 |
$this->include_values = array();
|
11 |
-
if (
|
12 |
-
$this->include_values = explode(',',
|
13 |
}
|
14 |
-
if (
|
15 |
-
$exclude = explode(',',
|
16 |
$this->include_values = array_diff($this->include_values, $exclude);
|
17 |
}
|
18 |
}
|
19 |
|
20 |
-
function get_posts_json($posts, $status = 'ok') {
|
21 |
-
global $wp_query;
|
22 |
-
return $this->get_json(array(
|
23 |
-
'count' => count($posts),
|
24 |
-
'count_total' => $wp_query->found_posts,
|
25 |
-
'pages' => $wp_query->max_num_pages,
|
26 |
-
'posts' => $posts
|
27 |
-
), $status);
|
28 |
-
}
|
29 |
-
|
30 |
-
function get_posts_object_json($posts, $object, $status = 'ok') {
|
31 |
-
global $wp_query;
|
32 |
-
$object_key = strtolower(substr(get_class($object), 9));
|
33 |
-
return $this->get_json(array(
|
34 |
-
'count' => count($posts),
|
35 |
-
'pages' => $wp_query->max_num_pages,
|
36 |
-
$object_key => $object,
|
37 |
-
'posts' => $posts
|
38 |
-
), $status);
|
39 |
-
}
|
40 |
-
|
41 |
function get_json($data, $status = 'ok') {
|
42 |
// Include a status value with the response
|
43 |
if (is_array($data)) {
|
@@ -49,17 +25,14 @@ class JSON_API_Response {
|
|
49 |
|
50 |
$data = apply_filters('json_api_encode', $data);
|
51 |
|
52 |
-
if (
|
53 |
-
// Don't JSON encode the data in dev mode
|
54 |
-
return $data;
|
55 |
-
} else if (function_exists('json_encode')) {
|
56 |
// Use the built-in json_encode function if it's available
|
57 |
return json_encode($data);
|
58 |
} else {
|
59 |
// Use PEAR's Services_JSON encoder otherwise
|
60 |
if (!class_exists('Services_JSON')) {
|
61 |
-
|
62 |
-
require_once "$
|
63 |
}
|
64 |
$json = new Services_JSON();
|
65 |
return $json->encode($data);
|
@@ -76,13 +49,16 @@ class JSON_API_Response {
|
|
76 |
|
77 |
function respond($result, $status = 'ok') {
|
78 |
global $json_api;
|
|
|
79 |
$status_redirect = "redirect_$status";
|
80 |
-
if ($json_api->query->dev) {
|
81 |
-
// Output the result
|
82 |
if (!headers_sent()) {
|
83 |
header('Content-Type: text/plain; charset: UTF-8', true);
|
|
|
|
|
84 |
}
|
85 |
-
|
86 |
} else if (!empty($_REQUEST[$status_redirect])) {
|
87 |
wp_redirect($_REQUEST[$status_redirect]);
|
88 |
} else if ($json_api->query->redirect) {
|
@@ -90,10 +66,10 @@ class JSON_API_Response {
|
|
90 |
wp_redirect($url);
|
91 |
} else if ($json_api->query->callback) {
|
92 |
// Run a JSONP-style callback with the result
|
93 |
-
$this->callback($json_api->query->callback, $
|
94 |
} else {
|
95 |
-
// Output the result
|
96 |
-
$this->output($
|
97 |
}
|
98 |
exit;
|
99 |
}
|
@@ -104,7 +80,7 @@ class JSON_API_Response {
|
|
104 |
header("Content-Type: application/json; charset=$charset", true);
|
105 |
header("Content-Disposition: attachment; filename=\"json_api.json\"", true);
|
106 |
}
|
107 |
-
echo $result;
|
108 |
}
|
109 |
|
110 |
function callback($callback, $result) {
|
@@ -134,6 +110,63 @@ class JSON_API_Response {
|
|
134 |
return $url;
|
135 |
}
|
136 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
137 |
}
|
138 |
|
139 |
?>
|
2 |
|
3 |
class JSON_API_Response {
|
4 |
|
5 |
+
function setup() {
|
6 |
+
global $json_api;
|
|
|
|
|
|
|
7 |
$this->include_values = array();
|
8 |
+
if ($json_api->query->include) {
|
9 |
+
$this->include_values = explode(',', $json_api->query->include);
|
10 |
}
|
11 |
+
if ($json_api->query->exclude) {
|
12 |
+
$exclude = explode(',', $json_api->query->exclude);
|
13 |
$this->include_values = array_diff($this->include_values, $exclude);
|
14 |
}
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
function get_json($data, $status = 'ok') {
|
18 |
// Include a status value with the response
|
19 |
if (is_array($data)) {
|
25 |
|
26 |
$data = apply_filters('json_api_encode', $data);
|
27 |
|
28 |
+
if (function_exists('json_encode')) {
|
|
|
|
|
|
|
29 |
// Use the built-in json_encode function if it's available
|
30 |
return json_encode($data);
|
31 |
} else {
|
32 |
// Use PEAR's Services_JSON encoder otherwise
|
33 |
if (!class_exists('Services_JSON')) {
|
34 |
+
$dir = dirname(dirname(__FILE__));
|
35 |
+
require_once "$dir/library/JSON.php";
|
36 |
}
|
37 |
$json = new Services_JSON();
|
38 |
return $json->encode($data);
|
49 |
|
50 |
function respond($result, $status = 'ok') {
|
51 |
global $json_api;
|
52 |
+
$json = $this->get_json($result, $status);
|
53 |
$status_redirect = "redirect_$status";
|
54 |
+
if ($json_api->query->dev || !empty($_REQUEST['dev'])) {
|
55 |
+
// Output the result in a human-redable format
|
56 |
if (!headers_sent()) {
|
57 |
header('Content-Type: text/plain; charset: UTF-8', true);
|
58 |
+
} else {
|
59 |
+
echo '<pre>';
|
60 |
}
|
61 |
+
echo $this->prettify($json);
|
62 |
} else if (!empty($_REQUEST[$status_redirect])) {
|
63 |
wp_redirect($_REQUEST[$status_redirect]);
|
64 |
} else if ($json_api->query->redirect) {
|
66 |
wp_redirect($url);
|
67 |
} else if ($json_api->query->callback) {
|
68 |
// Run a JSONP-style callback with the result
|
69 |
+
$this->callback($json_api->query->callback, $json);
|
70 |
} else {
|
71 |
+
// Output the result
|
72 |
+
$this->output($json);
|
73 |
}
|
74 |
exit;
|
75 |
}
|
80 |
header("Content-Type: application/json; charset=$charset", true);
|
81 |
header("Content-Disposition: attachment; filename=\"json_api.json\"", true);
|
82 |
}
|
83 |
+
echo $result;
|
84 |
}
|
85 |
|
86 |
function callback($callback, $result) {
|
110 |
return $url;
|
111 |
}
|
112 |
|
113 |
+
function prettify($ugly) {
|
114 |
+
$pretty = "";
|
115 |
+
$indent = "";
|
116 |
+
$last = '';
|
117 |
+
$pos = 0;
|
118 |
+
$level = 0;
|
119 |
+
$string = false;
|
120 |
+
while ($pos < strlen($ugly)) {
|
121 |
+
$char = substr($ugly, $pos++, 1);
|
122 |
+
if (!$string) {
|
123 |
+
if ($char == '{' || $char == '[') {
|
124 |
+
if ($char == '[' && substr($ugly, $pos, 1) == ']') {
|
125 |
+
$pretty .= "[]";
|
126 |
+
$pos++;
|
127 |
+
} else if ($char == '{' && substr($ugly, $pos, 1) == '}') {
|
128 |
+
$pretty .= "{}";
|
129 |
+
$pos++;
|
130 |
+
} else {
|
131 |
+
$pretty .= "$char\n";
|
132 |
+
$indent = str_repeat(' ', ++$level);
|
133 |
+
$pretty .= "$indent";
|
134 |
+
}
|
135 |
+
} else if ($char == '}' || $char == ']') {
|
136 |
+
$indent = str_repeat(' ', --$level);
|
137 |
+
if ($last != '}' && $last != ']') {
|
138 |
+
$pretty .= "\n$indent";
|
139 |
+
} else if (substr($pretty, -2, 2) == ' ') {
|
140 |
+
$pretty = substr($pretty, 0, -2);
|
141 |
+
}
|
142 |
+
$pretty .= $char;
|
143 |
+
if (substr($ugly, $pos, 1) == ',') {
|
144 |
+
$pretty .= ",";
|
145 |
+
$last = ',';
|
146 |
+
$pos++;
|
147 |
+
}
|
148 |
+
$pretty .= "\n$indent";
|
149 |
+
} else if ($char == ':') {
|
150 |
+
$pretty .= ": ";
|
151 |
+
} else if ($char == ',') {
|
152 |
+
$pretty .= ",\n$indent";
|
153 |
+
} else if ($char == '"') {
|
154 |
+
$pretty .= '"';
|
155 |
+
$string = true;
|
156 |
+
} else {
|
157 |
+
$pretty .= $char;
|
158 |
+
}
|
159 |
+
} else {
|
160 |
+
if ($last != '\\' && $char == '"') {
|
161 |
+
$string = false;
|
162 |
+
}
|
163 |
+
$pretty .= $char;
|
164 |
+
}
|
165 |
+
$last = $char;
|
166 |
+
}
|
167 |
+
return $pretty;
|
168 |
+
}
|
169 |
+
|
170 |
}
|
171 |
|
172 |
?>
|