WC_API_Customers

The WooCommerce WC API Customers class.

Defined (3)

The class is defined in the following location(s).

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