Version Description
Update/delete post methods and some other bugfixes and improvements
Download this release
Release Info
Developer | dphiffer |
Plugin | JSON API |
Version | 1.0.9 |
Comparing to | |
See all releases |
Code changes from version 1.0.8 to 1.0.9
- controllers/core.php +10 -23
- controllers/posts.php +52 -1
- json-api.php +1 -1
- library/JSON.php +113 -41
- models/attachment.php +1 -1
- readme.txt +62 -9
- singletons/api.php +1 -1
- singletons/introspector.php +29 -2
- singletons/response.php +19 -3
controllers/core.php
CHANGED
@@ -60,31 +60,12 @@ class JSON_API_Core_Controller {
|
|
60 |
|
61 |
public function get_post() {
|
62 |
global $json_api, $post;
|
63 |
-
|
64 |
-
if ($
|
65 |
-
if (!$id) {
|
66 |
-
$id = $post_id;
|
67 |
-
}
|
68 |
-
$posts = $json_api->introspector->get_posts(array(
|
69 |
-
'p' => $id
|
70 |
-
), true);
|
71 |
-
} else if ($slug || $post_slug) {
|
72 |
-
if (!$slug) {
|
73 |
-
$slug = $post_slug;
|
74 |
-
}
|
75 |
-
$posts = $json_api->introspector->get_posts(array(
|
76 |
-
'name' => $slug
|
77 |
-
), true);
|
78 |
-
} else {
|
79 |
-
$json_api->error("Include 'id' or 'slug' var in your request.");
|
80 |
-
}
|
81 |
-
if (count($posts) == 1) {
|
82 |
-
$post = $posts[0];
|
83 |
$previous = get_adjacent_post(false, '', true);
|
84 |
$next = get_adjacent_post(false, '', false);
|
85 |
-
$post = new JSON_API_Post($post);
|
86 |
$response = array(
|
87 |
-
'post' => $post
|
88 |
);
|
89 |
if ($previous) {
|
90 |
$response['previous_url'] = get_permalink($previous->ID);
|
@@ -227,7 +208,13 @@ class JSON_API_Core_Controller {
|
|
227 |
|
228 |
public function get_category_index() {
|
229 |
global $json_api;
|
230 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
return array(
|
232 |
'count' => count($categories),
|
233 |
'categories' => $categories
|
60 |
|
61 |
public function get_post() {
|
62 |
global $json_api, $post;
|
63 |
+
$post = $json_api->introspector->get_current_post();
|
64 |
+
if ($post) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
$previous = get_adjacent_post(false, '', true);
|
66 |
$next = get_adjacent_post(false, '', false);
|
|
|
67 |
$response = array(
|
68 |
+
'post' => new JSON_API_Post($post)
|
69 |
);
|
70 |
if ($previous) {
|
71 |
$response['previous_url'] = get_permalink($previous->ID);
|
208 |
|
209 |
public function get_category_index() {
|
210 |
global $json_api;
|
211 |
+
$args = null;
|
212 |
+
if (!empty($json_api->query->parent)) {
|
213 |
+
$args = array(
|
214 |
+
'parent' => $json_api->query->parent
|
215 |
+
);
|
216 |
+
}
|
217 |
+
$categories = $json_api->introspector->get_categories($args);
|
218 |
return array(
|
219 |
'count' => count($categories),
|
220 |
'categories' => $categories
|
controllers/posts.php
CHANGED
@@ -9,7 +9,7 @@ class JSON_API_Posts_Controller {
|
|
9 |
public function create_post() {
|
10 |
global $json_api;
|
11 |
if (!current_user_can('edit_posts')) {
|
12 |
-
$json_api->error("You need to login with a user
|
13 |
}
|
14 |
if (!$json_api->query->nonce) {
|
15 |
$json_api->error("You must include a 'nonce' value to create posts. Use the `get_nonce` Core API method.");
|
@@ -29,6 +29,57 @@ class JSON_API_Posts_Controller {
|
|
29 |
);
|
30 |
}
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
}
|
33 |
|
34 |
?>
|
9 |
public function create_post() {
|
10 |
global $json_api;
|
11 |
if (!current_user_can('edit_posts')) {
|
12 |
+
$json_api->error("You need to login with a user that has 'edit_posts' capacity.");
|
13 |
}
|
14 |
if (!$json_api->query->nonce) {
|
15 |
$json_api->error("You must include a 'nonce' value to create posts. Use the `get_nonce` Core API method.");
|
29 |
);
|
30 |
}
|
31 |
|
32 |
+
public function update_post() {
|
33 |
+
global $json_api;
|
34 |
+
$post = $json_api->introspector->get_current_post();
|
35 |
+
if (empty($post)) {
|
36 |
+
$json_api->error("Post not found.");
|
37 |
+
}
|
38 |
+
if (!current_user_can('edit_post', $post->ID)) {
|
39 |
+
$json_api->error("You need to login with a user that has the 'edit_post' capacity for that post.");
|
40 |
+
}
|
41 |
+
if (!$json_api->query->nonce) {
|
42 |
+
$json_api->error("You must include a 'nonce' value to update posts. Use the `get_nonce` Core API method.");
|
43 |
+
}
|
44 |
+
$nonce_id = $json_api->get_nonce_id('posts', 'update_post');
|
45 |
+
if (!wp_verify_nonce($json_api->query->nonce, $nonce_id)) {
|
46 |
+
$json_api->error("Your 'nonce' value was incorrect. Use the 'get_nonce' API method.");
|
47 |
+
}
|
48 |
+
nocache_headers();
|
49 |
+
$post = new JSON_API_Post($post);
|
50 |
+
$post->update($_REQUEST);
|
51 |
+
return array(
|
52 |
+
'post' => $post
|
53 |
+
);
|
54 |
+
}
|
55 |
+
|
56 |
+
public function delete_post() {
|
57 |
+
global $json_api;
|
58 |
+
$post = $json_api->introspector->get_current_post();
|
59 |
+
if (empty($post)) {
|
60 |
+
$json_api->error("Post not found.");
|
61 |
+
}
|
62 |
+
if (!current_user_can('edit_post', $post->ID)) {
|
63 |
+
$json_api->error("You need to login with a user that has the 'edit_post' capacity for that post.");
|
64 |
+
}
|
65 |
+
if (!current_user_can('delete_posts')) {
|
66 |
+
$json_api->error("You need to login with a user that has the 'delete_posts' capacity.");
|
67 |
+
}
|
68 |
+
if ($post->post_author != get_current_user_id() && !current_user_can('delete_other_posts')) {
|
69 |
+
$json_api->error("You need to login with a user that has the 'delete_other_posts' capacity.");
|
70 |
+
}
|
71 |
+
if (!$json_api->query->nonce) {
|
72 |
+
$json_api->error("You must include a 'nonce' value to update posts. Use the `get_nonce` Core API method.");
|
73 |
+
}
|
74 |
+
$nonce_id = $json_api->get_nonce_id('posts', 'delete_post');
|
75 |
+
if (!wp_verify_nonce($json_api->query->nonce, $nonce_id)) {
|
76 |
+
$json_api->error("Your 'nonce' value was incorrect. Use the 'get_nonce' API method.");
|
77 |
+
}
|
78 |
+
nocache_headers();
|
79 |
+
wp_delete_post($post->ID);
|
80 |
+
return array();
|
81 |
+
}
|
82 |
+
|
83 |
}
|
84 |
|
85 |
?>
|
json-api.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/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 |
*/
|
3 |
Plugin Name: JSON API
|
4 |
Plugin URI: http://wordpress.org/plugins/json-api/
|
5 |
Description: A RESTful API for WordPress
|
6 |
+
Version: 1.0.9
|
7 |
Author: Dan Phiffer
|
8 |
Author URI: http://phiffer.org/
|
9 |
*/
|
library/JSON.php
CHANGED
@@ -50,7 +50,7 @@
|
|
50 |
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
51 |
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
52 |
* @copyright 2005 Michal Migurski
|
53 |
-
* @version CVS: $Id: JSON.php
|
54 |
* @license http://www.opensource.org/licenses/bsd-license.php
|
55 |
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
56 |
*/
|
@@ -90,6 +90,11 @@ define('SERVICES_JSON_LOOSE_TYPE', 16);
|
|
90 |
*/
|
91 |
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
92 |
|
|
|
|
|
|
|
|
|
|
|
93 |
/**
|
94 |
* Converts to and from JSON format.
|
95 |
*
|
@@ -128,12 +133,24 @@ class Services_JSON
|
|
128 |
* By default, a deeply-nested resource will
|
129 |
* bubble up with an error, so all return values
|
130 |
* from encode() should be checked with isError()
|
|
|
|
|
|
|
|
|
|
|
131 |
*/
|
132 |
function Services_JSON($use = 0)
|
133 |
{
|
134 |
$this->use = $use;
|
|
|
|
|
|
|
135 |
}
|
136 |
-
|
|
|
|
|
|
|
|
|
137 |
/**
|
138 |
* convert a string from one UTF-16 char to one UTF-8 char
|
139 |
*
|
@@ -148,7 +165,7 @@ class Services_JSON
|
|
148 |
function utf162utf8($utf16)
|
149 |
{
|
150 |
// oh please oh please oh please oh please oh please
|
151 |
-
if(
|
152 |
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
153 |
}
|
154 |
|
@@ -192,11 +209,11 @@ class Services_JSON
|
|
192 |
function utf82utf16($utf8)
|
193 |
{
|
194 |
// oh please oh please oh please oh please oh please
|
195 |
-
if(
|
196 |
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
197 |
}
|
198 |
|
199 |
-
switch(
|
200 |
case 1:
|
201 |
// this case should never be reached, because we are in ASCII range
|
202 |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
@@ -236,10 +253,10 @@ class Services_JSON
|
|
236 |
function encode($var)
|
237 |
{
|
238 |
header('Content-type: application/json');
|
239 |
-
return $this->
|
240 |
}
|
241 |
/**
|
242 |
-
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow
|
243 |
*
|
244 |
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
245 |
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
@@ -251,7 +268,13 @@ class Services_JSON
|
|
251 |
*/
|
252 |
function encodeUnsafe($var)
|
253 |
{
|
254 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
/**
|
257 |
* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format
|
@@ -279,12 +302,12 @@ class Services_JSON
|
|
279 |
|
280 |
case 'double':
|
281 |
case 'float':
|
282 |
-
return
|
283 |
|
284 |
case 'string':
|
285 |
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
286 |
$ascii = '';
|
287 |
-
$strlen_var =
|
288 |
|
289 |
/*
|
290 |
* Iterate over every character in the string,
|
@@ -457,8 +480,27 @@ class Services_JSON
|
|
457 |
return '[' . join(',', $elements) . ']';
|
458 |
|
459 |
case 'object':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
460 |
$vars = get_object_vars($var);
|
461 |
-
|
462 |
$properties = array_map(array($this, 'name_value'),
|
463 |
array_keys($vars),
|
464 |
array_values($vars));
|
@@ -568,14 +610,14 @@ class Services_JSON
|
|
568 |
|
569 |
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
570 |
// STRINGS RETURNED IN UTF-8 FORMAT
|
571 |
-
$delim =
|
572 |
-
$chrs =
|
573 |
$utf8 = '';
|
574 |
-
$strlen_chrs =
|
575 |
|
576 |
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
577 |
|
578 |
-
$substr_chrs_c_2 =
|
579 |
$ord_chrs_c = ord($chrs{$c});
|
580 |
|
581 |
switch (true) {
|
@@ -610,10 +652,10 @@ class Services_JSON
|
|
610 |
}
|
611 |
break;
|
612 |
|
613 |
-
case preg_match('/\\\u[0-9A-F]{4}/i',
|
614 |
// single, escaped unicode character
|
615 |
-
$utf16 = chr(hexdec(
|
616 |
-
. chr(hexdec(
|
617 |
$utf8 .= $this->utf162utf8($utf16);
|
618 |
$c += 5;
|
619 |
break;
|
@@ -625,35 +667,35 @@ class Services_JSON
|
|
625 |
case ($ord_chrs_c & 0xE0) == 0xC0:
|
626 |
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
627 |
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
628 |
-
$utf8 .=
|
629 |
++$c;
|
630 |
break;
|
631 |
|
632 |
case ($ord_chrs_c & 0xF0) == 0xE0:
|
633 |
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
634 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
635 |
-
$utf8 .=
|
636 |
$c += 2;
|
637 |
break;
|
638 |
|
639 |
case ($ord_chrs_c & 0xF8) == 0xF0:
|
640 |
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
641 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
642 |
-
$utf8 .=
|
643 |
$c += 3;
|
644 |
break;
|
645 |
|
646 |
case ($ord_chrs_c & 0xFC) == 0xF8:
|
647 |
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
648 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
649 |
-
$utf8 .=
|
650 |
$c += 4;
|
651 |
break;
|
652 |
|
653 |
case ($ord_chrs_c & 0xFE) == 0xFC:
|
654 |
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
655 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
656 |
-
$utf8 .=
|
657 |
$c += 5;
|
658 |
break;
|
659 |
|
@@ -683,7 +725,7 @@ class Services_JSON
|
|
683 |
'where' => 0,
|
684 |
'delim' => false));
|
685 |
|
686 |
-
$chrs =
|
687 |
$chrs = $this->reduce_string($chrs);
|
688 |
|
689 |
if ($chrs == '') {
|
@@ -698,19 +740,19 @@ class Services_JSON
|
|
698 |
|
699 |
//print("\nparsing {$chrs}\n");
|
700 |
|
701 |
-
$strlen_chrs =
|
702 |
|
703 |
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
704 |
|
705 |
$top = end($stk);
|
706 |
-
$substr_chrs_c_2 =
|
707 |
|
708 |
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
709 |
// found a comma that is not inside a string, array, etc.,
|
710 |
// OR we've reached the end of the character list
|
711 |
-
$slice =
|
712 |
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
713 |
-
//print("Found split at {$c}: "
|
714 |
|
715 |
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
716 |
// we are in an array, so just push an element onto the stack
|
@@ -723,20 +765,19 @@ class Services_JSON
|
|
723 |
// for now
|
724 |
$parts = array();
|
725 |
|
726 |
-
|
727 |
-
|
728 |
$key = $this->decode($parts[1]);
|
729 |
-
$val = $this->decode($parts[
|
730 |
-
|
731 |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
732 |
$obj[$key] = $val;
|
733 |
} else {
|
734 |
$obj->$key = $val;
|
735 |
}
|
736 |
-
} elseif (preg_match('/^\s*(\w+)\s
|
737 |
// name:value pair, where name is unquoted
|
738 |
$key = $parts[1];
|
739 |
-
$val = $this->decode($parts[
|
740 |
|
741 |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
742 |
$obj[$key] = $val;
|
@@ -754,12 +795,12 @@ class Services_JSON
|
|
754 |
|
755 |
} elseif (($chrs{$c} == $top['delim']) &&
|
756 |
($top['what'] == SERVICES_JSON_IN_STR) &&
|
757 |
-
((
|
758 |
// found a quote, we're in a string, and it's not escaped
|
759 |
// we know that it's not escaped becase there is _not_ an
|
760 |
// odd number of backslashes at the end of the string so far
|
761 |
array_pop($stk);
|
762 |
-
//print("Found end of string at {$c}: "
|
763 |
|
764 |
} elseif (($chrs{$c} == '[') &&
|
765 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
@@ -770,7 +811,7 @@ class Services_JSON
|
|
770 |
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
771 |
// found a right-bracket, and we're in an array
|
772 |
array_pop($stk);
|
773 |
-
//print("Found end of array at {$c}: "
|
774 |
|
775 |
} elseif (($chrs{$c} == '{') &&
|
776 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
@@ -781,7 +822,7 @@ class Services_JSON
|
|
781 |
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
782 |
// found a right-brace, and we're in an object
|
783 |
array_pop($stk);
|
784 |
-
//print("Found end of object at {$c}: "
|
785 |
|
786 |
} elseif (($substr_chrs_c_2 == '/*') &&
|
787 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
@@ -798,7 +839,7 @@ class Services_JSON
|
|
798 |
for ($i = $top['where']; $i <= $c; ++$i)
|
799 |
$chrs = substr_replace($chrs, ' ', $i, 1);
|
800 |
|
801 |
-
//print("Found end of comment at {$c}: "
|
802 |
|
803 |
}
|
804 |
|
@@ -830,6 +871,38 @@ class Services_JSON
|
|
830 |
|
831 |
return false;
|
832 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
833 |
}
|
834 |
|
835 |
if (class_exists('PEAR_Error')) {
|
@@ -856,6 +929,5 @@ if (class_exists('PEAR_Error')) {
|
|
856 |
|
857 |
}
|
858 |
}
|
859 |
-
|
860 |
}
|
861 |
-
|
50 |
* @author Matt Knapp <mdknapp[at]gmail[dot]com>
|
51 |
* @author Brett Stimmerman <brettstimmerman[at]gmail[dot]com>
|
52 |
* @copyright 2005 Michal Migurski
|
53 |
+
* @version CVS: $Id: JSON.php 305040 2010-11-02 23:19:03Z alan_k $
|
54 |
* @license http://www.opensource.org/licenses/bsd-license.php
|
55 |
* @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198
|
56 |
*/
|
90 |
*/
|
91 |
define('SERVICES_JSON_SUPPRESS_ERRORS', 32);
|
92 |
|
93 |
+
/**
|
94 |
+
* Behavior switch for Services_JSON::decode()
|
95 |
+
*/
|
96 |
+
define('SERVICES_JSON_USE_TO_JSON', 64);
|
97 |
+
|
98 |
/**
|
99 |
* Converts to and from JSON format.
|
100 |
*
|
133 |
* By default, a deeply-nested resource will
|
134 |
* bubble up with an error, so all return values
|
135 |
* from encode() should be checked with isError()
|
136 |
+
* - SERVICES_JSON_USE_TO_JSON: call toJSON when serializing objects
|
137 |
+
* It serializes the return value from the toJSON call rather
|
138 |
+
* than the object it'self, toJSON can return associative arrays,
|
139 |
+
* strings or numbers, if you return an object, make sure it does
|
140 |
+
* not have a toJSON method, otherwise an error will occur.
|
141 |
*/
|
142 |
function Services_JSON($use = 0)
|
143 |
{
|
144 |
$this->use = $use;
|
145 |
+
$this->_mb_strlen = function_exists('mb_strlen');
|
146 |
+
$this->_mb_convert_encoding = function_exists('mb_convert_encoding');
|
147 |
+
$this->_mb_substr = function_exists('mb_substr');
|
148 |
}
|
149 |
+
// private - cache the mbstring lookup results..
|
150 |
+
var $_mb_strlen = false;
|
151 |
+
var $_mb_substr = false;
|
152 |
+
var $_mb_convert_encoding = false;
|
153 |
+
|
154 |
/**
|
155 |
* convert a string from one UTF-16 char to one UTF-8 char
|
156 |
*
|
165 |
function utf162utf8($utf16)
|
166 |
{
|
167 |
// oh please oh please oh please oh please oh please
|
168 |
+
if($this->_mb_convert_encoding) {
|
169 |
return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16');
|
170 |
}
|
171 |
|
209 |
function utf82utf16($utf8)
|
210 |
{
|
211 |
// oh please oh please oh please oh please oh please
|
212 |
+
if($this->_mb_convert_encoding) {
|
213 |
return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8');
|
214 |
}
|
215 |
|
216 |
+
switch($this->strlen8($utf8)) {
|
217 |
case 1:
|
218 |
// this case should never be reached, because we are in ASCII range
|
219 |
// see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
253 |
function encode($var)
|
254 |
{
|
255 |
header('Content-type: application/json');
|
256 |
+
return $this->encodeUnsafe($var);
|
257 |
}
|
258 |
/**
|
259 |
+
* encodes an arbitrary variable into JSON format without JSON Header - warning - may allow XSS!!!!)
|
260 |
*
|
261 |
* @param mixed $var any number, boolean, string, array, or object to be encoded.
|
262 |
* see argument 1 to Services_JSON() above for array-parsing behavior.
|
268 |
*/
|
269 |
function encodeUnsafe($var)
|
270 |
{
|
271 |
+
// see bug #16908 - regarding numeric locale printing
|
272 |
+
$lc = setlocale(LC_NUMERIC, 0);
|
273 |
+
setlocale(LC_NUMERIC, 'C');
|
274 |
+
$ret = $this->_encode($var);
|
275 |
+
setlocale(LC_NUMERIC, $lc);
|
276 |
+
return $ret;
|
277 |
+
|
278 |
}
|
279 |
/**
|
280 |
* PRIVATE CODE that does the work of encodes an arbitrary variable into JSON format
|
302 |
|
303 |
case 'double':
|
304 |
case 'float':
|
305 |
+
return (float) $var;
|
306 |
|
307 |
case 'string':
|
308 |
// STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT
|
309 |
$ascii = '';
|
310 |
+
$strlen_var = $this->strlen8($var);
|
311 |
|
312 |
/*
|
313 |
* Iterate over every character in the string,
|
480 |
return '[' . join(',', $elements) . ']';
|
481 |
|
482 |
case 'object':
|
483 |
+
|
484 |
+
// support toJSON methods.
|
485 |
+
if (($this->use & SERVICES_JSON_USE_TO_JSON) && method_exists($var, 'toJSON')) {
|
486 |
+
// this may end up allowing unlimited recursion
|
487 |
+
// so we check the return value to make sure it's not got the same method.
|
488 |
+
$recode = $var->toJSON();
|
489 |
+
|
490 |
+
if (method_exists($recode, 'toJSON')) {
|
491 |
+
|
492 |
+
return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS)
|
493 |
+
? 'null'
|
494 |
+
: new Services_JSON_Error(class_name($var).
|
495 |
+
" toJSON returned an object with a toJSON method.");
|
496 |
+
|
497 |
+
}
|
498 |
+
|
499 |
+
return $this->_encode( $recode );
|
500 |
+
}
|
501 |
+
|
502 |
$vars = get_object_vars($var);
|
503 |
+
|
504 |
$properties = array_map(array($this, 'name_value'),
|
505 |
array_keys($vars),
|
506 |
array_values($vars));
|
610 |
|
611 |
} elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) {
|
612 |
// STRINGS RETURNED IN UTF-8 FORMAT
|
613 |
+
$delim = $this->substr8($str, 0, 1);
|
614 |
+
$chrs = $this->substr8($str, 1, -1);
|
615 |
$utf8 = '';
|
616 |
+
$strlen_chrs = $this->strlen8($chrs);
|
617 |
|
618 |
for ($c = 0; $c < $strlen_chrs; ++$c) {
|
619 |
|
620 |
+
$substr_chrs_c_2 = $this->substr8($chrs, $c, 2);
|
621 |
$ord_chrs_c = ord($chrs{$c});
|
622 |
|
623 |
switch (true) {
|
652 |
}
|
653 |
break;
|
654 |
|
655 |
+
case preg_match('/\\\u[0-9A-F]{4}/i', $this->substr8($chrs, $c, 6)):
|
656 |
// single, escaped unicode character
|
657 |
+
$utf16 = chr(hexdec($this->substr8($chrs, ($c + 2), 2)))
|
658 |
+
. chr(hexdec($this->substr8($chrs, ($c + 4), 2)));
|
659 |
$utf8 .= $this->utf162utf8($utf16);
|
660 |
$c += 5;
|
661 |
break;
|
667 |
case ($ord_chrs_c & 0xE0) == 0xC0:
|
668 |
// characters U-00000080 - U-000007FF, mask 110XXXXX
|
669 |
//see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
670 |
+
$utf8 .= $this->substr8($chrs, $c, 2);
|
671 |
++$c;
|
672 |
break;
|
673 |
|
674 |
case ($ord_chrs_c & 0xF0) == 0xE0:
|
675 |
// characters U-00000800 - U-0000FFFF, mask 1110XXXX
|
676 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
677 |
+
$utf8 .= $this->substr8($chrs, $c, 3);
|
678 |
$c += 2;
|
679 |
break;
|
680 |
|
681 |
case ($ord_chrs_c & 0xF8) == 0xF0:
|
682 |
// characters U-00010000 - U-001FFFFF, mask 11110XXX
|
683 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
684 |
+
$utf8 .= $this->substr8($chrs, $c, 4);
|
685 |
$c += 3;
|
686 |
break;
|
687 |
|
688 |
case ($ord_chrs_c & 0xFC) == 0xF8:
|
689 |
// characters U-00200000 - U-03FFFFFF, mask 111110XX
|
690 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
691 |
+
$utf8 .= $this->substr8($chrs, $c, 5);
|
692 |
$c += 4;
|
693 |
break;
|
694 |
|
695 |
case ($ord_chrs_c & 0xFE) == 0xFC:
|
696 |
// characters U-04000000 - U-7FFFFFFF, mask 1111110X
|
697 |
// see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
698 |
+
$utf8 .= $this->substr8($chrs, $c, 6);
|
699 |
$c += 5;
|
700 |
break;
|
701 |
|
725 |
'where' => 0,
|
726 |
'delim' => false));
|
727 |
|
728 |
+
$chrs = $this->substr8($str, 1, -1);
|
729 |
$chrs = $this->reduce_string($chrs);
|
730 |
|
731 |
if ($chrs == '') {
|
740 |
|
741 |
//print("\nparsing {$chrs}\n");
|
742 |
|
743 |
+
$strlen_chrs = $this->strlen8($chrs);
|
744 |
|
745 |
for ($c = 0; $c <= $strlen_chrs; ++$c) {
|
746 |
|
747 |
$top = end($stk);
|
748 |
+
$substr_chrs_c_2 = $this->substr8($chrs, $c, 2);
|
749 |
|
750 |
if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) {
|
751 |
// found a comma that is not inside a string, array, etc.,
|
752 |
// OR we've reached the end of the character list
|
753 |
+
$slice = $this->substr8($chrs, $top['where'], ($c - $top['where']));
|
754 |
array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false));
|
755 |
+
//print("Found split at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
756 |
|
757 |
if (reset($stk) == SERVICES_JSON_IN_ARR) {
|
758 |
// we are in an array, so just push an element onto the stack
|
765 |
// for now
|
766 |
$parts = array();
|
767 |
|
768 |
+
if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:/Uis', $slice, $parts)) {
|
769 |
+
// "name":value pair
|
770 |
$key = $this->decode($parts[1]);
|
771 |
+
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
|
|
772 |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
773 |
$obj[$key] = $val;
|
774 |
} else {
|
775 |
$obj->$key = $val;
|
776 |
}
|
777 |
+
} elseif (preg_match('/^\s*(\w+)\s*:/Uis', $slice, $parts)) {
|
778 |
// name:value pair, where name is unquoted
|
779 |
$key = $parts[1];
|
780 |
+
$val = $this->decode(trim(substr($slice, strlen($parts[0])), ", \t\n\r\0\x0B"));
|
781 |
|
782 |
if ($this->use & SERVICES_JSON_LOOSE_TYPE) {
|
783 |
$obj[$key] = $val;
|
795 |
|
796 |
} elseif (($chrs{$c} == $top['delim']) &&
|
797 |
($top['what'] == SERVICES_JSON_IN_STR) &&
|
798 |
+
(($this->strlen8($this->substr8($chrs, 0, $c)) - $this->strlen8(rtrim($this->substr8($chrs, 0, $c), '\\'))) % 2 != 1)) {
|
799 |
// found a quote, we're in a string, and it's not escaped
|
800 |
// we know that it's not escaped becase there is _not_ an
|
801 |
// odd number of backslashes at the end of the string so far
|
802 |
array_pop($stk);
|
803 |
+
//print("Found end of string at {$c}: ".$this->substr8($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n");
|
804 |
|
805 |
} elseif (($chrs{$c} == '[') &&
|
806 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
811 |
} elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) {
|
812 |
// found a right-bracket, and we're in an array
|
813 |
array_pop($stk);
|
814 |
+
//print("Found end of array at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
815 |
|
816 |
} elseif (($chrs{$c} == '{') &&
|
817 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
822 |
} elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) {
|
823 |
// found a right-brace, and we're in an object
|
824 |
array_pop($stk);
|
825 |
+
//print("Found end of object at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
826 |
|
827 |
} elseif (($substr_chrs_c_2 == '/*') &&
|
828 |
in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) {
|
839 |
for ($i = $top['where']; $i <= $c; ++$i)
|
840 |
$chrs = substr_replace($chrs, ' ', $i, 1);
|
841 |
|
842 |
+
//print("Found end of comment at {$c}: ".$this->substr8($chrs, $top['where'], (1 + $c - $top['where']))."\n");
|
843 |
|
844 |
}
|
845 |
|
871 |
|
872 |
return false;
|
873 |
}
|
874 |
+
|
875 |
+
/**
|
876 |
+
* Calculates length of string in bytes
|
877 |
+
* @param string
|
878 |
+
* @return integer length
|
879 |
+
*/
|
880 |
+
function strlen8( $str )
|
881 |
+
{
|
882 |
+
if ( $this->_mb_strlen ) {
|
883 |
+
return mb_strlen( $str, "8bit" );
|
884 |
+
}
|
885 |
+
return strlen( $str );
|
886 |
+
}
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Returns part of a string, interpreting $start and $length as number of bytes.
|
890 |
+
* @param string
|
891 |
+
* @param integer start
|
892 |
+
* @param integer length
|
893 |
+
* @return integer length
|
894 |
+
*/
|
895 |
+
function substr8( $string, $start, $length=false )
|
896 |
+
{
|
897 |
+
if ( $length === false ) {
|
898 |
+
$length = $this->strlen8( $string ) - $start;
|
899 |
+
}
|
900 |
+
if ( $this->_mb_substr ) {
|
901 |
+
return mb_substr( $string, $start, $length, "8bit" );
|
902 |
+
}
|
903 |
+
return substr( $string, $start, $length );
|
904 |
+
}
|
905 |
+
|
906 |
}
|
907 |
|
908 |
if (class_exists('PEAR_Error')) {
|
929 |
|
930 |
}
|
931 |
}
|
932 |
+
|
933 |
}
|
|
models/attachment.php
CHANGED
@@ -41,7 +41,7 @@ class JSON_API_Attachment {
|
|
41 |
$sizes = array_merge(array('full'), get_intermediate_image_sizes());
|
42 |
}
|
43 |
$this->images = array();
|
44 |
-
$home = get_bloginfo('
|
45 |
foreach ($sizes as $size) {
|
46 |
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
|
47 |
$filename = ABSPATH . substr($url, strlen($home) + 1);
|
41 |
$sizes = array_merge(array('full'), get_intermediate_image_sizes());
|
42 |
}
|
43 |
$this->images = array();
|
44 |
+
$home = get_bloginfo('url');
|
45 |
foreach ($sizes as $size) {
|
46 |
list($url, $width, $height) = wp_get_attachment_image_src($this->id, $size);
|
47 |
$filename = ABSPATH . substr($url, strlen($home) + 1);
|
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
|
|
4 |
Tags: json, api, ajax, cms, admin, integration, moma
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 3.5.1
|
7 |
-
Stable tag: 1.0.
|
8 |
|
9 |
A RESTful API for WordPress
|
10 |
|
@@ -54,10 +54,10 @@ See the [Other Notes](http://wordpress.org/extend/plugins/json-api/other_notes/)
|
|
54 |
5. [Extending JSON API](#5.-Extending-JSON-API)
|
55 |
5.1. [Plugin hooks](#5.1.-Plugin-hooks)
|
56 |
5.2. [Developing JSON API controllers](#5.2.-Developing-JSON-API-controllers)
|
57 |
-
5.3. [Configuration options](#5.3.-Configuration-options)
|
58 |
-
6. [Unit tests](#6.-Unit-tests)
|
59 |
-
6.1. [Preparing a WordPress test site](#6.1.-Preparing-a-WordPress-test-site)
|
60 |
-
6.2. [Running the tests](#6.2.-Running-the-tests)
|
61 |
|
62 |
== 1. General Concepts ==
|
63 |
|
@@ -191,7 +191,7 @@ Returns information about JSON API.
|
|
191 |
|
192 |
* `controller` - returns detailed information about a specific controller
|
193 |
|
194 |
-
= Response
|
195 |
|
196 |
{
|
197 |
"status": "ok",
|
@@ -202,7 +202,7 @@ Returns information about JSON API.
|
|
202 |
}
|
203 |
|
204 |
|
205 |
-
= Response
|
206 |
|
207 |
{
|
208 |
"status": "ok",
|
@@ -224,7 +224,7 @@ Returns an array of recent posts. You can invoke this from the WordPress home pa
|
|
224 |
* `page` - return a specific page number from the results
|
225 |
* `post_type` - used to retrieve custom post types
|
226 |
|
227 |
-
= Response
|
228 |
|
229 |
{
|
230 |
"status": "ok",
|
@@ -252,7 +252,7 @@ Returns posts according to WordPress's [`WP_Query` parameters](http://codex.word
|
|
252 |
__Further reading__
|
253 |
See the [`WP_Query` documentation](http://codex.wordpress.org/Class_Reference/WP_Query#Parameters) for a full list of supported parameters. The `post_status` parameter is currently ignored.
|
254 |
|
255 |
-
= Response
|
256 |
|
257 |
{
|
258 |
"status": "ok",
|
@@ -490,6 +490,10 @@ Note: the tree is arranged by `response.tree.[year].[month].[number of posts]`.
|
|
490 |
|
491 |
Returns an array of active categories.
|
492 |
|
|
|
|
|
|
|
|
|
493 |
= Response =
|
494 |
|
495 |
{
|
@@ -594,6 +598,43 @@ Creates a new post.
|
|
594 |
|
595 |
Note: including a file upload field called `attachment` will cause an attachment to be stored with your new post.
|
596 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
597 |
|
598 |
== 2.3. Respond controller methods ==
|
599 |
|
@@ -648,6 +689,8 @@ The following arguments modify how you get results back from the API. The redire
|
|
648 |
* 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).
|
649 |
* Setting `redirect_[status]` allows you to control the resulting browser redirection depending on the `status` value.
|
650 |
* Setting `dev` to a non-empty value adds whitespace for readability and responds with `text/plain`
|
|
|
|
|
651 |
* Omitting all of the above arguments will result in a standard JSON response.
|
652 |
|
653 |
== 3.2. Content-modifying arguments ==
|
@@ -991,6 +1034,13 @@ You should see the test results print out culminating in a summary:
|
|
991 |
|
992 |
== Changelog ==
|
993 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
994 |
= 1.0.8 (2013-06-12): =
|
995 |
* Added `widgets` controller
|
996 |
* Added a generic `get_posts` method to the core controller
|
@@ -1108,6 +1158,9 @@ You should see the test results print out culminating in a summary:
|
|
1108 |
|
1109 |
== Upgrade Notice ==
|
1110 |
|
|
|
|
|
|
|
1111 |
= 1.0.8 =
|
1112 |
Long overdue bugfix/improvement release
|
1113 |
|
4 |
Tags: json, api, ajax, cms, admin, integration, moma
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 3.5.1
|
7 |
+
Stable tag: 1.0.9
|
8 |
|
9 |
A RESTful API for WordPress
|
10 |
|
54 |
5. [Extending JSON API](#5.-Extending-JSON-API)
|
55 |
5.1. [Plugin hooks](#5.1.-Plugin-hooks)
|
56 |
5.2. [Developing JSON API controllers](#5.2.-Developing-JSON-API-controllers)
|
57 |
+
5.3. [Configuration options](#5.3.-Configuration-options)
|
58 |
+
6. [Unit tests](#6.-Unit-tests)
|
59 |
+
6.1. [Preparing a WordPress test site](#6.1.-Preparing-a-WordPress-test-site)
|
60 |
+
6.2. [Running the tests](#6.2.-Running-the-tests)
|
61 |
|
62 |
== 1. General Concepts ==
|
63 |
|
191 |
|
192 |
* `controller` - returns detailed information about a specific controller
|
193 |
|
194 |
+
= Response =
|
195 |
|
196 |
{
|
197 |
"status": "ok",
|
202 |
}
|
203 |
|
204 |
|
205 |
+
= Response with “controller=core” =
|
206 |
|
207 |
{
|
208 |
"status": "ok",
|
224 |
* `page` - return a specific page number from the results
|
225 |
* `post_type` - used to retrieve custom post types
|
226 |
|
227 |
+
= Response =
|
228 |
|
229 |
{
|
230 |
"status": "ok",
|
252 |
__Further reading__
|
253 |
See the [`WP_Query` documentation](http://codex.wordpress.org/Class_Reference/WP_Query#Parameters) for a full list of supported parameters. The `post_status` parameter is currently ignored.
|
254 |
|
255 |
+
= Response =
|
256 |
|
257 |
{
|
258 |
"status": "ok",
|
490 |
|
491 |
Returns an array of active categories.
|
492 |
|
493 |
+
= Optional argument =
|
494 |
+
|
495 |
+
* `parent` - returns categories that are direct children of the parent ID
|
496 |
+
|
497 |
= Response =
|
498 |
|
499 |
{
|
598 |
|
599 |
Note: including a file upload field called `attachment` will cause an attachment to be stored with your new post.
|
600 |
|
601 |
+
== Method: update_post ==
|
602 |
+
|
603 |
+
Updates a post.
|
604 |
+
|
605 |
+
= Required argument =
|
606 |
+
|
607 |
+
* `nonce` - available from the `get_nonce` method (call with vars `controller=posts` and `method=update_post`)
|
608 |
+
|
609 |
+
= One of the following is required =
|
610 |
+
|
611 |
+
* `id` or `post_id` - set to the post's ID
|
612 |
+
* `slug` or `post_slug` - set to the post's URL slug
|
613 |
+
|
614 |
+
= Optional arguments =
|
615 |
+
|
616 |
+
* `status` - sets the post status ("draft" or "publish"), default is "draft"
|
617 |
+
* `title` - the post title
|
618 |
+
* `content` - the post content
|
619 |
+
* `author` - the post's author (login name), default is the current logged in user
|
620 |
+
* `categories` - a comma-separated list of categories (URL slugs)
|
621 |
+
* `tags` - a comma-separated list of tags (URL slugs)
|
622 |
+
|
623 |
+
Note: including a file upload field called `attachment` will cause an attachment to be stored with your post.
|
624 |
+
|
625 |
+
== Method: delete_post ==
|
626 |
+
|
627 |
+
Deletes a post.
|
628 |
+
|
629 |
+
= Required argument =
|
630 |
+
|
631 |
+
* `nonce` - available from the `get_nonce` method (call with vars `controller=posts` and `method=delete_post`)
|
632 |
+
|
633 |
+
= One of the following is required =
|
634 |
+
|
635 |
+
* `id` or `post_id` - set to the post's ID
|
636 |
+
* `slug` or `post_slug` - set to the post's URL slug
|
637 |
+
|
638 |
|
639 |
== 2.3. Respond controller methods ==
|
640 |
|
689 |
* 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).
|
690 |
* Setting `redirect_[status]` allows you to control the resulting browser redirection depending on the `status` value.
|
691 |
* Setting `dev` to a non-empty value adds whitespace for readability and responds with `text/plain`
|
692 |
+
* Setting `json_encode_options` will let you specify an integer bitmask to modify the behavior of [PHP's `json_encode`](http://php.net/manual/en/function.json-encode.php)
|
693 |
+
* Setting `json_unescaped_unicode` will replace unicode-escaped characters with their unescaped equivalents (e.g., `\u00e1` becomes á)
|
694 |
* Omitting all of the above arguments will result in a standard JSON response.
|
695 |
|
696 |
== 3.2. Content-modifying arguments ==
|
1034 |
|
1035 |
== Changelog ==
|
1036 |
|
1037 |
+
= 1.0.9 (2013-06-21): =
|
1038 |
+
* Added `update_post` and `delete_post` methods to Post controller
|
1039 |
+
* Added two JSON encoding arguments: `json_encode_options` and `json_unescaped_unicode`
|
1040 |
+
* Added a `parent` argument to `get_category_index`
|
1041 |
+
* Fixed a couple places where the code was generating PHP notifications
|
1042 |
+
* Updated bundled Services_JSON library (only used if `json_encode` is unavailable)
|
1043 |
+
|
1044 |
= 1.0.8 (2013-06-12): =
|
1045 |
* Added `widgets` controller
|
1046 |
* Added a generic `get_posts` method to the core controller
|
1158 |
|
1159 |
== Upgrade Notice ==
|
1160 |
|
1161 |
+
= 1.0.9 =
|
1162 |
+
Update/delete post methods and some other bugfixes and improvements
|
1163 |
+
|
1164 |
= 1.0.8 =
|
1165 |
Long overdue bugfix/improvement release
|
1166 |
|
singletons/api.php
CHANGED
@@ -172,7 +172,7 @@ class JSON_API {
|
|
172 |
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>';
|
173 |
}
|
174 |
|
175 |
-
if ($info['url']) {
|
176 |
echo ' | ';
|
177 |
echo '<a href="' . $info['url'] . '" target="_blank">Docs</a></div>';
|
178 |
}
|
172 |
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>';
|
173 |
}
|
174 |
|
175 |
+
if (!empty($info['url'])) {
|
176 |
echo ' | ';
|
177 |
echo '<a href="' . $info['url'] . '" target="_blank">Docs</a></div>';
|
178 |
}
|
singletons/introspector.php
CHANGED
@@ -67,8 +67,8 @@ class JSON_API_Introspector {
|
|
67 |
return $this->month_archives["$year$month"];
|
68 |
}
|
69 |
|
70 |
-
public function get_categories() {
|
71 |
-
$wp_categories = get_categories();
|
72 |
$categories = array();
|
73 |
foreach ($wp_categories as $wp_category) {
|
74 |
if ($wp_category->term_id == 1 && $wp_category->slug == 'uncategorized') {
|
@@ -79,6 +79,33 @@ class JSON_API_Introspector {
|
|
79 |
return $categories;
|
80 |
}
|
81 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
public function get_current_category() {
|
83 |
global $json_api;
|
84 |
extract($json_api->query->get(array('id', 'slug', 'category_id', 'category_slug')));
|
67 |
return $this->month_archives["$year$month"];
|
68 |
}
|
69 |
|
70 |
+
public function get_categories($args = null) {
|
71 |
+
$wp_categories = get_categories($args);
|
72 |
$categories = array();
|
73 |
foreach ($wp_categories as $wp_category) {
|
74 |
if ($wp_category->term_id == 1 && $wp_category->slug == 'uncategorized') {
|
79 |
return $categories;
|
80 |
}
|
81 |
|
82 |
+
public function get_current_post() {
|
83 |
+
global $json_api;
|
84 |
+
extract($json_api->query->get(array('id', 'slug', 'post_id', 'post_slug')));
|
85 |
+
if ($id || $post_id) {
|
86 |
+
if (!$id) {
|
87 |
+
$id = $post_id;
|
88 |
+
}
|
89 |
+
$posts = $this->get_posts(array(
|
90 |
+
'p' => $id
|
91 |
+
), true);
|
92 |
+
} else if ($slug || $post_slug) {
|
93 |
+
if (!$slug) {
|
94 |
+
$slug = $post_slug;
|
95 |
+
}
|
96 |
+
$posts = $this->get_posts(array(
|
97 |
+
'name' => $slug
|
98 |
+
), true);
|
99 |
+
} else {
|
100 |
+
$json_api->error("Include 'id' or 'slug' var in your request.");
|
101 |
+
}
|
102 |
+
if (!empty($posts)) {
|
103 |
+
return $posts[0];
|
104 |
+
} else {
|
105 |
+
return null;
|
106 |
+
}
|
107 |
+
}
|
108 |
+
|
109 |
public function get_current_category() {
|
110 |
global $json_api;
|
111 |
extract($json_api->query->get(array('id', 'slug', 'category_id', 'category_slug')));
|
singletons/response.php
CHANGED
@@ -20,6 +20,7 @@ class JSON_API_Response {
|
|
20 |
}
|
21 |
|
22 |
function get_json($data, $status = 'ok') {
|
|
|
23 |
// Include a status value with the response
|
24 |
if (is_array($data)) {
|
25 |
$data = array_merge(array('status' => $status), $data);
|
@@ -32,16 +33,27 @@ class JSON_API_Response {
|
|
32 |
|
33 |
if (function_exists('json_encode')) {
|
34 |
// Use the built-in json_encode function if it's available
|
35 |
-
|
|
|
|
|
|
|
|
|
36 |
} else {
|
37 |
// Use PEAR's Services_JSON encoder otherwise
|
38 |
if (!class_exists('Services_JSON')) {
|
39 |
$dir = json_api_dir();
|
40 |
require_once "$dir/library/JSON.php";
|
41 |
}
|
42 |
-
$
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
44 |
}
|
|
|
|
|
45 |
}
|
46 |
|
47 |
function is_value_included($key) {
|
@@ -179,6 +191,10 @@ class JSON_API_Response {
|
|
179 |
return $pretty;
|
180 |
}
|
181 |
|
|
|
|
|
|
|
|
|
182 |
}
|
183 |
|
184 |
?>
|
20 |
}
|
21 |
|
22 |
function get_json($data, $status = 'ok') {
|
23 |
+
global $json_api;
|
24 |
// Include a status value with the response
|
25 |
if (is_array($data)) {
|
26 |
$data = array_merge(array('status' => $status), $data);
|
33 |
|
34 |
if (function_exists('json_encode')) {
|
35 |
// Use the built-in json_encode function if it's available
|
36 |
+
$json_encode_options = 0;
|
37 |
+
if ($json_api->query->json_encode_options) {
|
38 |
+
$json_encode_options = $json_api->query->json_encode_options;
|
39 |
+
}
|
40 |
+
$json = json_encode($data, $json_encode_options);
|
41 |
} else {
|
42 |
// Use PEAR's Services_JSON encoder otherwise
|
43 |
if (!class_exists('Services_JSON')) {
|
44 |
$dir = json_api_dir();
|
45 |
require_once "$dir/library/JSON.php";
|
46 |
}
|
47 |
+
$json_service = new Services_JSON();
|
48 |
+
$json = $json_service->encode($data);
|
49 |
+
}
|
50 |
+
|
51 |
+
if ($json_api->query->json_unescaped_unicode) {
|
52 |
+
$callback = array($this, 'replace_unicode_escape_sequence');
|
53 |
+
$json = preg_replace_callback('/\\\\u([0-9a-f]{4})/i', $callback, $json);
|
54 |
}
|
55 |
+
|
56 |
+
return $json;
|
57 |
}
|
58 |
|
59 |
function is_value_included($key) {
|
191 |
return $pretty;
|
192 |
}
|
193 |
|
194 |
+
function replace_unicode_escape_sequence($match) {
|
195 |
+
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
|
196 |
+
}
|
197 |
+
|
198 |
}
|
199 |
|
200 |
?>
|