-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathnamespace.php
More file actions
112 lines (93 loc) · 2.55 KB
/
namespace.php
File metadata and controls
112 lines (93 loc) · 2.55 KB
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
<?php
namespace WordPress\Discovery;
use Exception;
use Requests;
/**
* Discover the WordPress API from a URI.
*
* @param string $uri URI to start the search from.
* @param bool $legacy Should we check for the legacy API too?
* @return Site|null Site data if available, null if not a WP site.
*/
function discover( $uri, $legacy = false ) {
// Step 1: Find the API itself.
$root = discover_api_root( $uri, $legacy );
if ( empty( $root ) ) {
return null;
}
// Step 2: Ask the API for information.
return get_index_information( $root );
}
/**
* Discover the API root from an address.
*
* @throws \Requests_Exception on HTTP error.
*
* @param string $uri URI to search for the API from.
* @param bool $legacy Should we check for the legacy API too?
* @return string|null API root URL if found, null if no API is available.
*/
function discover_api_root( $uri, $legacy = false ) {
$response = Requests::head( $uri );
$response->throw_for_status();
$header_value = $response->headers->getValues( 'Link' );
$links = explode( ',', $header_value[0] );
// Find the correct link by relation
foreach ( $links as $link ) {
$attrs = parse_link_header( $link );
if ( empty( $attrs ) || empty( $attrs['rel'] ) ) {
continue;
}
switch ( $attrs['rel'] ) {
case 'https://api.w.org/':
break;
case 'https://github.com/WP-API/WP-API':
// Only allow this if legacy mode is on.
if ( $legacy ) {
break;
}
// Fall-through.
default:
continue 2;
}
return $attrs['href'];
}
return null;
}
/**
* Parse a Link header into attributes.
*
* @param string $link Link header from the response.
* @return array Map of attribute key => attribute value, with link href in `href` key.
*/
function parse_link_header( $link ) {
$parts = explode( ';', $link );
$attrs = array(
'href' => trim( array_shift( $parts ), '<>' ),
);
foreach ( $parts as $part ) {
if ( ! strpos( $part, '=' ) ) {
continue;
}
list( $key, $value ) = explode( '=', $part, 2 );
$key = trim( $key );
$value = trim( $value, '" ' );
$attrs[ $key ] = $value;
}
return $attrs;
}
/**
* Get the index information from a site.
*
* @param string $url URL for the API index.
* @return Site Data from the index for the site.
*/
function get_index_information( $url ) {
$response = Requests::get( $url );
$response->throw_for_status();
$index = json_decode( $response->body );
if ( empty( $index ) && json_last_error() !== JSON_ERROR_NONE ) {
throw new Exception( json_last_error_msg(), json_last_error() );
}
return new Site( $index, $url );
}