Aucune description

class-wc-rest-taxes-v1-controller.php 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. <?php
  2. /**
  3. * REST API Taxes controller
  4. *
  5. * Handles requests to the /taxes endpoint.
  6. *
  7. * @package WooCommerce\RestApi
  8. * @since 3.0.0
  9. */
  10. if ( ! defined( 'ABSPATH' ) ) {
  11. exit;
  12. }
  13. /**
  14. * REST API Taxes controller class.
  15. *
  16. * @package WooCommerce\RestApi
  17. * @extends WC_REST_Controller
  18. */
  19. class WC_REST_Taxes_V1_Controller extends WC_REST_Controller {
  20. /**
  21. * Endpoint namespace.
  22. *
  23. * @var string
  24. */
  25. protected $namespace = 'wc/v1';
  26. /**
  27. * Route base.
  28. *
  29. * @var string
  30. */
  31. protected $rest_base = 'taxes';
  32. /**
  33. * Register the routes for taxes.
  34. */
  35. public function register_routes() {
  36. register_rest_route(
  37. $this->namespace,
  38. '/' . $this->rest_base,
  39. array(
  40. array(
  41. 'methods' => WP_REST_Server::READABLE,
  42. 'callback' => array( $this, 'get_items' ),
  43. 'permission_callback' => array( $this, 'get_items_permissions_check' ),
  44. 'args' => $this->get_collection_params(),
  45. ),
  46. array(
  47. 'methods' => WP_REST_Server::CREATABLE,
  48. 'callback' => array( $this, 'create_item' ),
  49. 'permission_callback' => array( $this, 'create_item_permissions_check' ),
  50. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
  51. ),
  52. 'schema' => array( $this, 'get_public_item_schema' ),
  53. )
  54. );
  55. register_rest_route(
  56. $this->namespace,
  57. '/' . $this->rest_base . '/(?P<id>[\d]+)',
  58. array(
  59. 'args' => array(
  60. 'id' => array(
  61. 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
  62. 'type' => 'integer',
  63. ),
  64. ),
  65. array(
  66. 'methods' => WP_REST_Server::READABLE,
  67. 'callback' => array( $this, 'get_item' ),
  68. 'permission_callback' => array( $this, 'get_item_permissions_check' ),
  69. 'args' => array(
  70. 'context' => $this->get_context_param( array( 'default' => 'view' ) ),
  71. ),
  72. ),
  73. array(
  74. 'methods' => WP_REST_Server::EDITABLE,
  75. 'callback' => array( $this, 'update_item' ),
  76. 'permission_callback' => array( $this, 'update_item_permissions_check' ),
  77. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
  78. ),
  79. array(
  80. 'methods' => WP_REST_Server::DELETABLE,
  81. 'callback' => array( $this, 'delete_item' ),
  82. 'permission_callback' => array( $this, 'delete_item_permissions_check' ),
  83. 'args' => array(
  84. 'force' => array(
  85. 'default' => false,
  86. 'type' => 'boolean',
  87. 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ),
  88. ),
  89. ),
  90. ),
  91. 'schema' => array( $this, 'get_public_item_schema' ),
  92. )
  93. );
  94. register_rest_route(
  95. $this->namespace,
  96. '/' . $this->rest_base . '/batch',
  97. array(
  98. array(
  99. 'methods' => WP_REST_Server::EDITABLE,
  100. 'callback' => array( $this, 'batch_items' ),
  101. 'permission_callback' => array( $this, 'batch_items_permissions_check' ),
  102. 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
  103. ),
  104. 'schema' => array( $this, 'get_public_batch_schema' ),
  105. )
  106. );
  107. }
  108. /**
  109. * Check whether a given request has permission to read taxes.
  110. *
  111. * @param WP_REST_Request $request Full details about the request.
  112. * @return WP_Error|boolean
  113. */
  114. public function get_items_permissions_check( $request ) {
  115. if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
  116. return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  117. }
  118. return true;
  119. }
  120. /**
  121. * Check if a given request has access create taxes.
  122. *
  123. * @param WP_REST_Request $request Full details about the request.
  124. *
  125. * @return bool|WP_Error
  126. */
  127. public function create_item_permissions_check( $request ) {
  128. if ( ! wc_rest_check_manager_permissions( 'settings', 'create' ) ) {
  129. return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you are not allowed to create resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  130. }
  131. return true;
  132. }
  133. /**
  134. * Check if a given request has access to read a tax.
  135. *
  136. * @param WP_REST_Request $request Full details about the request.
  137. * @return WP_Error|boolean
  138. */
  139. public function get_item_permissions_check( $request ) {
  140. if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) {
  141. return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  142. }
  143. return true;
  144. }
  145. /**
  146. * Check if a given request has access update a tax.
  147. *
  148. * @param WP_REST_Request $request Full details about the request.
  149. *
  150. * @return bool|WP_Error
  151. */
  152. public function update_item_permissions_check( $request ) {
  153. if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) {
  154. return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you are not allowed to edit this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  155. }
  156. return true;
  157. }
  158. /**
  159. * Check if a given request has access delete a tax.
  160. *
  161. * @param WP_REST_Request $request Full details about the request.
  162. *
  163. * @return bool|WP_Error
  164. */
  165. public function delete_item_permissions_check( $request ) {
  166. if ( ! wc_rest_check_manager_permissions( 'settings', 'delete' ) ) {
  167. return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'Sorry, you are not allowed to delete this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  168. }
  169. return true;
  170. }
  171. /**
  172. * Check if a given request has access batch create, update and delete items.
  173. *
  174. * @param WP_REST_Request $request Full details about the request.
  175. *
  176. * @return bool|WP_Error
  177. */
  178. public function batch_items_permissions_check( $request ) {
  179. if ( ! wc_rest_check_manager_permissions( 'settings', 'batch' ) ) {
  180. return new WP_Error( 'woocommerce_rest_cannot_batch', __( 'Sorry, you are not allowed to batch manipulate this resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
  181. }
  182. return true;
  183. }
  184. /**
  185. * Get all taxes.
  186. *
  187. * @param WP_REST_Request $request Full details about the request.
  188. * @return WP_Error|WP_REST_Response
  189. */
  190. public function get_items( $request ) {
  191. global $wpdb;
  192. $prepared_args = array();
  193. $prepared_args['order'] = $request['order'];
  194. $prepared_args['number'] = $request['per_page'];
  195. if ( ! empty( $request['offset'] ) ) {
  196. $prepared_args['offset'] = $request['offset'];
  197. } else {
  198. $prepared_args['offset'] = ( $request['page'] - 1 ) * $prepared_args['number'];
  199. }
  200. $orderby_possibles = array(
  201. 'id' => 'tax_rate_id',
  202. 'order' => 'tax_rate_order',
  203. 'priority' => 'tax_rate_priority',
  204. );
  205. $prepared_args['orderby'] = $orderby_possibles[ $request['orderby'] ];
  206. $prepared_args['class'] = $request['class'];
  207. /**
  208. * Filter arguments, before passing to $wpdb->get_results(), when querying taxes via the REST API.
  209. *
  210. * @param array $prepared_args Array of arguments for $wpdb->get_results().
  211. * @param WP_REST_Request $request The current request.
  212. */
  213. $prepared_args = apply_filters( 'woocommerce_rest_tax_query', $prepared_args, $request );
  214. $orderby = sanitize_key( $prepared_args['orderby'] ) . ' ' . sanitize_key( $prepared_args['order'] );
  215. $query = "
  216. SELECT *
  217. FROM {$wpdb->prefix}woocommerce_tax_rates
  218. %s
  219. ORDER BY {$orderby}
  220. LIMIT %%d, %%d
  221. ";
  222. $wpdb_prepare_args = array(
  223. $prepared_args['offset'],
  224. $prepared_args['number'],
  225. );
  226. // Filter by tax class.
  227. if ( empty( $prepared_args['class'] ) ) {
  228. $query = sprintf( $query, '' );
  229. } else {
  230. $class = 'standard' !== $prepared_args['class'] ? sanitize_title( $prepared_args['class'] ) : '';
  231. array_unshift( $wpdb_prepare_args, $class );
  232. $query = sprintf( $query, 'WHERE tax_rate_class = %s' );
  233. }
  234. // Query taxes.
  235. // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
  236. $results = $wpdb->get_results(
  237. $wpdb->prepare(
  238. $query,
  239. $wpdb_prepare_args
  240. )
  241. );
  242. // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
  243. $taxes = array();
  244. foreach ( $results as $tax ) {
  245. $data = $this->prepare_item_for_response( $tax, $request );
  246. $taxes[] = $this->prepare_response_for_collection( $data );
  247. }
  248. $response = rest_ensure_response( $taxes );
  249. // Store pagination values for headers then unset for count query.
  250. $per_page = (int) $prepared_args['number'];
  251. $page = ceil( ( ( (int) $prepared_args['offset'] ) / $per_page ) + 1 );
  252. // Query only for ids.
  253. // phpcs:disable WordPress.DB.PreparedSQL.NotPrepared
  254. $query = str_replace( 'SELECT *', 'SELECT tax_rate_id', $query );
  255. $wpdb->get_results(
  256. $wpdb->prepare(
  257. $query,
  258. $wpdb_prepare_args
  259. )
  260. );
  261. // phpcs:enable WordPress.DB.PreparedSQL.NotPrepared
  262. // Calculate totals.
  263. $total_taxes = (int) $wpdb->num_rows;
  264. $response->header( 'X-WP-Total', (int) $total_taxes );
  265. $max_pages = ceil( $total_taxes / $per_page );
  266. $response->header( 'X-WP-TotalPages', (int) $max_pages );
  267. $base = add_query_arg( $request->get_query_params(), rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ) );
  268. if ( $page > 1 ) {
  269. $prev_page = $page - 1;
  270. if ( $prev_page > $max_pages ) {
  271. $prev_page = $max_pages;
  272. }
  273. $prev_link = add_query_arg( 'page', $prev_page, $base );
  274. $response->link_header( 'prev', $prev_link );
  275. }
  276. if ( $max_pages > $page ) {
  277. $next_page = $page + 1;
  278. $next_link = add_query_arg( 'page', $next_page, $base );
  279. $response->link_header( 'next', $next_link );
  280. }
  281. return $response;
  282. }
  283. /**
  284. * Take tax data from the request and return the updated or newly created rate.
  285. *
  286. * @param WP_REST_Request $request Full details about the request.
  287. * @param stdClass|null $current Existing tax object.
  288. * @return object
  289. */
  290. protected function create_or_update_tax( $request, $current = null ) {
  291. $id = absint( isset( $request['id'] ) ? $request['id'] : 0 );
  292. $data = array();
  293. $fields = array(
  294. 'tax_rate_country',
  295. 'tax_rate_state',
  296. 'tax_rate',
  297. 'tax_rate_name',
  298. 'tax_rate_priority',
  299. 'tax_rate_compound',
  300. 'tax_rate_shipping',
  301. 'tax_rate_order',
  302. 'tax_rate_class',
  303. );
  304. foreach ( $fields as $field ) {
  305. // Keys via API differ from the stored names returned by _get_tax_rate.
  306. $key = 'tax_rate' === $field ? 'rate' : str_replace( 'tax_rate_', '', $field );
  307. // Remove data that was not posted.
  308. if ( ! isset( $request[ $key ] ) ) {
  309. continue;
  310. }
  311. // Test new data against current data.
  312. if ( $current && $current->$field === $request[ $key ] ) {
  313. continue;
  314. }
  315. // Add to data array.
  316. switch ( $key ) {
  317. case 'tax_rate_priority':
  318. case 'tax_rate_compound':
  319. case 'tax_rate_shipping':
  320. case 'tax_rate_order':
  321. $data[ $field ] = absint( $request[ $key ] );
  322. break;
  323. case 'tax_rate_class':
  324. $data[ $field ] = 'standard' !== $request['tax_rate_class'] ? $request['tax_rate_class'] : '';
  325. break;
  326. default:
  327. $data[ $field ] = wc_clean( $request[ $key ] );
  328. break;
  329. }
  330. }
  331. if ( ! $id ) {
  332. $id = WC_Tax::_insert_tax_rate( $data );
  333. } elseif ( $data ) {
  334. WC_Tax::_update_tax_rate( $id, $data );
  335. }
  336. // Add locales.
  337. if ( ! empty( $request['postcode'] ) ) {
  338. WC_Tax::_update_tax_rate_postcodes( $id, wc_clean( $request['postcode'] ) );
  339. }
  340. if ( ! empty( $request['city'] ) ) {
  341. WC_Tax::_update_tax_rate_cities( $id, wc_clean( $request['city'] ) );
  342. }
  343. return WC_Tax::_get_tax_rate( $id, OBJECT );
  344. }
  345. /**
  346. * Create a single tax.
  347. *
  348. * @param WP_REST_Request $request Full details about the request.
  349. * @return WP_Error|WP_REST_Response
  350. */
  351. public function create_item( $request ) {
  352. if ( ! empty( $request['id'] ) ) {
  353. return new WP_Error( 'woocommerce_rest_tax_exists', __( 'Cannot create existing resource.', 'woocommerce' ), array( 'status' => 400 ) );
  354. }
  355. $tax = $this->create_or_update_tax( $request );
  356. $this->update_additional_fields_for_object( $tax, $request );
  357. /**
  358. * Fires after a tax is created or updated via the REST API.
  359. *
  360. * @param stdClass $tax Data used to create the tax.
  361. * @param WP_REST_Request $request Request object.
  362. * @param boolean $creating True when creating tax, false when updating tax.
  363. */
  364. do_action( 'woocommerce_rest_insert_tax', $tax, $request, true );
  365. $request->set_param( 'context', 'edit' );
  366. $response = $this->prepare_item_for_response( $tax, $request );
  367. $response = rest_ensure_response( $response );
  368. $response->set_status( 201 );
  369. $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ) );
  370. return $response;
  371. }
  372. /**
  373. * Get a single tax.
  374. *
  375. * @param WP_REST_Request $request Full details about the request.
  376. * @return WP_Error|WP_REST_Response
  377. */
  378. public function get_item( $request ) {
  379. $id = (int) $request['id'];
  380. $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT );
  381. if ( empty( $id ) || empty( $tax_obj ) ) {
  382. return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) );
  383. }
  384. $tax = $this->prepare_item_for_response( $tax_obj, $request );
  385. $response = rest_ensure_response( $tax );
  386. return $response;
  387. }
  388. /**
  389. * Update a single tax.
  390. *
  391. * @param WP_REST_Request $request Full details about the request.
  392. * @return WP_Error|WP_REST_Response
  393. */
  394. public function update_item( $request ) {
  395. $id = (int) $request['id'];
  396. $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT );
  397. if ( empty( $id ) || empty( $tax_obj ) ) {
  398. return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) );
  399. }
  400. $tax = $this->create_or_update_tax( $request, $tax_obj );
  401. $this->update_additional_fields_for_object( $tax, $request );
  402. /**
  403. * Fires after a tax is created or updated via the REST API.
  404. *
  405. * @param stdClass $tax Data used to create the tax.
  406. * @param WP_REST_Request $request Request object.
  407. * @param boolean $creating True when creating tax, false when updating tax.
  408. */
  409. do_action( 'woocommerce_rest_insert_tax', $tax, $request, false );
  410. $request->set_param( 'context', 'edit' );
  411. $response = $this->prepare_item_for_response( $tax, $request );
  412. $response = rest_ensure_response( $response );
  413. return $response;
  414. }
  415. /**
  416. * Delete a single tax.
  417. *
  418. * @param WP_REST_Request $request Full details about the request.
  419. * @return WP_Error|WP_REST_Response
  420. */
  421. public function delete_item( $request ) {
  422. global $wpdb;
  423. $id = (int) $request['id'];
  424. $force = isset( $request['force'] ) ? (bool) $request['force'] : false;
  425. // We don't support trashing for this type, error out.
  426. if ( ! $force ) {
  427. return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Taxes do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) );
  428. }
  429. $tax = WC_Tax::_get_tax_rate( $id, OBJECT );
  430. if ( empty( $id ) || empty( $tax ) ) {
  431. return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) );
  432. }
  433. $request->set_param( 'context', 'edit' );
  434. $response = $this->prepare_item_for_response( $tax, $request );
  435. WC_Tax::_delete_tax_rate( $id );
  436. if ( 0 === $wpdb->rows_affected ) {
  437. return new WP_Error( 'woocommerce_rest_cannot_delete', __( 'The resource cannot be deleted.', 'woocommerce' ), array( 'status' => 500 ) );
  438. }
  439. /**
  440. * Fires after a tax is deleted via the REST API.
  441. *
  442. * @param stdClass $tax The tax data.
  443. * @param WP_REST_Response $response The response returned from the API.
  444. * @param WP_REST_Request $request The request sent to the API.
  445. */
  446. do_action( 'woocommerce_rest_delete_tax', $tax, $response, $request );
  447. return $response;
  448. }
  449. /**
  450. * Prepare a single tax output for response.
  451. *
  452. * @param stdClass $tax Tax object.
  453. * @param WP_REST_Request $request Request object.
  454. *
  455. * @return WP_REST_Response $response Response data.
  456. */
  457. public function prepare_item_for_response( $tax, $request ) {
  458. $id = (int) $tax->tax_rate_id;
  459. $data = array(
  460. 'id' => $id,
  461. 'country' => $tax->tax_rate_country,
  462. 'state' => $tax->tax_rate_state,
  463. 'postcode' => '',
  464. 'city' => '',
  465. 'rate' => $tax->tax_rate,
  466. 'name' => $tax->tax_rate_name,
  467. 'priority' => (int) $tax->tax_rate_priority,
  468. 'compound' => (bool) $tax->tax_rate_compound,
  469. 'shipping' => (bool) $tax->tax_rate_shipping,
  470. 'order' => (int) $tax->tax_rate_order,
  471. 'class' => $tax->tax_rate_class ? $tax->tax_rate_class : 'standard',
  472. );
  473. $data = $this->add_tax_rate_locales( $data, $tax );
  474. $context = ! empty( $request['context'] ) ? $request['context'] : 'view';
  475. $data = $this->add_additional_fields_to_object( $data, $request );
  476. $data = $this->filter_response_by_context( $data, $context );
  477. // Wrap the data in a response object.
  478. $response = rest_ensure_response( $data );
  479. $response->add_links( $this->prepare_links( $tax ) );
  480. /**
  481. * Filter tax object returned from the REST API.
  482. *
  483. * @param WP_REST_Response $response The response object.
  484. * @param stdClass $tax Tax object used to create response.
  485. * @param WP_REST_Request $request Request object.
  486. */
  487. return apply_filters( 'woocommerce_rest_prepare_tax', $response, $tax, $request );
  488. }
  489. /**
  490. * Prepare links for the request.
  491. *
  492. * @param stdClass $tax Tax object.
  493. * @return array Links for the given tax.
  494. */
  495. protected function prepare_links( $tax ) {
  496. $links = array(
  497. 'self' => array(
  498. 'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $tax->tax_rate_id ) ),
  499. ),
  500. 'collection' => array(
  501. 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
  502. ),
  503. );
  504. return $links;
  505. }
  506. /**
  507. * Add tax rate locales to the response array.
  508. *
  509. * @param array $data Response data.
  510. * @param stdClass $tax Tax object.
  511. *
  512. * @return array
  513. */
  514. protected function add_tax_rate_locales( $data, $tax ) {
  515. global $wpdb;
  516. // Get locales from a tax rate.
  517. $locales = $wpdb->get_results(
  518. $wpdb->prepare(
  519. "
  520. SELECT location_code, location_type
  521. FROM {$wpdb->prefix}woocommerce_tax_rate_locations
  522. WHERE tax_rate_id = %d
  523. ",
  524. $tax->tax_rate_id
  525. )
  526. );
  527. if ( ! is_wp_error( $tax ) && ! is_null( $tax ) ) {
  528. foreach ( $locales as $locale ) {
  529. $data[ $locale->location_type ] = $locale->location_code;
  530. }
  531. }
  532. return $data;
  533. }
  534. /**
  535. * Get the Taxes schema, conforming to JSON Schema.
  536. *
  537. * @return array
  538. */
  539. public function get_item_schema() {
  540. $schema = array(
  541. '$schema' => 'http://json-schema.org/draft-04/schema#',
  542. 'title' => 'tax',
  543. 'type' => 'object',
  544. 'properties' => array(
  545. 'id' => array(
  546. 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
  547. 'type' => 'integer',
  548. 'context' => array( 'view', 'edit' ),
  549. 'readonly' => true,
  550. ),
  551. 'country' => array(
  552. 'description' => __( 'Country ISO 3166 code.', 'woocommerce' ),
  553. 'type' => 'string',
  554. 'context' => array( 'view', 'edit' ),
  555. ),
  556. 'state' => array(
  557. 'description' => __( 'State code.', 'woocommerce' ),
  558. 'type' => 'string',
  559. 'context' => array( 'view', 'edit' ),
  560. ),
  561. 'postcode' => array(
  562. 'description' => __( 'Postcode / ZIP.', 'woocommerce' ),
  563. 'type' => 'string',
  564. 'context' => array( 'view', 'edit' ),
  565. ),
  566. 'city' => array(
  567. 'description' => __( 'City name.', 'woocommerce' ),
  568. 'type' => 'string',
  569. 'context' => array( 'view', 'edit' ),
  570. ),
  571. 'rate' => array(
  572. 'description' => __( 'Tax rate.', 'woocommerce' ),
  573. 'type' => 'string',
  574. 'context' => array( 'view', 'edit' ),
  575. ),
  576. 'name' => array(
  577. 'description' => __( 'Tax rate name.', 'woocommerce' ),
  578. 'type' => 'string',
  579. 'context' => array( 'view', 'edit' ),
  580. ),
  581. 'priority' => array(
  582. 'description' => __( 'Tax priority.', 'woocommerce' ),
  583. 'type' => 'integer',
  584. 'default' => 1,
  585. 'context' => array( 'view', 'edit' ),
  586. ),
  587. 'compound' => array(
  588. 'description' => __( 'Whether or not this is a compound rate.', 'woocommerce' ),
  589. 'type' => 'boolean',
  590. 'default' => false,
  591. 'context' => array( 'view', 'edit' ),
  592. ),
  593. 'shipping' => array(
  594. 'description' => __( 'Whether or not this tax rate also gets applied to shipping.', 'woocommerce' ),
  595. 'type' => 'boolean',
  596. 'default' => true,
  597. 'context' => array( 'view', 'edit' ),
  598. ),
  599. 'order' => array(
  600. 'description' => __( 'Indicates the order that will appear in queries.', 'woocommerce' ),
  601. 'type' => 'integer',
  602. 'context' => array( 'view', 'edit' ),
  603. ),
  604. 'class' => array(
  605. 'description' => __( 'Tax class.', 'woocommerce' ),
  606. 'type' => 'string',
  607. 'default' => 'standard',
  608. 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ),
  609. 'context' => array( 'view', 'edit' ),
  610. ),
  611. ),
  612. );
  613. return $this->add_additional_fields_schema( $schema );
  614. }
  615. /**
  616. * Get the query params for collections.
  617. *
  618. * @return array
  619. */
  620. public function get_collection_params() {
  621. $params = array();
  622. $params['context'] = $this->get_context_param();
  623. $params['context']['default'] = 'view';
  624. $params['page'] = array(
  625. 'description' => __( 'Current page of the collection.', 'woocommerce' ),
  626. 'type' => 'integer',
  627. 'default' => 1,
  628. 'sanitize_callback' => 'absint',
  629. 'validate_callback' => 'rest_validate_request_arg',
  630. 'minimum' => 1,
  631. );
  632. $params['per_page'] = array(
  633. 'description' => __( 'Maximum number of items to be returned in result set.', 'woocommerce' ),
  634. 'type' => 'integer',
  635. 'default' => 10,
  636. 'minimum' => 1,
  637. 'maximum' => 100,
  638. 'sanitize_callback' => 'absint',
  639. 'validate_callback' => 'rest_validate_request_arg',
  640. );
  641. $params['offset'] = array(
  642. 'description' => __( 'Offset the result set by a specific number of items.', 'woocommerce' ),
  643. 'type' => 'integer',
  644. 'sanitize_callback' => 'absint',
  645. 'validate_callback' => 'rest_validate_request_arg',
  646. );
  647. $params['order'] = array(
  648. 'default' => 'asc',
  649. 'description' => __( 'Order sort attribute ascending or descending.', 'woocommerce' ),
  650. 'enum' => array( 'asc', 'desc' ),
  651. 'sanitize_callback' => 'sanitize_key',
  652. 'type' => 'string',
  653. 'validate_callback' => 'rest_validate_request_arg',
  654. );
  655. $params['orderby'] = array(
  656. 'default' => 'order',
  657. 'description' => __( 'Sort collection by object attribute.', 'woocommerce' ),
  658. 'enum' => array(
  659. 'id',
  660. 'order',
  661. 'priority',
  662. ),
  663. 'sanitize_callback' => 'sanitize_key',
  664. 'type' => 'string',
  665. 'validate_callback' => 'rest_validate_request_arg',
  666. );
  667. $params['class'] = array(
  668. 'description' => __( 'Sort by tax class.', 'woocommerce' ),
  669. 'enum' => array_merge( array( 'standard' ), WC_Tax::get_tax_class_slugs() ),
  670. 'sanitize_callback' => 'sanitize_title',
  671. 'type' => 'string',
  672. 'validate_callback' => 'rest_validate_request_arg',
  673. );
  674. return $params;
  675. }
  676. }