|
1 <?php |
|
2 /** |
|
3 * REST API: WP_REST_Response class |
|
4 * |
|
5 * @package WordPress |
|
6 * @subpackage REST_API |
|
7 * @since 4.4.0 |
|
8 */ |
|
9 |
|
10 /** |
|
11 * Core class used to implement a REST response object. |
|
12 * |
|
13 * @since 4.4.0 |
|
14 * |
|
15 * @see WP_HTTP_Response |
|
16 */ |
|
17 class WP_REST_Response extends WP_HTTP_Response { |
|
18 |
|
19 /** |
|
20 * Links related to the response. |
|
21 * |
|
22 * @since 4.4.0 |
|
23 * @var array |
|
24 */ |
|
25 protected $links = array(); |
|
26 |
|
27 /** |
|
28 * The route that was to create the response. |
|
29 * |
|
30 * @since 4.4.0 |
|
31 * @var string |
|
32 */ |
|
33 protected $matched_route = ''; |
|
34 |
|
35 /** |
|
36 * The handler that was used to create the response. |
|
37 * |
|
38 * @since 4.4.0 |
|
39 * @var null|array |
|
40 */ |
|
41 protected $matched_handler = null; |
|
42 |
|
43 /** |
|
44 * Adds a link to the response. |
|
45 * |
|
46 * @internal The $rel parameter is first, as this looks nicer when sending multiple. |
|
47 * |
|
48 * @since 4.4.0 |
|
49 * |
|
50 * @link https://tools.ietf.org/html/rfc5988 |
|
51 * @link https://www.iana.org/assignments/link-relations/link-relations.xml |
|
52 * |
|
53 * @param string $rel Link relation. Either an IANA registered type, |
|
54 * or an absolute URL. |
|
55 * @param string $href Target URI for the link. |
|
56 * @param array $attributes Optional. Link parameters to send along with the URL. Default empty array. |
|
57 */ |
|
58 public function add_link( $rel, $href, $attributes = array() ) { |
|
59 if ( empty( $this->links[ $rel ] ) ) { |
|
60 $this->links[ $rel ] = array(); |
|
61 } |
|
62 |
|
63 if ( isset( $attributes['href'] ) ) { |
|
64 // Remove the href attribute, as it's used for the main URL. |
|
65 unset( $attributes['href'] ); |
|
66 } |
|
67 |
|
68 $this->links[ $rel ][] = array( |
|
69 'href' => $href, |
|
70 'attributes' => $attributes, |
|
71 ); |
|
72 } |
|
73 |
|
74 /** |
|
75 * Removes a link from the response. |
|
76 * |
|
77 * @since 4.4.0 |
|
78 * |
|
79 * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. |
|
80 * @param string $href Optional. Only remove links for the relation matching the given href. |
|
81 * Default null. |
|
82 */ |
|
83 public function remove_link( $rel, $href = null ) { |
|
84 if ( ! isset( $this->links[ $rel ] ) ) { |
|
85 return; |
|
86 } |
|
87 |
|
88 if ( $href ) { |
|
89 $this->links[ $rel ] = wp_list_filter( $this->links[ $rel ], array( 'href' => $href ), 'NOT' ); |
|
90 } else { |
|
91 $this->links[ $rel ] = array(); |
|
92 } |
|
93 |
|
94 if ( ! $this->links[ $rel ] ) { |
|
95 unset( $this->links[ $rel ] ); |
|
96 } |
|
97 } |
|
98 |
|
99 /** |
|
100 * Adds multiple links to the response. |
|
101 * |
|
102 * Link data should be an associative array with link relation as the key. |
|
103 * The value can either be an associative array of link attributes |
|
104 * (including `href` with the URL for the response), or a list of these |
|
105 * associative arrays. |
|
106 * |
|
107 * @since 4.4.0 |
|
108 * |
|
109 * @param array $links Map of link relation to list of links. |
|
110 */ |
|
111 public function add_links( $links ) { |
|
112 foreach ( $links as $rel => $set ) { |
|
113 // If it's a single link, wrap with an array for consistent handling. |
|
114 if ( isset( $set['href'] ) ) { |
|
115 $set = array( $set ); |
|
116 } |
|
117 |
|
118 foreach ( $set as $attributes ) { |
|
119 $this->add_link( $rel, $attributes['href'], $attributes ); |
|
120 } |
|
121 } |
|
122 } |
|
123 |
|
124 /** |
|
125 * Retrieves links for the response. |
|
126 * |
|
127 * @since 4.4.0 |
|
128 * |
|
129 * @return array List of links. |
|
130 */ |
|
131 public function get_links() { |
|
132 return $this->links; |
|
133 } |
|
134 |
|
135 /** |
|
136 * Sets a single link header. |
|
137 * |
|
138 * @internal The $rel parameter is first, as this looks nicer when sending multiple. |
|
139 * |
|
140 * @since 4.4.0 |
|
141 * |
|
142 * @link https://tools.ietf.org/html/rfc5988 |
|
143 * @link https://www.iana.org/assignments/link-relations/link-relations.xml |
|
144 * |
|
145 * @param string $rel Link relation. Either an IANA registered type, or an absolute URL. |
|
146 * @param string $link Target IRI for the link. |
|
147 * @param array $other Optional. Other parameters to send, as an assocative array. |
|
148 * Default empty array. |
|
149 */ |
|
150 public function link_header( $rel, $link, $other = array() ) { |
|
151 $header = '<' . $link . '>; rel="' . $rel . '"'; |
|
152 |
|
153 foreach ( $other as $key => $value ) { |
|
154 if ( 'title' === $key ) { |
|
155 $value = '"' . $value . '"'; |
|
156 } |
|
157 $header .= '; ' . $key . '=' . $value; |
|
158 } |
|
159 $this->header( 'Link', $header, false ); |
|
160 } |
|
161 |
|
162 /** |
|
163 * Retrieves the route that was used. |
|
164 * |
|
165 * @since 4.4.0 |
|
166 * |
|
167 * @return string The matched route. |
|
168 */ |
|
169 public function get_matched_route() { |
|
170 return $this->matched_route; |
|
171 } |
|
172 |
|
173 /** |
|
174 * Sets the route (regex for path) that caused the response. |
|
175 * |
|
176 * @since 4.4.0 |
|
177 * |
|
178 * @param string $route Route name. |
|
179 */ |
|
180 public function set_matched_route( $route ) { |
|
181 $this->matched_route = $route; |
|
182 } |
|
183 |
|
184 /** |
|
185 * Retrieves the handler that was used to generate the response. |
|
186 * |
|
187 * @since 4.4.0 |
|
188 * |
|
189 * @return null|array The handler that was used to create the response. |
|
190 */ |
|
191 public function get_matched_handler() { |
|
192 return $this->matched_handler; |
|
193 } |
|
194 |
|
195 /** |
|
196 * Retrieves the handler that was responsible for generating the response. |
|
197 * |
|
198 * @since 4.4.0 |
|
199 * |
|
200 * @param array $handler The matched handler. |
|
201 */ |
|
202 public function set_matched_handler( $handler ) { |
|
203 $this->matched_handler = $handler; |
|
204 } |
|
205 |
|
206 /** |
|
207 * Checks if the response is an error, i.e. >= 400 response code. |
|
208 * |
|
209 * @since 4.4.0 |
|
210 * |
|
211 * @return bool Whether the response is an error. |
|
212 */ |
|
213 public function is_error() { |
|
214 return $this->get_status() >= 400; |
|
215 } |
|
216 |
|
217 /** |
|
218 * Retrieves a WP_Error object from the response. |
|
219 * |
|
220 * @since 4.4.0 |
|
221 * |
|
222 * @return WP_Error|null WP_Error or null on not an errored response. |
|
223 */ |
|
224 public function as_error() { |
|
225 if ( ! $this->is_error() ) { |
|
226 return null; |
|
227 } |
|
228 |
|
229 $error = new WP_Error; |
|
230 |
|
231 if ( is_array( $this->get_data() ) ) { |
|
232 $data = $this->get_data(); |
|
233 $error->add( $data['code'], $data['message'], $data['data'] ); |
|
234 if ( ! empty( $data['additional_errors'] ) ) { |
|
235 foreach( $data['additional_errors'] as $err ) { |
|
236 $error->add( $err['code'], $err['message'], $err['data'] ); |
|
237 } |
|
238 } |
|
239 } else { |
|
240 $error->add( $this->get_status(), '', array( 'status' => $this->get_status() ) ); |
|
241 } |
|
242 |
|
243 return $error; |
|
244 } |
|
245 |
|
246 /** |
|
247 * Retrieves the CURIEs (compact URIs) used for relations. |
|
248 * |
|
249 * @since 4.5.0 |
|
250 * |
|
251 * @return array Compact URIs. |
|
252 */ |
|
253 public function get_curies() { |
|
254 $curies = array( |
|
255 array( |
|
256 'name' => 'wp', |
|
257 'href' => 'https://api.w.org/{rel}', |
|
258 'templated' => true, |
|
259 ), |
|
260 ); |
|
261 |
|
262 /** |
|
263 * Filters extra CURIEs available on API responses. |
|
264 * |
|
265 * CURIEs allow a shortened version of URI relations. This allows a more |
|
266 * usable form for custom relations than using the full URI. These work |
|
267 * similarly to how XML namespaces work. |
|
268 * |
|
269 * Registered CURIES need to specify a name and URI template. This will |
|
270 * automatically transform URI relations into their shortened version. |
|
271 * The shortened relation follows the format `{name}:{rel}`. `{rel}` in |
|
272 * the URI template will be replaced with the `{rel}` part of the |
|
273 * shortened relation. |
|
274 * |
|
275 * For example, a CURIE with name `example` and URI template |
|
276 * `http://w.org/{rel}` would transform a `http://w.org/term` relation |
|
277 * into `example:term`. |
|
278 * |
|
279 * Well-behaved clients should expand and normalise these back to their |
|
280 * full URI relation, however some naive clients may not resolve these |
|
281 * correctly, so adding new CURIEs may break backward compatibility. |
|
282 * |
|
283 * @since 4.5.0 |
|
284 * |
|
285 * @param array $additional Additional CURIEs to register with the API. |
|
286 */ |
|
287 $additional = apply_filters( 'rest_response_link_curies', array() ); |
|
288 return array_merge( $curies, $additional ); |
|
289 } |
|
290 } |