PageRenderTime 101ms CodeModel.GetById 19ms RepoModel.GetById 2ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/api/class-wc-api-customers.php

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