Ejemplo n.º 1
0
	/**
	 * Insert/Update the node with the response record
	 *
	 * Method will insert/update the node with the response record. Its made public so order syncing can you it also
	 *
	 * @access public
	 * @param array $responseData The reponse data from QB
	 * @param array $nodeData The optional node data array. If set then update, else insert
	 * @return int The new or updtaed node ID on success, FALSE on error
	 */
	public function syncResponseRecord2Store($responseData, $nodeData=false)
	{
		static $_cacheHTTPHost = null;

		/**
		 * Firstly, don't import if this has a customer type as it is a guest checkout customer
		 */
		if ($this->accounting->isCustomerGuestCheckout($responseData) || $this->accounting->isCustomerParent($responseData)) {
			return false;
		}

		/**
		 * Set the fillin email address domain name
		 */
		if (is_null($_cacheHTTPHost)) {
			$parts = parse_url(GetConfig("ShopPath"));

			if (!$parts || !isset($parts["host"]) || trim($parts["host"]) == '') {
				if (function_exists("apache_getenv")) {
					$_cacheHTTPHost = @apache_getenv("HTTP_HOST");
				}

				if (!$_cacheHTTPHost) {
					$_cacheHTTPHost = @$_SERVER["HTTP_HOST"];
				}
			} else {
				$_cacheHTTPHost = $parts["host"];
			}
		}

		if (!is_array($responseData)) {
			$xargs = func_get_args();
			throw new QBException("Invalid arguments when syncing customer record from QB", $xargs);
		}

		/**
		 * Check to see if this is a customer short name. Only do this if $nodeData is empty
		 */
		if (!is_array($nodeData) && $this->accounting->isCustomerShortName($responseData["Name"])) {
			$customerParts = $this->accounting->qbCustomerShortName2CustomerNameId($responseData["Name"]);

			if (is_array($customerParts) && isset($customerParts["customerid"]) && isId($customerParts["customerid"])) {
				$nodeData = $this->entityAPI->get($customerParts["customerid"]);
			}
		}

		/**
		 * We need to fill in the blanks with our node data if we have one
		 */
		if (is_array($nodeData)) {
			$map = array(
						"custconfirstname" => "FirstName",
						"custconlastname" => "LastName",
						"custconemail" => "Email",
						"custconphone" => "Phone",
						"custconcompany" => "CompanyName"
			);

			foreach ($map as $nodeKey => $responseKey) {
				if (!array_key_exists($responseKey, $responseData) || trim($responseData[$responseKey]) == '') {
					$responseData[$responseKey] = $nodeData[$nodeKey];
				}
			}
		}

		/**
		 * Create a fillin for the email address if it is not set
		 */
		if (!array_key_exists("Email", $responseData) || trim($responseData["Email"]) == '' || !is_email_address($responseData["Email"])) {
			$emailAddress = self::emailPreFixFillin .  mt_rand(10000, 99999) . "@" . $_cacheHTTPHost;

		/**
		 * Else check to see if it is unique
		 */
		} else if (!$this->checkEmailIsUnique($responseData["Email"], $nodeData)) {
			$emailAddress = self::emailPreFixFillin .  mt_rand(10000, 99999) . "@" . $_cacheHTTPHost;
			$this->accounting->logWarning("The QuickBooks customer '" . $responseData["FirstName"] . " " . $responseData["LastName"] . "' has a non-unique email address. Changing their email address to " . $emailAddress);

		/**
		 * Its all cool
		 */
		} else {
			$emailAddress = $responseData["Email"];
		}

		/**
		 * If the first or last name are 25 chanracters then use the original values. This is because QBWC puts a 25 character
		 * limit on those fields and will cut it off if it is exceeded, so best to be safe than sorry
		 */
		if (is_array($nodeData)) {
			if (strlen($responseData["FirstName"]) == 25) {
				$this->accounting->logWarning("The QuickBooks customer '" . $responseData["FirstName"] . " " . $responseData["LastName"] . "' has had their first name truncated. Defaulting to the original first name of '" . $nodeData["custconfirstname"] . "'");
				$responseData["FirstName"] = $nodeData["custconfirstname"];
			}

			if (strlen($responseData["LastName"]) == 25) {
				$this->accounting->logWarning("The QuickBooks customer '" . $responseData["FirstName"] . " " . $responseData["LastName"] . "' has had their last name truncated. Defaulting to the original last name of '" . $nodeData["custconlastname"] . "'");
				$responseData["LastName"] = $nodeData["custconlastname"];
			}
		}

		$savedata = array(
			"custconfirstname" => @$responseData["FirstName"],
			"custconlastname" => @$responseData["LastName"],
			"custconemail" => $emailAddress,
			"custconphone" => @$responseData["Phone"],
			"custconcompany" => @$responseData["CompanyName"]
		);

		/**
		 * The addresses
		 */
		$addresses = array();

		foreach (array("BillAddress", "ShipAddress") as $addressType) {

			if (!array_key_exists($addressType, $responseData) || !is_array($responseData[$addressType])) {
				continue;
			}

			if (trim(@$responseData[$addressType]["Addr1"]) !== '') {

				/**
				 * Firstly lets check to see if we already have this addressd
				 */
				$shipId = '';

				if (is_array($nodeData) && isset($nodeData["addresses"]) && is_array($nodeData["addresses"])) {
					foreach ($nodeData["addresses"] as $address) {
						if (isc_strtolower(trim($address["shipaddress1"])) == isc_strtolower(trim(@$responseData[$addressType]["Addr1"]))) {
							$shipId = $address["shipid"];

							/**
							 * Now fill in the blanks
							 */
							$map = array(
										"shipaddress1" => "Addr1",
										"shipaddress2" => "Addr2",
										"shipcity" => "City",
										"shipstate" => "State",
										"shipzip" => "PostalCode",
										"shipcountry" => "Country"
							);

							foreach ($map as $nodeKey => $responseKey) {
								if (!array_key_exists($responseKey, $responseData[$addressType]) || trim($responseData[$addressType][$responseKey]) == '') {
									$responseData[$addressType][$responseKey] = $address[$nodeKey];
								}
							}
						}
					}
				}

				/**
				 * Find the country and state IDs
				 */
				$countryId = $this->getCountryId(@$responseData[$addressType]["Country"], $properCountryName);
				$stateId = '';

				if (isId($countryId) && trim(@$responseData[$addressType]["State"]) !== '') {
					$responseData[$addressType]["Country"] = $properCountryName;
					$stateId = $this->getStateId($responseData[$addressType]["State"], $countryId, $properStateName);
					if (!isId($stateId)) {
						$stateId = '';
					} else if (trim($properStateName) !== '') {
						$responseData[$addressType]["State"] = $properStateName;
					}
				} else {
					$countryId = '';
				}

				$addresses[] = array(
									"shipid" => $shipId,
									"shipfirstname" => @$responseData["FirstName"],
									"shiplastname" => @$responseData["LastName"],
									"shipcompany" => @$responseData["CompanyName"],
									"shipaddress1" => @$responseData[$addressType]["Addr1"],
									"shipaddress2" => @$responseData[$addressType]["Addr2"],
									"shipcity" => @$responseData[$addressType]["City"],
									"shipstate" => @$responseData[$addressType]["State"],
									"shipzip" => @$responseData[$addressType]["PostalCode"],
									"shipcountry" => @$responseData[$addressType]["Country"],
									"shipphone" => @$responseData["Phone"],
									"shipstateid" => $stateId,
									"shipcountryid" => $countryId
				);

				/**
				 * Set something to each field if it is NULL as the database can't handle NULL values for this schema
				 */
				foreach ($addresses[count($addresses)-1] as $addKey => $addVal) {
					if (is_null($addVal)) {
						$addresses[count($addresses)-1][$addKey] = '';
					}
				}
			}
		}

		if (!empty($addresses)) {
			$savedata["addresses"] = $addresses;
		}

		$this->accounting->logDebug("The formatted customer data from QB", array("Savedata" => $savedata, "Response" => $responseData));

		/**
		 * Got all the info, now create the database record
		 */
		$customerId = false;
		if (is_array($nodeData) && array_key_exists("customerid", $nodeData) && isId($nodeData["customerid"])) {
			$savedata["customerid"] = $nodeData["customerid"];
			if ($this->entityAPI->edit($savedata, false, true) !== false) {
				$customerId = $nodeData["customerid"];
			}
		} else {
			$savedata["password"] = Interspire_String::generateReadablePassword();
			$customerId = $this->entityAPI->add($savedata);
		}

		if (!isId($customerId)) {
			throw new QBException("Cannot save customer record with data from QB", array("SaveData" => $savedata, "NodeData" => $nodeData, "DB" => $GLOBALS["ISC_CLASS_DB"]->GetError()));
		}

		return $customerId;
	}
Ejemplo n.º 2
0
		/**
		 * Save the new password for the customer's account (via link in reset password email)
		 */
		private function SaveNewPassword()
		{

			if (isset($_GET['c']) && isset($_GET['t'])) {

				$customerId = (int)isc_html_escape($_GET['c']);
				$customerHash = isc_html_escape($_GET['t']);

				$query = "SELECT *
							FROM [|PREFIX|]customers
							WHERE customerid=" . $customerId;
				$result = $GLOBALS['ISC_CLASS_DB']->Query($query);
				$customer = $GLOBALS['ISC_CLASS_DB']->Fetch($result);

				// Can't find them in the database
				if (!isId($customerId) || !$customer) {
					return $this->ResetPassword("invalid_link", 1);
				}

				// Also check to see if our salted string matches this customer
				if (!$this->checkCustomerHash($customerHash, $customer['customerpasswordresettoken'], $customerId)) {
					return $this->ResetPassword("invalid_link", 1);
				}

				// OK, all the arguments are cool. Now we generate a password for them
				$password = Interspire_String::generateReadablePassword();
				$updateData = array(
					'customerpasswordresettoken' => '',
					'customerpasswordresetemail' => '',
				);

				if ($GLOBALS['ISC_CLASS_DB']->UpdateQuery('customers', $updateData, 'customerid=' . $customerId) === false) {
					return $this->ResetPassword("internal_error", 1);
				}

				$entity = new ISC_ENTITY_CUSTOMER();
				$entity->updatePassword($customerId, $password);

				// Send the email
				$store_name = GetConfig('StoreName');
				$email_message = sprintf(GetLang('ForgotPasswordEmailConfirmed'), $store_name, $password);

				// Create a new email API object to send the email
				require_once(ISC_BASE_PATH . "/lib/email.php");
				$obj_email = GetEmailClass();
				$obj_email->Set('CharSet', GetConfig('CharacterSet'));
				$obj_email->From(GetConfig('OrderEmail'), $store_name);
				$obj_email->Set("Subject", sprintf(GetLang('ForgotPasswordEmailConfirmedSubject'), $store_name));
				$obj_email->AddBody("html", $email_message);
				$obj_email->AddRecipient($customer['customerpasswordresetemail'], "", "h");
				$email_result = $obj_email->Send();

				if ($email_result['success']) {
					return $this->ShowLoginPage(sprintf(GetLang('ForgotPasswordChanged'), $customer['customerpasswordresetemail']), 0, true);
				} else {
					return $this->ResetPassword("internal_error", 1);
				}
			} else {
				$this->ShowLoginPage();
			}
		}