/includes/api/legacy/v3/class-wc-api-customers.php

  1. <?php 
  2. /** 
  3. * WooCommerce API Customers Class 
  4. * 
  5. * Handles requests to the /customers endpoint 
  6. * 
  7. * @author WooThemes 
  8. * @category API 
  9. * @package WooCommerce/API 
  10. * @since 2.2 
  11. */ 
  12.  
  13. if ( ! defined( 'ABSPATH' ) ) { 
  14. exit; // Exit if accessed directly 
  15.  
  16. class WC_API_Customers extends WC_API_Resource { 
  17.  
  18. /** @var string $base the route base */ 
  19. protected $base = '/customers'; 
  20.  
  21. /** @var string $created_at_min for date filtering */ 
  22. private $created_at_min = null; 
  23.  
  24. /** @var string $created_at_max for date filtering */ 
  25. private $created_at_max = null; 
  26.  
  27. /** 
  28. * Setup class, overridden to provide customer data to order response 
  29. * 
  30. * @since 2.1 
  31. * @param WC_API_Server $server 
  32. * @return WC_API_Customers 
  33. */ 
  34. public function __construct( WC_API_Server $server ) { 
  35.  
  36. parent::__construct( $server ); 
  37.  
  38. // add customer data to order responses 
  39. add_filter( 'woocommerce_api_order_response', array( $this, 'add_customer_data' ), 10, 2 ); 
  40.  
  41. // modify WP_User_Query to support created_at date filtering 
  42. add_action( 'pre_user_query', array( $this, 'modify_user_query' ) ); 
  43.  
  44. /** 
  45. * Register the routes for this class 
  46. * 
  47. * GET /customers 
  48. * GET /customers/count 
  49. * GET /customers/<id> 
  50. * GET /customers/<id>/orders 
  51. * 
  52. * @since 2.2 
  53. * @param array $routes 
  54. * @return array 
  55. */ 
  56. public function register_routes( $routes ) { 
  57.  
  58. # GET/POST /customers 
  59. $routes[ $this->base ] = array( 
  60. array( array( $this, 'get_customers' ), WC_API_SERVER::READABLE ),  
  61. array( array( $this, 'create_customer' ), WC_API_SERVER::CREATABLE | WC_API_Server::ACCEPT_DATA ),  
  62. ); 
  63.  
  64. # GET /customers/count 
  65. $routes[ $this->base . '/count' ] = array( 
  66. array( array( $this, 'get_customers_count' ), WC_API_SERVER::READABLE ),  
  67. ); 
  68.  
  69. # GET/PUT/DELETE /customers/<id> 
  70. $routes[ $this->base . '/(?P<id>\d+)' ] = array( 
  71. array( array( $this, 'get_customer' ), WC_API_SERVER::READABLE ),  
  72. array( array( $this, 'edit_customer' ), WC_API_SERVER::EDITABLE | WC_API_SERVER::ACCEPT_DATA ),  
  73. array( array( $this, 'delete_customer' ), WC_API_SERVER::DELETABLE ),  
  74. ); 
  75.  
  76. # GET /customers/email/<email> 
  77. $routes[ $this->base . '/email/(?P<email>.+)' ] = array( 
  78. array( array( $this, 'get_customer_by_email' ), WC_API_SERVER::READABLE ),  
  79. ); 
  80.  
  81. # GET /customers/<id>/orders 
  82. $routes[ $this->base . '/(?P<id>\d+)/orders' ] = array( 
  83. array( array( $this, 'get_customer_orders' ), WC_API_SERVER::READABLE ),  
  84. ); 
  85.  
  86. # GET /customers/<id>/downloads 
  87. $routes[ $this->base . '/(?P<id>\d+)/downloads' ] = array( 
  88. array( array( $this, 'get_customer_downloads' ), WC_API_SERVER::READABLE ),  
  89. ); 
  90.  
  91. # POST|PUT /customers/bulk 
  92. $routes[ $this->base . '/bulk' ] = array( 
  93. array( array( $this, 'bulk' ), WC_API_Server::EDITABLE | WC_API_Server::ACCEPT_DATA ),  
  94. ); 
  95.  
  96. return $routes; 
  97.  
  98. /** 
  99. * Get all customers 
  100. * 
  101. * @since 2.1 
  102. * @param array $fields 
  103. * @param array $filter 
  104. * @param int $page 
  105. * @return array 
  106. */ 
  107. public function get_customers( $fields = null, $filter = array(), $page = 1 ) { 
  108.  
  109. $filter['page'] = $page; 
  110.  
  111. $query = $this->query_customers( $filter ); 
  112.  
  113. $customers = array(); 
  114.  
  115. foreach ( $query->get_results() as $user_id ) { 
  116.  
  117. if ( ! $this->is_readable( $user_id ) ) { 
  118. continue; 
  119.  
  120. $customers[] = current( $this->get_customer( $user_id, $fields ) ); 
  121.  
  122. $this->server->add_pagination_headers( $query ); 
  123.  
  124. return array( 'customers' => $customers ); 
  125.  
  126. /** 
  127. * Get the customer for the given ID 
  128. * 
  129. * @since 2.1 
  130. * @param int $id the customer ID 
  131. * @param array $fields 
  132. * @return array 
  133. */ 
  134. public function get_customer( $id, $fields = null ) { 
  135. global $wpdb; 
  136.  
  137. $id = $this->validate_request( $id, 'customer', 'read' ); 
  138.  
  139. if ( is_wp_error( $id ) ) { 
  140. return $id; 
  141.  
  142. $customer = new WC_Customer( $id ); 
  143. $last_order = $customer->get_last_order(); 
  144. $customer_data = array( 
  145. 'id' => $customer->get_id(),  
  146. 'created_at' => $this->server->format_datetime( $customer->get_date_created() ? $customer->get_date_created()->getTimestamp() : 0 ), // API gives UTC times. 
  147. 'last_update' => $this->server->format_datetime( $customer->get_date_modified() ? $customer->get_date_modified()->getTimestamp() : 0 ), // API gives UTC times. 
  148. 'email' => $customer->get_email(),  
  149. 'first_name' => $customer->get_first_name(),  
  150. 'last_name' => $customer->get_last_name(),  
  151. 'username' => $customer->get_username(),  
  152. 'role' => $customer->get_role(),  
  153. 'last_order_id' => is_object( $last_order ) ? $last_order->get_id() : null,  
  154. 'last_order_date' => is_object( $last_order ) ? $this->server->format_datetime( $last_order->get_date_created() ? $last_order->get_date_created()->getTimestamp() : 0 ) : null, // API gives UTC times. 
  155. 'orders_count' => $customer->get_order_count(),  
  156. 'total_spent' => wc_format_decimal( $customer->get_total_spent(), 2 ),  
  157. 'avatar_url' => $customer->get_avatar_url(),  
  158. 'billing_address' => array( 
  159. 'first_name' => $customer->get_billing_first_name(),  
  160. 'last_name' => $customer->get_billing_last_name(),  
  161. 'company' => $customer->get_billing_company(),  
  162. 'address_1' => $customer->get_billing_address_1(),  
  163. 'address_2' => $customer->get_billing_address_2(),  
  164. 'city' => $customer->get_billing_city(),  
  165. 'state' => $customer->get_billing_state(),  
  166. 'postcode' => $customer->get_billing_postcode(),  
  167. 'country' => $customer->get_billing_country(),  
  168. 'email' => $customer->get_billing_email(),  
  169. 'phone' => $customer->get_billing_phone(),  
  170. ),  
  171. 'shipping_address' => array( 
  172. 'first_name' => $customer->get_shipping_first_name(),  
  173. 'last_name' => $customer->get_shipping_last_name(),  
  174. 'company' => $customer->get_shipping_company(),  
  175. 'address_1' => $customer->get_shipping_address_1(),  
  176. 'address_2' => $customer->get_shipping_address_2(),  
  177. 'city' => $customer->get_shipping_city(),  
  178. 'state' => $customer->get_shipping_state(),  
  179. 'postcode' => $customer->get_shipping_postcode(),  
  180. 'country' => $customer->get_shipping_country(),  
  181. ),  
  182. ); 
  183.  
  184. return array( 'customer' => apply_filters( 'woocommerce_api_customer_response', $customer_data, $customer, $fields, $this->server ) ); 
  185.  
  186. /** 
  187. * Get the customer for the given email 
  188. * 
  189. * @since 2.1 
  190. * @param string $email the customer email 
  191. * @param array $fields 
  192. * @return array 
  193. */ 
  194. public function get_customer_by_email( $email, $fields = null ) { 
  195. try { 
  196. if ( is_email( $email ) ) { 
  197. $customer = get_user_by( 'email', $email ); 
  198. if ( ! is_object( $customer ) ) { 
  199. throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); 
  200. } else { 
  201. throw new WC_API_Exception( 'woocommerce_api_invalid_customer_email', __( 'Invalid customer email', 'woocommerce' ), 404 ); 
  202.  
  203. return $this->get_customer( $customer->ID, $fields ); 
  204. } catch ( WC_API_Exception $e ) { 
  205. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  206.  
  207. /** 
  208. * Get the total number of customers 
  209. * 
  210. * @since 2.1 
  211. * @param array $filter 
  212. * @return array 
  213. */ 
  214. public function get_customers_count( $filter = array() ) { 
  215. try { 
  216. if ( ! current_user_can( 'list_users' ) ) { 
  217. throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customers_count', __( 'You do not have permission to read the customers count', 'woocommerce' ), 401 ); 
  218.  
  219. $query = $this->query_customers( $filter ); 
  220.  
  221. return array( 'count' => $query->get_total() ); 
  222. } catch ( WC_API_Exception $e ) { 
  223. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  224.  
  225. /** 
  226. * Get customer billing address fields. 
  227. * 
  228. * @since 2.2 
  229. * @return array 
  230. */ 
  231. protected function get_customer_billing_address() { 
  232. $billing_address = apply_filters( 'woocommerce_api_customer_billing_address', array( 
  233. 'first_name',  
  234. 'last_name',  
  235. 'company',  
  236. 'address_1',  
  237. 'address_2',  
  238. 'city',  
  239. 'state',  
  240. 'postcode',  
  241. 'country',  
  242. 'email',  
  243. 'phone',  
  244. ) ); 
  245.  
  246. return $billing_address; 
  247.  
  248. /** 
  249. * Get customer shipping address fields. 
  250. * 
  251. * @since 2.2 
  252. * @return array 
  253. */ 
  254. protected function get_customer_shipping_address() { 
  255. $shipping_address = apply_filters( 'woocommerce_api_customer_shipping_address', array( 
  256. 'first_name',  
  257. 'last_name',  
  258. 'company',  
  259. 'address_1',  
  260. 'address_2',  
  261. 'city',  
  262. 'state',  
  263. 'postcode',  
  264. 'country',  
  265. ) ); 
  266.  
  267. return $shipping_address; 
  268.  
  269. /** 
  270. * Add/Update customer data. 
  271. * 
  272. * @since 2.2 
  273. * @param int $id the customer ID 
  274. * @param array $data 
  275. * @param WC_Customer $customer 
  276. */ 
  277. protected function update_customer_data( $id, $data, $customer ) { 
  278.  
  279. // Customer first name. 
  280. if ( isset( $data['first_name'] ) ) { 
  281. $customer->set_first_name( wc_clean( $data['first_name'] ) ); 
  282.  
  283. // Customer last name. 
  284. if ( isset( $data['last_name'] ) ) { 
  285. $customer->set_last_name( wc_clean( $data['last_name'] ) ); 
  286.  
  287. // Customer billing address. 
  288. if ( isset( $data['billing_address'] ) ) { 
  289. foreach ( $this->get_customer_billing_address() as $field ) { 
  290. if ( isset( $data['billing_address'][ $field ] ) ) { 
  291. if ( is_callable( array( $customer, "set_billing_{$field}" ) ) ) { 
  292. $customer->{"set_billing_{$field}"}( $data['billing_address'][ $field ] ); 
  293. } else { 
  294. $customer->update_meta_data( 'billing_' . $field, wc_clean( $data['billing_address'][ $field ] ) ); 
  295.  
  296. // Customer shipping address. 
  297. if ( isset( $data['shipping_address'] ) ) { 
  298. foreach ( $this->get_customer_shipping_address() as $field ) { 
  299. if ( isset( $data['shipping_address'][ $field ] ) ) { 
  300. if ( is_callable( array( $customer, "set_shipping_{$field}" ) ) ) { 
  301. $customer->{"set_shipping_{$field}"}( $data['shipping_address'][ $field ] ); 
  302. } else { 
  303. $customer->update_meta_data( 'shipping_' . $field, wc_clean( $data['shipping_address'][ $field ] ) ); 
  304.  
  305. do_action( 'woocommerce_api_update_customer_data', $id, $data, $customer ); 
  306.  
  307. /** 
  308. * Create a customer 
  309. * 
  310. * @since 2.2 
  311. * @param array $data 
  312. * @return array 
  313. */ 
  314. public function create_customer( $data ) { 
  315. try { 
  316. if ( ! isset( $data['customer'] ) ) { 
  317. throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to create %1$s', 'woocommerce' ), 'customer' ), 400 ); 
  318.  
  319. $data = $data['customer']; 
  320.  
  321. // Checks with can create new users. 
  322. if ( ! current_user_can( 'create_users' ) ) { 
  323. throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'You do not have permission to create this customer', 'woocommerce' ), 401 ); 
  324.  
  325. $data = apply_filters( 'woocommerce_api_create_customer_data', $data, $this ); 
  326.  
  327. // Checks with the email is missing. 
  328. if ( ! isset( $data['email'] ) ) { 
  329. throw new WC_API_Exception( 'woocommerce_api_missing_customer_email', sprintf( __( 'Missing parameter %s', 'woocommerce' ), 'email' ), 400 ); 
  330.  
  331. // Create customer. 
  332. $customer = new WC_Customer; 
  333. $customer->set_username( ! empty( $data['username'] ) ? $data['username'] : '' ); 
  334. $customer->set_password( ! empty( $data['password'] ) ? $data['password'] : '' ); 
  335. $customer->set_email( $data['email'] ); 
  336. $customer->save(); 
  337.  
  338. if ( ! $customer->get_id() ) { 
  339. throw new WC_API_Exception( 'woocommerce_api_user_cannot_create_customer', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); 
  340.  
  341. // Added customer data. 
  342. $this->update_customer_data( $customer->get_id(), $data, $customer ); 
  343. $customer->save(); 
  344.  
  345. do_action( 'woocommerce_api_create_customer', $customer->get_id(), $data ); 
  346.  
  347. $this->server->send_status( 201 ); 
  348.  
  349. return $this->get_customer( $customer->get_id() ); 
  350. } catch ( Exception $e ) { 
  351. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  352.  
  353. /** 
  354. * Edit a customer 
  355. * 
  356. * @since 2.2 
  357. * @param int $id the customer ID 
  358. * @param array $data 
  359. * @return array 
  360. */ 
  361. public function edit_customer( $id, $data ) { 
  362. try { 
  363. if ( ! isset( $data['customer'] ) ) { 
  364. throw new WC_API_Exception( 'woocommerce_api_missing_customer_data', sprintf( __( 'No %1$s data specified to edit %1$s', 'woocommerce' ), 'customer' ), 400 ); 
  365.  
  366. $data = $data['customer']; 
  367.  
  368. // Validate the customer ID. 
  369. $id = $this->validate_request( $id, 'customer', 'edit' ); 
  370.  
  371. // Return the validate error. 
  372. if ( is_wp_error( $id ) ) { 
  373. throw new WC_API_Exception( $id->get_error_code(), $id->get_error_message(), 400 ); 
  374.  
  375. $data = apply_filters( 'woocommerce_api_edit_customer_data', $data, $this ); 
  376.  
  377. $customer = new WC_Customer( $id ); 
  378.  
  379. // Customer email. 
  380. if ( isset( $data['email'] ) ) { 
  381. $customer->set_email( $data['email'] ); 
  382.  
  383. // Customer password. 
  384. if ( isset( $data['password'] ) ) { 
  385. $customer->set_password( $data['password'] ); 
  386.  
  387. // Update customer data. 
  388. $this->update_customer_data( $customer->get_id(), $data, $customer ); 
  389.  
  390. $customer->save(); 
  391.  
  392. do_action( 'woocommerce_api_edit_customer', $customer->get_id(), $data ); 
  393.  
  394. return $this->get_customer( $customer->get_id() ); 
  395. } catch ( Exception $e ) { 
  396. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  397.  
  398. /** 
  399. * Delete a customer 
  400. * 
  401. * @since 2.2 
  402. * @param int $id the customer ID 
  403. * @return array 
  404. */ 
  405. public function delete_customer( $id ) { 
  406.  
  407. // Validate the customer ID. 
  408. $id = $this->validate_request( $id, 'customer', 'delete' ); 
  409.  
  410. // Return the validate error. 
  411. if ( is_wp_error( $id ) ) { 
  412. return $id; 
  413.  
  414. do_action( 'woocommerce_api_delete_customer', $id, $this ); 
  415.  
  416. return $this->delete( $id, 'customer' ); 
  417.  
  418. /** 
  419. * Get the orders for a customer 
  420. * 
  421. * @since 2.1 
  422. * @param int $id the customer ID 
  423. * @param string $fields fields to include in response 
  424. * @param array $filter filters 
  425. * @return array 
  426. */ 
  427. public function get_customer_orders( $id, $fields = null, $filter = array() ) { 
  428. $id = $this->validate_request( $id, 'customer', 'read' ); 
  429.  
  430. if ( is_wp_error( $id ) ) { 
  431. return $id; 
  432.  
  433. $filter['customer_id'] = $id; 
  434. $orders = WC()->api->WC_API_Orders->get_orders( $fields, $filter, null, -1 ); 
  435.  
  436. return $orders; 
  437.  
  438. /** 
  439. * Get the available downloads for a customer 
  440. * 
  441. * @since 2.2 
  442. * @param int $id the customer ID 
  443. * @param string $fields fields to include in response 
  444. * @return array 
  445. */ 
  446. public function get_customer_downloads( $id, $fields = null ) { 
  447. $id = $this->validate_request( $id, 'customer', 'read' ); 
  448.  
  449. if ( is_wp_error( $id ) ) { 
  450. return $id; 
  451.  
  452. $downloads = array(); 
  453. $_downloads = wc_get_customer_available_downloads( $id ); 
  454.  
  455. foreach ( $_downloads as $key => $download ) { 
  456. $downloads[] = array( 
  457. 'download_url' => $download['download_url'],  
  458. 'download_id' => $download['download_id'],  
  459. 'product_id' => $download['product_id'],  
  460. 'download_name' => $download['download_name'],  
  461. 'order_id' => $download['order_id'],  
  462. 'order_key' => $download['order_key'],  
  463. 'downloads_remaining' => $download['downloads_remaining'],  
  464. 'access_expires' => $download['access_expires'] ? $this->server->format_datetime( $download['access_expires'] ) : null,  
  465. 'file' => $download['file'],  
  466. ); 
  467.  
  468. return array( 'downloads' => apply_filters( 'woocommerce_api_customer_downloads_response', $downloads, $id, $fields, $this->server ) ); 
  469.  
  470. /** 
  471. * Helper method to get customer user objects 
  472. * 
  473. * Note that WP_User_Query does not have built-in pagination so limit & offset are used to provide limited 
  474. * pagination support 
  475. * 
  476. * The filter for role can only be a single role in a string. 
  477. * 
  478. * @since 2.3 
  479. * @param array $args request arguments for filtering query 
  480. * @return WP_User_Query 
  481. */ 
  482. private function query_customers( $args = array() ) { 
  483.  
  484. // default users per page 
  485. $users_per_page = get_option( 'posts_per_page' ); 
  486.  
  487. // Set base query arguments 
  488. $query_args = array( 
  489. 'fields' => 'ID',  
  490. 'role' => 'customer',  
  491. 'orderby' => 'registered',  
  492. 'number' => $users_per_page,  
  493. ); 
  494.  
  495. // Custom Role 
  496. if ( ! empty( $args['role'] ) ) { 
  497. $query_args['role'] = $args['role']; 
  498.  
  499. // Show users on all roles 
  500. if ( 'all' === $query_args['role'] ) { 
  501. unset( $query_args['role'] ); 
  502.  
  503. // Search 
  504. if ( ! empty( $args['q'] ) ) { 
  505. $query_args['search'] = $args['q']; 
  506.  
  507. // Limit number of users returned 
  508. if ( ! empty( $args['limit'] ) ) { 
  509. if ( -1 == $args['limit'] ) { 
  510. unset( $query_args['number'] ); 
  511. } else { 
  512. $query_args['number'] = absint( $args['limit'] ); 
  513. $users_per_page = absint( $args['limit'] ); 
  514. } else { 
  515. $args['limit'] = $query_args['number']; 
  516.  
  517. // Page 
  518. $page = ( isset( $args['page'] ) ) ? absint( $args['page'] ) : 1; 
  519.  
  520. // Offset 
  521. if ( ! empty( $args['offset'] ) ) { 
  522. $query_args['offset'] = absint( $args['offset'] ); 
  523. } else { 
  524. $query_args['offset'] = $users_per_page * ( $page - 1 ); 
  525.  
  526. // Created date 
  527. if ( ! empty( $args['created_at_min'] ) ) { 
  528. $this->created_at_min = $this->server->parse_datetime( $args['created_at_min'] ); 
  529.  
  530. if ( ! empty( $args['created_at_max'] ) ) { 
  531. $this->created_at_max = $this->server->parse_datetime( $args['created_at_max'] ); 
  532.  
  533. // Order (ASC or DESC, ASC by default) 
  534. if ( ! empty( $args['order'] ) ) { 
  535. $query_args['order'] = $args['order']; 
  536.  
  537. // Orderby 
  538. if ( ! empty( $args['orderby'] ) ) { 
  539. $query_args['orderby'] = $args['orderby']; 
  540.  
  541. // Allow sorting by meta value 
  542. if ( ! empty( $args['orderby_meta_key'] ) ) { 
  543. $query_args['meta_key'] = $args['orderby_meta_key']; 
  544.  
  545. $query = new WP_User_Query( $query_args ); 
  546.  
  547. // Helper members for pagination headers 
  548. $query->total_pages = ( -1 == $args['limit'] ) ? 1 : ceil( $query->get_total() / $users_per_page ); 
  549. $query->page = $page; 
  550.  
  551. return $query; 
  552.  
  553. /** 
  554. * Add customer data to orders 
  555. * 
  556. * @since 2.1 
  557. * @param $order_data 
  558. * @param $order 
  559. * @return array 
  560. */ 
  561. public function add_customer_data( $order_data, $order ) { 
  562.  
  563. if ( 0 == $order->get_user_id() ) { 
  564.  
  565. // add customer data from order 
  566. $order_data['customer'] = array( 
  567. 'id' => 0,  
  568. 'email' => $order->get_billing_email(),  
  569. 'first_name' => $order->get_billing_first_name(),  
  570. 'last_name' => $order->get_billing_last_name(),  
  571. 'billing_address' => array( 
  572. 'first_name' => $order->get_billing_first_name(),  
  573. 'last_name' => $order->get_billing_last_name(),  
  574. 'company' => $order->get_billing_company(),  
  575. 'address_1' => $order->get_billing_address_1(),  
  576. 'address_2' => $order->get_billing_address_2(),  
  577. 'city' => $order->get_billing_city(),  
  578. 'state' => $order->get_billing_state(),  
  579. 'postcode' => $order->get_billing_postcode(),  
  580. 'country' => $order->get_billing_country(),  
  581. 'email' => $order->get_billing_email(),  
  582. 'phone' => $order->get_billing_phone(),  
  583. ),  
  584. 'shipping_address' => array( 
  585. 'first_name' => $order->get_shipping_first_name(),  
  586. 'last_name' => $order->get_shipping_last_name(),  
  587. 'company' => $order->get_shipping_company(),  
  588. 'address_1' => $order->get_shipping_address_1(),  
  589. 'address_2' => $order->get_shipping_address_2(),  
  590. 'city' => $order->get_shipping_city(),  
  591. 'state' => $order->get_shipping_state(),  
  592. 'postcode' => $order->get_shipping_postcode(),  
  593. 'country' => $order->get_shipping_country(),  
  594. ),  
  595. ); 
  596.  
  597. } else { 
  598.  
  599. $order_data['customer'] = current( $this->get_customer( $order->get_user_id() ) ); 
  600.  
  601. return $order_data; 
  602.  
  603. /** 
  604. * Modify the WP_User_Query to support filtering on the date the customer was created 
  605. * 
  606. * @since 2.1 
  607. * @param WP_User_Query $query 
  608. */ 
  609. public function modify_user_query( $query ) { 
  610.  
  611. if ( $this->created_at_min ) { 
  612. $query->query_where .= sprintf( " AND user_registered >= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_min ) ); 
  613.  
  614. if ( $this->created_at_max ) { 
  615. $query->query_where .= sprintf( " AND user_registered <= STR_TO_DATE( '%s', '%%Y-%%m-%%d %%H:%%i:%%s' )", esc_sql( $this->created_at_max ) ); 
  616.  
  617. /** 
  618. * Validate the request by checking: 
  619. * 
  620. * 1) the ID is a valid integer 
  621. * 2) the ID returns a valid WP_User 
  622. * 3) the current user has the proper permissions 
  623. * 
  624. * @since 2.1 
  625. * @see WC_API_Resource::validate_request() 
  626. * @param integer $id the customer ID 
  627. * @param string $type the request type, unused because this method overrides the parent class 
  628. * @param string $context the context of the request, either `read`, `edit` or `delete` 
  629. * @return int|WP_Error valid user ID or WP_Error if any of the checks fails 
  630. */ 
  631. protected function validate_request( $id, $type, $context ) { 
  632.  
  633. try { 
  634. $id = absint( $id ); 
  635.  
  636. // validate ID 
  637. if ( empty( $id ) ) { 
  638. throw new WC_API_Exception( 'woocommerce_api_invalid_customer_id', __( 'Invalid customer ID', 'woocommerce' ), 404 ); 
  639.  
  640. // non-existent IDs return a valid WP_User object with the user ID = 0 
  641. $customer = new WP_User( $id ); 
  642.  
  643. if ( 0 === $customer->ID ) { 
  644. throw new WC_API_Exception( 'woocommerce_api_invalid_customer', __( 'Invalid customer', 'woocommerce' ), 404 ); 
  645.  
  646. // validate permissions 
  647. switch ( $context ) { 
  648.  
  649. case 'read': 
  650. if ( ! current_user_can( 'list_users' ) ) { 
  651. throw new WC_API_Exception( 'woocommerce_api_user_cannot_read_customer', __( 'You do not have permission to read this customer', 'woocommerce' ), 401 ); 
  652. break; 
  653.  
  654. case 'edit': 
  655. if ( ! current_user_can( 'edit_users' ) ) { 
  656. throw new WC_API_Exception( 'woocommerce_api_user_cannot_edit_customer', __( 'You do not have permission to edit this customer', 'woocommerce' ), 401 ); 
  657. break; 
  658.  
  659. case 'delete': 
  660. if ( ! current_user_can( 'delete_users' ) ) { 
  661. throw new WC_API_Exception( 'woocommerce_api_user_cannot_delete_customer', __( 'You do not have permission to delete this customer', 'woocommerce' ), 401 ); 
  662. break; 
  663.  
  664. return $id; 
  665. } catch ( WC_API_Exception $e ) { 
  666. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
  667.  
  668. /** 
  669. * Check if the current user can read users 
  670. * 
  671. * @since 2.1 
  672. * @see WC_API_Resource::is_readable() 
  673. * @param int|WP_Post $post unused 
  674. * @return bool true if the current user can read users, false otherwise 
  675. */ 
  676. protected function is_readable( $post ) { 
  677. return current_user_can( 'list_users' ); 
  678.  
  679. /** 
  680. * Bulk update or insert customers 
  681. * Accepts an array with customers in the formats supported by 
  682. * WC_API_Customers->create_customer() and WC_API_Customers->edit_customer() 
  683. * 
  684. * @since 2.4.0 
  685. * @param array $data 
  686. * @return array 
  687. */ 
  688. public function bulk( $data ) { 
  689.  
  690. try { 
  691. if ( ! isset( $data['customers'] ) ) { 
  692. throw new WC_API_Exception( 'woocommerce_api_missing_customers_data', sprintf( __( 'No %1$s data specified to create/edit %1$s', 'woocommerce' ), 'customers' ), 400 ); 
  693.  
  694. $data = $data['customers']; 
  695. $limit = apply_filters( 'woocommerce_api_bulk_limit', 100, 'customers' ); 
  696.  
  697. // Limit bulk operation 
  698. if ( count( $data ) > $limit ) { 
  699. throw new WC_API_Exception( 'woocommerce_api_customers_request_entity_too_large', sprintf( __( 'Unable to accept more than %s items for this request.', 'woocommerce' ), $limit ), 413 ); 
  700.  
  701. $customers = array(); 
  702.  
  703. foreach ( $data as $_customer ) { 
  704. $customer_id = 0; 
  705.  
  706. // Try to get the customer ID 
  707. if ( isset( $_customer['id'] ) ) { 
  708. $customer_id = intval( $_customer['id'] ); 
  709.  
  710. if ( $customer_id ) { 
  711.  
  712. // Customer exists / edit customer 
  713. $edit = $this->edit_customer( $customer_id, array( 'customer' => $_customer ) ); 
  714.  
  715. if ( is_wp_error( $edit ) ) { 
  716. $customers[] = array( 
  717. 'id' => $customer_id,  
  718. 'error' => array( 'code' => $edit->get_error_code(), 'message' => $edit->get_error_message() ),  
  719. ); 
  720. } else { 
  721. $customers[] = $edit['customer']; 
  722. } else { 
  723.  
  724. // Customer don't exists / create customer 
  725. $new = $this->create_customer( array( 'customer' => $_customer ) ); 
  726.  
  727. if ( is_wp_error( $new ) ) { 
  728. $customers[] = array( 
  729. 'id' => $customer_id,  
  730. 'error' => array( 'code' => $new->get_error_code(), 'message' => $new->get_error_message() ),  
  731. ); 
  732. } else { 
  733. $customers[] = $new['customer']; 
  734.  
  735. return array( 'customers' => apply_filters( 'woocommerce_api_customers_bulk_response', $customers, $this ) ); 
  736. } catch ( WC_API_Exception $e ) { 
  737. return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) ); 
.