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