Skip to content
This repository was archived by the owner on Aug 14, 2019. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 116 additions & 6 deletions lib/class-wp-rest-site-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,40 @@ public function __construct() {
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'args' => $this->get_collection_params(),
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'args' => $this->get_collection_params(),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
),
'schema' => array( $this, 'get_public_item_schema' ),
'schema' => array( $this, 'get_public_item_schema' ),
) );

register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<option>[\w-]+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
),
),
array(
'methods' => WP_REST_Server::EDITABLE,
'callback' => array( $this, 'update_item' ),
'permission_callback' => array( $this, 'update_item_permissions_check' ),
'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
}

public function get_items_permissions_check( $request ) {

if ( ! current_user_can( 'manage_options' ) ) {
return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to view site options.' ), array( 'status' => rest_authorization_required_code() ) );
}

return true;
}

/**
Expand All @@ -50,12 +74,98 @@ public function get_items( $request ) {
return rest_ensure_response( $response );
}

public function delete_item_permission_check( $request ) {
/**
* Check if a given request has access to get a specific site option.
*
* @param WP_REST_Request $request Full data about the request.
* @return WP_Error|boolean
*/
public function get_item_permissions_check( $request ) {
return $this->get_items_permissions_check( $request );
}

/**
* Get a single site setting.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|WP_REST_Response
*/
public function get_item( $request ) {
$schema = $this->get_item_schema();
$option_name = $request['option'];
$value = $request[ $option_name ];

if ( ! array_key_exists( $option_name, $schema['properties'] ) ) {
return new WP_Error( 'rest_site_invalid_option', __( 'Invalid site option name.' ), array( 'status' => 404 ) );
}

$options = $this->get_endpoint_args_for_item_schema( WP_REST_Server::READABLE );
$response = array();

foreach ( $options as $name => $args ) {
if ( ! $this->get_item_mapping( $name ) ) {
continue;
}

if ( $name === $request['option'] ) {
$response[ $name ] = $this->prepare_item_for_response( $name, $request );
break;
}
}

return rest_ensure_response( $response );
}

public function create_item_permissions_check( $request ) {
// No op;
}

public function create_item( $request ) {
// No op
}

public function delete_item( $request ) {
public function update_item_permissions_check( $request ) {

if ( ! current_user_can( 'manage_options' ) ) {
return new WP_Error( 'rest_forbidden', __( 'Sorry, you are not allowed to edit site options.' ), array( 'status' => rest_authorization_required_code() ) );
}

return true;
}

/**
* Update a single site option
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|WP_REST_Response
*/
public function update_item( $request ) {
$schema = $this->get_item_schema();
$option_name = $request['option'];
$value = $request[ $option_name ];

if ( ! array_key_exists( $option_name, $schema['properties'] ) ) {
return new WP_Error( 'rest_site_invalid_option', __( 'Invalid site option name.' ), array( 'status' => 404 ) );
}

if ( isset( $schema['properties'][ $option_name ]['arg_options']['sanitize_callback'] ) && ! empty( $schema['properties'][ $option_name ]['arg_options']['sanitize_callback'] ) ) {
$value = call_user_func( $schema['properties'][ $option_name ]['arg_options']['sanitize_callback'], $value );
}

update_option( $this->get_item_mapping( $option_name ), $value );

$request->set_param( 'context', 'edit' );
$response = $this->get_item( $request );

return rest_ensure_response( $response );
}

public function delete_item_permissions_check( $request ) {
// No op
}

public function delete_item( $request ) {
// No op
}

/**
Expand Down
87 changes: 83 additions & 4 deletions tests/test-rest-site-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ class WP_Test_REST_Site_Controller extends WP_Test_REST_Controller_Testcase {
public function setUp() {
parent::setUp();

$this->user = $this->factory->user->create( array(
'role' => 'administrator',
) );
wp_set_current_user( $this->user );

$this->endpoint = new WP_REST_Site_Controller();
}

Expand All @@ -28,35 +33,109 @@ public function test_context_param() {
}

public function test_get_items() {
$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
$request->set_param( 'context', 'view' );
$options = $this->endpoint->get_item_mappings();

$request = new WP_REST_Request( 'GET', '/wp/v2/site' );
$response = $this->server->dispatch( $request );
$data = $response->get_data();

$this->assertEquals( 200, $response->get_status() );
$this->assertCount( count( $options ), $data );
}

public function test_get_items_unauthenticated() {
wp_set_current_user( 0 );
$request = new WP_REST_Request( 'GET', '/wp/v2/site' );
$response = $this->server->dispatch( $request );

$this->assertErrorResponse( 'rest_forbidden', $response, 401 );
}

public function test_get_item() {
$request = new WP_REST_Request( 'GET', '/wp/v2/site/title' );
$response = $this->server->dispatch( $request );
$data = $response->get_data();

$this->assertEquals( 200, $response->get_status() );
$this->assertNotEmpty( $data );
}

public function test_create_item() {
public function test_get_item_unauthenticated() {
wp_set_current_user( 0 );
$request = new WP_REST_Request( 'GET', '/wp/v2/site/title' );
$response = $this->server->dispatch( $request );

$this->assertErrorResponse( 'rest_forbidden', $response, 401 );
}

public function test_get_item_invalid_site_option() {
$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/site/%d', 0 ) );
$response = $this->server->dispatch( $request );

$this->assertErrorResponse( 'rest_site_invalid_option', $response, 404 );
}

public function test_create_item() {
// No op
}

public function test_update_item() {
update_option( 'blogname', 'Old Title' );
$_POST['title'] = 'New Title';

$request = new WP_REST_Request( 'PUT', '/wp/v2/site/title' );
$request->set_body_params( $_POST );
$response = $this->server->dispatch( $request );
$data = $response->get_data();

$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'New Title', $data['title'] );
}

public function test_delete_item() {
public function test_update_item_unauthenticated() {
wp_set_current_user( 0 );
$_POST['title'] = 'New Title';

$request = new WP_REST_Request( 'PUT', '/wp/v2/site/title' );
$request->set_body_params( $_POST );
$response = $this->server->dispatch( $request );

$this->assertErrorResponse( 'rest_forbidden', $response, 401 );
}

public function test_update_item_invalid_site_option() {
$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/site/%d', 0 ) );
$response = $this->server->dispatch( $request );

$this->assertErrorResponse( 'rest_site_invalid_option', $response, 404 );
}

public function test_delete_item() {
// No op
}

public function test_prepare_item() {
$title = get_option( 'blogname' );
$request = new WP_REST_Request( 'GET', '/wp/v2/site/title' );
$response = $this->server->dispatch( $request );
$data = $this->endpoint->prepare_item_for_response( 'title', $request );
$data = $response->get_data();

$this->assertEquals( $title, $data['title'] );
}

public function test_get_item_schema() {
$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/site' );
$response = $this->server->dispatch( $request );
$data = $response->get_data();
$properties = $data['schema']['properties'];
$options = $this->endpoint->get_item_mappings();

$this->assertEquals( count( $options ), count( $properties ) );

foreach ( $options as $key => $option ) {
$this->assertArrayHasKey( $key, $properties );
}
}

}