Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

Commit

Permalink
Add data endpoints for getting currencies (#9)
Browse files Browse the repository at this point in the history
* Adds endpoints for getting a list of supported currencies, along with their name and symbol.

* Limit regex check for currency code to 3 characters.
  • Loading branch information
justinshreve authored Jun 6, 2017
1 parent db1c191 commit 6c7e95e
Show file tree
Hide file tree
Showing 4 changed files with 324 additions and 1 deletion.
18 changes: 18 additions & 0 deletions api/class-wc-rest-dev-data-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ public function get_items_permissions_check( $request ) {
return true;
}

/**
* Check whether a given request has permission to read site settings.
*
* @param WP_REST_Request $request Full details about the request.
* @return WP_Error|boolean
*/
public function get_item_permissions_check( $request ) {
if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
}

return true;
}

/**
* Return the list of data resources.
*
Expand All @@ -84,6 +98,10 @@ public function get_items( $request ) {
'slug' => 'countries',
'description' => __( 'List of supported states in a given country.', 'woocommerce' ),
),
array(
'slug' => 'currencies',
'description' => __( 'List of supported currencies.', 'woocommerce' ),
),
);

foreach ( $resources as $resource ) {
Expand Down
218 changes: 218 additions & 0 deletions api/class-wc-rest-dev-data-currencies-controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
<?php
/**
* REST API Data currencies controller.
*
* Handles requests to the /data/currencies endpoint.
*
* @author Automattic
* @category API
* @package WooCommerce/API
*/

if ( ! defined( 'ABSPATH' ) ) {
exit;
}

/**
* REST API Data Currencies controller class.
*
* @package WooCommerce/API
*/
class WC_REST_Dev_Data_Currencies_Controller extends WC_REST_Dev_Data_Controller {

/**
* Endpoint namespace.
*
* @var string
*/
protected $namespace = 'wc/v3';

/**
* Route base.
*
* @var string
*/
protected $rest_base = 'data/currencies';

/**
* Register routes.
*/
public function register_routes() {
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_items' ),
'permission_callback' => array( $this, 'get_items_permissions_check' ),
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/current', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_current_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P<currency>[\w-]{3}+)', array(
array(
'methods' => WP_REST_Server::READABLE,
'callback' => array( $this, 'get_item' ),
'permission_callback' => array( $this, 'get_item_permissions_check' ),
'args' => array(
'location' => array(
'description' => __( 'ISO4217 currency code.', 'woocommerce' ),
'type' => 'string',
),
),
),
'schema' => array( $this, 'get_public_item_schema' ),
) );
}

/**
* Get currency information.
*
* @param string $code
* @param WP_REST_Request $request
* @return array|mixed Response data, ready for insertion into collection data.
*/
public function get_currency( $code = false, $request ) {
$currencies = get_woocommerce_currencies();
$data = array();

if ( ! array_key_exists( $code, $currencies ) ) {
return false;
}

$currency = array(
'code' => $code,
'name' => $currencies[ $code ],
'symbol' => get_woocommerce_currency_symbol( $code ),
);

return $currency;
}

/**
* Return the list of currencies.
*
* @param WP_REST_Request $request
* @return WP_Error|WP_REST_Response
*/
public function get_items( $request ) {
$currencies = get_woocommerce_currencies();
foreach ( array_keys( $currencies ) as $code ) {
$currency = $this->get_currency( $code, $request );
$response = $this->prepare_item_for_response( $currency, $request );
$data[] = $this->prepare_response_for_collection( $response );
}

return rest_ensure_response( $data );
}

/**
* Return information for a specific currency.
*
* @param WP_REST_Request $request
* @return WP_Error|WP_REST_Response
*/
public function get_item( $request ) {
$data = $this->get_currency( strtoupper( $request['currency'] ), $request );
if ( empty( $data ) ) {
return new WP_Error( 'woocommerce_rest_data_invalid_currency', __( 'There are no currencies matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) );
}
return $this->prepare_item_for_response( $data, $request );
}

/**
* Return information for the current site currency.
*
* @param WP_REST_Request $request
* @return WP_Error|WP_REST_Response
*/
public function get_current_item( $request ) {
$currency = get_option( 'woocommerce_currency' );
return $this->prepare_item_for_response( $this->get_currency( $currency, $request ), $request );
}

/**
* Prepare the data object for response.
*
* @param object $item Data object.
* @param WP_REST_Request $request Request object.
* @return WP_REST_Response $response Response data.
*/
public function prepare_item_for_response( $item, $request ) {
$data = $this->add_additional_fields_to_object( $item, $request );
$data = $this->filter_response_by_context( $data, 'view' );
$response = rest_ensure_response( $data );

$response->add_links( $this->prepare_links( $item ) );

/**
* Filter currency returned from the API.
*
* @param WP_REST_Response $response The response object.
* @param array $item Currency data.
* @param WP_REST_Request $request Request used to generate the response.
*/
return apply_filters( 'woocommerce_rest_prepare_data_currency', $response, $item, $request );
}

/**
* Prepare links for the request.
*
* @param object $item Data object.
* @return array Links for the given currency.
*/
protected function prepare_links( $item ) {
$code = strtoupper( $item['code'] );
$links = array(
'self' => array(
'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $code ) ),
),
'collection' => array(
'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
),
);

return $links;
}


/**
* Get the currency schema, conforming to JSON Schema.
*
* @return array
*/
public function get_item_schema() {
$schema = array(
'$schema' => 'http://json-schema.org/draft-04/schema#',
'title' => 'data_currencies',
'type' => 'object',
'properties' => array(
'code' => array(
'type' => 'string',
'description' => __( 'ISO4217 currency code.', 'woocommerce' ),
'context' => array( 'view' ),
'readonly' => true,
),
'name' => array(
'type' => 'string',
'description' => __( 'Full name of currency.', 'woocommerce' ),
'context' => array( 'view' ),
'readonly' => true,
),
'symbol' => array(
'type' => 'string',
'description' => __( 'Currency symbol.', 'woocommerce' ),
'context' => array( 'view' ),
'readonly' => true,
),
),
);

return $this->add_additional_fields_schema( $schema );
}
}
87 changes: 86 additions & 1 deletion tests/unit-tests/data.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ public function test_register_routes() {
$this->assertArrayHasKey( '/wc/v3/data', $routes );
$this->assertArrayHasKey( '/wc/v3/data/continents', $routes );
$this->assertArrayHasKey( '/wc/v3/data/countries', $routes );
$this->assertArrayHasKey( '/wc/v3/data/currencies', $routes );
$this->assertArrayHasKey( '/wc/v3/data/currencies/current', $routes );
$this->assertArrayHasKey( '/wc/v3/data/currencies/(?P<currency>[\w-]{3}+)', $routes );
}

/**
Expand All @@ -38,9 +41,10 @@ public function test_get_index() {
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data' ) );
$index = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertCount( 2, $index );
$this->assertCount( 3, $index );
$this->assertEquals( 'continents', $index[0]['slug'] );
$this->assertEquals( 'countries', $index[1]['slug'] );
$this->assertEquals( 'currencies', $index[2]['slug'] );
}

/**
Expand Down Expand Up @@ -149,4 +153,85 @@ public function test_get_countries_without_permission() {
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/countries' ) );
$this->assertEquals( 401, $response->get_status() );
}

/**
* Test getting currencies.
*/
public function test_get_currencies() {
wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies' ) );
$currencies = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertTrue( is_array( $currencies ) );
$this->assertGreaterThan( 1, count( $currencies ) );
$this->assertNotEmpty( $currencies[0]['code'] );
$this->assertNotEmpty( $currencies[0]['name'] );
$this->assertNotEmpty( $currencies[0]['symbol'] );
$this->assertNotEmpty( $currencies[0]['_links'] );
}

/**
* Test getting a single currency.
*/
public function test_get_currency() {
wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies/CAD' ) );
$currency = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'CAD', $currency['code'] );
$this->assertEquals( 'Canadian dollar', $currency['name'] );
$this->assertEquals( '&#36;', $currency['symbol'] );
$links = $response->get_links();
$this->assertCount( 2, $links );
}

/**
* Test getting current currency.
*/
public function test_get_current_currency() {
$current = get_option( 'woocommerce_currency' );
update_option( 'woocommerce_currency', 'BTC' );

wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies/current' ) );
$currency = $response->get_data();
$this->assertEquals( 200, $response->get_status() );
$this->assertEquals( 'BTC', $currency['code'] );
$this->assertEquals( 'Bitcoin', $currency['name'] );
$this->assertEquals( '&#3647;', $currency['symbol'] );
$links = $response->get_links();
$this->assertCount( 2, $links );

update_option( 'woocommerce_currency', $current );
}

/**
* Test getting currency from an invalid code.
*/
public function test_get_currency_from_invalid_code() {
wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies/xxy' ) );
$this->assertEquals( 404, $response->get_status() );
$this->assertEquals( 'woocommerce_rest_data_invalid_currency', $response->data['code'] );
}

/**
* Test getting currency from an code that is too long.
*/
public function test_get_currency_from_long_code() {
wp_set_current_user( $this->user );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies/xxyy' ) );
$this->assertEquals( 404, $response->get_status() );
$this->assertEquals( 'rest_no_route', $response->data['code'] );
}

/**
* Test getting currencies without permissions.
*/
public function test_get_currency_without_permission() {
wp_set_current_user( 0 );
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v3/data/currencies' ) );
$this->assertEquals( 401, $response->get_status() );
}

}
2 changes: 2 additions & 0 deletions wc-api-dev.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ public function includes() {
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-data-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-data-continents-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-data-countries-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-data-currencies-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-orders-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-order-notes-controller.php' );
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-dev-order-refunds-controller.php' );
Expand Down Expand Up @@ -121,6 +122,7 @@ public function register_routes() {
'WC_REST_Dev_Data_Controller',
'WC_REST_Dev_Data_Continents_Controller',
'WC_REST_Dev_Data_Countries_Controller',
'WC_REST_Dev_Data_Currencies_Controller',
'WC_REST_Dev_Order_Notes_Controller',
'WC_REST_Dev_Order_Refunds_Controller',
'WC_REST_Dev_Orders_Controller',
Expand Down

0 comments on commit 6c7e95e

Please sign in to comment.