From 00ed627b299ee9743a33a12d12f201fdd128dc12 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 14 Nov 2016 18:18:08 +0000 Subject: [PATCH 1/4] Data stores --- includes/abstracts/abstract-wc-data.php | 8 +- .../class-wc-rest-customers-controller.php | 2 +- includes/class-wc-cache-helper.php | 3 +- includes/class-wc-customer.php | 1409 ++++++++--------- includes/class-wc-data-store.php | 4 +- .../class-wc-customer-data-store-session.php | 175 ++ .../class-wc-customer-data-store.php | 242 +++ .../wc-customer-data-store-interface.php | 48 + includes/legacy/class-wc-legacy-customer.php | 7 + .../shortcodes/class-wc-shortcode-cart.php | 3 +- includes/wc-formatting-functions.php | 11 + .../helpers/class-wc-helper-customer.php | 3 +- tests/unit-tests/customer/crud.php | 32 +- woocommerce.php | 6 +- 14 files changed, 1169 insertions(+), 784 deletions(-) create mode 100644 includes/data-stores/class-wc-customer-data-store-session.php create mode 100644 includes/data-stores/class-wc-customer-data-store.php create mode 100644 includes/data-stores/interfaces/wc-customer-data-store-interface.php diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index 66784922d8a..d8df87a0a6e 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -110,12 +110,18 @@ abstract class WC_Data { } /** - * Updates object data in the database. + * Delete an object, set the ID to 0, and return result. + * + * @param bool $force_delete + * @return bool result */ public function delete( $force_delete = false ) { if ( $this->data_store ) { $this->data_store->delete( $this, $force_delete ); + $this->set_id( 0 ); + return true; } + return false; } /** diff --git a/includes/api/class-wc-rest-customers-controller.php b/includes/api/class-wc-rest-customers-controller.php index b6464d66143..41ec3f612b9 100644 --- a/includes/api/class-wc-rest-customers-controller.php +++ b/includes/api/class-wc-rest-customers-controller.php @@ -311,7 +311,7 @@ class WC_REST_Customers_Controller extends WC_REST_Controller { $customer->set_username( $request['username'] ); $customer->set_password( $request['password'] ); $customer->set_email( $request['email'] ); - $customer->create(); + $customer->save(); if ( ! $customer->get_id() ) { throw new WC_REST_Exception( 'woocommerce_rest_cannot_create', __( 'This resource cannot be created.', 'woocommerce' ), 400 ); diff --git a/includes/class-wc-cache-helper.php b/includes/class-wc-cache-helper.php index 150fdd22f98..ef9a513d17a 100644 --- a/includes/class-wc-cache-helper.php +++ b/includes/class-wc-cache-helper.php @@ -55,8 +55,7 @@ class WC_Cache_Helper { * @return string */ public static function geolocation_ajax_get_location_hash() { - $customer = new WC_Customer(); - $customer->load_session(); + $customer = new WC_Customer( 0, true ); $location = array(); $location['country'] = $customer->get_billing_country(); $location['state'] = $customer->get_billing_state(); diff --git a/includes/class-wc-customer.php b/includes/class-wc-customer.php index ed513b92e71..e894d2c5aee 100644 --- a/includes/class-wc-customer.php +++ b/includes/class-wc-customer.php @@ -18,6 +18,7 @@ class WC_Customer extends WC_Legacy_Customer { /** * Stores customer data. + * * @var array */ protected $data = array( @@ -56,38 +57,8 @@ class WC_Customer extends WC_Legacy_Customer { ); /** - * Keys which are also stored in a session (so we can make sure they get updated...) - * @var array - */ - protected $session_keys = array( - 'billing_postcode', - 'billing_city', - 'billing_address_1', - 'billing_address', - 'billing_address_2', - 'billing_state', - 'billing_country', - 'shipping_postcode', - 'shipping_city', - 'shipping_address_1', - 'shipping_address', - 'shipping_address_2', - 'shipping_state', - 'shipping_country', - 'is_vat_exempt', - 'calculated_shipping', - 'billing_first_name', - 'billing_last_name', - 'billing_company', - 'billing_phone', - 'billing_email', - 'shipping_first_name', - 'shipping_last_name', - 'shipping_company', - ); - - /** - * Data stored in meta keys, but not considered "meta" + * Data stored in meta keys, but not considered "meta". + * * @since 2.7.0 * @var array */ @@ -134,30 +105,28 @@ class WC_Customer extends WC_Legacy_Customer { /** * Internal meta type used to store user data. + * * @var string */ protected $meta_type = 'user'; - /** - * If this is the customer session, this is true. When true, guest accounts will not be saved to the DB. - * @var boolean - */ - protected $is_session = false; - /** * Stores a password if this needs to be changed. Write-only and hidden from _data. + * * @var string */ protected $password = ''; /** * Stores if user is VAT exempt for this session. + * * @var string */ protected $is_vat_exempt = false; /** * Stores if user has calculated shipping in this session. + * * @var string */ protected $calculated_shipping = false; @@ -168,146 +137,69 @@ class WC_Customer extends WC_Legacy_Customer { * If $customer is 'new', you can build a new WC_Customer object. If it's empty, some * data will be pulled from the session for the current user/customer. * - * @param int $customer_id Customer ID + * @param WC_Customer|int $data Customer ID or data. * @param bool $is_session True if this is the customer session + * @throws Exception if customer cannot be read/found and $data is set. */ - public function __construct( $customer_id = 0, $is_session = false ) { - if ( $customer_id > 0 ) { - $this->read( $customer_id ); - } - if ( $is_session ) { - $this->is_session = true; - $this->load_session(); - add_action( 'shutdown', array( $this, 'save_to_session' ), 10 ); - } - } + public function __construct( $data = 0, $is_session = false ) { + parent::__construct( $data ); - /** - * Loads a WC session into the customer class. - */ - public function load_session() { - $data = (array) WC()->session->get( 'customer' ); - if ( ! empty( $data ) ) { - foreach ( $this->session_keys as $session_key ) { - $function_key = $session_key; - if ( 'billing_' === substr( $session_key, 0, 8 ) ) { - $session_key = str_replace( 'billing_', '', $session_key ); - } - if ( ! empty( $data[ $session_key ] ) && is_callable( array( $this, "set_{$function_key}" ) ) ) { - $this->{"set_{$function_key}"}( $data[ $session_key ] ); - } - } - } - $this->load_defaults(); - } - - /** - * Load default values if props are unset. - */ - protected function load_defaults() { - $default = wc_get_customer_default_location(); - - // Set some defaults if some of our values are still not set. - if ( ! $this->get_billing_country() ) { - $this->set_billing_country( $default['country'] ); + if ( $data instanceof WC_Customer ) { + $this->set_id( absint( $data->get_id() ) ); + } elseif ( is_numeric( $data ) ) { + $this->set_id( $data ); } - if ( ! $this->get_shipping_country() ) { - $this->set_shipping_country( $this->get_billing_country() ); - } + $this->data_store = WC_Data_Store::load( 'customer' ); - if ( ! $this->get_billing_state() ) { - $this->set_billing_state( $default['state'] ); - } - - if ( ! $this->get_shipping_state() ) { - $this->set_shipping_state( $this->get_billing_state() ); - } - } - - /** - * Gets the customers last order. - * @return WC_Order|false - */ - public function get_last_order() { - global $wpdb; - - $last_order = $wpdb->get_var( "SELECT posts.ID - FROM $wpdb->posts AS posts - LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id - WHERE meta.meta_key = '_customer_user' - AND meta.meta_value = '" . esc_sql( $this->get_id() ) . "' - AND posts.post_type = 'shop_order' - AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) - ORDER BY posts.ID DESC - " ); - - if ( $last_order ) { - return wc_get_order( absint( $last_order ) ); + // If we have an ID, load the user from the DB. + if ( $this->get_id() ) { + $this->data_store->read( $this ); } else { - return false; + $this->set_object_read( true ); + } + + // If this is a session, set or change the data store to sessions. Changes do not persist in the database. + if ( $is_session ) { + $this->data_store = WC_Data_Store::load( 'customer-session' ); + $this->data_store->read( $this ); } } /** - * Return the number of orders this customer has. - * @since 2.7.0 - * @return integer + * Callback to remove unwanted meta data. + * + * @param object $meta + * @return bool */ - public function get_order_count() { - $count = get_user_meta( $this->get_id(), '_order_count', true ); - - if ( '' === $count ) { - global $wpdb; - - $count = $wpdb->get_var( "SELECT COUNT(*) - FROM $wpdb->posts as posts - LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id - WHERE meta.meta_key = '_customer_user' - AND posts.post_type = 'shop_order' - AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) - AND meta_value = '" . esc_sql( $this->get_id() ) . "' - " ); - update_user_meta( $this->get_id(), '_order_count', $count ); - } - - return absint( $count ); - } + protected function exclude_internal_meta_keys( $meta ) { + global $wpdb; + return ! in_array( $meta->meta_key, $this->get_internal_meta_keys() ) + && 0 !== strpos( $meta->meta_key, 'closedpostboxes_' ) + && 0 !== strpos( $meta->meta_key, 'metaboxhidden_' ) + && 0 !== strpos( $meta->meta_key, 'manageedit-' ) + && ! strstr( $meta->meta_key, $wpdb->prefix ); + } /** - * Return how much money this customer has spent. + * Delete a customer and reassign posts.. + * + * @param int $reassign Reassign posts and links to new User ID. * @since 2.7.0 - * @return float + * @return bool */ - public function get_total_spent() { - $spent = get_user_meta( $this->get_id(), '_money_spent', true ); - - if ( '' === $spent ) { - global $wpdb; - - $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); - $spent = $wpdb->get_var( "SELECT SUM(meta2.meta_value) - FROM $wpdb->posts as posts - LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id - LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id - WHERE meta.meta_key = '_customer_user' - AND meta.meta_value = '" . esc_sql( $this->get_id() ) . "' - AND posts.post_type = 'shop_order' - AND posts.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) - AND meta2.meta_key = '_order_total' - " ); - - if ( ! $spent ) { - $spent = 0; - } - update_user_meta( $this->get_id(), '_money_spent', $spent ); + public function delete_and_reassign( $reassign = null ) { + if ( $this->data_store ) { + $this->data_store->delete( $this, true, $reassign ); + $this->set_id( 0 ); + return true; } - - return wc_format_decimal( $spent, 2 ); + return false; } /** * Is customer outside base country (for tax purposes)? + * * @return bool */ public function is_customer_outside_base() { @@ -324,76 +216,9 @@ class WC_Customer extends WC_Legacy_Customer { return false; } - /** - * Is customer VAT exempt? - * @return bool - */ - public function is_vat_exempt() { - return $this->get_is_vat_exempt(); - } - - /** - * Has calculated shipping? - * @return bool - */ - public function has_calculated_shipping() { - return $this->get_calculated_shipping(); - } - - /* - |-------------------------------------------------------------------------- - | Getters - |-------------------------------------------------------------------------- - | Methods for getting data from the customer object. - */ - - /** - * Return the customer's username. - * @since 2.7.0 - * @return string - */ - public function get_username() { - return $this->data['username']; - } - - /** - * Return the customer's email. - * @since 2.7.0 - * @return string - */ - public function get_email() { - return $this->data['email']; - } - - /** - * Return customer's first name. - * @since 2.7.0 - * @return string - */ - public function get_first_name() { - return $this->data['first_name']; - } - - /** - * Return customer's last name. - * @since 2.7.0 - * @return string - */ - public function get_last_name() { - return $this->data['last_name']; - } - - /** - * Return customer's user role. - * @since 2.7.0 - * @return string - */ - public function get_role() { - return $this->data['role']; - } - /** * Return this customer's avatar. + * * @since 2.7.0 * @return string */ @@ -410,217 +235,6 @@ class WC_Customer extends WC_Legacy_Customer { return ''; } - /** - * Return the date this customer was created. - * @since 2.7.0 - * @return integer - */ - public function get_date_created() { - return absint( $this->data['date_created'] ); - } - - /** - * Return the date this customer was last updated. - * @since 2.7.0 - * @return integer - */ - public function get_date_modified() { - return absint( $this->data['date_modified'] ); - } - - /** - * Gets customer billing first name. - * @return string - */ - public function get_billing_first_name() { - return $this->data['billing']['first_name']; - } - - /** - * Gets customer billing last name. - * @return string - */ - public function get_billing_last_name() { - return $this->data['billing']['last_name']; - } - - /** - * Gets customer billing company. - * @return string - */ - public function get_billing_company() { - return $this->data['billing']['company']; - } - - /** - * Gets billing phone. - * @return string - */ - public function get_billing_phone() { - return $this->data['billing']['phone']; - } - - /** - * Gets billing email. - * @return string - */ - public function get_billing_email() { - return $this->data['billing']['email']; - } - - /** - * Gets customer postcode. - * @return string - */ - public function get_billing_postcode() { - return wc_format_postcode( $this->data['billing']['postcode'], $this->get_billing_country() ); - } - - /** - * Get customer city. - * @return string - */ - public function get_billing_city() { - return $this->data['billing']['city']; - } - - /** - * Get customer address. - * @return string - */ - public function get_billing_address() { - return $this->data['billing']['address_1']; - } - - /** - * Get customer address. - * @return string - */ - public function get_billing_address_1() { - return $this->get_billing_address(); - } - - /** - * Get customer's second address. - * @return string - */ - public function get_billing_address_2() { - return $this->data['billing']['address_2']; - } - - /** - * Get customer state. - * @return string - */ - public function get_billing_state() { - return $this->data['billing']['state']; - } - - /** - * Get customer country. - * @return string - */ - public function get_billing_country() { - return $this->data['billing']['country']; - } - - /** - * Gets customer shipping first name. - * @return string - */ - public function get_shipping_first_name() { - return $this->data['shipping']['first_name']; - } - - /** - * Gets customer shipping last name. - * @return string - */ - public function get_shipping_last_name() { - return $this->data['shipping']['last_name']; - } - - /** - * Gets customer shipping company. - * @return string - */ - public function get_shipping_company() { - return $this->data['shipping']['company']; - } - - /** - * Get customer's shipping state. - * @return string - */ - public function get_shipping_state() { - return $this->data['shipping']['state']; - } - - /** - * Get customer's shipping country. - * @return string - */ - public function get_shipping_country() { - return $this->data['shipping']['country']; - } - - /** - * Get customer's shipping postcode. - * @return string - */ - public function get_shipping_postcode() { - return wc_format_postcode( $this->data['shipping']['postcode'], $this->get_shipping_country() ); - } - - /** - * Get customer's shipping city. - * @return string - */ - public function get_shipping_city() { - return $this->data['shipping']['city']; - } - - /** - * Get customer's shipping address. - * @return string - */ - public function get_shipping_address() { - return $this->data['shipping']['address_1']; - } - - /** - * Get customer address. - * @return string - */ - public function get_shipping_address_1() { - return $this->get_shipping_address(); - } - - /** - * Get customer's second shipping address. - * @return string - */ - public function get_shipping_address_2() { - return $this->data['shipping']['address_2']; - } - - /** - * Get if customer is VAT exempt? - * @since 2.7.0 - * @return bool - */ - public function get_is_vat_exempt() { - return $this->is_vat_exempt; - } - - /** - * Has customer calculated shipping? - * @return bool - */ - public function get_calculated_shipping() { - return $this->calculated_shipping; - } - /** * Get taxable address. * @return array @@ -655,6 +269,7 @@ class WC_Customer extends WC_Legacy_Customer { /** * Gets a customer's downloadable products. + * * @return array Array of downloadable products */ public function get_downloadable_products() { @@ -666,35 +281,465 @@ class WC_Customer extends WC_Legacy_Customer { } /** - * Is the user a paying customer? + * Is customer VAT exempt? + * + * @return bool + */ + public function is_vat_exempt() { + return $this->get_is_vat_exempt(); + } + + /** + * Has calculated shipping? + * + * @return bool + */ + public function has_calculated_shipping() { + return $this->get_calculated_shipping(); + } + + /** + * Get if customer is VAT exempt? + * * @since 2.7.0 * @return bool */ - function get_is_paying_customer() { - return (bool) $this->data['is_paying_customer']; + public function get_is_vat_exempt() { + return $this->is_vat_exempt; + } + + /** + * Get password (only used when updating the user object). + * + * @return string + */ + public function get_password() { + return $this->password; + } + + /** + * Has customer calculated shipping? + * + * @param string $context + * @return bool + */ + public function get_calculated_shipping() { + return $this->calculated_shipping; + } + + /** + * Set if customer has tax exemption. + * + * @param bool $is_vat_exempt + */ + public function set_is_vat_exempt( $is_vat_exempt ) { + $this->is_vat_exempt = (bool) $is_vat_exempt; + } + + /** + * Calculated shipping? + * + * @param boolean $calculated + */ + public function set_calculated_shipping( $calculated = true ) { + $this->calculated_shipping = (bool) $calculated; + } + + /** + * Set customer's password. + * + * @since 2.7.0 + * @param string $password + * @throws WC_Data_Exception + */ + public function set_password( $password ) { + $this->password = wc_clean( $password ); + } + + /** + * Gets the customers last order. + * + * @param WC_Customer + * @return WC_Order|false + */ + public function get_last_order() { + return $this->data_store->get_last_order( $this ); + } + + /** + * Return the number of orders this customer has. + * + * @param WC_Customer + * @return integer + */ + public function get_order_count() { + return $this->data_store->get_order_count( $this ); + } + + /** + * Return how much money this customer has spent. + * + * @param WC_Customer + * @return float + */ + public function get_total_spent() { + return $this->data_store->get_total_spent( $this ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Return the customer's username. + * + * @since 2.7.0 + * @param string $context + * @return string + */ + public function get_username( $context = 'view' ) { + return $this->get_prop( 'username', $context ); + } + + /** + * Return the customer's email. + * + * @since 2.7.0 + * @param string $context + * @return string + */ + public function get_email( $context = 'view' ) { + return $this->get_prop( 'email', $context ); + } + + /** + * Return customer's first name. + * + * @since 2.7.0 + * @param string $context + * @return string + */ + public function get_first_name( $context = 'view' ) { + return $this->get_prop( 'first_name', $context ); + } + + /** + * Return customer's last name. + * + * @since 2.7.0 + * @param string $context + * @return string + */ + public function get_last_name( $context = 'view' ) { + return $this->get_prop( 'last_name', $context ); + } + + /** + * Return customer's user role. + * + * @since 2.7.0 + * @param string $context + * @return string + */ + public function get_role( $context = 'view' ) { + return $this->get_prop( 'role', $context ); + } + + /** + * Return the date this customer was created. + * + * @since 2.7.0 + * @param string $context + * @return integer + */ + public function get_date_created( $context = 'view' ) { + return $this->get_prop( 'date_created', $context ); + } + + /** + * Return the date this customer was last updated. + * + * @since 2.7.0 + * @param string $context + * @return integer + */ + public function get_date_modified( $context = 'view' ) { + return $this->get_prop( 'date_modified', $context ); + } + + /** + * Gets customer billing first name. + * + * @param string $context + * @return string + */ + public function get_billing_first_name( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['first_name']; + } + + /** + * Gets customer billing last name. + * + * @param string $context + * @return string + */ + public function get_billing_last_name( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['last_name']; + } + + /** + * Gets customer billing company. + * + * @param string $context + * @return string + */ + public function get_billing_company( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['company']; + } + + /** + * Gets billing phone. + * + * @param string $context + * @return string + */ + public function get_billing_phone( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['phone']; + } + + /** + * Gets billing email. + * + * @param string $context + * @return string + */ + public function get_billing_email( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['email']; + } + + /** + * Gets customer postcode. + * + * @param string $context + * @return string + */ + public function get_billing_postcode( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return 'view' === $context ? wc_format_postcode( $billing['postcode'], $this->get_billing_country() ) : $billing['postcode']; + } + + /** + * Get customer city. + * + * @param string $context + * @return string + */ + public function get_billing_city( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['city']; + } + + /** + * Get customer address. + * + * @param string $context + * @return string + */ + public function get_billing_address( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['address_1']; + } + + /** + * Get customer address. + * + * @param string $context + * @return string + */ + public function get_billing_address_1( $context = 'view' ) { + return $this->get_billing_address( $context ); + } + + /** + * Get customer's second address. + * + * @param string $context + * @return string + */ + public function get_billing_address_2( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['address_2']; + } + + /** + * Get customer state. + * + * @param string $context + * @return string + */ + public function get_billing_state( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['state']; + } + + /** + * Get customer country. + * + * @param string $context + * @return string + */ + public function get_billing_country( $context = 'view' ) { + $billing = $this->get_prop( 'billing', $context ); + return $billing['country']; + } + + /** + * Gets customer shipping first name. + * + * @param string $context + * @return string + */ + public function get_shipping_first_name( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['first_name']; + } + + /** + * Gets customer shipping last name. + * + * @param string $context + * @return string + */ + public function get_shipping_last_name( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['last_name']; + } + + /** + * Gets customer shipping company. + * + * @param string $context + * @return string + */ + public function get_shipping_company( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['company']; + } + + /** + * Get customer's shipping state. + * + * @param string $context + * @return string + */ + public function get_shipping_state( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['state']; + } + + /** + * Get customer's shipping country. + * + * @param string $context + * @return string + */ + public function get_shipping_country( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['country']; + } + + /** + * Get customer's shipping postcode. + * + * @param string $context + * @return string + */ + public function get_shipping_postcode( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return 'view' === $context ? wc_format_postcode( $shipping['postcode'], $this->get_shipping_country() ) : $shipping['postcode']; + } + + /** + * Get customer's shipping city. + * + * @param string $context + * @return string + */ + public function get_shipping_city( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['city']; + } + + /** + * Get customer's shipping address. + * + * @param string $context + * @return string + */ + public function get_shipping_address( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['address_1']; + } + + /** + * Get customer address. + * + * @param string $context + * @return string + */ + public function get_shipping_address_1( $context = 'view' ) { + return $this->get_shipping_address( $context ); + } + + /** + * Get customer's second shipping address. + * + * @param string $context + * @return string + */ + public function get_shipping_address_2( $context = 'view' ) { + $shipping = $this->get_prop( 'shipping', $context ); + return $shipping['address_2']; + } + + /** + * Is the user a paying customer? + * + * @since 2.7.0 + * @param string $context + * @return bool + */ + function get_is_paying_customer( $context = 'view' ) { + return $this->get_prop( 'is_paying_customer', $context ); } /* |-------------------------------------------------------------------------- | Setters |-------------------------------------------------------------------------- - | Functions for setting customer data. These should not update anything in the - | database itself and should only change what is stored in the class - | object. */ /** * Set customer's username. + * * @since 2.7.0 * @param string $username * @throws WC_Data_Exception */ public function set_username( $username ) { - $this->data['username'] = $username; + $this->set_prop( 'username', $username ); } /** * Set customer's email. + * * @since 2.7.0 * @param string $value * @throws WC_Data_Exception @@ -703,31 +748,34 @@ class WC_Customer extends WC_Legacy_Customer { if ( $value && ! is_email( $value ) ) { $this->error( 'customer_invalid_email', __( 'Invalid email address', 'woocommerce' ) ); } - $this->data['email'] = sanitize_email( $value ); + $this->set_prop( 'email', sanitize_email( $value ) ); } /** * Set customer's first name. + * * @since 2.7.0 * @param string $first_name * @throws WC_Data_Exception */ public function set_first_name( $first_name ) { - $this->data['first_name'] = $first_name; + $this->set_prop( 'first_name', $first_name ); } /** * Set customer's last name. + * * @since 2.7.0 * @param string $last_name * @throws WC_Data_Exception */ public function set_last_name( $last_name ) { - $this->data['last_name'] = $last_name; + $this->set_prop( 'last_name', $last_name ); } /** * Set customer's user role(s). + * * @since 2.7.0 * @param mixed $role * @throws WC_Data_Exception @@ -738,82 +786,56 @@ class WC_Customer extends WC_Legacy_Customer { if ( $role && ! empty( $wp_roles->roles ) && ! in_array( $role, array_keys( $wp_roles->roles ) ) ) { $this->error( 'customer_invalid_role', __( 'Invalid role', 'woocommerce' ) ); } - $this->data['role'] = $role; - } - - /** - * Set customer's password. - * @since 2.7.0 - * @param string $password - * @throws WC_Data_Exception - */ - public function set_password( $password ) { - $this->password = wc_clean( $password ); + $this->set_prop( 'role', $role ); } /** * Set the date this customer was last updated. + * * @since 2.7.0 * @param integer $timestamp * @throws WC_Data_Exception */ public function set_date_modified( $timestamp ) { - $this->data['date_modified'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + $this->set_prop( 'date_modified', is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ) ); } /** * Set the date this customer was last updated. + * * @since 2.7.0 * @param integer $timestamp * @throws WC_Data_Exception */ public function set_date_created( $timestamp ) { - $this->data['date_created'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + $this->set_prop( 'date_created', is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ) ); } /** * Set customer address to match shop base address. + * * @since 2.7.0 * @throws WC_Data_Exception */ public function set_billing_address_to_base() { $base = wc_get_customer_default_location(); - $this->data['billing']['country'] = $base['country']; - $this->data['billing']['state'] = $base['state']; - $this->data['billing']['postcode'] = ''; - $this->data['billing']['city'] = ''; + $this->set_billing_location( $base['country'], $base['state'], '', '' ); } /** * Set customer shipping address to base address. + * * @since 2.7.0 * @throws WC_Data_Exception */ public function set_shipping_address_to_base() { $base = wc_get_customer_default_location(); - $this->data['shipping']['country'] = $base['country']; - $this->data['shipping']['state'] = $base['state']; - $this->data['shipping']['postcode'] = ''; - $this->data['shipping']['city'] = ''; - } - - /** - * Sets all shipping info at once. - * @param string $country - * @param string $state - * @param string $postcode - * @param string $city - * @throws WC_Data_Exception - */ - public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) { - $this->data['shipping']['country'] = $country; - $this->data['shipping']['state'] = $state; - $this->data['shipping']['postcode'] = $postcode; - $this->data['shipping']['city'] = $city; + $this->set_shipping_location( $base['country'], $base['state'], '', '' ); } /** * Sets all address info at once. + * * @param string $country * @param string $state * @param string $postcode @@ -821,428 +843,303 @@ class WC_Customer extends WC_Legacy_Customer { * @throws WC_Data_Exception */ public function set_billing_location( $country, $state, $postcode = '', $city = '' ) { - $this->data['billing']['country'] = $country; - $this->data['billing']['state'] = $state; - $this->data['billing']['postcode'] = $postcode; - $this->data['billing']['city'] = $city; + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['country'] = $country; + $billing['state'] = $state; + $billing['postcode'] = $postcode; + $billing['city'] = $city; + $this->set_prop( 'billing', $billing ); + } + + /** + * Sets all shipping info at once. + * + * @param string $country + * @param string $state + * @param string $postcode + * @param string $city + * @throws WC_Data_Exception + */ + public function set_shipping_location( $country, $state = '', $postcode = '', $city = '' ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['country'] = $country; + $shipping['state'] = $state; + $shipping['postcode'] = $postcode; + $shipping['city'] = $city; + $this->set_prop( 'shipping', $shipping ); } /** * Set billing first name. - * @return string + * + * @param string $value * @throws WC_Data_Exception */ public function set_billing_first_name( $value ) { - $this->data['billing']['first_name'] = $value; + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['first_name'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set billing last name. - * @return string + * + * @param string $value * @throws WC_Data_Exception */ public function set_billing_last_name( $value ) { - $this->data['billing']['last_name'] = $value; + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['last_name'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set billing company. - * @return string + * + * @param string $value * @throws WC_Data_Exception */ public function set_billing_company( $value ) { - $this->data['billing']['company'] = $value; + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['company'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set billing phone. - * @return string + * + * @param string $value * @throws WC_Data_Exception */ public function set_billing_phone( $value ) { - $this->data['billing']['phone'] = $value; + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['phone'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set billing email. + * * @param string $value - * @return string * @throws WC_Data_Exception */ public function set_billing_email( $value ) { if ( $value && ! is_email( $value ) ) { $this->error( 'customer_invalid_billing_email', __( 'Invalid billing email address', 'woocommerce' ) ); } - $this->data['billing']['email'] = sanitize_email( $value ); + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['email'] = sanitize_email( $value ); + $this->set_prop( 'billing', $billing ); } /** * Set customer country. - * @param mixed $country + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_country( $country ) { - $this->data['billing']['country'] = $country; + public function set_billing_country( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['country'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set customer state. - * @param mixed $state + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_state( $state ) { - $this->data['billing']['state'] = $state; + public function set_billing_state( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['state'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Sets customer postcode. - * @param mixed $postcode + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_postcode( $postcode ) { - $this->data['billing']['postcode'] = $postcode; + public function set_billing_postcode( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['postcode'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Sets customer city. - * @param mixed $city + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_city( $city ) { - $this->data['billing']['city'] = $city; + public function set_billing_city( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['city'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set customer address. - * @param mixed $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_address( $address ) { - $this->data['billing']['address_1'] = $address; + public function set_billing_address( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['address_1'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Set customer address. - * @param mixed $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_address_1( $address ) { - $this->set_billing_address( $address ); + public function set_billing_address_1( $value ) { + $this->set_billing_address( $value ); } /** * Set customer's second address. - * @param mixed $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_billing_address_2( $address ) { - $this->data['billing']['address_2'] = $address; + public function set_billing_address_2( $value ) { + $billing = $this->get_prop( 'billing', 'edit' ); + $billing['address_2'] = $value; + $this->set_prop( 'billing', $billing ); } /** * Sets customer shipping first name. - * @param string $first_name + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_first_name( $first_name ) { - $this->data['shipping']['first_name'] = $first_name; + public function set_shipping_first_name( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['first_name'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Sets customer shipping last name. - * @param string $last_name + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_last_name( $last_name ) { - $this->data['shipping']['last_name'] = $last_name; + public function set_shipping_last_name( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['last_name'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Sets customer shipping company. - * @param string $company. + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_company( $company ) { - $this->data['shipping']['company'] = $company; + public function set_shipping_company( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['company'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set shipping country. - * @param string $country + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_country( $country ) { - $this->data['shipping']['country'] = $country; + public function set_shipping_country( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['country'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set shipping state. - * @param string $state + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_state( $state ) { - $this->data['shipping']['state'] = $state; + public function set_shipping_state( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['state'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set shipping postcode. - * @param string $postcode + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_postcode( $postcode ) { - $this->data['shipping']['postcode'] = $postcode; + public function set_shipping_postcode( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['postcode'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Sets shipping city. - * @param string $city + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_city( $city ) { - $this->data['shipping']['city'] = $city; + public function set_shipping_city( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['city'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set shipping address. - * @param string $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_address( $address ) { - $this->data['shipping']['address_1'] = $address; + public function set_shipping_address( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['address_1'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set customer shipping address. - * @param mixed $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_address_1( $address ) { - $this->set_shipping_address( $address ); + public function set_shipping_address_1( $value ) { + $this->set_shipping_address( $value ); } /** * Set second shipping address. - * @param string $address + * + * @param string $value * @throws WC_Data_Exception */ - public function set_shipping_address_2( $address ) { - $this->data['shipping']['address_2'] = $address; + public function set_shipping_address_2( $value ) { + $shipping = $this->get_prop( 'shipping', 'edit' ); + $shipping['address_2'] = $value; + $this->set_prop( 'shipping', $shipping ); } /** * Set if the user a paying customer. + * * @since 2.7.0 - * @param boolean $is_paying_customer + * @param bool $is_paying_customer * @throws WC_Data_Exception */ function set_is_paying_customer( $is_paying_customer ) { - $this->data['is_paying_customer'] = (bool) $is_paying_customer; + $this->set_prop( 'is_paying_customer', (bool) $is_paying_customer ); } - - /** - * Set if customer has tax exemption. - * @param bool $is_vat_exempt - */ - public function set_is_vat_exempt( $is_vat_exempt ) { - $this->is_vat_exempt = (bool) $is_vat_exempt; - } - - /** - * Calculated shipping? - * @param boolean $calculated - */ - public function set_calculated_shipping( $calculated = true ) { - $this->calculated_shipping = (bool) $calculated; - } - - /* - |-------------------------------------------------------------------------- - | CRUD methods - |-------------------------------------------------------------------------- - | Methods which create, read, update and delete from the database. - | - | A save method is included for convenience (chooses update or create based - | on if the order exists yet). - */ - - /** - * Create a customer. - * @since 2.7.0. - */ - public function create() { - $customer_id = wc_create_new_customer( $this->get_email(), $this->get_username(), $this->password ); - - if ( ! is_wp_error( $customer_id ) ) { - $this->set_id( $customer_id ); - $this->update_post_meta(); - wp_update_user( array( 'ID' => $this->get_id(), 'role' => $this->get_role() ) ); - $wp_user = new WP_User( $this->get_id() ); - $this->set_date_created( strtotime( $wp_user->user_registered ) ); - $this->set_date_modified( get_user_meta( $this->get_id(), 'last_update', true ) ); - $this->read_meta_data(); - } - } - - /** - * Helper method that updates all the meta for a customer. Used for update & create. - * @since 2.7.0 - */ - private function update_post_meta() { - update_user_meta( $this->get_id(), 'billing_first_name', $this->get_billing_first_name() ); - update_user_meta( $this->get_id(), 'billing_last_name', $this->get_billing_last_name() ); - update_user_meta( $this->get_id(), 'billing_company', $this->get_billing_company() ); - update_user_meta( $this->get_id(), 'billing_phone', $this->get_billing_phone() ); - update_user_meta( $this->get_id(), 'billing_email', $this->get_billing_email() ); - update_user_meta( $this->get_id(), 'billing_postcode', $this->get_billing_postcode() ); - update_user_meta( $this->get_id(), 'billing_city', $this->get_billing_city() ); - update_user_meta( $this->get_id(), 'billing_address_1', $this->get_billing_address() ); - update_user_meta( $this->get_id(), 'billing_address_2', $this->get_billing_address_2() ); - update_user_meta( $this->get_id(), 'billing_state', $this->get_billing_state() ); - update_user_meta( $this->get_id(), 'billing_country', $this->get_billing_country() ); - update_user_meta( $this->get_id(), 'shipping_first_name', $this->get_shipping_first_name() ); - update_user_meta( $this->get_id(), 'shipping_last_name', $this->get_shipping_last_name() ); - update_user_meta( $this->get_id(), 'shipping_company', $this->get_shipping_company() ); - update_user_meta( $this->get_id(), 'shipping_postcode', $this->get_shipping_postcode() ); - update_user_meta( $this->get_id(), 'shipping_city', $this->get_shipping_city() ); - update_user_meta( $this->get_id(), 'shipping_address_1', $this->get_shipping_address() ); - update_user_meta( $this->get_id(), 'shipping_address_2', $this->get_shipping_address_2() ); - update_user_meta( $this->get_id(), 'shipping_state', $this->get_shipping_state() ); - update_user_meta( $this->get_id(), 'shipping_country', $this->get_shipping_country() ); - update_user_meta( $this->get_id(), 'paying_customer', $this->get_is_paying_customer() ); - update_user_meta( $this->get_id(), 'first_name', $this->get_first_name() ); - update_user_meta( $this->get_id(), 'last_name', $this->get_last_name() ); - } - - /** - * Callback which flattens post meta (gets the first value). - * @param array $value - * @return mixed - */ - private function flatten_post_meta( $value ) { - return is_array( $value ) ? current( $value ) : $value; - } - - /** - * Read a customer from the database. - * @since 2.7.0 - * @param integer $id - */ - public function read( $id ) { - global $wpdb; - - // User object is required. - if ( ! $id || ! ( $user_object = get_user_by( 'id', $id ) ) || empty( $user_object->ID ) ) { - $this->set_id( 0 ); - return; - } - - // Only users on this site should be read. - if ( is_multisite() && ! is_user_member_of_blog( $id ) ) { - $this->set_id( 0 ); - return; - } - - $this->set_id( $user_object->ID ); - $this->set_props( array_map( array( $this, 'flatten_post_meta' ), get_user_meta( $id ) ) ); - $this->set_props( array( - 'is_paying_customer' => get_user_meta( $id, 'paying_customer', true ), - 'email' => $user_object->user_email, - 'username' => $user_object->user_login, - 'date_created' => strtotime( $user_object->user_registered ), - 'date_modified' => get_user_meta( $id, 'last_update', true ), - 'role' => ! empty( $user_object->roles[0] ) ? $user_object->roles[0] : 'customer', - ) ); - $this->read_meta_data(); - } - - /** - * Update a customer. - * @since 2.7.0 - */ - public function update() { - wp_update_user( array( 'ID' => $this->get_id(), 'user_email' => $this->get_email() ) ); - // Only update password if a new one was set with set_password - if ( ! empty( $this->password ) ) { - wp_update_user( array( 'ID' => $this->get_id(), 'user_pass' => $this->password ) ); - $this->password = ''; - } - - $this->update_post_meta(); - $this->set_date_modified( get_user_meta( $this->get_id(), 'last_update', true ) ); - $this->save_meta_data(); - } - - /** - * Delete a customer. - * @since 2.7.0 - */ - public function delete( $force_delete = false ) { - if ( ! $this->get_id() ) { - return; - } - return wp_delete_user( $this->get_id() ); - } - - /** - * Delete a customer and reassign posts.. - * - * @param int $reassign Reassign posts and links to new User ID. - * @since 2.7.0 - */ - public function delete_and_reassign( $reassign = null ) { - if ( ! $this->get_id() ) { - return; - } - return wp_delete_user( $this->get_id(), $reassign ); - } - - /** - * Save data. Create when creating a new user/class, update when editing - * an existing user, and save session when working on a logged out guest - * session. - * @since 2.7.0 - */ - public function save() { - if ( $this->is_session ) { - $this->save_to_session(); - } elseif ( ! $this->get_id() ) { - $this->create(); - } else { - $this->update(); - } - } - - /** - * Saves data to the session only (does not overwrite DB values). - * @since 2.7.0 - */ - public function save_to_session() { - $data = array(); - foreach ( $this->session_keys as $session_key ) { - $function_key = $session_key; - if ( 'billing_' === substr( $session_key, 0, 8 ) ) { - $session_key = str_replace( 'billing_', '', $session_key ); - } - $data[ $session_key ] = $this->{"get_$function_key"}(); - } - if ( WC()->session->get( 'customer' ) !== $data ) { - WC()->session->set( 'customer', $data ); - } - } - - /** - * Callback to remove unwanted meta data. - * - * @param object $meta - * @return bool - */ - protected function exclude_internal_meta_keys( $meta ) { - global $wpdb; - return ! in_array( $meta->meta_key, $this->get_internal_meta_keys() ) - && 0 !== strpos( $meta->meta_key, 'closedpostboxes_' ) - && 0 !== strpos( $meta->meta_key, 'metaboxhidden_' ) - && 0 !== strpos( $meta->meta_key, 'manageedit-' ) - && ! strstr( $meta->meta_key, $wpdb->prefix ); - } - } diff --git a/includes/class-wc-data-store.php b/includes/class-wc-data-store.php index 0e81b149c1d..c96a42c0040 100644 --- a/includes/class-wc-data-store.php +++ b/includes/class-wc-data-store.php @@ -28,7 +28,9 @@ class WC_Data_Store { * Ran through `woocommerce_data_stores`. */ private $stores = array( - 'coupon' => 'WC_Coupon_Data_Store_CPT', + 'coupon' => 'WC_Coupon_Data_Store_CPT', + 'customer' => 'WC_Customer_Data_Store', + 'customer-session' => 'WC_Customer_Data_Store_Session', ); /** * Contains the name of the current data store's class name. diff --git a/includes/data-stores/class-wc-customer-data-store-session.php b/includes/data-stores/class-wc-customer-data-store-session.php new file mode 100644 index 00000000000..964e429df4e --- /dev/null +++ b/includes/data-stores/class-wc-customer-data-store-session.php @@ -0,0 +1,175 @@ +save_to_session( $customer ); + } + + /** + * Simply update the session. + * + * @param WC_Customer + */ + public function update( &$customer ) { + $this->save_to_session( $customer ); + } + + /** + * Saves all customer data to the session. + * + * @param WC_Customer + */ + public function save_to_session( $customer ) { + $data = array(); + foreach ( $this->session_keys as $session_key ) { + $function_key = $session_key; + if ( 'billing_' === substr( $session_key, 0, 8 ) ) { + $session_key = str_replace( 'billing_', '', $session_key ); + } + $data[ $session_key ] = $customer->{"get_$function_key"}( 'edit' ); + } + if ( WC()->session->get( 'customer' ) !== $data ) { + WC()->session->set( 'customer', $data ); + } + } + + /** + * Read customer data from the session. + * + * @since 2.7.0 + * @param WC_Customer + */ + public function read( &$customer ) { + $data = (array) WC()->session->get( 'customer' ); + if ( ! empty( $data ) ) { + foreach ( $this->session_keys as $session_key ) { + $function_key = $session_key; + if ( 'billing_' === substr( $session_key, 0, 8 ) ) { + $session_key = str_replace( 'billing_', '', $session_key ); + } + if ( ! empty( $data[ $session_key ] ) && is_callable( array( $customer, "set_{$function_key}" ) ) ) { + $customer->{"set_{$function_key}"}( $data[ $session_key ] ); + } + } + } + $this->set_defaults( $customer ); + $customer->set_object_read( true ); + } + + /** + * Load default values if props are unset. + * + * @param WC_Customer + */ + protected function set_defaults( &$customer ) { + $default = wc_get_customer_default_location(); + + // Set some defaults if some of our values are still not set. + if ( ! $customer->get_billing_country() ) { + $customer->set_billing_country( $default['country'] ); + } + + if ( ! $customer->get_shipping_country() ) { + $customer->set_shipping_country( $customer->get_billing_country() ); + } + + if ( ! $customer->get_billing_state() ) { + $customer->set_billing_state( $default['state'] ); + } + + if ( ! $customer->get_shipping_state() ) { + $customer->set_shipping_state( $customer->get_billing_state() ); + } + } + + /** + * Deletes a customer from the database. + * + * @since 2.7.0 + * @param WC_Customer + * @param int|null $reassign Who to reassign posts to. + */ + public function delete( &$customer, $force_delete = true, $reassign = null ) { + WC()->session->set( 'customer', null ); + } + + /** + * Gets the customers last order. + * + * @since 2.7.0 + * @param WC_Customer + * @return WC_Order|false + */ + public function get_last_order( &$customer ) { + return false; + } + + /** + * Return the number of orders this customer has. + * + * @since 2.7.0 + * @param WC_Customer + * @return integer + */ + public function get_order_count( &$customer ) { + return 0; + } + + /** + * Return how much money this customer has spent. + * + * @since 2.7.0 + * @param WC_Customer + * @return float + */ + public function get_total_spent( &$customer ) { + return 0; + } +} diff --git a/includes/data-stores/class-wc-customer-data-store.php b/includes/data-stores/class-wc-customer-data-store.php new file mode 100644 index 00000000000..c68be2847e9 --- /dev/null +++ b/includes/data-stores/class-wc-customer-data-store.php @@ -0,0 +1,242 @@ +get_email(), $customer->get_username(), $customer->get_password() ); + + if ( ! is_wp_error( $customer_id ) ) { + $customer->set_id( $customer_id ); + $this->update_user_meta( $customer ); + wp_update_user( array( 'ID' => $customer->get_id(), 'role' => $customer->get_role() ) ); + $wp_user = new WP_User( $customer->get_id() ); + $customer->set_date_created( strtotime( $wp_user->user_registered ) ); + $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); + $customer->read_meta_data(); + } + } + + /** + * Method to read a customer object. + * + * @since 2.7.0 + * @param WC_Customer + */ + public function read( &$customer ) { + global $wpdb; + + // User object is required. + if ( ! $customer->get_id() || ! ( $user_object = get_user_by( 'id', $customer->get_id() ) ) || empty( $user_object->ID ) ) { + throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); + return; + } + + // Only users on this site should be read. + if ( is_multisite() && ! is_user_member_of_blog( $customer->get_id() ) ) { + throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); + return; + } + + $customer_id = $customer->get_id(); + $customer->set_props( array_map( 'wc_flatten_meta_callback', get_user_meta( $customer_id ) ) ); + $customer->set_props( array( + 'is_paying_customer' => get_user_meta( $customer_id, 'paying_customer', true ), + 'email' => $user_object->user_email, + 'username' => $user_object->user_login, + 'date_created' => strtotime( $user_object->user_registered ), + 'date_modified' => get_user_meta( $customer_id, 'last_update', true ), + 'role' => ! empty( $user_object->roles[0] ) ? $user_object->roles[0] : 'customer', + ) ); + $customer->read_meta_data(); + $customer->set_object_read( true ); + } + + /** + * Updates a customer in the database. + * + * @since 2.7.0 + * @param WC_Customer + */ + public function update( &$customer ) { + wp_update_user( array( 'ID' => $customer->get_id(), 'user_email' => $customer->get_email() ) ); + // Only update password if a new one was set with set_password + if ( ! empty( $customer->get_password() ) ) { + wp_update_user( array( 'ID' => $customer->get_id(), 'user_pass' => $customer->get_password() ) ); + $customer->set_password( '' ); + } + $this->update_user_meta( $customer ); + $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); + $customer->save_meta_data(); + } + + /** + * Deletes a customer from the database. + * + * @since 2.7.0 + * @param WC_Customer + * @param bool $force_delete Unused for customers. + * @param int|null $reassign Who to reassign posts to. + */ + public function delete( &$customer, $force_delete = true, $reassign = null ) { + if ( ! $customer->get_id() ) { + return; + } + return wp_delete_user( $customer->get_id(), $reassign ); + } + + /** + * Helper method that updates all the meta for a customer. Used for update & create. + * @since 2.7.0 + * @param WC_Customer + */ + private function update_user_meta( $customer ) { + $updated_props = array(); + $changed_props = array_keys( $customer->get_changes() ); + + $meta_key_to_props = array( + 'paying_customer' => 'is_paying_customer', + 'first_name' => 'first_name', + 'last_name' => 'last_name', + ); + + foreach ( $meta_key_to_props as $meta_key => $prop ) { + if ( ! in_array( $prop, $changed_props ) ) { + continue; + } + + if ( update_user_meta( $customer->get_id(), $meta_key, $customer->{"get_$prop"}( 'edit' ) ) ) { + $updated_props[] = $prop; + } + } + + if ( in_array( 'billing', $changed_props ) ) { + update_user_meta( $customer->get_id(), 'billing_first_name', $customer->get_billing_first_name( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_last_name', $customer->get_billing_last_name( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_company', $customer->get_billing_company( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_phone', $customer->get_billing_phone( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_email', $customer->get_billing_email( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_postcode', $customer->get_billing_postcode( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_city', $customer->get_billing_city( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_address_1', $customer->get_billing_address( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_address_2', $customer->get_billing_address_2( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_state', $customer->get_billing_state( 'edit' ) ); + update_user_meta( $customer->get_id(), 'billing_country', $customer->get_billing_country( 'edit' ) ); + } + + if ( in_array( 'shipping', $changed_props ) ) { + update_user_meta( $customer->get_id(), 'shipping_first_name', $customer->get_shipping_first_name( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_last_name', $customer->get_shipping_last_name( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_company', $customer->get_shipping_company( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_postcode', $customer->get_shipping_postcode( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_city', $customer->get_shipping_city( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_address_1', $customer->get_shipping_address( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_address_2', $customer->get_shipping_address_2( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_state', $customer->get_shipping_state( 'edit' ) ); + update_user_meta( $customer->get_id(), 'shipping_country', $customer->get_shipping_country( 'edit' ) ); + } + } + + /** + * Gets the customers last order. + * + * @since 2.7.0 + * @param WC_Customer + * @return WC_Order|false + */ + public function get_last_order( &$customer ) { + global $wpdb; + + $last_order = $wpdb->get_var( "SELECT posts.ID + FROM $wpdb->posts AS posts + LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id + WHERE meta.meta_key = '_customer_user' + AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) + ORDER BY posts.ID DESC + " ); + + if ( $last_order ) { + return wc_get_order( absint( $last_order ) ); + } else { + return false; + } + } + + /** + * Return the number of orders this customer has. + * + * @since 2.7.0 + * @param WC_Customer + * @return integer + */ + public function get_order_count( &$customer ) { + $count = get_user_meta( $customer->get_id(), '_order_count', true ); + + if ( '' === $count ) { + global $wpdb; + + $count = $wpdb->get_var( "SELECT COUNT(*) + FROM $wpdb->posts as posts + LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id + WHERE meta.meta_key = '_customer_user' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' ) + AND meta_value = '" . esc_sql( $customer->get_id() ) . "' + " ); + update_user_meta( $customer->get_id(), '_order_count', $count ); + } + + return absint( $count ); + } + + /** + * Return how much money this customer has spent. + * + * @since 2.7.0 + * @param WC_Customer + * @return float + */ + public function get_total_spent( &$customer ) { + $spent = get_user_meta( $customer->get_id(), '_money_spent', true ); + + if ( '' === $spent ) { + global $wpdb; + + $statuses = array_map( 'esc_sql', wc_get_is_paid_statuses() ); + $spent = $wpdb->get_var( "SELECT SUM(meta2.meta_value) + FROM $wpdb->posts as posts + LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id + LEFT JOIN {$wpdb->postmeta} AS meta2 ON posts.ID = meta2.post_id + WHERE meta.meta_key = '_customer_user' + AND meta.meta_value = '" . esc_sql( $customer->get_id() ) . "' + AND posts.post_type = 'shop_order' + AND posts.post_status IN ( 'wc-" . implode( "','wc-", $statuses ) . "' ) + AND meta2.meta_key = '_order_total' + " ); + + if ( ! $spent ) { + $spent = 0; + } + update_user_meta( $customer->get_id(), '_money_spent', $spent ); + } + + return wc_format_decimal( $spent, 2 ); + } +} diff --git a/includes/data-stores/interfaces/wc-customer-data-store-interface.php b/includes/data-stores/interfaces/wc-customer-data-store-interface.php new file mode 100644 index 00000000000..4dc649e8768 --- /dev/null +++ b/includes/data-stores/interfaces/wc-customer-data-store-interface.php @@ -0,0 +1,48 @@ +save(); + } + /** * Is the user a paying customer? * @todo should this be moved to a get_ readonly? diff --git a/includes/shortcodes/class-wc-shortcode-cart.php b/includes/shortcodes/class-wc-shortcode-cart.php index fa0851dad5f..a4529d43c7c 100644 --- a/includes/shortcodes/class-wc-shortcode-cart.php +++ b/includes/shortcodes/class-wc-shortcode-cart.php @@ -38,8 +38,7 @@ class WC_Shortcode_Cart { } WC()->customer->set_calculated_shipping( true ); - - WC()->customer->save_to_session(); + WC()->customer->save(); wc_add_notice( __( 'Shipping costs updated.', 'woocommerce' ), 'notice' ); diff --git a/includes/wc-formatting-functions.php b/includes/wc-formatting-functions.php index 5391c8499ba..9f10a558972 100644 --- a/includes/wc-formatting-functions.php +++ b/includes/wc-formatting-functions.php @@ -568,6 +568,17 @@ function wc_timezone_string() { return $timezone; } +/** + * Callback which can flatten post meta (gets the first value if it's an array). + * + * @since 2.7.0 + * @param array $value + * @return mixed + */ +function wc_flatten_meta_callback( $value ) { + return is_array( $value ) ? current( $value ) : $value; +} + if ( ! function_exists( 'wc_rgb_from_hex' ) ) { /** diff --git a/tests/framework/helpers/class-wc-helper-customer.php b/tests/framework/helpers/class-wc-helper-customer.php index 9a37f02358b..82ec13afa3d 100644 --- a/tests/framework/helpers/class-wc-helper-customer.php +++ b/tests/framework/helpers/class-wc-helper-customer.php @@ -33,8 +33,7 @@ class WC_Helper_Customer { WC_Helper_Customer::set_customer_details( $customer_data ); - $customer = new WC_Customer(); - $customer->load_session(); + $customer = new WC_Customer( 0, true ); return $customer; } diff --git a/tests/unit-tests/customer/crud.php b/tests/unit-tests/customer/crud.php index 7dd920b9219..47ec69b5078 100644 --- a/tests/unit-tests/customer/crud.php +++ b/tests/unit-tests/customer/crud.php @@ -16,7 +16,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer->set_username( 'testusername-' . time() ); $customer->set_password( 'test123' ); $customer->set_email( 'test@woo.local' ); - $customer->create(); + $customer->save(); $wp_user = new WP_User( $customer->get_id() ); $this->assertEquals( $username, $customer->get_username() ); @@ -36,7 +36,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer->set_email( 'test@wc.local' ); $customer->set_first_name( 'Justin' ); $customer->set_billing_address_2( 'Apt 5' ); - $customer->update(); + $customer->save(); $customer = new WC_Customer( $customer_id ); // so we can read fresh copies from the DB $this->assertEquals( 'test@wc.local', $customer->get_email() ); @@ -80,7 +80,6 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer_id = $customer->get_id(); $this->assertNotEquals( 0, $customer->get_id() ); $customer->delete(); - $customer->read( $customer_id ); $this->assertEquals( 0, $customer->get_id() ); } @@ -94,16 +93,15 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer->set_username( $username ); $customer->set_email( 'test@woo.local' ); $customer->set_password( 'hunter2' ); - $customer->set_first_name( 'Bob' ); + $customer->set_first_name( 'Billy' ); $customer->set_last_name( 'Bob' ); - $customer->create(); + $customer->save(); $customer_id = $customer->get_id(); - $customer_read = new WC_Customer(); - $customer_read->read( $customer_id ); + $customer_read = new WC_Customer( $customer_id ); $this->assertEquals( $customer_id, $customer_read->get_id() ); $this->assertEquals( 'test@woo.local', $customer_read->get_email() ); - $this->assertEquals( 'Bob', $customer_read->get_first_name() ); + $this->assertEquals( 'Billy', $customer_read->get_first_name() ); $this->assertEquals( 'Bob', $customer_read->get_last_name() ); $this->assertEquals( $username, $customer_read->get_username() ); } @@ -221,7 +219,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer = WC_Helper_Customer::create_customer(); $customer_id = $customer->get_id(); $order = WC_Helper_Order::create_order( $customer_id ); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $last_order = $customer->get_last_order(); $this->assertEquals( $order->get_id(), $last_order ? $last_order->get_id() : 0 ); $this->assertEquals( $order->get_date_created(), $last_order ? $last_order->get_date_created() : 0 ); @@ -238,7 +236,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { WC_Helper_Order::create_order( $customer_id ); WC_Helper_Order::create_order( $customer_id ); WC_Helper_Order::create_order( $customer_id ); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $this->assertEquals( 3, $customer->get_order_count() ); } @@ -250,10 +248,10 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer = WC_Helper_Customer::create_customer(); $customer_id = $customer->get_id(); $order = WC_Helper_Order::create_order( $customer_id ); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $this->assertEquals( 0, $customer->get_total_spent() ); $order->update_status( 'wc-completed' ); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $this->assertEquals( 40, $customer->get_total_spent() ); $order->delete(); } @@ -306,7 +304,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer->set_shipping_postcode( '11111' ); $customer->set_shipping_city( 'Test' ); $customer->save(); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); update_option( 'woocommerce_tax_based_on', 'shipping' ); $taxable = $customer->get_taxable_address(); @@ -437,14 +435,12 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $this->assertEquals( 'Philadelphia', $session->get_billing_city() ); $session->set_billing_address( '124 South Street' ); - $session->save_to_session(); + $session->save(); $session = new WC_Customer( 0, true ); - $session->load_session(); $this->assertEquals( '124 South Street', $session->get_billing_address() ); $session = new WC_Customer( 0, true ); - $session->load_session(); $session->set_billing_postcode( '32191' ); $session->save(); @@ -462,7 +458,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $customer_id = $customer->get_id(); $meta_value = time() . '-custom-value'; add_user_meta( $customer_id, 'test_field', $meta_value, true ); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $fields = $customer->get_meta_data(); $this->assertEquals( $meta_value, $customer->get_meta( 'test_field' ) ); } @@ -477,7 +473,7 @@ class WC_Tests_CustomerCRUD extends WC_Unit_Test_Case { $meta_value = time() . '-custom-value'; $customer->add_meta_data( 'my-field', $meta_value, true ); $customer->save(); - $customer->read( $customer_id ); + $customer = new WC_Customer( $customer_id ); $this->assertEquals( $meta_value, $customer->get_meta( 'my-field' ) ); } } diff --git a/woocommerce.php b/woocommerce.php index f3101100b36..66f037024db 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -287,8 +287,11 @@ final class WooCommerce { include_once( WC_ABSPATH . 'includes/class-wc-data-store.php' ); // WC_Data_Store for CRUD include_once( WC_ABSPATH . 'includes/data-stores/interfaces/interface-wc-object-data-store.php' ); include_once( WC_ABSPATH . 'includes/data-stores/interfaces/interface-wc-coupon-data-store.php' ); + include_once( WC_ABSPATH . 'includes/data-stores/interfaces/wc-customer-data-store-interface.php' ); include_once( WC_ABSPATH . 'includes/data-stores/class-wc-data-store-cpt.php' ); include_once( WC_ABSPATH . 'includes/data-stores/class-wc-coupon-data-store-cpt.php' ); + include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store.php' ); + include_once( WC_ABSPATH . 'includes/data-stores/class-wc-customer-data-store-session.php' ); if ( defined( 'WP_CLI' ) && WP_CLI ) { include_once( WC_ABSPATH . 'includes/class-wc-cli.php' ); @@ -349,8 +352,9 @@ final class WooCommerce { // Classes/actions loaded for the frontend and for ajax requests. if ( $this->is_request( 'frontend' ) ) { $this->cart = new WC_Cart(); // Cart class, stores the cart contents - $this->customer = new WC_Customer( get_current_user_id(), true ); // Customer class, handles data such as customer location $this->structured_data = new WC_Structured_Data(); // Structured Data class, generates and handles structured data + $this->customer = new WC_Customer( get_current_user_id(), true ); // Customer class, handles data such as customer location + add_action( 'shutdown', array( $this->customer, 'save' ), 10 ); // Customer should be saved during shutdown. } $this->load_webhooks(); From eade55041c4c6bf3fe47dc2b5c95a79861c444a4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 15 Nov 2016 18:11:25 +0000 Subject: [PATCH 2/4] Delete args --- includes/class-wc-data-store.php | 6 +++--- .../class-wc-coupon-data-store-cpt.php | 11 ++++++++--- .../class-wc-customer-data-store-session.php | 4 ++-- .../data-stores/class-wc-customer-data-store.php | 16 +++++++++------- .../interface-wc-object-data-store.php | 1 + tests/framework/class-wc-dummy-data-store.php | 4 ++-- 6 files changed, 25 insertions(+), 17 deletions(-) diff --git a/includes/class-wc-data-store.php b/includes/class-wc-data-store.php index bc9c2a8502a..053d559348f 100644 --- a/includes/class-wc-data-store.php +++ b/includes/class-wc-data-store.php @@ -125,10 +125,10 @@ class WC_Data_Store { * * @since 2.7.0 * @param WC_Data - * @param bool $force_delete True to permently delete, false to trash. + * @param array $args Array of args to pass to the delete method. */ - public function delete( &$data, $force_delete = false ) { - $this->instance->delete( $data, $force_delete ); + public function delete( &$data, $args = array() ) { + $this->instance->delete( $data, $args ); } /** diff --git a/includes/data-stores/class-wc-coupon-data-store-cpt.php b/includes/data-stores/class-wc-coupon-data-store-cpt.php index ac737f9696a..03fff7bd472 100644 --- a/includes/data-stores/class-wc-coupon-data-store-cpt.php +++ b/includes/data-stores/class-wc-coupon-data-store-cpt.php @@ -106,11 +106,16 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_CPT implements WC_Coupon_Da * * @since 2.7.0 * @param WC_Coupon - * @param bool $force_delete True to permently delete, false to trash. + * @param array $args Array of args to pass to the delete method. */ - public function delete( &$coupon, $force_delete = false ) { + public function delete( &$coupon, $args = array() ) { + $args = wp_parse_args( $args, array( + 'force_delete' => false, + ) ); + $id = $coupon->get_id(); - if ( $force_delete ) { + + if ( $args['force_delete'] ) { wp_delete_post( $coupon->get_id() ); $coupon->set_id( 0 ); } else { diff --git a/includes/data-stores/class-wc-customer-data-store-session.php b/includes/data-stores/class-wc-customer-data-store-session.php index 964e429df4e..a2e8e39965d 100644 --- a/includes/data-stores/class-wc-customer-data-store-session.php +++ b/includes/data-stores/class-wc-customer-data-store-session.php @@ -134,9 +134,9 @@ class WC_Customer_Data_Store_Session implements WC_Customer_Data_Store_Interface * * @since 2.7.0 * @param WC_Customer - * @param int|null $reassign Who to reassign posts to. + * @param array $args Array of args to pass to the delete method. */ - public function delete( &$customer, $force_delete = true, $reassign = null ) { + public function delete( &$customer, $args = array() ) { WC()->session->set( 'customer', null ); } diff --git a/includes/data-stores/class-wc-customer-data-store.php b/includes/data-stores/class-wc-customer-data-store.php index c68be2847e9..8e1695e4a52 100644 --- a/includes/data-stores/class-wc-customer-data-store.php +++ b/includes/data-stores/class-wc-customer-data-store.php @@ -28,7 +28,8 @@ class WC_Customer_Data_Store implements WC_Customer_Data_Store_Interface, WC_Obj $wp_user = new WP_User( $customer->get_id() ); $customer->set_date_created( strtotime( $wp_user->user_registered ) ); $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); - $customer->read_meta_data(); + $customer->save_meta_data(); + $customer->apply_changes(); } } @@ -44,13 +45,11 @@ class WC_Customer_Data_Store implements WC_Customer_Data_Store_Interface, WC_Obj // User object is required. if ( ! $customer->get_id() || ! ( $user_object = get_user_by( 'id', $customer->get_id() ) ) || empty( $user_object->ID ) ) { throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); - return; } // Only users on this site should be read. if ( is_multisite() && ! is_user_member_of_blog( $customer->get_id() ) ) { throw new Exception( __( 'Invalid customer.', 'woocommerce' ) ); - return; } $customer_id = $customer->get_id(); @@ -83,6 +82,7 @@ class WC_Customer_Data_Store implements WC_Customer_Data_Store_Interface, WC_Obj $this->update_user_meta( $customer ); $customer->set_date_modified( get_user_meta( $customer->get_id(), 'last_update', true ) ); $customer->save_meta_data(); + $customer->apply_changes(); } /** @@ -90,14 +90,16 @@ class WC_Customer_Data_Store implements WC_Customer_Data_Store_Interface, WC_Obj * * @since 2.7.0 * @param WC_Customer - * @param bool $force_delete Unused for customers. - * @param int|null $reassign Who to reassign posts to. + * @param array $args Array of args to pass to the delete method. */ - public function delete( &$customer, $force_delete = true, $reassign = null ) { + public function delete( &$customer, $args = array() ) { if ( ! $customer->get_id() ) { return; } - return wp_delete_user( $customer->get_id(), $reassign ); + $args = wp_parse_args( $args, array( + 'reassign' => 0, + ) ); + return wp_delete_user( $customer->get_id(), $args['reassign'] ); } /** diff --git a/includes/data-stores/interfaces/interface-wc-object-data-store.php b/includes/data-stores/interfaces/interface-wc-object-data-store.php index ec05d08573d..0cf948d1772 100644 --- a/includes/data-stores/interfaces/interface-wc-object-data-store.php +++ b/includes/data-stores/interfaces/interface-wc-object-data-store.php @@ -34,6 +34,7 @@ interface WC_Object_Data_Store { * Deletes a record from the database. * @param WC_Data * @param bool $force_delete True to permently delete, false to trash. + * @return bool result */ public function delete( &$data, $force_delete = false ); } diff --git a/tests/framework/class-wc-dummy-data-store.php b/tests/framework/class-wc-dummy-data-store.php index bc622b49afb..39fdbc38f73 100644 --- a/tests/framework/class-wc-dummy-data-store.php +++ b/tests/framework/class-wc-dummy-data-store.php @@ -16,7 +16,7 @@ class WC_Dummy_Data_Store_CPT implements WC_Object_Data_Store { public function create( &$data ) { } public function read( &$data ) { } public function update( &$data ) { } - public function delete( &$data, $force_delete = false ) { } + public function delete( &$data, $args = array() ) { } } /** @@ -32,5 +32,5 @@ class WC_Dummy_Data_Store_Custom_Table implements WC_Object_Data_Store { public function create( &$data ) { } public function read( &$data ) { } public function update( &$data ) { } - public function delete( &$data, $force_delete = false ) { } + public function delete( &$data, $args = array() ) { } } From 53524141b7c9ac0de6f50de7a19886e9f428c8cf Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 15 Nov 2016 11:35:10 -0800 Subject: [PATCH 3/4] Fix up the other delete signatures. --- includes/abstracts/abstract-wc-data.php | 2 +- includes/class-wc-customer.php | 2 +- .../interfaces/interface-wc-object-data-store.php | 6 +++--- .../interfaces/wc-customer-data-store-interface.php | 8 -------- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/includes/abstracts/abstract-wc-data.php b/includes/abstracts/abstract-wc-data.php index c8419406df1..051f7230128 100644 --- a/includes/abstracts/abstract-wc-data.php +++ b/includes/abstracts/abstract-wc-data.php @@ -117,7 +117,7 @@ abstract class WC_Data { */ public function delete( $force_delete = false ) { if ( $this->data_store ) { - $this->data_store->delete( $this, $force_delete ); + $this->data_store->delete( $this, array( 'force_delete' => $force_delete ) ); $this->set_id( 0 ); return true; } diff --git a/includes/class-wc-customer.php b/includes/class-wc-customer.php index e894d2c5aee..b9e29b5b41f 100644 --- a/includes/class-wc-customer.php +++ b/includes/class-wc-customer.php @@ -190,7 +190,7 @@ class WC_Customer extends WC_Legacy_Customer { */ public function delete_and_reassign( $reassign = null ) { if ( $this->data_store ) { - $this->data_store->delete( $this, true, $reassign ); + $this->data_store->delete( $this, array( 'force_delete' => true, 'reassign' => $reassign ) ); $this->set_id( 0 ); return true; } diff --git a/includes/data-stores/interfaces/interface-wc-object-data-store.php b/includes/data-stores/interfaces/interface-wc-object-data-store.php index 0cf948d1772..f0de8bd8405 100644 --- a/includes/data-stores/interfaces/interface-wc-object-data-store.php +++ b/includes/data-stores/interfaces/interface-wc-object-data-store.php @@ -32,9 +32,9 @@ interface WC_Object_Data_Store { /** * Deletes a record from the database. - * @param WC_Data - * @param bool $force_delete True to permently delete, false to trash. + * @param WC_Data + * @param array $args Array of args to pass to the delete method. * @return bool result */ - public function delete( &$data, $force_delete = false ); + public function delete( &$data, $args = array() ); } diff --git a/includes/data-stores/interfaces/wc-customer-data-store-interface.php b/includes/data-stores/interfaces/wc-customer-data-store-interface.php index 4dc649e8768..8a1996c3e82 100644 --- a/includes/data-stores/interfaces/wc-customer-data-store-interface.php +++ b/includes/data-stores/interfaces/wc-customer-data-store-interface.php @@ -14,14 +14,6 @@ if ( ! defined( 'ABSPATH' ) ) { */ interface WC_Customer_Data_Store_Interface { - /** - * Deletes a customer from the database. - * - * @param WC_Customer - * @param int|null $reassign Who to reassign posts to. - */ - public function delete( &$data, $reassign = null ); - /** * Gets the customers last order. * From e83ec0c235f06f29e8f103d4d609ad743d481de4 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 15 Nov 2016 15:25:36 -0800 Subject: [PATCH 4/4] Call apply_changes when updating and creating a coupon. --- includes/data-stores/class-wc-coupon-data-store-cpt.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/data-stores/class-wc-coupon-data-store-cpt.php b/includes/data-stores/class-wc-coupon-data-store-cpt.php index 03fff7bd472..c281c5e5530 100644 --- a/includes/data-stores/class-wc-coupon-data-store-cpt.php +++ b/includes/data-stores/class-wc-coupon-data-store-cpt.php @@ -36,6 +36,7 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_CPT implements WC_Coupon_Da $coupon->set_id( $coupon_id ); $this->update_post_meta( $coupon ); $coupon->save_meta_data(); + $coupon->apply_changes(); do_action( 'woocommerce_new_coupon', $coupon_id ); } } @@ -98,6 +99,7 @@ class WC_Coupon_Data_Store_CPT extends WC_Data_Store_CPT implements WC_Coupon_Da wp_update_post( $post_data ); $this->update_post_meta( $coupon ); $coupon->save_meta_data(); + $coupon->apply_changes(); do_action( 'woocommerce_update_coupon', $coupon->get_id() ); }