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