From 60af19232410dedf07bfe1049599dc4e1b4ad424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Thu, 12 Aug 2021 14:49:27 +0200 Subject: [PATCH] Add WPMCRM v2 without test for now --- src/CrmApiV2.php | 34 ++ src/Enums/ApiError.php | 9 + src/Models/Answer.php | 13 +- src/Models/ArcadiaMailDefault.php | 4 + src/Models/ArcadiaMailGame.php | 4 + src/Models/Customer.php | 28 ++ src/Models/Question.php | 13 +- src/Models/SingleOptin.php | 4 + src/WordPress/WPCrm.php | 575 ++++++++++++++++++++++++++++++ src/WordPress/WPCrmAnswer.php | 68 ++++ src/WordPress/WPCrmQuestion.php | 111 ++++++ src/WordPress/WPCrmUser.php | 171 +++++++++ 12 files changed, 1030 insertions(+), 4 deletions(-) create mode 100644 src/WordPress/WPCrm.php create mode 100644 src/WordPress/WPCrmAnswer.php create mode 100644 src/WordPress/WPCrmQuestion.php create mode 100644 src/WordPress/WPCrmUser.php diff --git a/src/CrmApiV2.php b/src/CrmApiV2.php index c23c7e7..134c16e 100644 --- a/src/CrmApiV2.php +++ b/src/CrmApiV2.php @@ -32,6 +32,8 @@ class CrmApiV2 * Use this the ping the crm and know its current status * * @return boolean + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response */ public function ping(): bool { @@ -48,6 +50,10 @@ class CrmApiV2 * * @param string $identification The customer hashcode or email * @return Customer + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function getCustomerOrNew(string $identification): Customer { @@ -62,6 +68,10 @@ class CrmApiV2 * * @param string $identification The customer hashcode or email * @return Customer + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function getCustomer(string $identification): ?Customer { @@ -73,6 +83,10 @@ class CrmApiV2 * * @param string $identification The customer hashcode or email * @return Customer + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function getQuestions(string $identification): ?Customer { @@ -86,9 +100,29 @@ class CrmApiV2 * @param boolean $opt_in * @return boolean true if succeeded * @throws ApiErrorException ApiError::singleOptinCustomerExists If single optin already exists + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function setStatus(string $email, bool $opt_in): bool { return SingleOptin::setStatus($email, $opt_in); } + + /** + * Test a customer credentials to see if it can login + * + * @param string $email + * @param string $password + * @return boolean + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + public static function login(string $email, string $password): bool + { + return Customer::login($email, $password); + } } diff --git a/src/Enums/ApiError.php b/src/Enums/ApiError.php index ebac0b1..85ecf45 100644 --- a/src/Enums/ApiError.php +++ b/src/Enums/ApiError.php @@ -51,6 +51,13 @@ use Kwaadpepper\Enum\BaseEnum; * Too many requests have been attempted. The is a throttle security. * Normally you should not trigger this. * If this happens fill a ticket on https://supportweb.ldc.fr + * with some technical details + * + * @method static self authorizationException() + * You are maybe trying to access data that is out of your range. + * This should not happen normally, it is here to allow you to handle this case. + * If this happens fill a ticket on https://supportweb.ldc.fr + * with some technical details * * @package LDCCrmClient * @subpackage enums @@ -71,6 +78,7 @@ class ApiError extends BaseEnum 'singleOptinCustomerExists' => 120, 'methodNotAllowed' => 150, 'wrongTimeStamp' => 151, + 'authorizationException' => 403, 'throttleRequestsException' => 429 ]; } @@ -88,6 +96,7 @@ class ApiError extends BaseEnum 'needAuth' => trans('You need to be authenticated'), 'methodNotAllowed' => trans('This method is not allowed for this request'), 'wrongTimeStamp' => trans('Your request is malformed, please check timestamp header and parameter'), + 'authorizationException' => trans('You are not autorized to access this'), 'throttleRequestsException' => trans('Throttle: too many request have been attempted, please retry later') ]; } diff --git a/src/Models/Answer.php b/src/Models/Answer.php index 95a11fb..f81f241 100644 --- a/src/Models/Answer.php +++ b/src/Models/Answer.php @@ -81,10 +81,17 @@ class Answer extends CrmClientModel // PUBLIC METHODS /** - * Get unanswered question for a specific customer + * Set unanswered question for a specific customer * - * @param \LDC\LDCCRM\Models\Customer $customer - * @return bool + * @param string $hashcode The customer hashcode + * @param integer $questionId The question id + * @param array $answersId An array with answers id + * @return bool true if succeeded + * + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function setQuestionAnswers(string $hashcode, int $questionId, array $answersId): bool { diff --git a/src/Models/ArcadiaMailDefault.php b/src/Models/ArcadiaMailDefault.php index 07dff6b..3bdc215 100644 --- a/src/Models/ArcadiaMailDefault.php +++ b/src/Models/ArcadiaMailDefault.php @@ -228,6 +228,10 @@ class ArcadiaMailDefault extends CrmClientModel * Send The actual mail * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function send(Customer $customer): bool { diff --git a/src/Models/ArcadiaMailGame.php b/src/Models/ArcadiaMailGame.php index b112f77..71e6e63 100644 --- a/src/Models/ArcadiaMailGame.php +++ b/src/Models/ArcadiaMailGame.php @@ -145,6 +145,10 @@ class ArcadiaMailGame extends CrmClientModel * Send The actual mail * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function send(Customer $customer): bool { diff --git a/src/Models/Customer.php b/src/Models/Customer.php index 8ef2203..a39514e 100644 --- a/src/Models/Customer.php +++ b/src/Models/Customer.php @@ -397,6 +397,10 @@ class Customer extends CrmClientModel * * @param string $hashcode * @return self|null + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function find(string $hashcode): ?self { @@ -424,6 +428,10 @@ class Customer extends CrmClientModel * * @param string $email * @return self|null + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function findWithEmail(string $email): ?self { @@ -434,6 +442,10 @@ class Customer extends CrmClientModel * Save the actual account in the crm * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function save(): bool { @@ -488,6 +500,10 @@ class Customer extends CrmClientModel * Delete the actual account in the crm * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function delete(): bool { @@ -505,6 +521,10 @@ class Customer extends CrmClientModel * Activate the account in the crm * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function activate(): bool { @@ -523,6 +543,10 @@ class Customer extends CrmClientModel * Toggle the account optin value in the crm * * @return boolean true if succeeded + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public function toggleOptin(): bool { @@ -536,6 +560,10 @@ class Customer extends CrmClientModel * @param string $email * @param string $password * @return boolean + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function login(string $email, string $password): bool { diff --git a/src/Models/Question.php b/src/Models/Question.php index d98d8d6..ea5f845 100644 --- a/src/Models/Question.php +++ b/src/Models/Question.php @@ -189,10 +189,13 @@ class Question extends CrmClientModel /** * Get all questions only * - * @param string $hashcode * @return array * * with \LDC\LDCCRM\Models\Question[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function all(): array { @@ -226,6 +229,10 @@ class Question extends CrmClientModel * * with \LDC\LDCCRM\Models\Question[] * and the customer \LDC\LDCCRM\Models\Answer[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function allWithCustomerAnswers(Customer $customer): array { @@ -258,6 +265,10 @@ class Question extends CrmClientModel * * @param \LDC\LDCCRM\Models\Customer $customer * @return \LDC\LDCCRM\Models\Question[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function unansweredBy(Customer $customer): array { diff --git a/src/Models/SingleOptin.php b/src/Models/SingleOptin.php index d47f530..cbdcabb 100644 --- a/src/Models/SingleOptin.php +++ b/src/Models/SingleOptin.php @@ -35,6 +35,10 @@ abstract class SingleOptin extends CrmClientModel * @param boolean $opt_in * @return boolean true if succeeded * @throws ApiErrorException ApiError::singleOptinCustomerExists If single optin already exists + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs */ public static function setStatus(string $email, bool $opt_in): bool { diff --git a/src/WordPress/WPCrm.php b/src/WordPress/WPCrm.php new file mode 100644 index 0000000..4f072fc --- /dev/null +++ b/src/WordPress/WPCrm.php @@ -0,0 +1,575 @@ + + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ + +namespace LDC\LDCCRM\WordPress; + +use Exception; +use LDC\LDCCRM\CrmApiV2; +use LDC\LDCCRM\Enums\ApiError; +use LDC\LDCCRM\Exceptions\ApiErrorException; +use LDC\LDCCRM\Exceptions\CrmException; +use LDC\LDCCRM\Models\ArcadiaMailDefault; +use LDC\LDCCRM\Models\ArcadiaMailGame; +use LDC\LDCCRM\Models\Customer; +use LDC\LDCCRM\Models\SingleOptin; +use ReflectionClass; + +// phpcs:ignore Squiz.PHP.CommentedOutCode.Found +// TABLE LDC CUSTOMERS +// CREATE TABLE `ldc_wp_customers` ( +// `hashcode` VARCHAR(36) NOT NULL DEFAULT '' COMMENT 'Le hashcode (UUID)', +// `email` VARCHAR(255) NOT NULL DEFAULT '' COMMENT 'Le customer email', +// PRIMARY KEY (`hashcode`) +// ) +// COMMENT='Les customers sur un WP liées à la CRM' +// COLLATE='utf8mb4_unicode_ci'; + +/** + * Class de gestion des users en session avec Wordpress (ce truc immonde) + * + * @category API + * @package LDCCrmClient + * @subpackage Wordpress + * @author Jérémy Munsch + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ +class WPCrm +{ + + private static $sessionKey = 'LDC_CRM_USER'; + + private static $sessionDestroyed = false; + + /** + * The user object + * + * @var \LDC\LDCCRM\CrmApiV2 + */ + protected static $api = null; + + /** + * The user object + * + * @var \LDCCRM\WPCrmUser + */ + protected static $user = null; + + /** + * Try to login with CRM API + * return api response code if an error occurs + * + * @param string $email The customer email + * @param string $password The customer password + * + * @return \LDCCRM\WPCrmUser|false + */ + public static function login($email, $password) + { + self::bootSessionIfNeeded(); + return self::loginUserWithApi($email, $password); + } + + /** + * Get the current user + * return null if the user is not logged in + * + * @return \LDCCRM\WPCrmUser|null + */ + public static function getUser() + { + self::bootSessionIfNeeded(); + return self::$user; + } + + /** + * Get the current user + * return api response code if an error occurs + * + * @param string $identification The customer hashcode or email + * + * @return \LDCCRM\WPCrmUser|false + */ + public static function getUserFromApi(string $identification) + { + self::initLdcApi(); + + try { + if (!($response = self::makeApiV2Call(self::$api, 'getCustomer', [$identification]))) { + return $response; + } + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::modelNotFound(): + return false; + default: + throw $e; + } + } + /** @var \LDC\LDCCRM\Models\Customer */ + $customer = $response; + self::setUser($customer); + return self::$user; + } + + /** + * Get the current user + * return null if the user is not logged in + * + * @param string $email The customer email + * @param string $password The customer password + * + * @return \LDCCRM\WPCrmUser|false + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + private static function loginUserWithApi(string $email, string $password) + { + self::initLdcApi(); + try { + if (!($response = self::makeApiV2Call(self::$api, 'login', [$email, $password]))) { + return $response; + } + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::customerNotActivated(): + case ApiError::modelNotFound(): + case ApiError::authFailed(): + return false; + default: + throw $e; + } + } + if ($out = self::getUserFromApi($email)) { + self::saveOrUpdateUserToTable(); + } + return $out; + } + + /** + * Destroy the customer from session + * and therefore logout + * + * @return void + */ + public static function logout() + { + self::bootSessionIfNeeded(); + unset($_SESSION[self::$sessionKey]); + session_destroy(); + self::$sessionDestroyed = true; + } + + /** + * Check if the user is Authenticated + * + * @return bool + */ + public static function check() + { + self::bootSessionIfNeeded(); + return (bool)self::getUser(); + } + + /** + * Save current customer to + * the local database and on crm + * + * @return boolean true if the operation succeeded false otherwise + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * with \LDC\LDCCRM\Enums\ApiError::customerExists() + */ + public static function saveUser(): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + try { + if (!self::makeApiV2Call($customer, 'save')) { + return false; + } + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::modelNotFound(): + return false; + default: + throw $e; + } + } + self::saveOrUpdateUserToTable(); + return true; + } + + /** + * Delete current customer from + * the local database and the crm + * + * @return boolean true if the operation succeeded + */ + public static function deleteUser(): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + try { + + if (!self::makeApiV2Call($customer, 'delete')) { + return false; + } + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::modelNotFound(): + return false; + default: + throw $e; + } + } + self::deleteUserFromTable(); + return true; + } + + /** + * Toggle the current user optin value + * on the current user and the crm + * + * @return boolean true if the operation succeeded + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * with \LDC\LDCCRM\Enums\ApiError::singleOptinCustomerExists() + */ + public static function toggleUserOptin(): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + try { + if (!self::makeApiV2Call($customer, 'save')) { + return false; + } + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::modelNotFound(): + return false; + default: + throw $e; + } + } + $customer->opt_in = !$customer->opt_in; + return true; + } + + /** + * Set the single optin status for an email + * on the crm + * + * @param string $email + * @param boolean $opt_in + * + * @return boolean true if the operation succeeded false otherwise + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * with \LDC\LDCCRM\Enums\ApiError::singleOptinCustomerExists() + */ + public static function setSingleOptin(string $email, bool $opt_in): bool + { + return self::makeApiV2Call(SingleOptin::class, 'setStatus', [ + $email, $opt_in + ]); + } + + /** + * send An arcadia mail with type default + * This methods requires to have a user in session (to be logged in) + * + * @param ArcadiaMailDefault $mail + * @return boolean true if succeed + */ + public static function sendArcadiaMailDefault(ArcadiaMailDefault $mail): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + $customer = self::getCustomer(); + return $mail->send($customer); + } + + /** + * send An arcadia mail with type game + * This methods requires to have a user in session (to be logged in) + * + * @param ArcadiaMailGame $mail + * @return boolean true if succeed + */ + public static function sendArcadiaMailGame(ArcadiaMailGame $mail): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + $customer = self::getCustomer(); + return $mail->send($customer); + } + + /** + * Toggle the current user optin value + * on the current user and the crm + * + * @return boolean true if the operation succeeded + */ + public static function activateUser(): bool + { + if (!self::getUser() or !($customer = self::getCustomer())) { + return false; + } + if ($customer->status) { + return true; + } + if (!self::makeApiV2Call($customer, 'activate')) { + return false; + } + $customer->opt_in = !$customer->opt_in; + return true; + } + + // --- PRIVATE --- METHODS + + /** + * Get all customer infos + * + * @return \LDC\LDCCRM\Models\Customer|null + */ + private static function getCustomer(): ?Customer + { + if (!self::getUser()) { + return null; + } + if (!self::getRawProperty(self::$user, 'customer')) { + self::getUserFromApi(self::$user->hashcode); + } + /** @var \LDC\LDCCRM\Models\Customer */ + $customer = self::getRawProperty(self::$user, 'customer'); + return $customer; + } + + /** + * Create a user + * stores it to the session + * and finally saves it to the database if it does not exists + * + * @var \LDC\LDCCRM\Models\Customer $customer + * + * @return void + */ + private static function setUser(Customer $customer) + { + self::bootSessionIfNeeded(); + if (!self::$user) { + self::$user = new self($customer->hashcode, $customer->email); + } + self::$user->setInfo($customer); + $_SESSION[self::$sessionKey] = json_encode(self::$user); + } + + /** + * Get the initialized API object + * + * @return \LDCCRM\ApiV1 + */ + private static function initLdcApi() + { + if (!self::$api) { + if (!extension_loaded('curl')) { + throw new Exception( + 'WPCrm requires php extension curl' + ); + } + self::$api = new CrmApiV2(); + } + return self::$api; + } + + /** + * Make a call using apiV2 + * + * @param string $method + * @param array $arguments + * @return mixed|false + */ + private static function makeApiV2Call($obj, string $method, array $arguments = []) + { + try { + return \forward_static_call_array([$obj, $method], $arguments); + } catch (ApiErrorException $e) { + switch ($e->getApiError()) { + case ApiError::apiAuthFailed(): + default: + self::logError($e->getMessage()); + throw $e; + } + } catch (CrmException $e) { + self::logError($e->getMessage()); + return false; + } + } + + private static function logError(string $message): void + { + // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Found + error_log($message); + } + + /** + * Boot the php session if needed + * + * @return void + */ + private static function bootSessionIfNeeded() + { + if (!session_id() && !self::$sessionDestroyed) { + session_start(); + } + if (!self::$user and array_key_exists(self::$sessionKey, $_SESSION)) { + /** + * The user object + * + * @var \LDCCRM\WPCrmUser + */ + self::$user = WPCrmUser::parseFromJson( + $_SESSION[self::$sessionKey] ?? null + ); + } + } + + /** + * Get a customer from table + * + * @param string $hashcode The customer hashcode + * + * @return object|null + */ + public static function getUserFromTable(string $hashcode) + { + return self::getWpDb()->get_row( + 'SELECT * FROM `ldc_wp_customers` WHERE `hashcode` = ' . $hashcode + ); + } + + /** + * Get a customer from table by an email + * + * @param int $email The customer email + * + * @return object|null + */ + public static function getUserFromTableByEmail($email) + { + return self::getWpDb()->get_row( + 'SELECT * FROM `ldc_wp_customers` WHERE `email` = "' . $email . '"' + ); + } + + /** + * Get a customer from table + * + * @return object|null + */ + public static function getUserToTable() + { + return self::getWpDb()->get_row( + 'SELECT * FROM `ldc_wp_customers` WHERE `hashcode` = ' . + self::$user->hashcode + ); + } + + /** + * Save or update the user to the table + * + * @return void + */ + private static function saveOrUpdateUserToTable() + { + if (self::getUserToTable()) { + self::query( + 'UPDATE `ldc_wp_customers` SET `hashcode` = %s, `email` = %s WHERE `hashcode` = %s', + [ + 'hashcode' => self::$user->hashcode, + 'email' => self::$user->email, + 'hashcode' => self::$user->hashcode + ] + ); + } else { + self::query( + 'INSERT INTO `ldc_wp_customers` VALUES (%s, %s)', + [ + 'hashcode' => self::$user->hashcode, + 'email' => self::$user->email, + ] + ); + } + } + + /** + * Save or update the user to the table + * + * @return void + */ + private static function deleteUserFromTable() + { + self::query( + 'DELETE FROM `ldc_wp_customers` WHERE `hashcode` = %s;', + [ + 'hashcode' => self::$user->hashcode + ] + ); + } + + /** + * Query in DB + * + * @param string $query La request avec les variables en points d'interrogation + * @param array $params Les paramètres des la requète + * + * @return object Containing the row columns + */ + private static function query($query, array $params = []) + { + return self::getWpDb()->query( + self::getWpDb()->prepare($query, $params) + ); + } + + /** + * Get WP 'pdo instance' + * + * @return object The $wpdb variable + */ + private static function getWpDb() + { + // phpcs:ignore Squiz.PHP.GlobalKeyword.NotAllowed + global $wpdb; + return $wpdb; + } + + /** + * Get a property + * + * @param string $field + * @param mixed $value + * @return mixed + */ + protected static function getRawProperty(object $object, string $field) + { + $refClass = new ReflectionClass(\get_class($object)); + $refProp = $refClass->getProperty($field); + $refProp->setAccessible(true); + return $refProp->getValue($object); + } +} diff --git a/src/WordPress/WPCrmAnswer.php b/src/WordPress/WPCrmAnswer.php new file mode 100644 index 0000000..27da80b --- /dev/null +++ b/src/WordPress/WPCrmAnswer.php @@ -0,0 +1,68 @@ + + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ + +namespace LDC\LDCCRM\WordPress; + +use LDC\LDCCRM\Models\Answer; +use ReflectionClass; + +/** + * Class de gestion de la segmentation question avec Wordpress (ce truc immonde) + * + * @category API + * @package LDCCrmClient + * @subpackage Wordpress + * @author Jérémy Munsch + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ +abstract class WPCrmAnswer +{ + + /** + * Set unanswered question for a specific customer + * + * @param string $hashcode The customer hashcode + * @param integer $questionId The question id + * @param array $answersId An array with answers id + * @return bool true if succeeded + * + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + public function setQuestionAnswers(WPCrmUser $user, int $questionId, array $answersId): bool + { + if (!self::getRawProperty($user, 'customer')) { + WPCrm::getUserFromApi($user->hashcode); + } + /** @var \LDC\LDCCRM\Models\Customer */ + $customer = self::getRawProperty($user, 'customer'); + return Answer::setQuestionAnswers($user->hashcode, $questionId, $answersId); + } + + /** + * Get a property + * + * @param string $field + * @param mixed $value + * @return mixed + */ + protected static function getRawProperty(object $object, string $field) + { + $refClass = new ReflectionClass(\get_class($object)); + $refProp = $refClass->getProperty($field); + $refProp->setAccessible(true); + return $refProp->getValue($object); + } +} diff --git a/src/WordPress/WPCrmQuestion.php b/src/WordPress/WPCrmQuestion.php new file mode 100644 index 0000000..0d14701 --- /dev/null +++ b/src/WordPress/WPCrmQuestion.php @@ -0,0 +1,111 @@ + + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ + +namespace LDC\LDCCRM\WordPress; + +use LDC\LDCCRM\Models\Question; +use ReflectionClass; + +/** + * Class de gestion de la segmentation question avec Wordpress (ce truc immonde) + * + * @category API + * @package LDCCrmClient + * @subpackage Wordpress + * @author Jérémy Munsch + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ +abstract class WPCrmQuestion +{ + + /** + * Get all questions only + * + * @return array + * + * with \LDC\LDCCRM\Models\Question[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + public function getAll(): array + { + return Question::all(); + } + + /** + * Get all the questions with user answers + * + * @param \LDC\LDCCRM\WordPress\WPCrmUser $user + * @return array + * + * [ + * 0 => [ + * 'question' => \LDC\LDCCRM\Models\Question, + * 'customerAnswers' => \LDC\LDCCRM\Models\Answer[] + * ] + * ] + * + * with \LDC\LDCCRM\Models\Question[] + * and the customer \LDC\LDCCRM\Models\Answer[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + public function allWithCustomerAnswers(WPCrmUser $user): array + { + if (!self::getRawProperty($user, 'customer')) { + WPCrm::getUserFromApi($user->hashcode); + } + /** @var \LDC\LDCCRM\Models\Customer */ + $customer = self::getRawProperty($user, 'customer'); + return Question::allWithCustomerAnswers($customer); + } + + /** + * Get unanswered question for a specific customer + * + * @param \LDC\LDCCRM\WordPress\WPCrmUser $user + * @return \LDC\LDCCRM\Models\Question[] + * @throws \LDC\LDCCRM\Exceptions\CrmException + * if an error occurs on server side or on getting response + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * If any error or \LDC\LDCCRM\Enums\ApiError occurs + */ + public function unansweredBy(WPCrmUser $user): array + { + if (!self::getRawProperty($user, 'customer')) { + WPCrm::getUserFromApi($user->hashcode); + } + /** @var \LDC\LDCCRM\Models\Customer */ + $customer = self::getRawProperty($user, 'customer'); + return Question::unansweredBy($customer); + } + + /** + * Get a property + * + * @param string $field + * @param mixed $value + * @return mixed + */ + protected static function getRawProperty(object $object, string $field) + { + $refClass = new ReflectionClass(\get_class($object)); + $refProp = $refClass->getProperty($field); + $refProp->setAccessible(true); + return $refProp->getValue($object); + } +} diff --git a/src/WordPress/WPCrmUser.php b/src/WordPress/WPCrmUser.php new file mode 100644 index 0000000..56c8c03 --- /dev/null +++ b/src/WordPress/WPCrmUser.php @@ -0,0 +1,171 @@ + + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ + +namespace LDC\LDCCRM\WordPress; + +use JsonSerializable; +use LDC\LDCCRM\Models\Customer; + +/** + * Class de gestion des users en session avec Wordpress (ce truc immonde) + * + * @category API + * @package LDCCrmClient + * @subpackage Wordpress + * @author Jérémy Munsch + * @license MIT https://opensource.org/licenses/MIT + * @link / + */ +class WPCrmUser implements JsonSerializable +{ + + /** + * The CRM hashcode (UUID) + * + * @var string + */ + protected $hashcode = null; + + /** + * The CRM customer email + * + * @var string + */ + protected $email = null; + + /** + * The CRM customer info (the api response) + * + * @var \LDC\LDCCRM\Models\Customer + */ + protected $customer = null; + + /** + * WPCrmUser construct + * + * @param string $hashcode The customer hashcode (UUID) + * @param string $email The customer email + */ + public function __construct(string $hashcode, string $email) + { + $this->hashcode = $hashcode; + $this->email = $email; + } + + /** + * Magic getter + * + * @param string $prop The prop to get + * + * @return bool|string|\LDC\LDCCRM\Enums\Country + */ + public function __get($prop) + { + if (is_null($this->info)) { + WPCrm::getUserFromApi($this->email); + } + return $this->customer->{$prop}; + } + + /** + * Set the customer info + * with api response + * + * @param LDC\LDCCRM\Models\Customer $customer The Api object reponse (user) + * + * @return void + */ + public function setInfo(Customer $customer) + { + $this->info = $customer; + $this->email = $customer->email; + $this->hashcode = $customer->hashcode; + } + + /** + * Generate a user from session data + * + * @param string $string The json data stored in session + * + * @return \LDCCRM\WPCrmUser + */ + public static function parseFromJson($string) + { + $a = json_decode($string, true); + return new self( + $a['hashcode'], + $a['email'], + $a['info'] + ); + } + + /** + * Serialize this object to an array + * + * @return array + */ + public function jsonSerialize() + { + return [ + 'hashcode' => $this->hashcode, + 'email' => $this->email, + 'info' => $this->info + ]; + } + + /** + * Save current customer to + * the local database and on crm + * + * @return boolean true if the operation succeeded false otherwise + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * with \LDC\LDCCRM\Enums\ApiError::customerExists() + */ + public function save(): bool + { + return WPCrm::saveUser(); + } + + /** + * Delete current customer to + * the local database and on crm + * + * @return boolean true if the operation succeeded false otherwise + */ + public function delete(): bool + { + return WPCrm::deleteUser(); + } + + /** + * Toggle the current user optin value + * on the current user and the crm + * + * @return boolean true if the operation succeeded + * @throws \LDC\LDCCRM\Exceptions\ApiErrorException + * with \LDC\LDCCRM\Enums\ApiError::singleOptinCustomerExists() + */ + public function toggleOptin(): bool + { + return WPCrm::toggleUserOptin(); + } + + /** + * Activate the account in the crm + * + * @return boolean true if succeeded + */ + public function activate(): bool + { + return WPCrm::activateUser(); + } +}