-
Notifications
You must be signed in to change notification settings - Fork 1
/
jsonapi-serializer.class.php
162 lines (117 loc) · 4.35 KB
/
jsonapi-serializer.class.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
158
159
160
161
162
<?php
class JSONAPI_Serializer {
public static function rest_post_dispatch($result, $server, $request) {
$method = $request->get_method();
/**
* Currently only supporting READ operations.
*/
if ( 'GET' === $method ) {
$data = [];
$included = [];
$meta = null;
if ( self::isQuery( $result ) ) {
foreach ( $result->data as $post ) {
$doc = self::serialize( $post );
$data[] = $doc->doc();
$included = array_merge($included, $doc->includes());
}
$included = self::remove_duplicates( $included );
$meta = array(
'total' => $result->headers['X-WP-Total'],
'total-pages' => $result->headers['X-WP-TotalPages'],
'page' => $request->get_param('page')
);
} else {
if ( !empty( $result->data ) ) {
$doc = self::serialize( $result->data );
$data = $doc->doc();
$included = $doc->includes();
}
}
$payload = array(
'data' => $data,
'included' => $included
);
if ( $meta ) {
$payload['meta'] = $meta;
}
$result->set_data( $payload );
}
return $result;
}
static function serialize( $post ) {
$type = isset( $post['type'] ) ? $post['type'] : $post['taxonomy'];
$doc = new JSONAPI_Doc( $post['id'], $type );
return $doc;
}
protected static function remove_duplicates( $array ) {
$seen = [];
$unique = [];
array_walk( $array, function( $val ) use ( &$seen, &$unique ) {
$index = "$val[type]::$val[id]";
if ( false === array_search( $index, $seen ) ) {
array_push( $seen, $index );
array_push( $unique, $val );
}
} );
return $unique;
}
/**
* Mostly copied from WP_REST_Server::get_json_last_error
*/
public static function get_json_last_error() {
// See https://core.trac.wordpress.org/ticket/27799.
if ( ! function_exists( 'json_last_error' ) ) {
return false;
}
$last_error_code = json_last_error();
if ( ( defined( 'JSON_ERROR_NONE' ) && JSON_ERROR_NONE === $last_error_code ) || empty( $last_error_code ) ) {
return false;
}
return json_last_error_msg();
}
/**
* Mostly copied from WP_REST_Server::get_json_last_error
*
* TODO: adjust this to JSONAPI response
*/
protected function error_to_response( $error ) {
$error_data = $error->get_error_data();
if ( is_array( $error_data ) && isset( $error_data['status'] ) ) {
$status = $error_data['status'];
} else {
$status = 500;
}
$errors = array();
foreach ( (array) $error->errors as $code => $messages ) {
foreach ( (array) $messages as $message ) {
$errors[] = array( 'code' => $code, 'message' => $message, 'data' => $error->get_error_data( $code ) );
}
}
$data = $errors[0];
if ( count( $errors ) > 1 ) {
// Remove the primary error.
array_shift( $errors );
$data['additional_errors'] = $errors;
}
$response = new WP_REST_Response( $data, $status );
return $response;
}
public static function rest_pre_serve_request( $served, $result, $request, $server ) {
if ( 'GET' !== $request->get_method() ) {
return false;
}
$result = wp_json_encode( $result->get_data() );
$json_error_message = self::get_json_last_error();
if ( $json_error_message ) {
$json_error_obj = new WP_Error( 'rest_encode_error', $json_error_message, array( 'status' => 500 ) );
$result = $server->error_to_response( $json_error_obj );
$result = wp_json_encode( $result->data[0] );
}
echo $result;
return true;
}
public static function isQuery( $result ) {
return isset($result->headers['X-WP-Total']) && isset($result->headers['X-WP-TotalPages']);
}
}