From c25c26b9da2914a57e7ea4ca003f58e72d5dbc44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9F=D0=B0=D0=B2=D0=B5=D0=BB?= Date: Tue, 2 Jun 2020 17:12:10 +0300 Subject: [PATCH] WIP: Combining everything... --- .../class-wc-retailcrm-abstract-builder.php | 172 ++-- src/include/class-wc-retailcrm-plugin.php | 16 + ... class-wc-retailcrm-customer-switcher.php} | 321 +++---- .../class-wc-retailcrm-history-assembler.php | 802 +++++++++--------- .../class-wc-retailcrm-paginated-request.php | 376 ++++---- ...class-wc-retailcrm-wc-customer-builder.php | 470 +++++----- ...etailcrm-wc-customer-corporate-builder.php | 497 +++++------ .../class-wc-retailcrm-builder-interface.php | 96 +-- ...wc-retailcrm-customer-switcher-result.php} | 100 +-- ...-wc-retailcrm-customer-switcher-state.php} | 292 +++---- src/retailcrm.php | 7 +- 11 files changed, 1591 insertions(+), 1558 deletions(-) rename src/include/components/{class-wc-retailcrm-customer-data-replacer.php => class-wc-retailcrm-customer-switcher.php} (54%) rename src/include/models/{class-wc-retailcrm-customer-data-replacer-result.php => class-wc-retailcrm-customer-switcher-result.php} (83%) rename src/include/models/{class-wc-retailcrm-customer-data-replacer-state.php => class-wc-retailcrm-customer-switcher-state.php} (80%) diff --git a/src/include/abstracts/class-wc-retailcrm-abstract-builder.php b/src/include/abstracts/class-wc-retailcrm-abstract-builder.php index a0842b3..dc2ac80 100644 --- a/src/include/abstracts/class-wc-retailcrm-abstract-builder.php +++ b/src/include/abstracts/class-wc-retailcrm-abstract-builder.php @@ -1,86 +1,86 @@ -data = $data; - return $this; - } - - /** - * @return array|mixed - */ - public function getData() - { - return $this->data; - } - - /** - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function reset() - { - $this->data = array(); - return $this; - } - - /** - * Returns key if it's present in data array (or object which implements ArrayAccess). - * Returns default value if key is not present in data, or data is not accessible as array. - * - * @param string $key - * @param mixed $default - * - * @return mixed - */ - protected function dataValue($key, $default = '') - { - return self::arrayValue($this->data, $key, $default); - } - - /** - * Returns key from array if it's present in array - * - * @param array|\ArrayObject $data - * @param mixed $key - * @param string $default - * - * @return mixed|string - */ - protected static function arrayValue($data, $key, $default = '') - { - if (!is_array($data) && !($data instanceof ArrayAccess)) { - return $default; - } - - if (array_key_exists($key, $data) && !empty($data[$key])) { - return $data[$key]; - } - - return $default; - } - - /** - * @return \WC_Retailcrm_Builder_Interface - */ - abstract public function build(); - - /** - * Returns builder result. Should return null if WC_Retailcrm_Abstract_Builder::isBuilt() == false. - * - * @return mixed|null - */ - abstract public function getResult(); -} +data = $data; + return $this; + } + + /** + * @return array|mixed + */ + public function getData() + { + return $this->data; + } + + /** + * @return $this|\WC_Retailcrm_Builder_Interface + */ + public function reset() + { + $this->data = array(); + return $this; + } + + /** + * Returns key if it's present in data array (or object which implements ArrayAccess). + * Returns default value if key is not present in data, or data is not accessible as array. + * + * @param string $key + * @param mixed $default + * + * @return mixed + */ + protected function dataValue($key, $default = '') + { + return self::arrayValue($this->data, $key, $default); + } + + /** + * Returns key from array if it's present in array + * + * @param array|\ArrayObject $data + * @param mixed $key + * @param string $default + * + * @return mixed|string + */ + protected static function arrayValue($data, $key, $default = '') + { + if (!is_array($data) && !($data instanceof ArrayAccess)) { + return $default; + } + + if (array_key_exists($key, $data) && !empty($data[$key])) { + return $data[$key]; + } + + return $default; + } + + /** + * @return \WC_Retailcrm_Builder_Interface + */ + abstract public function build(); + + /** + * Returns builder result. Should return null if WC_Retailcrm_Abstract_Builder::isBuilt() == false. + * + * @return mixed|null + */ + abstract public function getResult(); +} diff --git a/src/include/class-wc-retailcrm-plugin.php b/src/include/class-wc-retailcrm-plugin.php index ea5722a..5bb3232 100644 --- a/src/include/class-wc-retailcrm-plugin.php +++ b/src/include/class-wc-retailcrm-plugin.php @@ -164,6 +164,22 @@ class WC_Retailcrm_Plugin { return $result; } + /** + * Returns WC_Customer by id. Returns null if there's no such customer. + * + * @param int $id + * + * @return \WC_Customer|null + */ + public static function getWcCustomerById($id) + { + try { + return new WC_Customer($id); + } catch (\Exception $exception) { + return null; + } + } + /** * Check running history * diff --git a/src/include/components/class-wc-retailcrm-customer-data-replacer.php b/src/include/components/class-wc-retailcrm-customer-switcher.php similarity index 54% rename from src/include/components/class-wc-retailcrm-customer-data-replacer.php rename to src/include/components/class-wc-retailcrm-customer-switcher.php index ec9eee7..3a1594c 100644 --- a/src/include/components/class-wc-retailcrm-customer-data-replacer.php +++ b/src/include/components/class-wc-retailcrm-customer-switcher.php @@ -1,152 +1,169 @@ -reset(); - } - - /** - * In fact, this will execute customer change in provided order. - * This will not build anything. - * - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function build() - { - $this->data->validate(); - - $wcOrder = $this->data->getWcOrder(); - $newCustomer = $this->data->getNewCustomer(); - $newCorporateCustomer = $this->data->getNewCorporateCustomer(); - $newContact = $this->data->getNewContact(); - $newCompany = $this->data->getNewCompany(); - - if (!empty($newCustomer)) { - $this->processChangeToRegular($wcOrder, $newCustomer); - return $this; - } - - if (!empty($newContact)) { - $this->processChangeToContactPerson($wcOrder, $newContact); - } - - if (!empty($newCompany)) { - $this->updateCompany($wcOrder, $newCorporateCustomer, $newCompany); - } - - return $this; - } - - /** - * Change order customer to regular one - * - * @param \WC_Order $wcOrder - * @param array $newCustomer - */ - public function processChangeToRegular($wcOrder, $newCustomer) - { - // TODO: Implement - } - - /** - * Change order customer to corporate one (we only care about it's contact) - * - * @param \WC_Order $wcOrder - * @param array $newContact - */ - public function processChangeToContactPerson($wcOrder, $newContact) - { - // TODO: Implement - } - - /** - * Update company in the order - * - * @param WC_Order $wcOrder - * @param array $corporateCustomer - * @param array $company - */ - public function updateCompany($wcOrder, $corporateCustomer, $company) - { - // TODO: Implement - } - - /** - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function reset() - { - $this->data = new WC_Retailcrm_Customer_Data_Replacer_State(); - $this->result = null; - return $this; - } - - /** - * Set initial state into component - * - * @param \WC_Retailcrm_Customer_Data_Replacer_State $data - * - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function setData($data) - { - if (!($data instanceof WC_Retailcrm_Customer_Data_Replacer_State)) { - throw new \InvalidArgumentException('Invalid data type'); - } - - $this->data = $data; - return $this; - } - - /** - * @return \WC_Retailcrm_Customer_Data_Replacer_Result|null - */ - public function getResult() - { - return $this->result; - } - - /** - * @return \WC_Retailcrm_Customer_Data_Replacer_State - */ - public function getData() - { - return $this->data; - } - - /** - * Returns WC_Customer by id. Returns null if there's no such customer. - * - * @param int $id - * - * @return \WC_Customer|null - */ - private function getWcCustomerById($id) - { - try { - return new WC_Customer($id); - } catch (\Exception $exception) { - return null; - } - } -} +reset(); + } + + /** + * In fact, this will execute customer change in provided order. + * This will not build anything. + * + * @return $this|\WC_Retailcrm_Builder_Interface + * @throws \WC_Data_Exception + */ + public function build() + { + $this->data->validate(); + + $wcOrder = $this->data->getWcOrder(); + $newCustomer = $this->data->getNewCustomer(); + $newCorporateCustomer = $this->data->getNewCorporateCustomer(); + $newContact = $this->data->getNewContact(); + $newCompany = $this->data->getNewCompany(); + + if (!empty($newCustomer)) { + $this->processChangeToRegular($wcOrder, $newCustomer); + return $this; + } + + if (!empty($newContact)) { + $this->processChangeToRegular($wcOrder, $newContact); + } + + if (!empty($newCompany)) { + $this->updateCompany($wcOrder, $newCorporateCustomer, $newCompany); + } + + return $this; + } + + /** + * Change order customer to regular one + * + * @param \WC_Order $wcOrder + * @param array $newCustomer + * + * @throws \WC_Data_Exception + */ + public function processChangeToRegular($wcOrder, $newCustomer) + { + $wcCustomer = null; + + if (isset($newCustomer['externalId'])) { + $wcCustomer = WC_Retailcrm_Plugin::getWcCustomerById($newCustomer['externalId']); + + if (!empty($wcCustomer)) { + $wcOrder->set_customer_id($wcCustomer->get_id()); + } + } + + $fields = array( + 'billing_first_name' => self::arrayValue($newCustomer, 'firstName'), + 'billing_last_name' => self::arrayValue($newCustomer, 'lastName'), + 'billing_email' => self::arrayValue($newCustomer, 'email') + ); + + foreach ($fields as $field => $value) { + $wcOrder->{'set_' . $field}($value); + } + + $wcOrder->set_billing_company(''); + $this->result = new WC_Retailcrm_Customer_Switcher_Result($wcCustomer, $wcOrder); + } + + /** + * Update company in the order + * + * @param WC_Order $wcOrder + * @param array $corporateCustomer + * @param array $company + */ + public function updateCompany($wcOrder, $corporateCustomer, $company) + { + // TODO: Implement + } + + /** + * @return $this|\WC_Retailcrm_Builder_Interface + */ + public function reset() + { + $this->data = new WC_Retailcrm_Customer_Switcher_State(); + $this->result = null; + return $this; + } + + /** + * Set initial state into component + * + * @param \WC_Retailcrm_Customer_Switcher_State $data + * + * @return $this|\WC_Retailcrm_Builder_Interface + */ + public function setData($data) + { + if (!($data instanceof WC_Retailcrm_Customer_Switcher_State)) { + throw new \InvalidArgumentException('Invalid data type'); + } + + $this->data = $data; + return $this; + } + + /** + * @return \WC_Retailcrm_Customer_Switcher_Result|null + */ + public function getResult() + { + return $this->result; + } + + /** + * @return \WC_Retailcrm_Customer_Switcher_State + */ + public function getData() + { + return $this->data; + } + + /** + * @param array|\ArrayObject|\ArrayAccess $arr + * @param string $key + * @param string $def + * + * @return mixed|string + */ + private static function arrayValue($arr, $key, $def = '') + { + if (!is_array($arr) && !($arr instanceof ArrayObject) && !($arr instanceof ArrayAccess)) { + return $def; + } + + if (!array_key_exists($key, $arr) && !empty($arr[$key])) { + return $def; + } + + return $arr[$key]; + } +} diff --git a/src/include/components/class-wc-retailcrm-history-assembler.php b/src/include/components/class-wc-retailcrm-history-assembler.php index 85ffe09..f7f47a1 100644 --- a/src/include/components/class-wc-retailcrm-history-assembler.php +++ b/src/include/components/class-wc-retailcrm-history-assembler.php @@ -1,402 +1,402 @@ - &$customer) { - if (empty($customer['id']) && !empty($id)) { - $customer['id'] = $id; - $customer['deleted'] = true; - } - } - - return $customersCorporate; - } - - /** - * Returns mapping data for retailCRM entities. Used to assembly entities from history. - * - * @param array $groupFilter - * - * @return array - */ - private static function getMappingValues($groupFilter = array()) - { - $fields = array(); - $mappingFile = implode( - DIRECTORY_SEPARATOR, - array(WP_CONTENT_DIR, 'plugins', 'woo-retailcrm', 'config', 'objects.xml') - ); - - if (file_exists($mappingFile)) { - $objects = simplexml_load_file($mappingFile); - - foreach($objects->fields->field as $object) { - if (empty($groupFilter) || in_array($object["group"], $groupFilter)) { - $fields[(string)$object["group"]][(string)$object["id"]] = (string)$object; - } - } - } - - return $fields; - } - - /** - * Value accessor - * - * @param array $value - * - * @return mixed - */ - private static function newValue($value) - { - if (isset($value['code'])) { - return $value['code']; - } else { - return $value; - } - } - - /** - * Returns array without values which are considered empty - * - * @param array|\ArrayAccess $inputArray - * - * @return array - */ - private static function removeEmpty($inputArray) - { - $outputArray = array(); - - if (!empty($inputArray)) { - foreach ($inputArray as $key => $element) { - if(!empty($element) || $element === 0 || $element === '0'){ - if (is_array($element)) { - $element = self::removeEmpty($element); - } - - $outputArray[$key] = $element; - } - } - } - - return $outputArray; - } - - /** - * Filters out history by these terms: - * - Changes from current API key will be added only if CMS changes are more actual than history. - * - All other changes will be merged as usual. - * It fixes these problems: - * - Changes from current API key are merged when it's not needed. - * - Changes from CRM can overwrite more actual changes from CMS due to ignoring current API key changes. - * - * @param array $historyEntries Raw history from CRM - * @param string $recordType Entity field name, e.g. `customer` or `order`. - * - * @return array - */ - private static function filterHistory($historyEntries, $recordType) - { - $history = array(); - $organizedHistory = array(); - $notOurChanges = array(); - - foreach ($historyEntries as $entry) { - if (!isset($entry[$recordType]['externalId'])) { - if ($entry['source'] == 'api' - && isset($change['apiKey']['current']) - && $entry['apiKey']['current'] == true - && $entry['field'] != 'externalId' - ) { - continue; - } else { - $history[] = $entry; - } - - continue; - } - - $externalId = $entry[$recordType]['externalId']; - $field = $entry['field']; - - if (!isset($organizedHistory[$externalId])) { - $organizedHistory[$externalId] = array(); - } - - if (!isset($notOurChanges[$externalId])) { - $notOurChanges[$externalId] = array(); - } - - if ($entry['source'] == 'api' - && isset($entry['apiKey']['current']) - && $entry['apiKey']['current'] == true - ) { - if (isset($notOurChanges[$externalId][$field]) || $entry['field'] == 'externalId') { - $organizedHistory[$externalId][] = $entry; - } else { - continue; - } - } else { - $organizedHistory[$externalId][] = $entry; - $notOurChanges[$externalId][$field] = true; - } - } - - unset($notOurChanges); - - foreach ($organizedHistory as $historyChunk) { - $history = array_merge($history, $historyChunk); - } - - return $history; - } + &$customer) { + if (empty($customer['id']) && !empty($id)) { + $customer['id'] = $id; + $customer['deleted'] = true; + } + } + + return $customersCorporate; + } + + /** + * Returns mapping data for retailCRM entities. Used to assembly entities from history. + * + * @param array $groupFilter + * + * @return array + */ + private static function getMappingValues($groupFilter = array()) + { + $fields = array(); + $mappingFile = implode( + DIRECTORY_SEPARATOR, + array(WP_CONTENT_DIR, 'plugins', 'woo-retailcrm', 'config', 'objects.xml') + ); + + if (file_exists($mappingFile)) { + $objects = simplexml_load_file($mappingFile); + + foreach($objects->fields->field as $object) { + if (empty($groupFilter) || in_array($object["group"], $groupFilter)) { + $fields[(string)$object["group"]][(string)$object["id"]] = (string)$object; + } + } + } + + return $fields; + } + + /** + * Value accessor + * + * @param array $value + * + * @return mixed + */ + private static function newValue($value) + { + if (isset($value['code'])) { + return $value['code']; + } else { + return $value; + } + } + + /** + * Returns array without values which are considered empty + * + * @param array|\ArrayAccess $inputArray + * + * @return array + */ + private static function removeEmpty($inputArray) + { + $outputArray = array(); + + if (!empty($inputArray)) { + foreach ($inputArray as $key => $element) { + if(!empty($element) || $element === 0 || $element === '0'){ + if (is_array($element)) { + $element = self::removeEmpty($element); + } + + $outputArray[$key] = $element; + } + } + } + + return $outputArray; + } + + /** + * Filters out history by these terms: + * - Changes from current API key will be added only if CMS changes are more actual than history. + * - All other changes will be merged as usual. + * It fixes these problems: + * - Changes from current API key are merged when it's not needed. + * - Changes from CRM can overwrite more actual changes from CMS due to ignoring current API key changes. + * + * @param array $historyEntries Raw history from CRM + * @param string $recordType Entity field name, e.g. `customer` or `order`. + * + * @return array + */ + private static function filterHistory($historyEntries, $recordType) + { + $history = array(); + $organizedHistory = array(); + $notOurChanges = array(); + + foreach ($historyEntries as $entry) { + if (!isset($entry[$recordType]['externalId'])) { + if ($entry['source'] == 'api' + && isset($change['apiKey']['current']) + && $entry['apiKey']['current'] == true + && $entry['field'] != 'externalId' + ) { + continue; + } else { + $history[] = $entry; + } + + continue; + } + + $externalId = $entry[$recordType]['externalId']; + $field = $entry['field']; + + if (!isset($organizedHistory[$externalId])) { + $organizedHistory[$externalId] = array(); + } + + if (!isset($notOurChanges[$externalId])) { + $notOurChanges[$externalId] = array(); + } + + if ($entry['source'] == 'api' + && isset($entry['apiKey']['current']) + && $entry['apiKey']['current'] == true + ) { + if (isset($notOurChanges[$externalId][$field]) || $entry['field'] == 'externalId') { + $organizedHistory[$externalId][] = $entry; + } else { + continue; + } + } else { + $organizedHistory[$externalId][] = $entry; + $notOurChanges[$externalId][$field] = true; + } + } + + unset($notOurChanges); + + foreach ($organizedHistory as $historyChunk) { + $history = array_merge($history, $historyChunk); + } + + return $history; + } } \ No newline at end of file diff --git a/src/include/components/class-wc-retailcrm-paginated-request.php b/src/include/components/class-wc-retailcrm-paginated-request.php index 9c5fa28..e190de9 100644 --- a/src/include/components/class-wc-retailcrm-paginated-request.php +++ b/src/include/components/class-wc-retailcrm-paginated-request.php @@ -1,188 +1,188 @@ -reset(); - } - - /** - * Sets retailCRM api client to request - * - * @param \WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V5 $api - * - * @return self - */ - public function setApi($api) - { - $this->api = $api; - return $this; - } - - /** - * Sets API client method to request - * - * @param string $method - * - * @return self - */ - public function setMethod($method) - { - $this->method = $method; - return $this; - } - - /** - * Sets method params for API client (leave `{{page}}` instead of page and `{{limit}}` instead of limit) - * - * @param array $params - * - * @return self - */ - public function setParams($params) - { - $this->params = $params; - return $this; - } - - /** - * Sets dataKey (key with data in response) - * - * @param string $dataKey - * - * @return self - */ - public function setDataKey($dataKey) - { - $this->dataKey = $dataKey; - return $this; - } - - /** - * Sets record limit per request - * - * @param int $limit - * - * @return self - */ - public function setLimit($limit) - { - $this->limit = $limit; - return $this; - } - - /** - * Executes request - * - * @return $this - */ - public function execute() - { - $this->data = array(); - $response = true; - $page = 1; - - do { - $response = call_user_func_array( - array($this->api, $this->method), - $this->buildParams($this->params, $page) - ); - - if ($response instanceof WC_Retailcrm_Response && $response->offsetExists($this->dataKey)) { - $this->data = array_merge($response[$this->dataKey]); - $page = $response['pagination']['currentPage'] + 1; - } - - time_nanosleep(0, 300000000); - } while ($response && (isset($response['pagination']) - && $response['pagination']['currentPage'] < $response['pagination']['totalPageCount'])); - - return $this; - } - - /** - * Returns data - * - * @return array - */ - public function getData() - { - return $this->data; - } - - /** - * Reset paginated request - * - * @return $this - */ - public function reset() - { - $this->method = ''; - $this->limit = 100; - $this->data = array(); - - return $this; - } - - /** - * buildParams - * - * @param array $placeholderParams - * @param int $currentPage - * - * @return mixed - */ - private function buildParams($placeholderParams, $currentPage) - { - foreach ($placeholderParams as $key => $param) { - if ($param == '{{page}}') { - $placeholderParams[$key] = $currentPage; - } - - if ($param == '{{limit}}') { - $placeholderParams[$key] = $this->limit; - } - } - - return $placeholderParams; - } -} +reset(); + } + + /** + * Sets retailCRM api client to request + * + * @param \WC_Retailcrm_Proxy|\WC_Retailcrm_Client_V5 $api + * + * @return self + */ + public function setApi($api) + { + $this->api = $api; + return $this; + } + + /** + * Sets API client method to request + * + * @param string $method + * + * @return self + */ + public function setMethod($method) + { + $this->method = $method; + return $this; + } + + /** + * Sets method params for API client (leave `{{page}}` instead of page and `{{limit}}` instead of limit) + * + * @param array $params + * + * @return self + */ + public function setParams($params) + { + $this->params = $params; + return $this; + } + + /** + * Sets dataKey (key with data in response) + * + * @param string $dataKey + * + * @return self + */ + public function setDataKey($dataKey) + { + $this->dataKey = $dataKey; + return $this; + } + + /** + * Sets record limit per request + * + * @param int $limit + * + * @return self + */ + public function setLimit($limit) + { + $this->limit = $limit; + return $this; + } + + /** + * Executes request + * + * @return $this + */ + public function execute() + { + $this->data = array(); + $response = true; + $page = 1; + + do { + $response = call_user_func_array( + array($this->api, $this->method), + $this->buildParams($this->params, $page) + ); + + if ($response instanceof WC_Retailcrm_Response && $response->offsetExists($this->dataKey)) { + $this->data = array_merge($response[$this->dataKey]); + $page = $response['pagination']['currentPage'] + 1; + } + + time_nanosleep(0, 300000000); + } while ($response && (isset($response['pagination']) + && $response['pagination']['currentPage'] < $response['pagination']['totalPageCount'])); + + return $this; + } + + /** + * Returns data + * + * @return array + */ + public function getData() + { + return $this->data; + } + + /** + * Reset paginated request + * + * @return $this + */ + public function reset() + { + $this->method = ''; + $this->limit = 100; + $this->data = array(); + + return $this; + } + + /** + * buildParams + * + * @param array $placeholderParams + * @param int $currentPage + * + * @return mixed + */ + private function buildParams($placeholderParams, $currentPage) + { + foreach ($placeholderParams as $key => $param) { + if ($param == '{{page}}') { + $placeholderParams[$key] = $currentPage; + } + + if ($param == '{{limit}}') { + $placeholderParams[$key] = $this->limit; + } + } + + return $placeholderParams; + } +} diff --git a/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-builder.php b/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-builder.php index f65cf77..2ad5dc6 100644 --- a/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-builder.php +++ b/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-builder.php @@ -1,235 +1,235 @@ -reset(); - } - - /** - * @param string $firstName - * - * @return $this - */ - public function setFirstName($firstName) - { - $this->data['firstName'] = $firstName; - return $this; - } - - /** - * @param string $lastName - * - * @return $this - */ - public function setLastName($lastName) - { - $this->data['lastName'] = $lastName; - return $this; - } - - /** - * @param string $email - * - * @return $this - */ - public function setEmail($email) - { - $this->data['email'] = $email; - return $this; - } - - /** - * @param string $externalId - * - * @return $this - */ - public function setExternalId($externalId) - { - $this->data['externalId'] = $externalId; - return $this; - } - - /** - * @param array $phones - * - * @return $this - */ - public function setPhones($phones) - { - if (self::isPhonesArrayValid($phones)) { - $this->data['phones'] = $phones; - } - - return $this; - } - - /** - * @param array $address - * - * @return $this - */ - public function setAddress($address) - { - if (is_array($address)) { - $this->data['address'] = $address; - } - - return $this; - } - - /** - * @param \WC_Customer $customer - * - * @return $this - */ - public function setWcCustomer($customer) - { - if ($customer instanceof WC_Customer) { - $this->customer = $customer; - } - - return $this; - } - - /** - * Sets provided externalId and loads associated customer from DB (it it exists there). - * Returns true if everything went find; returns false if customer wasn't found. - * - * @param string $externalId - * - * @return bool - * @throws \Exception - */ - public function loadExternalId($externalId) - { - try { - $wcCustomer = new WC_Customer($externalId); - } catch (\Exception $exception) { - return false; - } - - $this->setExternalId($externalId); - $this->setWcCustomer($wcCustomer); - - return true; - } - - public function reset() - { - parent::reset(); - $this->customer = new WC_Customer(); - - return $this; - } - - /** - * Fill WC_Customer fields with customer data from retailCRM. - * If field is not present in retailCRM customer - it will remain unchanged. - * - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function build() - { - $this->checkBuilderValidity(); - WC_Retailcrm_Logger::debug(__METHOD__, 'Building WC_Customer from data:', $this->data); - $this->customer->set_first_name($this->dataValue('firstName', $this->customer->get_first_name())); - $this->customer->set_last_name($this->dataValue('lastName', $this->customer->get_last_name())); - $this->customer->set_billing_email($this->dataValue('email', $this->customer->get_billing_email())); - $phones = $this->dataValue('phones', array()); - - if (count($phones) > 0) { - $phoneData = reset($phones); - - if (is_array($phoneData) && isset($phoneData['number'])) { - $this->customer->set_billing_phone($phoneData['number']); - } - } - - if (!empty($this->dataValue('address'))) { - $address = $this->dataValue('address'); - - $this->customer->set_billing_state(self::arrayValue( - $address, - 'region', - $this->customer->get_billing_state()) - ); - $this->customer->set_billing_postcode(self::arrayValue( - $address, - 'index', - $this->customer->get_billing_postcode()) - ); - $this->customer->set_billing_country(self::arrayValue( - $address, - 'country', - $this->customer->get_billing_country()) - ); - $this->customer->set_billing_city(self::arrayValue( - $address, - 'city', - $this->customer->get_billing_city()) - ); - } - - return $this; - } - - /** - * @return mixed|\WC_Customer|null - */ - public function getResult() - { - return $this->customer; - } - - /** - * Throws an exception if internal state is not ready for data building. - * - * @throws \RuntimeException - */ - private function checkBuilderValidity() - { - if (empty($this->data)) { - throw new \RuntimeException('Empty data'); - } - - if (!is_array($this->data)) { - throw new \RuntimeException('Data must be an array'); - } - } - - /** - * Returns true if provided variable contains array with customer phones. - * - * @param mixed $phones - * - * @return bool - */ - private static function isPhonesArrayValid($phones) - { - if (!is_array($phones)) { - return false; - } - - foreach ($phones as $phone) { - if (!is_array($phone) || count($phone) != 1 || !array_key_exists('number', $phone)) { - return false; - } - } - - return true; - } -} +reset(); + } + + /** + * @param string $firstName + * + * @return $this + */ + public function setFirstName($firstName) + { + $this->data['firstName'] = $firstName; + return $this; + } + + /** + * @param string $lastName + * + * @return $this + */ + public function setLastName($lastName) + { + $this->data['lastName'] = $lastName; + return $this; + } + + /** + * @param string $email + * + * @return $this + */ + public function setEmail($email) + { + $this->data['email'] = $email; + return $this; + } + + /** + * @param string $externalId + * + * @return $this + */ + public function setExternalId($externalId) + { + $this->data['externalId'] = $externalId; + return $this; + } + + /** + * @param array $phones + * + * @return $this + */ + public function setPhones($phones) + { + if (self::isPhonesArrayValid($phones)) { + $this->data['phones'] = $phones; + } + + return $this; + } + + /** + * @param array $address + * + * @return $this + */ + public function setAddress($address) + { + if (is_array($address)) { + $this->data['address'] = $address; + } + + return $this; + } + + /** + * @param \WC_Customer $customer + * + * @return $this + */ + public function setWcCustomer($customer) + { + if ($customer instanceof WC_Customer) { + $this->customer = $customer; + } + + return $this; + } + + /** + * Sets provided externalId and loads associated customer from DB (it it exists there). + * Returns true if everything went find; returns false if customer wasn't found. + * + * @param string $externalId + * + * @return bool + * @throws \Exception + */ + public function loadExternalId($externalId) + { + try { + $wcCustomer = new WC_Customer($externalId); + } catch (\Exception $exception) { + return false; + } + + $this->setExternalId($externalId); + $this->setWcCustomer($wcCustomer); + + return true; + } + + public function reset() + { + parent::reset(); + $this->customer = new WC_Customer(); + + return $this; + } + + /** + * Fill WC_Customer fields with customer data from retailCRM. + * If field is not present in retailCRM customer - it will remain unchanged. + * + * @return $this|\WC_Retailcrm_Builder_Interface + */ + public function build() + { + $this->checkBuilderValidity(); + WC_Retailcrm_Logger::debug(__METHOD__, 'Building WC_Customer from data:', $this->data); + $this->customer->set_first_name($this->dataValue('firstName', $this->customer->get_first_name())); + $this->customer->set_last_name($this->dataValue('lastName', $this->customer->get_last_name())); + $this->customer->set_billing_email($this->dataValue('email', $this->customer->get_billing_email())); + $phones = $this->dataValue('phones', array()); + + if (count($phones) > 0) { + $phoneData = reset($phones); + + if (is_array($phoneData) && isset($phoneData['number'])) { + $this->customer->set_billing_phone($phoneData['number']); + } + } + + if (!empty($this->dataValue('address'))) { + $address = $this->dataValue('address'); + + $this->customer->set_billing_state(self::arrayValue( + $address, + 'region', + $this->customer->get_billing_state()) + ); + $this->customer->set_billing_postcode(self::arrayValue( + $address, + 'index', + $this->customer->get_billing_postcode()) + ); + $this->customer->set_billing_country(self::arrayValue( + $address, + 'country', + $this->customer->get_billing_country()) + ); + $this->customer->set_billing_city(self::arrayValue( + $address, + 'city', + $this->customer->get_billing_city()) + ); + } + + return $this; + } + + /** + * @return mixed|\WC_Customer|null + */ + public function getResult() + { + return $this->customer; + } + + /** + * Throws an exception if internal state is not ready for data building. + * + * @throws \RuntimeException + */ + private function checkBuilderValidity() + { + if (empty($this->data)) { + throw new \RuntimeException('Empty data'); + } + + if (!is_array($this->data)) { + throw new \RuntimeException('Data must be an array'); + } + } + + /** + * Returns true if provided variable contains array with customer phones. + * + * @param mixed $phones + * + * @return bool + */ + private static function isPhonesArrayValid($phones) + { + if (!is_array($phones)) { + return false; + } + + foreach ($phones as $phone) { + if (!is_array($phone) || count($phone) != 1 || !array_key_exists('number', $phone)) { + return false; + } + } + + return true; + } +} diff --git a/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-corporate-builder.php b/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-corporate-builder.php index 784ffd7..181742e 100644 --- a/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-corporate-builder.php +++ b/src/include/customer/woocommerce/class-wc-retailcrm-wc-customer-corporate-builder.php @@ -1,248 +1,249 @@ -reset(); - } - - /** - * @param array $contactPerson - * - * @return \WC_Retailcrm_WC_Customer_Corporate_Builder - */ - public function setContactPerson($contactPerson) - { - $this->contactPerson = $contactPerson; - return $this; - } - - /** - * @return array - */ - public function getContactPerson() - { - return $this->contactPerson; - } - - /** - * @param \WC_Retailcrm_Builder_Interface $customerBuilder - */ - public function setCustomerBuilder($customerBuilder) - { - $this->customerBuilder = $customerBuilder; - } - - /** - * @param string $firstName - * - * @return $this - */ - public function setFirstName($firstName) - { - $this->contactPerson['firstName'] = $firstName; - return $this; - } - - /** - * @param string $lastName - * - * @return $this - */ - public function setLastName($lastName) - { - $this->contactPerson['lastName'] = $lastName; - return $this; - } - - /** - * @param string $email - * - * @return $this - */ - public function setEmail($email) - { - $this->contactPerson['email'] = $email; - return $this; - } - - /** - * @param string $externalId - * - * @return $this - */ - public function setExternalId($externalId) - { - $this->contactPerson['externalId'] = $externalId; - return $this; - } - - /** - * @param array $phones - * - * @return $this - */ - public function setPhones($phones) - { - if (self::isPhonesArrayValid($phones)) { - $this->contactPerson['phones'] = $phones; - } - - return $this; - } - - /** - * @param array $address - * - * @return $this - */ - public function setAddress($address) - { - if (is_array($address)) { - $this->contactPerson['address'] = $address; - } - - return $this; - } - - /** - * @param \WC_Customer $customer - * - * @return $this - */ - public function setWcCustomer($customer) - { - if ($customer instanceof WC_Customer) { - $this->customer = $customer; - } - - return $this; - } - - /** - * Sets provided externalId and loads associated customer from DB (it it exists there). - * Returns true if everything went find; returns false if customer wasn't found. - * - * @param string $externalId - * - * @return bool - * @throws \Exception - */ - public function loadExternalId($externalId) - { - try { - $wcCustomer = new WC_Customer($externalId); - } catch (\Exception $exception) { - return false; - } - - $this->setExternalId($externalId); - $this->setWcCustomer($wcCustomer); - - return true; - } - - public function reset() - { - parent::reset(); - $this->customer = new WC_Customer(); - $this->contactPerson = array(); - $this->customerBuilder = new WC_Retailcrm_WC_Customer_Builder(); - - return $this; - } - - /** - * Fill WC_Customer fields with customer data from retailCRM. - * If field is not present in retailCRM customer - it will remain unchanged. - * - * @return $this|\WC_Retailcrm_Builder_Interface - */ - public function build() - { - $this->checkBuilderValidity(); - WC_Retailcrm_Logger::debug( - __METHOD__, - 'Building WC_Customer from corporate data:', - $this->data, - "\nContact:", - $this->contactPerson - ); - - $wcCustomer = $this->customerBuilder - ->setData($this->contactPerson) - ->build() - ->getResult(); - - return $this; - } - - /** - * @return mixed|\WC_Customer|null - */ - public function getResult() - { - return $this->customer; - } - - /** - * Throws an exception if internal state is not ready for data building. - * - * @throws \RuntimeException - */ - private function checkBuilderValidity() - { - if (empty($this->data)) { - throw new \RuntimeException('Empty data'); - } - - if (!is_array($this->data)) { - throw new \RuntimeException('Data must be an array'); - } - } - - /** - * Returns true if provided variable contains array with customer phones. - * - * @param mixed $phones - * - * @return bool - */ - private static function isPhonesArrayValid($phones) - { - if (!is_array($phones)) { - return false; - } - - foreach ($phones as $phone) { - if (!is_array($phone) || count($phone) != 1 || !array_key_exists('number', $phone)) { - return false; - } - } - - return true; - } -} +reset(); + } + + /** + * @param array $contactPerson + * + * @return \WC_Retailcrm_WC_Customer_Corporate_Builder + */ + public function setContactPerson($contactPerson) + { + $this->contactPerson = $contactPerson; + return $this; + } + + /** + * @return array + */ + public function getContactPerson() + { + return $this->contactPerson; + } + + /** + * @param \WC_Retailcrm_Builder_Interface $customerBuilder + */ + public function setCustomerBuilder($customerBuilder) + { + $this->customerBuilder = $customerBuilder; + } + + /** + * @param string $firstName + * + * @return $this + */ + public function setFirstName($firstName) + { + $this->contactPerson['firstName'] = $firstName; + return $this; + } + + /** + * @param string $lastName + * + * @return $this + */ + public function setLastName($lastName) + { + $this->contactPerson['lastName'] = $lastName; + return $this; + } + + /** + * @param string $email + * + * @return $this + */ + public function setEmail($email) + { + $this->contactPerson['email'] = $email; + return $this; + } + + /** + * @param string $externalId + * + * @return $this + */ + public function setExternalId($externalId) + { + $this->contactPerson['externalId'] = $externalId; + return $this; + } + + /** + * @param array $phones + * + * @return $this + */ + public function setPhones($phones) + { + if (self::isPhonesArrayValid($phones)) { + $this->contactPerson['phones'] = $phones; + } + + return $this; + } + + /** + * @param array $address + * + * @return $this + */ + public function setAddress($address) + { + if (is_array($address)) { + $this->contactPerson['address'] = $address; + } + + return $this; + } + + /** + * @param \WC_Customer $customer + * + * @return $this + */ + public function setWcCustomer($customer) + { + if ($customer instanceof WC_Customer) { + $this->customer = $customer; + } + + return $this; + } + + /** + * Sets provided externalId and loads associated customer from DB (it it exists there). + * Returns true if everything went find; returns false if customer wasn't found. + * + * @param string $externalId + * + * @return bool + * @throws \Exception + */ + public function loadExternalId($externalId) + { + try { + $wcCustomer = new WC_Customer($externalId); + } catch (\Exception $exception) { + return false; + } + + $this->setExternalId($externalId); + $this->setWcCustomer($wcCustomer); + + return true; + } + + public function reset() + { + parent::reset(); + $this->customer = new WC_Customer(); + $this->contactPerson = array(); + $this->customerBuilder = new WC_Retailcrm_WC_Customer_Builder(); + + return $this; + } + + /** + * Fill WC_Customer fields with customer data from retailCRM. + * If field is not present in retailCRM customer - it will remain unchanged. + * + * @return $this|\WC_Retailcrm_Builder_Interface + * @throws \Exception + */ + public function build() + { + $this->checkBuilderValidity(); + WC_Retailcrm_Logger::debug( + __METHOD__, + 'Building WC_Customer from corporate data:', + $this->data, + "\nContact:", + $this->contactPerson + ); + + $wcCustomer = $this->customerBuilder + ->setData($this->contactPerson) + ->build() + ->getResult(); + + return $this; + } + + /** + * @return mixed|\WC_Customer|null + */ + public function getResult() + { + return $this->customer; + } + + /** + * Throws an exception if internal state is not ready for data building. + * + * @throws \RuntimeException + */ + private function checkBuilderValidity() + { + if (empty($this->data)) { + throw new \RuntimeException('Empty data'); + } + + if (!is_array($this->data)) { + throw new \RuntimeException('Data must be an array'); + } + } + + /** + * Returns true if provided variable contains array with customer phones. + * + * @param mixed $phones + * + * @return bool + */ + private static function isPhonesArrayValid($phones) + { + if (!is_array($phones)) { + return false; + } + + foreach ($phones as $phone) { + if (!is_array($phone) || count($phone) != 1 || !array_key_exists('number', $phone)) { + return false; + } + } + + return true; + } +} diff --git a/src/include/interfaces/class-wc-retailcrm-builder-interface.php b/src/include/interfaces/class-wc-retailcrm-builder-interface.php index a493078..034b681 100644 --- a/src/include/interfaces/class-wc-retailcrm-builder-interface.php +++ b/src/include/interfaces/class-wc-retailcrm-builder-interface.php @@ -1,48 +1,48 @@ -wcCustomer = $wcCustomer; - $this->wcOrder = $wcOrder; - - if ((!is_null($this->wcCustomer) && !($this->wcCustomer instanceof WC_Customer)) - || !($this->wcOrder instanceof WC_Order) - ) { - throw new \InvalidArgumentException(sprintf('Incorrect data provided to %s', __CLASS__)); - } - } - - /** - * @return \WC_Customer|null - */ - public function getWcCustomer() - { - return $this->wcCustomer; - } - - /** - * @return \WC_Order - */ - public function getWcOrder() - { - return $this->wcOrder; - } -} +wcCustomer = $wcCustomer; + $this->wcOrder = $wcOrder; + + if ((!is_null($this->wcCustomer) && !($this->wcCustomer instanceof WC_Customer)) + || !($this->wcOrder instanceof WC_Order) + ) { + throw new \InvalidArgumentException(sprintf('Incorrect data provided to %s', __CLASS__)); + } + } + + /** + * @return \WC_Customer|null + */ + public function getWcCustomer() + { + return $this->wcCustomer; + } + + /** + * @return \WC_Order + */ + public function getWcOrder() + { + return $this->wcOrder; + } +} diff --git a/src/include/models/class-wc-retailcrm-customer-data-replacer-state.php b/src/include/models/class-wc-retailcrm-customer-switcher-state.php similarity index 80% rename from src/include/models/class-wc-retailcrm-customer-data-replacer-state.php rename to src/include/models/class-wc-retailcrm-customer-switcher-state.php index e7a0180..a4bc045 100644 --- a/src/include/models/class-wc-retailcrm-customer-data-replacer-state.php +++ b/src/include/models/class-wc-retailcrm-customer-switcher-state.php @@ -1,146 +1,146 @@ -wcOrder; - } - - /** - * @param \WC_Order $wcOrder - * - * @return WC_Retailcrm_Customer_Data_Replacer_State - */ - public function setWcOrder($wcOrder) - { - $this->wcOrder = $wcOrder; - return $this; - } - - /** - * @return array - */ - public function getNewCustomer() - { - return $this->newCustomer; - } - - /** - * @param array $newCustomer - * - * @return WC_Retailcrm_Customer_Data_Replacer_State - */ - public function setNewCustomer($newCustomer) - { - $this->newCustomer = $newCustomer; - return $this; - } - - /** - * @return array - */ - public function getNewContact() - { - return $this->newContact; - } - - /** - * @param array $newContact - * - * @return WC_Retailcrm_Customer_Data_Replacer_State - */ - public function setNewContact($newContact) - { - $this->newContact = $newContact; - return $this; - } - - /** - * @return array - */ - public function getNewCorporateCustomer() - { - return $this->newCorporateCustomer; - } - - /** - * @param array $newCorporateCustomer - * - * @return WC_Retailcrm_Customer_Data_Replacer_State - */ - public function setNewCorporateCustomer($newCorporateCustomer) - { - $this->newCorporateCustomer = $newCorporateCustomer; - return $this; - } - - /** - * @return array - */ - public function getNewCompany() - { - return $this->newCompany; - } - - /** - * @param array $newCompany - * - * @return WC_Retailcrm_Customer_Data_Replacer_State - */ - public function setNewCompany($newCompany) - { - $this->newCompany = $newCompany; - return $this; - } - - /** - * Throws an exception if state is not valid - * - * @throws \InvalidArgumentException - * @return void - */ - public function validate() - { - if (empty($this->getWcOrder())) { - throw new \InvalidArgumentException('Empty WC_Order.'); - } - - if (empty($this->getNewCustomer()) - && empty($this->getNewContact()) - && empty($this->getNewCorporateCustomer()) - ) { - throw new \InvalidArgumentException('New customer, new contact and new corporate customer is empty.'); - } - - if (!empty($this->getNewCustomer()) - && (!empty($this->getNewContact()) || !empty($this->getNewCorporateCustomer())) - ) { - throw new \InvalidArgumentException( - 'Too much data in state - cannot determine which customer should be used.' - ); - } - } -} +wcOrder; + } + + /** + * @param \WC_Order $wcOrder + * + * @return WC_Retailcrm_Customer_Switcher_State + */ + public function setWcOrder($wcOrder) + { + $this->wcOrder = $wcOrder; + return $this; + } + + /** + * @return array + */ + public function getNewCustomer() + { + return $this->newCustomer; + } + + /** + * @param array $newCustomer + * + * @return WC_Retailcrm_Customer_Switcher_State + */ + public function setNewCustomer($newCustomer) + { + $this->newCustomer = $newCustomer; + return $this; + } + + /** + * @return array + */ + public function getNewContact() + { + return $this->newContact; + } + + /** + * @param array $newContact + * + * @return WC_Retailcrm_Customer_Switcher_State + */ + public function setNewContact($newContact) + { + $this->newContact = $newContact; + return $this; + } + + /** + * @return array + */ + public function getNewCorporateCustomer() + { + return $this->newCorporateCustomer; + } + + /** + * @param array $newCorporateCustomer + * + * @return WC_Retailcrm_Customer_Switcher_State + */ + public function setNewCorporateCustomer($newCorporateCustomer) + { + $this->newCorporateCustomer = $newCorporateCustomer; + return $this; + } + + /** + * @return array + */ + public function getNewCompany() + { + return $this->newCompany; + } + + /** + * @param array $newCompany + * + * @return WC_Retailcrm_Customer_Switcher_State + */ + public function setNewCompany($newCompany) + { + $this->newCompany = $newCompany; + return $this; + } + + /** + * Throws an exception if state is not valid + * + * @throws \InvalidArgumentException + * @return void + */ + public function validate() + { + if (empty($this->getWcOrder())) { + throw new \InvalidArgumentException('Empty WC_Order.'); + } + + if (empty($this->getNewCustomer()) + && empty($this->getNewContact()) + && empty($this->getNewCorporateCustomer()) + ) { + throw new \InvalidArgumentException('New customer, new contact and new corporate customer is empty.'); + } + + if (!empty($this->getNewCustomer()) + && (!empty($this->getNewContact()) || !empty($this->getNewCorporateCustomer())) + ) { + throw new \InvalidArgumentException( + 'Too much data in state - cannot determine which customer should be used.' + ); + } + } +} diff --git a/src/retailcrm.php b/src/retailcrm.php index e3247fb..4937dfe 100644 --- a/src/retailcrm.php +++ b/src/retailcrm.php @@ -42,13 +42,12 @@ if (!class_exists( 'WC_Integration_Retailcrm')) : if (class_exists( 'WC_Integration' )) { require_once(dirname(__FILE__) . '/include/interfaces/class-wc-retailcrm-builder-interface.php'); - require_once(dirname(__FILE__ ) . '/include/models/class-wc-retailcrm-customer-data-replacer-state.php'); - require_once(dirname(__FILE__ ) . '/include/models/class-wc-retailcrm-customer-data-replacer-result.php'); + require_once(dirname(__FILE__) . '/include/models/class-wc-retailcrm-customer-switcher-state.php'); + require_once(dirname(__FILE__) . '/include/models/class-wc-retailcrm-customer-switcher-result.php'); require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-logger.php'); require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-history-assembler.php'); require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-paginated-request.php'); - require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-customer-data-replacer.php'); - require_once(dirname(__FILE__ ) . '/include/components/class-wc-retailcrm-customer-data-replacer.php'); + require_once(dirname(__FILE__) . '/include/components/class-wc-retailcrm-customer-switcher.php'); require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstract-builder.php'); require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-settings.php'); require_once(dirname(__FILE__ ) . '/include/abstracts/class-wc-retailcrm-abstracts-data.php');