2015-10-07 14:42:25 +00:00
< ? php
/**
* WooCommerce API Taxes Class
*
* Handles requests to the / taxes endpoint
*
* @ author WooThemes
* @ category API
* @ package WooCommerce / API
* @ since 2.5 . 0
*/
if ( ! defined ( 'ABSPATH' ) ) {
exit ; // Exit if accessed directly
}
class WC_API_Taxes extends WC_API_Resource {
/** @var string $base the route base */
protected $base = '/taxes' ;
/**
* Register the routes for this class
*
* GET / taxes
* GET / taxes / count
* GET / taxes /< id >
*
* @ since 2.1
* @ param array $routes
* @ return array
*/
public function register_routes ( $routes ) {
# GET/POST /taxes
$routes [ $this -> base ] = array (
2015-10-07 20:44:04 +00:00
array ( array ( $this , 'get_taxes' ), WC_API_Server :: READABLE ),
2015-10-07 14:42:25 +00:00
array ( array ( $this , 'create_tax' ), WC_API_Server :: CREATABLE | WC_API_Server :: ACCEPT_DATA ),
);
# GET /taxes/count
$routes [ $this -> base . '/count' ] = array (
array ( array ( $this , 'get_taxes_count' ), WC_API_Server :: READABLE ),
);
# GET/PUT/DELETE /taxes/<id>
$routes [ $this -> base . '/(?P<id>\d+)' ] = array (
array ( array ( $this , 'get_tax' ), WC_API_Server :: READABLE ),
array ( array ( $this , 'edit_tax' ), WC_API_SERVER :: EDITABLE | WC_API_SERVER :: ACCEPT_DATA ),
array ( array ( $this , 'delete_tax' ), WC_API_SERVER :: DELETABLE ),
);
2015-10-08 01:35:34 +00:00
# GET/POST /taxes/classes
2015-10-07 20:44:04 +00:00
$routes [ $this -> base . '/classes' ] = array (
array ( array ( $this , 'get_tax_classes' ), WC_API_Server :: READABLE ),
2015-10-08 01:52:45 +00:00
array ( array ( $this , 'create_tax_class' ), WC_API_Server :: CREATABLE | WC_API_Server :: ACCEPT_DATA ),
2015-10-07 20:44:04 +00:00
);
2015-10-08 01:35:34 +00:00
# GET /taxes/classes/count
$routes [ $this -> base . '/classes/count' ] = array (
array ( array ( $this , 'get_tax_classes_count' ), WC_API_Server :: READABLE ),
);
# GET /taxes/classes/<slug>
2015-10-08 01:27:42 +00:00
$routes [ $this -> base . '/classes/(?P<slug>\w[\w\s\-]*)' ] = array (
array ( array ( $this , 'delete_tax_class' ), WC_API_SERVER :: DELETABLE ),
);
2015-10-07 14:42:25 +00:00
# POST|PUT /taxes/bulk
$routes [ $this -> base . '/bulk' ] = array (
array ( array ( $this , 'bulk' ), WC_API_Server :: EDITABLE | WC_API_Server :: ACCEPT_DATA ),
);
return $routes ;
}
2015-10-07 20:44:04 +00:00
/**
* Get all taxes
*
* @ since 2.5 . 0
*
* @ param string $fields
2015-10-07 22:00:36 +00:00
* @ param array $filter
* @ param string $class
* @ param int $page
2015-10-07 20:44:04 +00:00
*
* @ return array
*/
2015-10-07 22:00:36 +00:00
public function get_taxes ( $fields = null , $filter = array (), $class = null , $page = 1 ) {
if ( ! empty ( $class ) ) {
2015-10-07 22:07:45 +00:00
$filter [ 'tax_rate_class' ] = $class ;
2015-10-07 22:00:36 +00:00
}
$filter [ 'page' ] = $page ;
$query = $this -> query_tax_rates ( $filter );
$taxes = array ();
foreach ( $query [ 'results' ] as $tax ) {
$taxes [] = current ( $this -> get_tax ( $tax -> tax_rate_id , $fields ) );
}
2015-10-07 20:44:04 +00:00
2015-10-07 22:00:36 +00:00
// Set pagination headers
$this -> server -> add_pagination_headers ( $query [ 'headers' ] );
return array ( 'taxes' => $taxes );
2015-10-07 20:44:04 +00:00
}
/**
* Get the tax for the given ID
*
* @ since 2.5 . 0
*
2015-10-08 01:27:42 +00:00
* @ param int $id The tax ID
2015-10-07 20:44:04 +00:00
* @ param string $fields fields to include in response
*
* @ return array | WP_Error
*/
public function get_tax ( $id , $fields = null ) {
global $wpdb ;
try {
$id = absint ( $id );
// Permissions check
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_read_tax_rate' , __ ( 'You do not have permission to read tax rate' , 'woocommerce' ), 401 );
}
// Get tax rate details
2015-10-08 20:24:37 +00:00
$tax = WC_Tax :: _get_tax_rate ( $id );
2015-10-07 20:44:04 +00:00
2015-10-08 20:24:37 +00:00
if ( is_wp_error ( $tax ) || empty ( $tax ) ) {
2015-10-07 20:44:04 +00:00
throw new WC_API_Exception ( 'woocommerce_api_invalid_tax_rate_id' , __ ( 'A tax rate with the provided ID could not be found' , 'woocommerce' ), 404 );
}
$tax_data = array (
2015-10-08 20:24:37 +00:00
'id' => $tax [ 'tax_rate_id' ],
'country' => $tax [ 'tax_rate_country' ],
'state' => $tax [ 'tax_rate_state' ],
2015-10-07 20:44:04 +00:00
'postcode' => '' ,
'city' => '' ,
2015-10-08 20:24:37 +00:00
'rate' => $tax [ 'tax_rate' ],
'name' => $tax [ 'tax_rate_name' ],
'priority' => ( int ) $tax [ 'tax_rate_priority' ],
'compound' => ( bool ) $tax [ 'tax_rate_compound' ],
'shipping' => ( bool ) $tax [ 'tax_rate_shipping' ],
'order' => ( int ) $tax [ 'tax_rate_order' ],
'class' => $tax [ 'tax_rate_class' ] ? $tax [ 'tax_rate_class' ] : 'standard'
2015-10-07 20:44:04 +00:00
);
// Get locales from a tax rate
$locales = $wpdb -> get_results ( $wpdb -> prepare ( "
SELECT location_code , location_type
FROM { $wpdb -> prefix } woocommerce_tax_rate_locations
WHERE tax_rate_id = % d
" , $id ) );
if ( ! is_wp_error ( $tax ) && ! is_null ( $tax ) ) {
foreach ( $locales as $locale ) {
$tax_data [ $locale -> location_type ] = $locale -> location_code ;
}
}
return array ( 'tax' => apply_filters ( 'woocommerce_api_tax_response' , $tax_data , $tax , $fields , $this ) );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-07 14:42:25 +00:00
/**
* Create a tax
*
* @ since 2.5 . 0
*
* @ param array $data
*
* @ return array
*/
public function create_tax ( $data ) {
2015-10-08 20:15:00 +00:00
try {
if ( ! isset ( $data [ 'tax' ] ) ) {
throw new WC_API_Exception ( 'woocommerce_api_missing_tax_rate_data' , sprintf ( __ ( 'No %1$s data specified to create %1$s' , 'woocommerce' ), 'tax' ), 400 );
}
// Check permissions
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_create_tax_rate' , __ ( 'You do not have permission to create tax rates' , 'woocommerce' ), 401 );
}
$data = $data [ 'tax' ];
2015-10-07 14:42:25 +00:00
2015-10-08 20:15:00 +00:00
$tax_data = array (
'tax_rate_country' => '' ,
'tax_rate_state' => '' ,
'tax_rate' => '' ,
'tax_rate_name' => '' ,
'tax_rate_priority' => 1 ,
'tax_rate_compound' => 0 ,
'tax_rate_shipping' => 1 ,
'tax_rate_order' => 0 ,
'tax_rate_class' => '' ,
);
foreach ( $tax_data as $key => $value ) {
$_key = str_replace ( 'tax_rate_' , '' , $key );
if ( isset ( $data [ $_key ] ) ) {
if ( in_array ( $_key , array ( 'compound' , 'shipping' ) ) ) {
error_log ( print_r ( array ( $_key , $data [ $_key ] ), true ) );
$tax_data [ $key ] = $data [ $_key ] ? 1 : 0 ;
} else {
$tax_data [ $key ] = $data [ $_key ];
}
}
}
// Create tax rate
$id = WC_Tax :: _insert_tax_rate ( $tax_data );
// Add locales
if ( ! empty ( $data [ 'postcode' ] ) ) {
WC_Tax :: _update_tax_rate_postcodes ( $id , wc_clean ( $data [ 'postcode' ] ) );
}
if ( ! empty ( $data [ 'city' ] ) ) {
WC_Tax :: _update_tax_rate_cities ( $id , wc_clean ( $data [ 'city' ] ) );
}
do_action ( 'woocommerce_api_create_tax_rate' , $id , $data );
$this -> server -> send_status ( 201 );
return $this -> get_tax ( $id );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
2015-10-07 14:42:25 +00:00
}
/**
* Edit a tax
*
* @ since 2.5 . 0
*
2015-10-08 01:27:42 +00:00
* @ param int $id The tax ID
2015-10-07 14:42:25 +00:00
* @ param array $data
*
* @ return array
*/
public function edit_tax ( $id , $data ) {
2015-10-08 20:15:00 +00:00
// WC_Tax::_update_tax_rate( $tax_rate_id, $tax_rate )
2015-10-07 14:42:25 +00:00
}
/**
* Delete a tax
*
* @ since 2.5 . 0
*
2015-10-08 01:27:42 +00:00
* @ param int $id The tax ID
2015-10-07 14:42:25 +00:00
*
* @ return array
*/
2015-10-08 01:10:33 +00:00
public function delete_tax ( $id ) {
global $wpdb ;
try {
// Check permissions
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_delete_tax_rate' , __ ( 'You do not have permission to delete tax rates' , 'woocommerce' ), 401 );
}
$id = absint ( $id );
2015-10-07 14:42:25 +00:00
2015-10-08 01:10:33 +00:00
WC_Tax :: _delete_tax_rate ( $id );
if ( 0 === $wpdb -> rows_affected ) {
throw new WC_API_Exception ( 'woocommerce_api_cannot_delete_tax_rate' , __ ( 'Could not delete the tax rate' , 'woocommerce' ), 401 );
}
return array ( 'message' => sprintf ( __ ( 'Deleted %s' , 'woocommerce' ), 'tax_rate' ) );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
2015-10-07 14:42:25 +00:00
}
2015-10-08 01:52:45 +00:00
/**
* Get the total number of taxes
*
* @ since 2.5 . 0
*
* @ param string $class
* @ param array $filter
*
* @ return array
*/
public function get_taxes_count ( $class = null , $filter = array () ) {
try {
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_read_taxes_count' , __ ( 'You do not have permission to read the taxes count' , 'woocommerce' ), 401 );
}
if ( ! empty ( $class ) ) {
$filter [ 'tax_rate_class' ] = $class ;
}
$query = $this -> query_tax_rates ( $filter , true );
return array ( 'count' => ( int ) $query [ 'headers' ] -> total );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-07 22:00:36 +00:00
/**
* Helper method to get tax rates objects
*
* @ since 2.5 . 0
*
* @ param array $args
*
* @ return array
*/
2015-10-07 22:07:45 +00:00
protected function query_tax_rates ( $args , $count_only = false ) {
2015-10-07 22:00:36 +00:00
global $wpdb ;
2015-10-07 22:07:45 +00:00
$results = '' ;
2015-10-07 22:00:36 +00:00
// Set args
$args = $this -> merge_query_args ( $args , array () );
$query = "
SELECT tax_rate_id
FROM { $wpdb -> prefix } woocommerce_tax_rates
WHERE 1 = 1
" ;
// Filter by tax class
2015-10-07 22:07:45 +00:00
if ( ! empty ( $args [ 'tax_rate_class' ] ) ) {
$tax_rate_class = 'standard' !== $args [ 'tax_rate_class' ] ? sanitize_title ( $args [ 'tax_rate_class' ] ) : '' ;
$query .= " AND tax_rate_class = ' $tax_rate_class ' " ;
2015-10-07 22:00:36 +00:00
}
// Order tax rates
$order_by = ' ORDER BY tax_rate_order' ;
// Pagination
$per_page = isset ( $args [ 'posts_per_page' ] ) ? $args [ 'posts_per_page' ] : get_option ( 'posts_per_page' );
$offset = 1 < $args [ 'paged' ] ? ( $args [ 'paged' ] - 1 ) * $per_page : 0 ;
$pagination = sprintf ( ' LIMIT %d, %d' , $offset , $per_page );
2015-10-07 22:07:45 +00:00
if ( ! $count_only ) {
$results = $wpdb -> get_results ( $query . $order_by . $pagination );
}
2015-10-07 22:00:36 +00:00
$wpdb -> get_results ( $query );
$headers = new stdClass ;
$headers -> page = $args [ 'paged' ];
$headers -> total = ( int ) $wpdb -> num_rows ;
$headers -> is_single = $per_page > $headers -> total ;
$headers -> total_pages = ceil ( $headers -> total / $per_page );
return array (
'results' => $results ,
'headers' => $headers
);
}
2015-10-07 14:42:25 +00:00
/**
* Bulk update or insert taxes
* Accepts an array with taxes in the formats supported by
* WC_API_Taxes -> create_tax () and WC_API_Taxes -> edit_tax ()
*
* @ since 2.5 . 0
*
* @ param array $data
*
* @ return array
*/
public function bulk ( $data ) {
}
2015-10-08 01:27:42 +00:00
/**
* Get all tax classes
*
* @ since 2.5 . 0
*
* @ param string $fields
*
* @ return array
*/
public function get_tax_classes ( $fields = null ) {
try {
// Permissions check
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_read_tax_classes' , __ ( 'You do not have permission to read tax classes' , 'woocommerce' ), 401 );
}
$tax_classes = array ();
// Add standard class
$tax_classes [] = array (
'slug' => 'standard' ,
'name' => __ ( 'Standard Rate' , 'woocommerce' )
);
$classes = WC_Tax :: get_tax_classes ();
foreach ( $classes as $class ) {
$tax_classes [] = apply_filters ( 'woocommerce_api_tax_class_response' , array (
'slug' => sanitize_title ( $class ),
'name' => $class
), $class , $fields , $this );
}
return array ( 'tax_classes' => apply_filters ( 'woocommerce_api_tax_classes_response' , $tax_classes , $classes , $fields , $this ) );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-08 01:35:34 +00:00
/**
2015-10-08 01:52:45 +00:00
* Create a tax class
2015-10-08 01:35:34 +00:00
*
* @ since 2.5 . 0
*
2015-10-08 01:52:45 +00:00
* @ param array $data
*
2015-10-08 01:35:34 +00:00
* @ return array
*/
2015-10-08 01:52:45 +00:00
public function create_tax_class ( $data ) {
2015-10-08 01:35:34 +00:00
try {
2015-10-08 01:52:45 +00:00
if ( ! isset ( $data [ 'tax_class' ] ) ) {
throw new WC_API_Exception ( 'woocommerce_api_missing_tax_class_data' , sprintf ( __ ( 'No %1$s data specified to create %1$s' , 'woocommerce' ), 'tax_class' ), 400 );
}
// Check permissions
2015-10-08 01:35:34 +00:00
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
2015-10-08 01:52:45 +00:00
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_create_tax_class' , __ ( 'You do not have permission to create tax classes' , 'woocommerce' ), 401 );
2015-10-08 01:35:34 +00:00
}
2015-10-08 01:52:45 +00:00
$data = $data [ 'tax_class' ];
2015-10-08 01:35:34 +00:00
2015-10-08 01:52:45 +00:00
if ( empty ( $data [ 'name' ] ) ) {
throw new WC_API_Exception ( 'woocommerce_api_missing_tax_class_name' , sprintf ( __ ( 'Missing parameter %s' , 'woocommerce' ), 'name' ), 400 );
}
$name = sanitize_text_field ( $data [ 'name' ] );
$slug = sanitize_title ( $name );
$classes = WC_Tax :: get_tax_classes ();
$exists = false ;
// Check if class exists
foreach ( $classes as $key => $class ) {
if ( sanitize_title ( $class ) === $slug ) {
$exists = true ;
break ;
}
}
// Return error if tax class already exists
if ( $exists ) {
throw new WC_API_Exception ( 'woocommerce_api_cannot_create_tax_class' , __ ( 'Tax class already exists' , 'woocommerce' ), 401 );
}
// Add the new class
$classes [] = $name ;
update_option ( 'woocommerce_tax_classes' , implode ( " \n " , $classes ) );
do_action ( 'woocommerce_api_create_tax_class' , $slug , $data );
$this -> server -> send_status ( 201 );
return array (
'tax_class' => array (
'slug' => $slug ,
'name' => $name
)
);
2015-10-08 01:35:34 +00:00
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-08 01:27:42 +00:00
/**
* Delete a tax class
*
* @ since 2.5 . 0
*
* @ param int $slug The tax class slug
*
* @ return array
*/
public function delete_tax_class ( $slug ) {
try {
// Check permissions
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_delete_tax_class' , __ ( 'You do not have permission to delete tax classes' , 'woocommerce' ), 401 );
}
$slug = sanitize_title ( $slug );
$classes = WC_Tax :: get_tax_classes ();
$deleted = false ;
foreach ( $classes as $key => $class ) {
2015-10-08 01:52:45 +00:00
if ( sanitize_title ( $class ) === $slug ) {
2015-10-08 01:27:42 +00:00
unset ( $classes [ $key ] );
$deleted = true ;
break ;
}
}
if ( ! $deleted ) {
throw new WC_API_Exception ( 'woocommerce_api_cannot_delete_tax_class' , __ ( 'Could not delete the tax class' , 'woocommerce' ), 401 );
}
update_option ( 'woocommerce_tax_classes' , implode ( " \n " , $classes ) );
return array ( 'message' => sprintf ( __ ( 'Deleted %s' , 'woocommerce' ), 'tax_class' ) );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-08 01:52:45 +00:00
/**
* Get the total number of tax classes
*
* @ since 2.5 . 0
*
* @ return array
*/
public function get_tax_classes_count () {
try {
if ( ! current_user_can ( 'manage_woocommerce' ) ) {
throw new WC_API_Exception ( 'woocommerce_api_user_cannot_read_tax_classes_count' , __ ( 'You do not have permission to read the tax classes count' , 'woocommerce' ), 401 );
}
$total = count ( WC_Tax :: get_tax_classes () ) + 1 ; // +1 for Standard Rate
return array ( 'count' => $total );
} catch ( WC_API_Exception $e ) {
return new WP_Error ( $e -> getErrorCode (), $e -> getMessage (), array ( 'status' => $e -> getCode () ) );
}
}
2015-10-07 14:42:25 +00:00
}