Нет описания

class-wc-rest-data-continents-controller.php 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. <?php
  2. /**
  3. * REST API Data continents controller.
  4. *
  5. * Handles requests to the /data/continents endpoint.
  6. *
  7. * @package WooCommerce\RestApi
  8. * @since 3.5.0
  9. */
  10. defined( 'ABSPATH' ) || exit;
  11. /**
  12. * REST API Data continents controller class.
  13. *
  14. * @package WooCommerce\RestApi
  15. * @extends WC_REST_Controller
  16. */
  17. class WC_REST_Data_Continents_Controller extends WC_REST_Data_Controller {
  18. /**
  19. * Endpoint namespace.
  20. *
  21. * @var string
  22. */
  23. protected $namespace = 'wc/v3';
  24. /**
  25. * Route base.
  26. *
  27. * @var string
  28. */
  29. protected $rest_base = 'data/continents';
  30. /**
  31. * Register routes.
  32. *
  33. * @since 3.5.0
  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. ),
  45. 'schema' => array( $this, 'get_public_item_schema' ),
  46. )
  47. );
  48. register_rest_route(
  49. $this->namespace,
  50. '/' . $this->rest_base . '/(?P<location>[\w-]+)',
  51. array(
  52. array(
  53. 'methods' => WP_REST_Server::READABLE,
  54. 'callback' => array( $this, 'get_item' ),
  55. 'permission_callback' => array( $this, 'get_items_permissions_check' ),
  56. 'args' => array(
  57. 'continent' => array(
  58. 'description' => __( '2 character continent code.', 'woocommerce' ),
  59. 'type' => 'string',
  60. ),
  61. ),
  62. ),
  63. 'schema' => array( $this, 'get_public_item_schema' ),
  64. )
  65. );
  66. }
  67. /**
  68. * Return the list of countries and states for a given continent.
  69. *
  70. * @since 3.5.0
  71. * @param string $continent_code Continent code.
  72. * @param WP_REST_Request $request Request data.
  73. * @return array|mixed Response data, ready for insertion into collection data.
  74. */
  75. public function get_continent( $continent_code, $request ) {
  76. $continents = WC()->countries->get_continents();
  77. $countries = WC()->countries->get_countries();
  78. $states = WC()->countries->get_states();
  79. $locale_info = include WC()->plugin_path() . '/i18n/locale-info.php';
  80. $data = array();
  81. if ( ! array_key_exists( $continent_code, $continents ) ) {
  82. return false;
  83. }
  84. $continent_list = $continents[ $continent_code ];
  85. $continent = array(
  86. 'code' => $continent_code,
  87. 'name' => $continent_list['name'],
  88. );
  89. $local_countries = array();
  90. foreach ( $continent_list['countries'] as $country_code ) {
  91. if ( isset( $countries[ $country_code ] ) ) {
  92. $country = array(
  93. 'code' => $country_code,
  94. 'name' => $countries[ $country_code ],
  95. );
  96. // If we have detailed locale information include that in the response.
  97. if ( array_key_exists( $country_code, $locale_info ) ) {
  98. // Defensive programming against unexpected changes in locale-info.php.
  99. $country_data = wp_parse_args(
  100. $locale_info[ $country_code ],
  101. array(
  102. 'currency_code' => 'USD',
  103. 'currency_pos' => 'left',
  104. 'decimal_sep' => '.',
  105. 'dimension_unit' => 'in',
  106. 'num_decimals' => 2,
  107. 'thousand_sep' => ',',
  108. 'weight_unit' => 'lbs',
  109. )
  110. );
  111. $country = array_merge( $country, $country_data );
  112. }
  113. $local_states = array();
  114. if ( isset( $states[ $country_code ] ) ) {
  115. foreach ( $states[ $country_code ] as $state_code => $state_name ) {
  116. $local_states[] = array(
  117. 'code' => $state_code,
  118. 'name' => $state_name,
  119. );
  120. }
  121. }
  122. $country['states'] = $local_states;
  123. // Allow only desired keys (e.g. filter out tax rates).
  124. $allowed = array(
  125. 'code',
  126. 'currency_code',
  127. 'currency_pos',
  128. 'decimal_sep',
  129. 'dimension_unit',
  130. 'name',
  131. 'num_decimals',
  132. 'states',
  133. 'thousand_sep',
  134. 'weight_unit',
  135. );
  136. $country = array_intersect_key( $country, array_flip( $allowed ) );
  137. $local_countries[] = $country;
  138. }
  139. }
  140. $continent['countries'] = $local_countries;
  141. return $continent;
  142. }
  143. /**
  144. * Return the list of states for all continents.
  145. *
  146. * @since 3.5.0
  147. * @param WP_REST_Request $request Request data.
  148. * @return WP_Error|WP_REST_Response
  149. */
  150. public function get_items( $request ) {
  151. $continents = WC()->countries->get_continents();
  152. $data = array();
  153. foreach ( array_keys( $continents ) as $continent_code ) {
  154. $continent = $this->get_continent( $continent_code, $request );
  155. $response = $this->prepare_item_for_response( $continent, $request );
  156. $data[] = $this->prepare_response_for_collection( $response );
  157. }
  158. return rest_ensure_response( $data );
  159. }
  160. /**
  161. * Return the list of locations for a given continent.
  162. *
  163. * @since 3.5.0
  164. * @param WP_REST_Request $request Request data.
  165. * @return WP_Error|WP_REST_Response
  166. */
  167. public function get_item( $request ) {
  168. $data = $this->get_continent( strtoupper( $request['location'] ), $request );
  169. if ( empty( $data ) ) {
  170. return new WP_Error( 'woocommerce_rest_data_invalid_location', __( 'There are no locations matching these parameters.', 'woocommerce' ), array( 'status' => 404 ) );
  171. }
  172. return $this->prepare_item_for_response( $data, $request );
  173. }
  174. /**
  175. * Prepare the data object for response.
  176. *
  177. * @since 3.5.0
  178. * @param object $item Data object.
  179. * @param WP_REST_Request $request Request object.
  180. * @return WP_REST_Response $response Response data.
  181. */
  182. public function prepare_item_for_response( $item, $request ) {
  183. $data = $this->add_additional_fields_to_object( $item, $request );
  184. $data = $this->filter_response_by_context( $data, 'view' );
  185. $response = rest_ensure_response( $data );
  186. $response->add_links( $this->prepare_links( $item ) );
  187. /**
  188. * Filter the location list returned from the API.
  189. *
  190. * Allows modification of the loction data right before it is returned.
  191. *
  192. * @param WP_REST_Response $response The response object.
  193. * @param array $item The original list of continent(s), countries, and states.
  194. * @param WP_REST_Request $request Request used to generate the response.
  195. */
  196. return apply_filters( 'woocommerce_rest_prepare_data_continent', $response, $item, $request );
  197. }
  198. /**
  199. * Prepare links for the request.
  200. *
  201. * @param object $item Data object.
  202. * @return array Links for the given continent.
  203. */
  204. protected function prepare_links( $item ) {
  205. $continent_code = strtolower( $item['code'] );
  206. $links = array(
  207. 'self' => array(
  208. 'href' => rest_url( sprintf( '/%s/%s/%s', $this->namespace, $this->rest_base, $continent_code ) ),
  209. ),
  210. 'collection' => array(
  211. 'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
  212. ),
  213. );
  214. return $links;
  215. }
  216. /**
  217. * Get the location schema, conforming to JSON Schema.
  218. *
  219. * @since 3.5.0
  220. * @return array
  221. */
  222. public function get_item_schema() {
  223. $schema = array(
  224. '$schema' => 'http://json-schema.org/draft-04/schema#',
  225. 'title' => 'data_continents',
  226. 'type' => 'object',
  227. 'properties' => array(
  228. 'code' => array(
  229. 'type' => 'string',
  230. 'description' => __( '2 character continent code.', 'woocommerce' ),
  231. 'context' => array( 'view' ),
  232. 'readonly' => true,
  233. ),
  234. 'name' => array(
  235. 'type' => 'string',
  236. 'description' => __( 'Full name of continent.', 'woocommerce' ),
  237. 'context' => array( 'view' ),
  238. 'readonly' => true,
  239. ),
  240. 'countries' => array(
  241. 'type' => 'array',
  242. 'description' => __( 'List of countries on this continent.', 'woocommerce' ),
  243. 'context' => array( 'view' ),
  244. 'readonly' => true,
  245. 'items' => array(
  246. 'type' => 'object',
  247. 'context' => array( 'view' ),
  248. 'readonly' => true,
  249. 'properties' => array(
  250. 'code' => array(
  251. 'type' => 'string',
  252. 'description' => __( 'ISO3166 alpha-2 country code.', 'woocommerce' ),
  253. 'context' => array( 'view' ),
  254. 'readonly' => true,
  255. ),
  256. 'currency_code' => array(
  257. 'type' => 'string',
  258. 'description' => __( 'Default ISO4127 alpha-3 currency code for the country.', 'woocommerce' ),
  259. 'context' => array( 'view' ),
  260. 'readonly' => true,
  261. ),
  262. 'currency_pos' => array(
  263. 'type' => 'string',
  264. 'description' => __( 'Currency symbol position for this country.', 'woocommerce' ),
  265. 'context' => array( 'view' ),
  266. 'readonly' => true,
  267. ),
  268. 'decimal_sep' => array(
  269. 'type' => 'string',
  270. 'description' => __( 'Decimal separator for displayed prices for this country.', 'woocommerce' ),
  271. 'context' => array( 'view' ),
  272. 'readonly' => true,
  273. ),
  274. 'dimension_unit' => array(
  275. 'type' => 'string',
  276. 'description' => __( 'The unit lengths are defined in for this country.', 'woocommerce' ),
  277. 'context' => array( 'view' ),
  278. 'readonly' => true,
  279. ),
  280. 'name' => array(
  281. 'type' => 'string',
  282. 'description' => __( 'Full name of country.', 'woocommerce' ),
  283. 'context' => array( 'view' ),
  284. 'readonly' => true,
  285. ),
  286. 'num_decimals' => array(
  287. 'type' => 'integer',
  288. 'description' => __( 'Number of decimal points shown in displayed prices for this country.', 'woocommerce' ),
  289. 'context' => array( 'view' ),
  290. 'readonly' => true,
  291. ),
  292. 'states' => array(
  293. 'type' => 'array',
  294. 'description' => __( 'List of states in this country.', 'woocommerce' ),
  295. 'context' => array( 'view' ),
  296. 'readonly' => true,
  297. 'items' => array(
  298. 'type' => 'object',
  299. 'context' => array( 'view' ),
  300. 'readonly' => true,
  301. 'properties' => array(
  302. 'code' => array(
  303. 'type' => 'string',
  304. 'description' => __( 'State code.', 'woocommerce' ),
  305. 'context' => array( 'view' ),
  306. 'readonly' => true,
  307. ),
  308. 'name' => array(
  309. 'type' => 'string',
  310. 'description' => __( 'Full name of state.', 'woocommerce' ),
  311. 'context' => array( 'view' ),
  312. 'readonly' => true,
  313. ),
  314. ),
  315. ),
  316. ),
  317. 'thousand_sep' => array(
  318. 'type' => 'string',
  319. 'description' => __( 'Thousands separator for displayed prices in this country.', 'woocommerce' ),
  320. 'context' => array( 'view' ),
  321. 'readonly' => true,
  322. ),
  323. 'weight_unit' => array(
  324. 'type' => 'string',
  325. 'description' => __( 'The unit weights are defined in for this country.', 'woocommerce' ),
  326. 'context' => array( 'view' ),
  327. 'readonly' => true,
  328. ),
  329. ),
  330. ),
  331. ),
  332. ),
  333. );
  334. return $this->add_additional_fields_schema( $schema );
  335. }
  336. }