changeset 18 | be944660c56a |
parent 16 | a86126ab1dd4 |
child 19 | 3d72ae0968f4 |
17:34716fd837a4 | 18:be944660c56a |
---|---|
35 |
35 |
36 $this->meta = new WP_REST_Comment_Meta_Fields(); |
36 $this->meta = new WP_REST_Comment_Meta_Fields(); |
37 } |
37 } |
38 |
38 |
39 /** |
39 /** |
40 * Registers the routes for the objects of the controller. |
40 * Registers the routes for comments. |
41 * |
41 * |
42 * @since 4.7.0 |
42 * @since 4.7.0 |
43 * |
43 * |
44 * @see register_rest_route() |
44 * @see register_rest_route() |
45 */ |
45 */ |
69 $this->namespace, |
69 $this->namespace, |
70 '/' . $this->rest_base . '/(?P<id>[\d]+)', |
70 '/' . $this->rest_base . '/(?P<id>[\d]+)', |
71 array( |
71 array( |
72 'args' => array( |
72 'args' => array( |
73 'id' => array( |
73 'id' => array( |
74 'description' => __( 'Unique identifier for the object.' ), |
74 'description' => __( 'Unique identifier for the comment.' ), |
75 'type' => 'integer', |
75 'type' => 'integer', |
76 ), |
76 ), |
77 ), |
77 ), |
78 array( |
78 array( |
79 'methods' => WP_REST_Server::READABLE, |
79 'methods' => WP_REST_Server::READABLE, |
259 if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { |
259 if ( isset( $registered['page'] ) && empty( $request['offset'] ) ) { |
260 $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); |
260 $prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 ); |
261 } |
261 } |
262 |
262 |
263 /** |
263 /** |
264 * Filters arguments, before passing to WP_Comment_Query, when querying comments via the REST API. |
264 * Filters WP_Comment_Query arguments when querying comments via the REST API. |
265 * |
265 * |
266 * @since 4.7.0 |
266 * @since 4.7.0 |
267 * |
267 * |
268 * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ |
268 * @link https://developer.wordpress.org/reference/classes/wp_comment_query/ |
269 * |
269 * |
270 * @param array $prepared_args Array of arguments for WP_Comment_Query. |
270 * @param array $prepared_args Array of arguments for WP_Comment_Query. |
271 * @param WP_REST_Request $request The current request. |
271 * @param WP_REST_Request $request The REST API request. |
272 */ |
272 */ |
273 $prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request ); |
273 $prepared_args = apply_filters( 'rest_comment_query', $prepared_args, $request ); |
274 |
274 |
275 $query = new WP_Comment_Query; |
275 $query = new WP_Comment_Query; |
276 $query_result = $query->query( $prepared_args ); |
276 $query_result = $query->query( $prepared_args ); |
447 array( 'status' => 401 ) |
447 array( 'status' => 401 ) |
448 ); |
448 ); |
449 } |
449 } |
450 |
450 |
451 /** |
451 /** |
452 * Filter whether comments can be created without authentication. |
452 * Filters whether comments can be created via the REST API without authentication. |
453 * |
453 * |
454 * Enables creating comments for anonymous users. |
454 * Enables creating comments for anonymous users. |
455 * |
455 * |
456 * @since 4.7.0 |
456 * @since 4.7.0 |
457 * |
457 * |
585 return $prepared_comment; |
585 return $prepared_comment; |
586 } |
586 } |
587 |
587 |
588 $prepared_comment['comment_type'] = 'comment'; |
588 $prepared_comment['comment_type'] = 'comment'; |
589 |
589 |
590 /* |
590 if ( ! isset( $prepared_comment['comment_content'] ) ) { |
591 * Do not allow a comment to be created with missing or empty |
591 $prepared_comment['comment_content'] = ''; |
592 * comment_content. See wp_handle_comment_submission(). |
592 } |
593 */ |
593 |
594 if ( empty( $prepared_comment['comment_content'] ) ) { |
594 if ( ! $this->check_is_comment_content_allowed( $prepared_comment ) ) { |
595 return new WP_Error( |
595 return new WP_Error( |
596 'rest_comment_content_invalid', |
596 'rest_comment_content_invalid', |
597 __( 'Invalid comment content.' ), |
597 __( 'Invalid comment content.' ), |
598 array( 'status' => 400 ) |
598 array( 'status' => 400 ) |
599 ); |
599 ); |
953 } |
953 } |
954 |
954 |
955 $force = isset( $request['force'] ) ? (bool) $request['force'] : false; |
955 $force = isset( $request['force'] ) ? (bool) $request['force'] : false; |
956 |
956 |
957 /** |
957 /** |
958 * Filters whether a comment can be trashed. |
958 * Filters whether a comment can be trashed via the REST API. |
959 * |
959 * |
960 * Return false to disable Trash support for the post. |
960 * Return false to disable trash support for the comment. |
961 * |
961 * |
962 * @since 4.7.0 |
962 * @since 4.7.0 |
963 * |
963 * |
964 * @param bool $supports_trash Whether the post type support trashing. |
964 * @param bool $supports_trash Whether the comment supports trashing. |
965 * @param WP_Post $comment The comment object being considered for trashing support. |
965 * @param WP_Comment $comment The comment object being considered for trashing support. |
966 */ |
966 */ |
967 $supports_trash = apply_filters( 'rest_comment_trashable', ( EMPTY_TRASH_DAYS > 0 ), $comment ); |
967 $supports_trash = apply_filters( 'rest_comment_trashable', ( EMPTY_TRASH_DAYS > 0 ), $comment ); |
968 |
968 |
969 $request->set_param( 'context', 'edit' ); |
969 $request->set_param( 'context', 'edit' ); |
970 |
970 |
1118 $response = rest_ensure_response( $data ); |
1118 $response = rest_ensure_response( $data ); |
1119 |
1119 |
1120 $response->add_links( $this->prepare_links( $comment ) ); |
1120 $response->add_links( $this->prepare_links( $comment ) ); |
1121 |
1121 |
1122 /** |
1122 /** |
1123 * Filters a comment returned from the API. |
1123 * Filters a comment returned from the REST API. |
1124 * |
1124 * |
1125 * Allows modification of the comment right before it is returned. |
1125 * Allows modification of the comment right before it is returned. |
1126 * |
1126 * |
1127 * @since 4.7.0 |
1127 * @since 4.7.0 |
1128 * |
1128 * |
1157 'embeddable' => true, |
1157 'embeddable' => true, |
1158 ); |
1158 ); |
1159 } |
1159 } |
1160 |
1160 |
1161 if ( 0 !== (int) $comment->comment_post_ID ) { |
1161 if ( 0 !== (int) $comment->comment_post_ID ) { |
1162 $post = get_post( $comment->comment_post_ID ); |
1162 $post = get_post( $comment->comment_post_ID ); |
1163 |
1163 $post_route = rest_get_route_for_post( $post ); |
1164 if ( ! empty( $post->ID ) ) { |
1164 |
1165 $obj = get_post_type_object( $post->post_type ); |
1165 if ( ! empty( $post->ID ) && $post_route ) { |
1166 $base = ! empty( $obj->rest_base ) ? $obj->rest_base : $obj->name; |
|
1167 |
|
1168 $links['up'] = array( |
1166 $links['up'] = array( |
1169 'href' => rest_url( 'wp/v2/' . $base . '/' . $comment->comment_post_ID ), |
1167 'href' => rest_url( $post_route ), |
1170 'embeddable' => true, |
1168 'embeddable' => true, |
1171 'post_type' => $post->post_type, |
1169 'post_type' => $post->post_type, |
1172 ); |
1170 ); |
1173 } |
1171 } |
1174 } |
1172 } |
1280 /* |
1278 /* |
1281 * Allow the comment_content to be set via the 'content' or |
1279 * Allow the comment_content to be set via the 'content' or |
1282 * the 'content.raw' properties of the Request object. |
1280 * the 'content.raw' properties of the Request object. |
1283 */ |
1281 */ |
1284 if ( isset( $request['content'] ) && is_string( $request['content'] ) ) { |
1282 if ( isset( $request['content'] ) && is_string( $request['content'] ) ) { |
1285 $prepared_comment['comment_content'] = $request['content']; |
1283 $prepared_comment['comment_content'] = trim( $request['content'] ); |
1286 } elseif ( isset( $request['content']['raw'] ) && is_string( $request['content']['raw'] ) ) { |
1284 } elseif ( isset( $request['content']['raw'] ) && is_string( $request['content']['raw'] ) ) { |
1287 $prepared_comment['comment_content'] = $request['content']['raw']; |
1285 $prepared_comment['comment_content'] = trim( $request['content']['raw'] ); |
1288 } |
1286 } |
1289 |
1287 |
1290 if ( isset( $request['post'] ) ) { |
1288 if ( isset( $request['post'] ) ) { |
1291 $prepared_comment['comment_post_ID'] = (int) $request['post']; |
1289 $prepared_comment['comment_post_ID'] = (int) $request['post']; |
1292 } |
1290 } |
1351 list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; |
1349 list( $prepared_comment['comment_date'], $prepared_comment['comment_date_gmt'] ) = $date_data; |
1352 } |
1350 } |
1353 } |
1351 } |
1354 |
1352 |
1355 /** |
1353 /** |
1356 * Filters a comment after it is prepared for the database. |
1354 * Filters a comment added via the REST API after it is prepared for insertion into the database. |
1357 * |
1355 * |
1358 * Allows modification of the comment right after it is prepared for the database. |
1356 * Allows modification of the comment right after it is prepared for the database. |
1359 * |
1357 * |
1360 * @since 4.7.0 |
1358 * @since 4.7.0 |
1361 * |
1359 * |
1381 '$schema' => 'http://json-schema.org/draft-04/schema#', |
1379 '$schema' => 'http://json-schema.org/draft-04/schema#', |
1382 'title' => 'comment', |
1380 'title' => 'comment', |
1383 'type' => 'object', |
1381 'type' => 'object', |
1384 'properties' => array( |
1382 'properties' => array( |
1385 'id' => array( |
1383 'id' => array( |
1386 'description' => __( 'Unique identifier for the object.' ), |
1384 'description' => __( 'Unique identifier for the comment.' ), |
1387 'type' => 'integer', |
1385 'type' => 'integer', |
1388 'context' => array( 'view', 'edit', 'embed' ), |
1386 'context' => array( 'view', 'edit', 'embed' ), |
1389 'readonly' => true, |
1387 'readonly' => true, |
1390 ), |
1388 ), |
1391 'author' => array( |
1389 'author' => array( |
1392 'description' => __( 'The ID of the user object, if author was a user.' ), |
1390 'description' => __( 'The ID of the user object, if author was a user.' ), |
1393 'type' => 'integer', |
1391 'type' => 'integer', |
1394 'context' => array( 'view', 'edit', 'embed' ), |
1392 'context' => array( 'view', 'edit', 'embed' ), |
1395 ), |
1393 ), |
1396 'author_email' => array( |
1394 'author_email' => array( |
1397 'description' => __( 'Email address for the object author.' ), |
1395 'description' => __( 'Email address for the comment author.' ), |
1398 'type' => 'string', |
1396 'type' => 'string', |
1399 'format' => 'email', |
1397 'format' => 'email', |
1400 'context' => array( 'edit' ), |
1398 'context' => array( 'edit' ), |
1401 'arg_options' => array( |
1399 'arg_options' => array( |
1402 'sanitize_callback' => array( $this, 'check_comment_author_email' ), |
1400 'sanitize_callback' => array( $this, 'check_comment_author_email' ), |
1403 'validate_callback' => null, // Skip built-in validation of 'email'. |
1401 'validate_callback' => null, // Skip built-in validation of 'email'. |
1404 ), |
1402 ), |
1405 ), |
1403 ), |
1406 'author_ip' => array( |
1404 'author_ip' => array( |
1407 'description' => __( 'IP address for the object author.' ), |
1405 'description' => __( 'IP address for the comment author.' ), |
1408 'type' => 'string', |
1406 'type' => 'string', |
1409 'format' => 'ip', |
1407 'format' => 'ip', |
1410 'context' => array( 'edit' ), |
1408 'context' => array( 'edit' ), |
1411 ), |
1409 ), |
1412 'author_name' => array( |
1410 'author_name' => array( |
1413 'description' => __( 'Display name for the object author.' ), |
1411 'description' => __( 'Display name for the comment author.' ), |
1414 'type' => 'string', |
1412 'type' => 'string', |
1415 'context' => array( 'view', 'edit', 'embed' ), |
1413 'context' => array( 'view', 'edit', 'embed' ), |
1416 'arg_options' => array( |
1414 'arg_options' => array( |
1417 'sanitize_callback' => 'sanitize_text_field', |
1415 'sanitize_callback' => 'sanitize_text_field', |
1418 ), |
1416 ), |
1419 ), |
1417 ), |
1420 'author_url' => array( |
1418 'author_url' => array( |
1421 'description' => __( 'URL for the object author.' ), |
1419 'description' => __( 'URL for the comment author.' ), |
1422 'type' => 'string', |
1420 'type' => 'string', |
1423 'format' => 'uri', |
1421 'format' => 'uri', |
1424 'context' => array( 'view', 'edit', 'embed' ), |
1422 'context' => array( 'view', 'edit', 'embed' ), |
1425 ), |
1423 ), |
1426 'author_user_agent' => array( |
1424 'author_user_agent' => array( |
1427 'description' => __( 'User agent for the object author.' ), |
1425 'description' => __( 'User agent for the comment author.' ), |
1428 'type' => 'string', |
1426 'type' => 'string', |
1429 'context' => array( 'edit' ), |
1427 'context' => array( 'edit' ), |
1430 'arg_options' => array( |
1428 'arg_options' => array( |
1431 'sanitize_callback' => 'sanitize_text_field', |
1429 'sanitize_callback' => 'sanitize_text_field', |
1432 ), |
1430 ), |
1433 ), |
1431 ), |
1434 'content' => array( |
1432 'content' => array( |
1435 'description' => __( 'The content for the object.' ), |
1433 'description' => __( 'The content for the comment.' ), |
1436 'type' => 'object', |
1434 'type' => 'object', |
1437 'context' => array( 'view', 'edit', 'embed' ), |
1435 'context' => array( 'view', 'edit', 'embed' ), |
1438 'arg_options' => array( |
1436 'arg_options' => array( |
1439 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). |
1437 'sanitize_callback' => null, // Note: sanitization implemented in self::prepare_item_for_database(). |
1440 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). |
1438 'validate_callback' => null, // Note: validation implemented in self::prepare_item_for_database(). |
1441 ), |
1439 ), |
1442 'properties' => array( |
1440 'properties' => array( |
1443 'raw' => array( |
1441 'raw' => array( |
1444 'description' => __( 'Content for the object, as it exists in the database.' ), |
1442 'description' => __( 'Content for the comment, as it exists in the database.' ), |
1445 'type' => 'string', |
1443 'type' => 'string', |
1446 'context' => array( 'edit' ), |
1444 'context' => array( 'edit' ), |
1447 ), |
1445 ), |
1448 'rendered' => array( |
1446 'rendered' => array( |
1449 'description' => __( 'HTML content for the object, transformed for display.' ), |
1447 'description' => __( 'HTML content for the comment, transformed for display.' ), |
1450 'type' => 'string', |
1448 'type' => 'string', |
1451 'context' => array( 'view', 'edit', 'embed' ), |
1449 'context' => array( 'view', 'edit', 'embed' ), |
1452 'readonly' => true, |
1450 'readonly' => true, |
1453 ), |
1451 ), |
1454 ), |
1452 ), |
1455 ), |
1453 ), |
1456 'date' => array( |
1454 'date' => array( |
1457 'description' => __( "The date the object was published, in the site's timezone." ), |
1455 'description' => __( "The date the comment was published, in the site's timezone." ), |
1458 'type' => 'string', |
1456 'type' => 'string', |
1459 'format' => 'date-time', |
1457 'format' => 'date-time', |
1460 'context' => array( 'view', 'edit', 'embed' ), |
1458 'context' => array( 'view', 'edit', 'embed' ), |
1461 ), |
1459 ), |
1462 'date_gmt' => array( |
1460 'date_gmt' => array( |
1463 'description' => __( 'The date the object was published, as GMT.' ), |
1461 'description' => __( 'The date the comment was published, as GMT.' ), |
1464 'type' => 'string', |
1462 'type' => 'string', |
1465 'format' => 'date-time', |
1463 'format' => 'date-time', |
1466 'context' => array( 'view', 'edit' ), |
1464 'context' => array( 'view', 'edit' ), |
1467 ), |
1465 ), |
1468 'link' => array( |
1466 'link' => array( |
1469 'description' => __( 'URL to the object.' ), |
1467 'description' => __( 'URL to the comment.' ), |
1470 'type' => 'string', |
1468 'type' => 'string', |
1471 'format' => 'uri', |
1469 'format' => 'uri', |
1472 'context' => array( 'view', 'edit', 'embed' ), |
1470 'context' => array( 'view', 'edit', 'embed' ), |
1473 'readonly' => true, |
1471 'readonly' => true, |
1474 ), |
1472 ), |
1475 'parent' => array( |
1473 'parent' => array( |
1476 'description' => __( 'The ID for the parent of the object.' ), |
1474 'description' => __( 'The ID for the parent of the comment.' ), |
1477 'type' => 'integer', |
1475 'type' => 'integer', |
1478 'context' => array( 'view', 'edit', 'embed' ), |
1476 'context' => array( 'view', 'edit', 'embed' ), |
1479 'default' => 0, |
1477 'default' => 0, |
1480 ), |
1478 ), |
1481 'post' => array( |
1479 'post' => array( |
1483 'type' => 'integer', |
1481 'type' => 'integer', |
1484 'context' => array( 'view', 'edit' ), |
1482 'context' => array( 'view', 'edit' ), |
1485 'default' => 0, |
1483 'default' => 0, |
1486 ), |
1484 ), |
1487 'status' => array( |
1485 'status' => array( |
1488 'description' => __( 'State of the object.' ), |
1486 'description' => __( 'State of the comment.' ), |
1489 'type' => 'string', |
1487 'type' => 'string', |
1490 'context' => array( 'view', 'edit' ), |
1488 'context' => array( 'view', 'edit' ), |
1491 'arg_options' => array( |
1489 'arg_options' => array( |
1492 'sanitize_callback' => 'sanitize_key', |
1490 'sanitize_callback' => 'sanitize_key', |
1493 ), |
1491 ), |
1494 ), |
1492 ), |
1495 'type' => array( |
1493 'type' => array( |
1496 'description' => __( 'Type of Comment for the object.' ), |
1494 'description' => __( 'Type of the comment.' ), |
1497 'type' => 'string', |
1495 'type' => 'string', |
1498 'context' => array( 'view', 'edit', 'embed' ), |
1496 'context' => array( 'view', 'edit', 'embed' ), |
1499 'readonly' => true, |
1497 'readonly' => true, |
1500 ), |
1498 ), |
1501 ), |
1499 ), |
1515 'context' => array( 'embed', 'view', 'edit' ), |
1513 'context' => array( 'embed', 'view', 'edit' ), |
1516 ); |
1514 ); |
1517 } |
1515 } |
1518 |
1516 |
1519 $schema['properties']['author_avatar_urls'] = array( |
1517 $schema['properties']['author_avatar_urls'] = array( |
1520 'description' => __( 'Avatar URLs for the object author.' ), |
1518 'description' => __( 'Avatar URLs for the comment author.' ), |
1521 'type' => 'object', |
1519 'type' => 'object', |
1522 'context' => array( 'view', 'edit', 'embed' ), |
1520 'context' => array( 'view', 'edit', 'embed' ), |
1523 'readonly' => true, |
1521 'readonly' => true, |
1524 'properties' => $avatar_properties, |
1522 'properties' => $avatar_properties, |
1525 ); |
1523 ); |
1611 'desc', |
1609 'desc', |
1612 ), |
1610 ), |
1613 ); |
1611 ); |
1614 |
1612 |
1615 $query_params['orderby'] = array( |
1613 $query_params['orderby'] = array( |
1616 'description' => __( 'Sort collection by object attribute.' ), |
1614 'description' => __( 'Sort collection by comment attribute.' ), |
1617 'type' => 'string', |
1615 'type' => 'string', |
1618 'default' => 'date_gmt', |
1616 'default' => 'date_gmt', |
1619 'enum' => array( |
1617 'enum' => array( |
1620 'date', |
1618 'date', |
1621 'date_gmt', |
1619 'date_gmt', |
1674 'description' => __( 'The password for the post if it is password protected.' ), |
1672 'description' => __( 'The password for the post if it is password protected.' ), |
1675 'type' => 'string', |
1673 'type' => 'string', |
1676 ); |
1674 ); |
1677 |
1675 |
1678 /** |
1676 /** |
1679 * Filter collection parameters for the comments controller. |
1677 * Filters REST API collection parameters for the comments controller. |
1680 * |
1678 * |
1681 * This filter registers the collection parameter, but does not map the |
1679 * This filter registers the collection parameter, but does not map the |
1682 * collection parameter to an internal WP_Comment_Query parameter. Use the |
1680 * collection parameter to an internal WP_Comment_Query parameter. Use the |
1683 * `rest_comment_query` filter to set WP_Comment_Query parameters. |
1681 * `rest_comment_query` filter to set WP_Comment_Query parameters. |
1684 * |
1682 * |
1866 return $check_email; |
1864 return $check_email; |
1867 } |
1865 } |
1868 |
1866 |
1869 return $email; |
1867 return $email; |
1870 } |
1868 } |
1869 |
|
1870 /** |
|
1871 * If empty comments are not allowed, checks if the provided comment content is not empty. |
|
1872 * |
|
1873 * @since 5.6.0 |
|
1874 * |
|
1875 * @param array $prepared_comment The prepared comment data. |
|
1876 * @return bool True if the content is allowed, false otherwise. |
|
1877 */ |
|
1878 protected function check_is_comment_content_allowed( $prepared_comment ) { |
|
1879 $check = wp_parse_args( |
|
1880 $prepared_comment, |
|
1881 array( |
|
1882 'comment_post_ID' => 0, |
|
1883 'comment_parent' => 0, |
|
1884 'user_ID' => 0, |
|
1885 'comment_author' => null, |
|
1886 'comment_author_email' => null, |
|
1887 'comment_author_url' => null, |
|
1888 ) |
|
1889 ); |
|
1890 |
|
1891 /** This filter is documented in wp-includes/comment.php */ |
|
1892 $allow_empty = apply_filters( 'allow_empty_comment', false, $check ); |
|
1893 |
|
1894 if ( $allow_empty ) { |
|
1895 return true; |
|
1896 } |
|
1897 |
|
1898 /* |
|
1899 * Do not allow a comment to be created with missing or empty |
|
1900 * comment_content. See wp_handle_comment_submission(). |
|
1901 */ |
|
1902 return '' !== $check['comment_content']; |
|
1903 } |
|
1871 } |
1904 } |