├── .gitignore
├── LICENSE.md
├── README.md
├── composer.json
├── composer.lock
├── lib
├── Site.php
└── namespace.php
└── www
├── details.php
├── error.php
├── index.php
├── layout.php
└── style.css
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor/
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Ryan McCue
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in all
11 | copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 | SOFTWARE.
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WordPress API Discovery
2 |
3 | This library allows autodiscovery of the WordPress REST API shipping in WordPress 4.4.
4 |
5 | ## Installing
6 |
7 | This library should be installed via Composer as `wp-api/discovery`.
8 |
9 | If manually installing (i.e. via `git clone`), be sure to run `composer install` after cloning the code.
10 |
11 | ## Using
12 |
13 | The main entry point is the `WordPress\Discovery\discover()` function. Simply pass in a URL to discover the API.
14 |
15 | ```php
16 | /**
17 | * Discover the WordPress API from a URI.
18 | *
19 | * @param string $uri URI to start the search from.
20 | * @param bool $legacy Should we check for the legacy API too?
21 | * @return Site|null Site data if available, null if not a WP site.
22 | */
23 | function discover( $uri, $legacy = false ) {
24 | ```
25 |
26 | This project also includes a demo web install:
27 |
28 | ```sh
29 | php -S 0.0.0.0:9000 www/index.php
30 | ```
31 |
32 | Then access http://localhost:9000/ to view the demo. It looks something like this:
33 |
34 |
35 |
36 | ## License
37 |
38 | This project is licensed under the MIT license. See [LICENSE.md](LICENSE.md) for the full license.
39 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wp-api/discovery",
3 | "license": "MIT",
4 | "require": {
5 | "rmccue/requests": "^1.6"
6 | },
7 | "autoload": {
8 | "psr-4": {
9 | "WordPress\\Discovery\\": "lib/"
10 | },
11 | "files": [
12 | "lib/namespace.php"
13 | ]
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/composer.lock:
--------------------------------------------------------------------------------
1 | {
2 | "_readme": [
3 | "This file locks the dependencies of your project to a known state",
4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5 | "This file is @generated automatically"
6 | ],
7 | "hash": "d6cdcbb5d77148f4254ffe854572760c",
8 | "content-hash": "56c71077c404681471147c558c1fd67a",
9 | "packages": [
10 | {
11 | "name": "rmccue/requests",
12 | "version": "v1.6.1",
13 | "source": {
14 | "type": "git",
15 | "url": "https://github.com/rmccue/Requests.git",
16 | "reference": "6aac485666c2955077d77b796bbdd25f0013a4ea"
17 | },
18 | "dist": {
19 | "type": "zip",
20 | "url": "https://api.github.com/repos/rmccue/Requests/zipball/6aac485666c2955077d77b796bbdd25f0013a4ea",
21 | "reference": "6aac485666c2955077d77b796bbdd25f0013a4ea",
22 | "shasum": ""
23 | },
24 | "require": {
25 | "php": ">=5.2"
26 | },
27 | "require-dev": {
28 | "satooshi/php-coveralls": "dev-master"
29 | },
30 | "type": "library",
31 | "autoload": {
32 | "psr-0": {
33 | "Requests": "library/"
34 | }
35 | },
36 | "notification-url": "https://packagist.org/downloads/",
37 | "license": [
38 | "ISC"
39 | ],
40 | "authors": [
41 | {
42 | "name": "Ryan McCue",
43 | "homepage": "http://ryanmccue.info"
44 | }
45 | ],
46 | "description": "A HTTP library written in PHP, for human beings.",
47 | "homepage": "http://github.com/rmccue/Requests",
48 | "keywords": [
49 | "curl",
50 | "fsockopen",
51 | "http",
52 | "idna",
53 | "ipv6",
54 | "iri",
55 | "sockets"
56 | ],
57 | "time": "2014-05-18 04:59:02"
58 | }
59 | ],
60 | "packages-dev": [],
61 | "aliases": [],
62 | "minimum-stability": "stable",
63 | "stability-flags": [],
64 | "prefer-stable": false,
65 | "prefer-lowest": false,
66 | "platform": [],
67 | "platform-dev": []
68 | }
69 |
--------------------------------------------------------------------------------
/lib/Site.php:
--------------------------------------------------------------------------------
1 | data = $data;
31 | $this->index = $index;
32 | }
33 |
34 | /**
35 | * Get the name of a site.
36 | *
37 | * @return string
38 | */
39 | public function getName() {
40 | return $this->data->name;
41 | }
42 |
43 | /**
44 | * Get the description for a site.
45 | *
46 | * @return string
47 | */
48 | public function getDescription() {
49 | return $this->data->description;
50 | }
51 |
52 | /**
53 | * Get the URL for a site.
54 | *
55 | * @return string
56 | */
57 | public function getURL() {
58 | return $this->data->url;
59 | }
60 |
61 | /**
62 | * Get the index URL for the API.
63 | *
64 | * @return string
65 | */
66 | public function getIndexURL() {
67 | return $this->index;
68 | }
69 |
70 | /**
71 | * Get namespaces supported by the site.
72 | *
73 | * @return string[] List of namespaces supported by the site.
74 | */
75 | public function getSupportedNamespaces() {
76 | if ( empty( $this->data->namespaces ) || ! is_array( $this->data->namespaces ) ) {
77 | return array();
78 | }
79 |
80 | return $this->data->namespaces;
81 | }
82 |
83 | /**
84 | * Does the site support a namespace?
85 | *
86 | * @param string $namespace Namespace to check.
87 | * @return bool True if supported by the site, false otherwise.
88 | */
89 | public function supportsNamespace( $namespace ) {
90 | return in_array( $namespace, $this->getSupportedNamespaces() );
91 | }
92 |
93 | /**
94 | * Get features supported by the site.
95 | *
96 | * @return array Map of authentication method => method-specific data.
97 | */
98 | public function getSupportedAuthentication() {
99 | if ( empty( $this->data->authentication ) || empty( $this->data->authentication ) ) {
100 | return array();
101 | }
102 |
103 | return (array) $this->data->authentication;
104 | }
105 |
106 | /**
107 | * Does the site support an authentication method?
108 | *
109 | * @param string $method Authentication method to check.
110 | * @return bool True if supported by the site, false otherwise.
111 | */
112 | public function supportsAuthentication( $method ) {
113 | return array_key_exists( $method, $this->getSupportedAuthentication() );
114 | }
115 |
116 | /**
117 | * Get method-specific data for the given authentication method.
118 | *
119 | * @param string $method Authentication method to get data for.
120 | * @return mixed Method-specific data if available, null if not supported.
121 | */
122 | public function getAuthenticationData( $method ) {
123 | if ( ! $this->supportsAuthentication( $method ) ) {
124 | return null;
125 | }
126 |
127 | $authentication = $this->getSupportedAuthentication();
128 | return $authentication[ $method ];
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/lib/namespace.php:
--------------------------------------------------------------------------------
1 | throw_for_status();
38 |
39 | $links = $response->headers->getValues( 'Link' );
40 |
41 | // Find the correct link by relation
42 | foreach ( $links as $link ) {
43 | $attrs = parse_link_header( $link );
44 |
45 | if ( empty( $attrs ) || empty( $attrs['rel'] ) ) {
46 | continue;
47 | }
48 | switch ( $attrs['rel'] ) {
49 | case 'https://api.w.org/':
50 | break;
51 |
52 | case 'https://github.com/WP-API/WP-API':
53 | // Only allow this if legacy mode is on.
54 | if ( $legacy ) {
55 | break;
56 | }
57 |
58 | // Fall-through.
59 | default:
60 | continue 2;
61 | }
62 |
63 | return $attrs['href'];
64 | }
65 |
66 | return null;
67 | }
68 |
69 | /**
70 | * Parse a Link header into attributes.
71 | *
72 | * @param string $link Link header from the response.
73 | * @return array Map of attribute key => attribute value, with link href in `href` key.
74 | */
75 | function parse_link_header( $link ) {
76 | $parts = explode( ';', $link );
77 | $attrs = array(
78 | 'href' => trim( array_shift( $parts ), '<>' ),
79 | );
80 |
81 | foreach ( $parts as $part ) {
82 | if ( ! strpos( $part, '=' ) ) {
83 | continue;
84 | }
85 |
86 | list( $key, $value ) = explode( '=', $part, 2 );
87 | $key = trim( $key );
88 | $value = trim( $value, '" ' );
89 | $attrs[ $key ] = $value;
90 | }
91 |
92 | return $attrs;
93 | }
94 |
95 | /**
96 | * Get the index information from a site.
97 | *
98 | * @param string $url URL for the API index.
99 | * @return Site Data from the index for the site.
100 | */
101 | function get_index_information( $url ) {
102 | $response = Requests::get( $url );
103 | $response->throw_for_status();
104 |
105 | $index = json_decode( $response->body );
106 | if ( empty( $index ) && json_last_error() !== JSON_ERROR_NONE ) {
107 | throw new Exception( json_last_error_msg(), json_last_error() );
108 | }
109 |
110 | return new Site( $index, $url );
111 | }
112 |
--------------------------------------------------------------------------------
/www/details.php:
--------------------------------------------------------------------------------
1 |
8 |
Site description: getDescription() ) ?>
15 | 16 |(No site description found.)
17 | 18 | 19 |Site URL: getURL() ) ?>
API Index: getIndexURL() ) ?>