Skip to content

Commit 8f8d5b1

Browse files
committed
Added Examples topic per Issue 180
1 parent 6b88eb3 commit 8f8d5b1

File tree

2 files changed

+290
-0
lines changed

2 files changed

+290
-0
lines changed

bin/manifest.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@
144144
"parent": "reference",
145145
"markdown_source": "https://github.com/WP-API/docs/blob/master/reference/nav_menus.md"
146146
},
147+
"reference/navigation-fallbacks": {
148+
"slug": "navigation-fallbacks",
149+
"parent": "reference",
150+
"markdown_source": "https://github.com/WP-API/docs/blob/master/reference/navigation-fallbacks.md"
151+
},
147152
"reference/page-revisions": {
148153
"slug": "page-revisions",
149154
"parent": "reference",
@@ -239,6 +244,11 @@
239244
"parent": "reference",
240245
"markdown_source": "https://github.com/WP-API/docs/blob/master/reference/wp-site-health-tests.md"
241246
},
247+
"reference/wp_global_styles-revisions": {
248+
"slug": "wp_global_styles-revisions",
249+
"parent": "reference",
250+
"markdown_source": "https://github.com/WP-API/docs/blob/master/reference/wp_global_styles-revisions.md"
251+
},
242252
"reference/wp_global_styles": {
243253
"slug": "wp_global_styles",
244254
"parent": "reference",
@@ -294,6 +304,11 @@
294304
"parent": "using-the-rest-api",
295305
"markdown_source": "https://github.com/WP-API/docs/blob/master/using-the-rest-api/discovery.md"
296306
},
307+
"using-the-rest-api/examples": {
308+
"slug": "examples",
309+
"parent": "using-the-rest-api",
310+
"markdown_source": "https://github.com/WP-API/docs/blob/master/using-the-rest-api/examples.md"
311+
},
297312
"using-the-rest-api/global-parameters": {
298313
"slug": "global-parameters",
299314
"parent": "using-the-rest-api",

using-the-rest-api/examples.md

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
# Examples
2+
3+
The following examples show how to use the WordPress REST API with PHP/cURL and the API's `WP_REST_Request` class. With external PHP scripts, you can access the REST API via the [libcurl library](https://www.php.net/manual/en/intro.curl.php). With the `WP_REST_Request` class, you can internally access the REST API from [WordPress PHP plugins](https://developer.wordpress.org/rest-api/frequently-asked-questions/#can-i-make-api-requests-from-php-within-a-plugin). The examples were tested with PHP version 8.3.8.
4+
5+
Although the REST API provides public data to clients anonymously, many REST operations require user authentication. To make authenticated requests, you must first set up an [authentication method](https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/) in WordPress.
6+
7+
[tip]
8+
**Tip:**
9+
You can optionally configure the REST API to [require authentication for all operations](https://developer.wordpress.org/rest-api/frequently-asked-questions/#require-authentication-for-all-requests).
10+
[/tip]
11+
12+
The examples in this topic assume a local development environment, with calls made with the http protocol. For calls requiring credentials, the Basic Authentication method is used as provided by the [Basic-Auth plugin](https://github.com/WP-API/Basic-Auth).
13+
14+
Alternatively, consider using [Basic Authentication with Application Passwords](https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/#basic-authentication-with-application-passwords). A core WordPress feature, it requires https.
15+
16+
If you are using a remote development environment, https is strongly recommended, with either a self-signed or trusted certificate.
17+
18+
## PHP/cURL
19+
20+
All of the examples use the following PHP/cURL options, set in an array. For an explanation, see [cURL options](https://www.php.net/manual/en/function.curl-setopt.php).
21+
22+
```php
23+
$curl_options = array(
24+
CURLOPT_RETURNTRANSFER => true,
25+
CURLOPT_ENCODING => '',
26+
CURLOPT_MAXREDIRS => -1,
27+
CURLOPT_FOLLOWLOCATION => true,
28+
CURLOPT_TIMEOUT => 0,
29+
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
30+
CURLOPT_SSL_VERIFYPEER => 1,
31+
CURLOPT_VERBOSE => true
32+
);
33+
```
34+
35+
In addition, the examples use the PHP functions `json_decode()` and `json_encode()` to print HTTP responses in prettified JSON format.
36+
37+
### Retrieving Approved Comments
38+
39+
This example uses the [comments](https://developer.wordpress.org/rest-api/reference/comments/) route to get comments with a status of `approved`. Approved comments do not require user credentials to retrieve.
40+
41+
```php
42+
$curl = curl_init();
43+
curl_setopt_array($curl, $curl_options);
44+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
45+
curl_setopt($curl, CURLOPT_URL, 'http://example.com/wp-json/wp/v2/comments');
46+
$response = curl_exec($curl);
47+
$json_pretty = json_encode(json_decode($response),JSON_PRETTY_PRINT);
48+
echo $json_pretty;
49+
curl_close($curl);
50+
```
51+
52+
### Retrieving Pending Comments
53+
54+
This example uses the [comments](https://developer.wordpress.org/rest-api/reference/comments/) route to get comments with a status of `hold`. Awaiting evaluation from an admin, retrieval of these comments requires an authenticated request.
55+
56+
```php
57+
$status="hold";
58+
$curl = curl_init();
59+
curl_setopt_array($curl, $curl_options);
60+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
61+
curl_setopt($curl, CURLOPT_URL, "http://example.com/wp-json/wp/v2/comments" . "?status=" . $status);
62+
curl_setopt($curl, CURLOPT_USERNAME, "USERNAME");
63+
curl_setopt($curl, CURLOPT_PASSWORD, "PASSWORD");
64+
$response = curl_exec($curl);
65+
$json_pretty = json_encode(json_decode($response),JSON_PRETTY_PRINT);
66+
echo $json_pretty;
67+
curl_close($curl);
68+
```
69+
70+
### Creating an Image
71+
72+
This example uses the [media](https://developer.wordpress.org/rest-api/reference/media) route to post an image to WordPress. The request specifies the route, sets metadata on the image, and includes the REST API's [_fields](https://developer.wordpress.org/rest-api/using-the-rest-api/global-parameters/#_fields) global parameter. The `_fields` parameter limits the data returned in the response.
73+
74+
```php
75+
$fileToUpload = file_get_contents("FILE_PATH");
76+
$postHeader = array(
77+
'content-disposition: attachment; filename=FILE_NAME',
78+
'Content-Type: image/jpeg'
79+
);
80+
$route="http://example.com/wp-json/wp/v2/media";
81+
$queryParams="?title=Before%20Wildfire&alt_text=Landscape%20prior%20to%20wildfire";
82+
$responseFields="&_fields=author,id,title,media_details";
83+
84+
$curl = curl_init();
85+
curl_setopt_array($curl, $curl_options);
86+
curl_setopt($curl, CURLOPT_URL, $route . $queryParams . $responseFields);
87+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
88+
curl_setopt($curl, CURLOPT_HTTPHEADER, $postHeader);
89+
curl_setopt($curl, CURLOPT_POSTFIELDS, $fileToUpload);
90+
curl_setopt($curl, CURLOPT_USERNAME, "USERNAME");
91+
curl_setopt($curl, CURLOPT_PASSWORD, "PASSWORD");
92+
$response = curl_exec($curl);
93+
$json_pretty = json_encode(json_decode($response),JSON_PRETTY_PRINT);
94+
echo $json_pretty;
95+
curl_close($curl);
96+
```
97+
98+
### Creating a Post
99+
100+
This example uses the [posts](https://developer.wordpress.org/rest-api/reference/posts/) route to create a new WordPress post. The `CURLOPT_POSTFIELDS` option seeds the post with initial data.
101+
102+
```php
103+
$postData = array(
104+
'title' => 'Warmer World Means More Wildfires',
105+
'content' => '[<b>Writer, provide context for this subject. Reference the latest empirical evidence and include the featured media.</b>]',
106+
'format' => 'standard',
107+
'featured_media' => '41',
108+
'status' => 'draft'
109+
);
110+
111+
$curl = curl_init();
112+
curl_setopt_array($curl, $curl_options);
113+
curl_setopt($curl, CURLOPT_URL, 'http://example.com/wp-json/wp/v2/posts');
114+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
115+
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
116+
curl_setopt($curl, CURLOPT_USERNAME, 'USERNAME');
117+
curl_setopt($curl, CURLOPT_PASSWORD, 'PASSWORD');
118+
$response = curl_exec($curl);
119+
$json_pretty = json_encode(json_decode($response),JSON_PRETTY_PRINT);
120+
echo $json_pretty;
121+
curl_close($curl);
122+
```
123+
124+
### Updating a Post
125+
126+
The following example [updates](https://developer.wordpress.org/rest-api/reference/posts/#update-a-post) the post created in the prior example. As with creating a post, an update is also made with a `POST` request, but the URL specifies the ID of the post to be updated. The update changes the `format` and `featured_media` of the original post.
127+
128+
```php
129+
$postData = array(
130+
'format' => 'gallery',
131+
'featured_media' => '168'
132+
);
133+
134+
$curl = curl_init();
135+
curl_setopt_array($curl, $curl_options);
136+
curl_setopt($curl, CURLOPT_URL, 'http://example.com/wp-json/wp/v2/posts/163');
137+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
138+
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
139+
curl_setopt($curl, CURLOPT_USERNAME, 'USERNAME');
140+
curl_setopt($curl, CURLOPT_PASSWORD, 'PASSWORD');
141+
$response = curl_exec($curl);
142+
$json_pretty = json_encode(json_decode($response),JSON_PRETTY_PRINT);
143+
echo $json_pretty;
144+
curl_close($curl);
145+
```
146+
147+
### Deleting Comments with a Trash Status
148+
149+
The following example [deletes](https://developer.wordpress.org/rest-api/reference/comments/#delete-a-comment) all comments with a `trash` status.
150+
151+
```php
152+
$curl = curl_init();
153+
curl_setopt_array($curl, $curl_options);
154+
155+
// Get all comments with trash status. Return only the IDs of the comments in the response.
156+
curl_setopt($curl, CURLOPT_URL, 'http://example.com/wp-json/wp/v2/comments?status=trash&_fields=id');
157+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
158+
curl_setopt($curl, CURLOPT_USERNAME, "USERNAME");
159+
curl_setopt($curl, CURLOPT_PASSWORD, "PASSWORD");
160+
$response = curl_exec($curl);
161+
echo "\nComments to be deleted: " . $response ."\n";
162+
163+
// Put all IDs of trash comments in PHP array.
164+
$ids=json_decode($response,true);
165+
$ids = array_column($ids,'id');
166+
167+
// For each ID, send an HTTP delete request.
168+
foreach ($ids as $key => $value) {
169+
echo "\nComment " . $value . " to be deleted\n";
170+
curl_setopt($curl, CURLOPT_URL, 'http://example.com/wp-json/wp/v2/comments/' . $value . '?force=true');
171+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'DELETE');
172+
$response = curl_exec($curl);
173+
echo "\nComment deleted: " . $value ."\n";
174+
}
175+
curl_close($curl);
176+
```
177+
178+
## PHP Plugins
179+
180+
The REST API supports internal HTTP requests from [WordPress PHP plugins](https://developer.wordpress.org/rest-api/frequently-asked-questions/#can-i-make-api-requests-from-php-within-a-plugin). You construct an HTTP request with the API's [WP_REST_Request](https://developer.wordpress.org/reference/classes/wp_rest_request/) class, then invoke the [rest_do_request](https://developer.wordpress.org/reference/functions/rest_do_request/) function to submit the request to the REST server. For internal requests from plugins, you do not have to explicitly authenticate the user in the REST API. Running as an extension to the WordPress core environment, a plugin, unlike an external PHP script, does not have to authenticate the user in the REST API.
181+
182+
### Tracking Activated Plugins
183+
184+
This plugin example tracks other plugins that are activated. Triggered by the `activated_plugin` hook, the `plugin_activated` callback function constructs an instance of `WP_REST_Request` that identifies the activated plugin, then executes the request with the `rest_do_request` function. The response is returned as a [WP_REST_Response](https://developer.wordpress.org/reference/classes/wp_rest_response/) object, which can be printed to a log or sent as an email notification.
185+
186+
```php
187+
add_action('activated_plugin', 'plugin_activated', 1, 2);
188+
189+
function plugin_activated( $plugin) {
190+
$request = new WP_REST_Request( 'GET', '/wp/v2/plugins' );
191+
$request->set_param( 'search', $plugin);
192+
$response = rest_do_request($request);
193+
// Optionally, log response or send notification about it.
194+
}
195+
```
196+
197+
### Forcisng Deletion of Rejected Comments
198+
199+
This plugin example evaluates newly submitted comments to determine their suitability for public exposure. If a comment is rejected, the plugin forces immediate deletion. Unlike plugins that work with logged-in WordPress users as in the previous example, this plugin works with anonymous front-end users, raising permission-related considerations.
200+
201+
The REST API class that handles comment operations, [WP_REST_Comments_Controller](https://developer.wordpress.org/reference/classes/wp_rest_comments_controller/), does a [permission check](https://developer.wordpress.org/reference/classes/wp_rest_comments_controller/delete_item_permissions_check/) when a request is submitted to delete a comment. For requests made with the core namespace (`wp/v2`) the check method disallows the request when initiated by an anonymous user.
202+
203+
To work around the REST API's default permission behavior, this example makes use of the API' capability to register [custom endpoints](https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/). You can configure the permission level of a custom endpoint.
204+
205+
The plugin code is triggered by two WordPress hooks: [comment_post](https://developer.wordpress.org/reference/hooks/comment_post/) and [rest_api_init](https://developer.wordpress.org/reference/hooks/rest_api_init/). When a new comment is posted, the callback function associated with `comment_post` evaluates the comment. If the comment is rejected, the plugin creates a deletion request and triggers the `rest_api_init` hook. The callback function associated with `rest_api_init` registers the custom endpoint and deletes the comment.
206+
207+
#### comment_post Hook
208+
209+
When the `comment_post` hook is triggered, the `check_for_unacceptable_comment` callback screens the comment. If the function rejects the comment, it instantiates `WP_REST_Request` to create a deletion request for the comment. In addition to specifying the ID of the comment to be deleted, the request specifies the namespace of the custom endpoint (`myplugin/v1`) and the path (`/comment/`). Two parameters are set on the request. The `force` parameter instructs WordPress to delete the comment after it's moved to the trash. The `requestOrigin` parameter is added for security, identifying the source of the request as this plugin, not an unauthorized client attempting to delete comments.
210+
211+
The `rest_do_request` function sends the request to the REST API. This initiates the REST API, firing the `rest_api_init` hook.
212+
213+
<pre id='check_for_unacceptable_comment'>
214+
add_action('comment_post', 'check_for_unacceptable_comment', 1, 2);
215+
216+
// Triggered when new comment posted
217+
function check_for_unacceptable_comment( $comment_ID, $comment_approved, $commentdata ) {
218+
219+
/** Placeholder code here that screens comment for disallowed values in the commentdata array
220+
* (e.g. comment_content, comment_author_url). If any found, sets $rejected flag to true.
221+
*/
222+
223+
if ($rejected) {
224+
$request = new WP_REST_Request( 'DELETE', '/myplugin/v1/comment/' . $comment_ID); // creates request with custom endpoint and path
225+
$request->set_param( 'force', true );
226+
$request->set_param( 'requestOrigin', 'plugin' ); // identifies this plugin as the origin of the request
227+
228+
// Initiates the REST API, which triggers rest_api_init hook below.
229+
$response = rest_do_request( $request ); // returns WP_REST_Response object.
230+
231+
// Optionally, log response or send notification about it.
232+
}
233+
}</pre>
234+
235+
#### rest_api_init Hook
236+
237+
When the `rest_api_init` hook is fired, the associated anonymous callback registers the custom endpoint with the [register_rest_route](https://developer.wordpress.org/reference/functions/register_rest_route/) function. It takes the following parameters:
238+
239+
* [Namespace](https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#namespaces) of the custom endpoint, `myplugin/v1`, and the resource path, `/comment/(?P<id>\d+)` (the comment ID).
240+
241+
* [HTTP method](https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#http-methods) to be used for this route (`DELETE`).
242+
243+
* [Endpoint callback](https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#callbacks) `delete_rejected`, which deletes a comment flagged as rejected in the [check_for_unacceptable_comment](#check_for_unacceptable_comment) function.
244+
245+
* Validation callback function for an extra parameter added to the request. In this example, the argument specified in the [args](https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#arguments) array is the `id` of the comment to be deleted. However, for this example, the intent of the `validate_callback` function is not to validate the `id` parameter, but rather to validate the `requestOrigin` parameter in the request. Recall that this parameter is added to the request in the [check_for_unacceptable_comment](#check_for_unacceptable_comment) function to ensure that any deletion request with the custom endpoint originates from this plugin, not from an external unauthorized source.
246+
247+
* [Permissions callback](https://developer.wordpress.org/rest-api/extending-the-rest-api/adding-custom-endpoints/#permissions-callback) to set the permission level of the user to delete a comment. In this example, the `__return_true` value allows unacceptable comments by anonymous users to be deleted.
248+
249+
```php
250+
// Anonymous function is triggered when REST API initiated
251+
add_action('rest_api_init', function() {
252+
register_rest_route( 'myplugin/v1', '/comment/(?P<id>\d+)', array(
253+
'methods' => 'DELETE',
254+
'callback' => 'delete_rejected',
255+
'args' => array(
256+
'id' => array(
257+
'validate_callback' => function($param, $request, $key) {
258+
return ($request->has_param("requestOrigin")); } )
259+
),
260+
'permission_callback' => '__return_true' );
261+
} );
262+
```
263+
264+
If the `validate_callback` function returns `true`, the `delete_rejected` function is invoked. This function instantiates `WP_REST_Comments_Controller` and passes the request to its [delete_item](https://developer.wordpress.org/reference/classes/wp_rest_comments_controller/delete_item/) method to delete the comment. The method returns a [WP_REST_Response](https://developer.wordpress.org/reference/classes/wp_rest_response/) object, and this function, in turn, returns the response object to the [check_for_unacceptable_comment](#check_for_unacceptable_comment) function.
265+
266+
```php
267+
function delete_rejected( $request )
268+
{
269+
$controller = new WP_REST_Comments_Controller();
270+
$response=$controller->delete_item($request);
271+
return $response;
272+
}
273+
```
274+
275+

0 commit comments

Comments
 (0)