WC_Customer_Data_Store

WC Customer Data Store.

Defined (1)

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

/includes/data-stores/class-wc-customer-data-store.php  
  1. class WC_Customer_Data_Store extends WC_Data_Store_WP implements WC_Customer_Data_Store_Interface, WC_Object_Data_Store_Interface { 
  2.  
  3. /** 
  4. * Data stored in meta keys, but not considered "meta". 
  5. * @since 3.0.0 
  6. * @var array 
  7. */ 
  8. protected $internal_meta_keys = array( 
  9. 'locale',  
  10. 'billing_postcode',  
  11. 'billing_city',  
  12. 'billing_address_1',  
  13. 'billing_address_2',  
  14. 'billing_state',  
  15. 'billing_country',  
  16. 'shipping_postcode',  
  17. 'shipping_city',  
  18. 'shipping_address_1',  
  19. 'shipping_address_2',  
  20. 'shipping_state',  
  21. 'shipping_country',  
  22. 'paying_customer',  
  23. 'last_update',  
  24. 'first_name',  
  25. 'last_name',  
  26. 'show_admin_bar_front',  
  27. 'use_ssl',  
  28. 'admin_color',  
  29. 'rich_editing',  
  30. 'comment_shortcuts',  
  31. 'dismissed_wp_pointers',  
  32. 'show_welcome_panel',  
  33. '_woocommerce_persistent_cart',  
  34. 'session_tokens',  
  35. 'nickname',  
  36. 'description',  
  37. 'billing_first_name',  
  38. 'billing_last_name',  
  39. 'billing_company',  
  40. 'billing_phone',  
  41. 'billing_email',  
  42. 'shipping_first_name',  
  43. 'shipping_last_name',  
  44. 'shipping_company',  
  45. 'wptests_capabilities',  
  46. 'wptests_user_level',  
  47. '_order_count',  
  48. '_money_spent',  
  49. ); 
  50.  
  51. /** 
  52. * Internal meta type used to store user data. 
  53. * @var string 
  54. */ 
  55. protected $meta_type = 'user'; 
  56.  
  57. /** 
  58. * Callback to remove unwanted meta data. 
  59. * @param object $meta 
  60. * @return bool 
  61. */ 
  62. protected function exclude_internal_meta_keys( $meta ) { 
  63. global $wpdb; 
  64.  
  65. $table_prefix = $wpdb->prefix ? $wpdb->prefix : 'wp_'; 
  66.  
  67. return ! in_array( $meta->meta_key, $this->internal_meta_keys ) 
  68. && 0 !== strpos( $meta->meta_key, 'closedpostboxes_' ) 
  69. && 0 !== strpos( $meta->meta_key, 'metaboxhidden_' ) 
  70. && 0 !== strpos( $meta->meta_key, 'manageedit-' ) 
  71. && ! strstr( $meta->meta_key, $table_prefix ) 
  72. && 0 !== stripos( $meta->meta_key, 'wp_' ); 
  73.  
  74. /** 
  75. * Method to create a new customer in the database. 
  76. * @since 3.0.0 
  77. * @param WC_Customer 
  78. */ 
  79. public function create( &$customer ) { 
  80. $id = wc_create_new_customer( $customer->get_email(), $customer->get_username(), $customer->get_password() ); 
  81.  
  82. if ( is_wp_error( $id ) ) { 
  83. throw new WC_Data_Exception( $id->get_error_code(), $id->get_error_message() ); 
  84.  
  85. $customer->set_id( $id ); 
  86. $this->update_user_meta( $customer ); 
  87.  
  88. // Prevent wp_update_user calls in the same request and customer trigger the 'Notice of Password Changed' email 
  89. $customer->set_password( '' ); 
  90.  
  91. wp_update_user( apply_filters( 'woocommerce_update_customer_args', array( 
  92. 'ID' => $customer->get_id(),  
  93. 'role' => $customer->get_role(),  
  94. 'display_name' => $customer->get_first_name() . ' ' . $customer->get_last_name(),  
  95. ), $customer ) ); 
  96. $wp_user = new WP_User( $customer->get_id() ); 
  97. $customer->set_date_created( $wp_user->user_registered ); 
  98. $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); 
  99. $customer->save_meta_data(); 
  100. $customer->apply_changes(); 
  101. do_action( 'woocommerce_new_customer', $customer->get_id() ); 
  102.  
  103. /** 
  104. * Method to read a customer object. 
  105. * @since 3.0.0 
  106. * @param WC_Customer 
  107. * @throws Exception 
  108. */ 
  109. public function read( &$customer ) { 
  110. global $wpdb; 
  111.  
  112. // User object is required. 
  113. if ( ! $customer->get_id() || ! ( $user_object = get_user_by( 'id', $customer->get_id() ) ) || empty( $user_object->ID ) ) { 
  114. throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); 
  115.  
  116. // Only users on this site should be read. 
  117. if ( is_multisite() && ! is_user_member_of_blog( $customer->get_id() ) ) { 
  118. throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); 
  119.  
  120. $customer_id = $customer->get_id(); 
  121. // Load meta but exclude deprecated props. 
  122. $user_meta = array_diff_key( array_map( 'wc_flatten_meta_callback', get_user_meta( $customer_id ) ), array_flip( array( 'country', 'state', 'postcode', 'city', 'address', 'address_2', 'default', 'location' ) ) ); 
  123. $customer->set_props( $user_meta ); 
  124. $customer->set_props( array( 
  125. 'is_paying_customer' => get_user_meta( $customer_id, 'paying_customer', true ),  
  126. 'email' => $user_object->user_email,  
  127. 'username' => $user_object->user_login,  
  128. 'date_created' => $user_object->user_registered, // Mysql string in local format. 
  129. 'date_modified' => get_user_meta( $customer_id, 'last_update', true ),  
  130. 'role' => ! empty( $user_object->roles[0] ) ? $user_object->roles[0] : 'customer',  
  131. ) ); 
  132. $customer->read_meta_data(); 
  133. $customer->set_object_read( true ); 
  134. do_action( 'woocommerce_customer_loaded', $customer ); 
  135.  
  136. /** 
  137. * Updates a customer in the database. 
  138. * @since 3.0.0 
  139. * @param WC_Customer 
  140. */ 
  141. public function update( &$customer ) { 
  142. wp_update_user( apply_filters( 'woocommerce_update_customer_args', array( 
  143. 'ID' => $customer->get_id(),  
  144. 'user_email' => $customer->get_email(),  
  145. 'display_name' => $customer->get_first_name() . ' ' . $customer->get_last_name(),  
  146. ), $customer ) ); 
  147. // Only update password if a new one was set with set_password. 
  148. if ( $customer->get_password() ) { 
  149. wp_update_user( array( 'ID' => $customer->get_id(), 'user_pass' => $customer->get_password() ) ); 
  150. $customer->set_password( '' ); 
  151. $this->update_user_meta( $customer ); 
  152. $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); 
  153. $customer->save_meta_data(); 
  154. $customer->apply_changes(); 
  155. do_action( 'woocommerce_update_customer', $customer->get_id() ); 
  156.  
  157. /** 
  158. * Deletes a customer from the database. 
  159. * @since 3.0.0 
  160. * @param WC_Customer 
  161. * @param array $args Array of args to pass to the delete method. 
  162. */ 
  163. public function delete( &$customer, $args = array() ) { 
  164. if ( ! $customer->get_id() ) { 
  165. return; 
  166. $args = wp_parse_args( $args, array( 
  167. 'reassign' => 0,  
  168. ) ); 
  169.  
  170. $id = $customer->get_id(); 
  171. wp_delete_user( $id, $args['reassign'] ); 
  172.  
  173. do_action( 'woocommerce_delete_customer', $id ); 
  174.  
  175. /** 
  176. * Helper method that updates all the meta for a customer. Used for update & create. 
  177. * @since 3.0.0 
  178. * @param WC_Customer 
  179. */ 
  180. private function update_user_meta( $customer ) { 
  181. $updated_props = array(); 
  182. $changed_props = $customer->get_changes(); 
  183.  
  184. $meta_key_to_props = array( 
  185. 'paying_customer' => 'is_paying_customer',  
  186. 'first_name' => 'first_name',  
  187. 'last_name' => 'last_name',  
  188. ); 
  189.  
  190. foreach ( $meta_key_to_props as $meta_key => $prop ) { 
  191. if ( ! array_key_exists( $prop, $changed_props ) ) { 
  192. continue; 
  193.  
  194. if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { 
  195. $updated_props[] = $prop; 
  196.  
  197. $billing_address_props = array( 
  198. 'billing_first_name' => 'billing_first_name',  
  199. 'billing_last_name' => 'billing_last_name',  
  200. 'billing_company' => 'billing_company',  
  201. 'billing_address_1' => 'billing_address_1',  
  202. 'billing_address_2' => 'billing_address_2',  
  203. 'billing_city' => 'billing_city',  
  204. 'billing_state' => 'billing_state',  
  205. 'billing_postcode' => 'billing_postcode',  
  206. 'billing_country' => 'billing_country',  
  207. 'billing_email' => 'billing_email',  
  208. 'billing_phone' => 'billing_phone',  
  209. ); 
  210.  
  211. foreach ( $billing_address_props as $meta_key => $prop ) { 
  212. $prop_key = substr( $prop, 8 ); 
  213. if ( ! isset( $changed_props['billing'] ) || ! array_key_exists( $prop_key, $changed_props['billing'] ) ) { 
  214. continue; 
  215. if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { 
  216. $updated_props[] = $prop; 
  217.  
  218. $shipping_address_props = array( 
  219. 'shipping_first_name' => 'shipping_first_name',  
  220. 'shipping_last_name' => 'shipping_last_name',  
  221. 'shipping_company' => 'shipping_company',  
  222. 'shipping_address_1' => 'shipping_address_1',  
  223. 'shipping_address_2' => 'shipping_address_2',  
  224. 'shipping_city' => 'shipping_city',  
  225. 'shipping_state' => 'shipping_state',  
  226. 'shipping_postcode' => 'shipping_postcode',  
  227. 'shipping_country' => 'shipping_country',  
  228. ); 
  229.  
  230. foreach ( $shipping_address_props as $meta_key => $prop ) { 
  231. $prop_key = substr( $prop, 9 ); 
  232. if ( ! isset( $changed_props['shipping'] ) || ! array_key_exists( $prop_key, $changed_props['shipping'] ) ) { 
  233. continue; 
  234. if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { 
  235. $updated_props[] = $prop; 
  236.  
  237. do_action( 'woocommerce_customer_object_updated_props', $customer, $updated_props ); 
  238.  
  239. /** 
  240. * Gets the customers last order. 
  241. * @since 3.0.0 
  242. * @param WC_Customer 
  243. * @return WC_Order|false 
  244. */ 
  245. public function get_last_order( &$customer ) { 
  246. global $wpdb; 
  247.  
  248. $last_order = $wpdb->get_var( "SELECT posts.ID 
  249. FROM $wpdb->posts AS posts 
  250. LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id 
  251. WHERE meta.meta_key = '_customer_user' 
  252. AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' 
  253. AND posts.post_type = 'shop_order' 
  254. AND posts.post_status IN ( '" . implode( "', '", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) 
  255. ORDER BY posts.ID DESC 
  256. " ); 
  257.  
  258. if ( $last_order ) { 
  259. return wc_get_order( absint( $last_order ) ); 
  260. } else { 
  261. return false; 
  262.  
  263. /** 
  264. * Return the number of orders this customer has. 
  265. * @since 3.0.0 
  266. * @param WC_Customer 
  267. * @return integer 
  268. */ 
  269. public function get_order_count( &$customer ) { 
  270. $count = get_user_meta( $customer->get_id(), '_order_count', true ); 
  271.  
  272. if ( '' === $count ) { 
  273. global $wpdb; 
  274.  
  275. $count = $wpdb->get_var( "SELECT COUNT(*) 
  276. FROM $wpdb->posts as posts 
  277. LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id 
  278. WHERE meta.meta_key = '_customer_user' 
  279. AND posts.post_type = 'shop_order' 
  280. AND posts.post_status IN ( '" . implode( "', '", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) 
  281. AND meta_value = '" . esc_sql( $customer->get_id() ) . "' 
  282. " ); 
  283. update_user_meta( $customer->get_id(), '_order_count', $count ); 
  284.  
  285. return absint( $count ); 
  286.  
  287. /** 
  288. * Return how much money this customer has spent. 
  289. * @since 3.0.0 
  290. * @param WC_Customer 
  291. * @return float 
  292. */ 
  293. public function get_total_spent( &$customer ) { 
  294. $spent = get_user_meta( $customer->get_id(), '_money_spent', true ); 
  295.  
  296. if ( '' === $spent ) { 
  297. global $wpdb; 
  298.  
  299. $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); 
  300. $spent = $wpdb->get_var( "SELECT SUM(meta2.meta_value) 
  301. FROM $wpdb->posts as posts 
  302. LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id 
  303. LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id 
  304. WHERE meta.meta_key = '_customer_user' 
  305. AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' 
  306. AND posts.post_type = 'shop_order' 
  307. AND posts.post_status IN ( 'wc-" . implode( "', 'wc-", $statuses ) . "' ) 
  308. AND meta2.meta_key = '_order_total' 
  309. " ); 
  310.  
  311. if ( ! $spent ) { 
  312. $spent = 0; 
  313. update_user_meta( $customer->get_id(), '_money_spent', $spent ); 
  314.  
  315. return wc_format_decimal( $spent, 2 ); 
  316.  
  317. /** 
  318. * Search customers and return customer IDs. 
  319. * @param string $term 
  320. * @return array 
  321. */ 
  322. public function search_customers( $term ) { 
  323. $query = new WP_User_Query( array( 
  324. 'search' => '*' . esc_attr( $term ) . '*',  
  325. 'search_columns' => array( 'user_login', 'user_url', 'user_email', 'user_nicename', 'display_name' ),  
  326. 'fields' => 'ID',  
  327. ) ); 
  328.  
  329. $query2 = new WP_User_Query( array( 
  330. 'fields' => 'ID',  
  331. 'meta_query' => array( 
  332. 'relation' => 'OR',  
  333. array( 
  334. 'key' => 'first_name',  
  335. 'value' => $term,  
  336. 'compare' => 'LIKE',  
  337. ),  
  338. array( 
  339. 'key' => 'last_name',  
  340. 'value' => $term,  
  341. 'compare' => 'LIKE',  
  342. ),  
  343. ),  
  344. ) ); 
  345. return wp_parse_id_list( array_merge( $query->get_results(), $query2->get_results() ) );