634 lines
17 KiB
PHP
634 lines
17 KiB
PHP
<?php
|
|
|
|
/**
|
|
* LDCCRM For Wordpress usage
|
|
*
|
|
* @category API
|
|
* @package None
|
|
* @author Jérémy Munsch <jeremy.munsch@ldc.fr>
|
|
* @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\Enums\LogLevel;
|
|
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 LDC\LDCCRM\Utils;
|
|
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',
|
|
// `uuid` VARCHAR(50) NOT NULL DEFAULT '' COMMENT 'Code unique (inscripton, validation, etc)',
|
|
// 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 <jeremy.munsch@ldc.fr>
|
|
* @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();
|
|
if ($user = self::loginUserWithApi($email, $password)) {
|
|
$_SESSION[self::$sessionKey] = json_encode($user);
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* Login user by setting user session
|
|
*
|
|
* @param string $email The customer email
|
|
* @param string $password The customer password
|
|
*
|
|
* @return \LDCCRM\WPCrmUser|null
|
|
*/
|
|
public static function forceLogin()
|
|
{
|
|
self::bootSessionIfNeeded();
|
|
if ($user = self::getUser()) {
|
|
$_SESSION[self::$sessionKey] = json_encode($user);
|
|
}
|
|
return $user;
|
|
}
|
|
|
|
/**
|
|
* 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 \LDC\LDCCRM\Wordpress\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::authorizationException():
|
|
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();
|
|
if (!($response = self::makeApiV2Call(self::$api, 'login', [$email, $password]))) {
|
|
return $response;
|
|
}
|
|
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;
|
|
}
|
|
|
|
/**
|
|
* Generate a new user
|
|
*
|
|
* @return WPCrmUser
|
|
*/
|
|
public static function getNewUser(): WPCrmUser
|
|
{
|
|
return self::$user = new WPCrmUser();
|
|
}
|
|
|
|
/**
|
|
* Remove active user
|
|
* to prevent WPCrm::check to return true
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function unsetActiveUser()
|
|
{
|
|
self::$user = null;
|
|
}
|
|
|
|
// --- 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, 'info')) {
|
|
self::getUserFromApi(self::$user->hashcode);
|
|
}
|
|
/** @var \LDC\LDCCRM\Models\Customer */
|
|
$customer = self::getRawProperty(self::$user, 'info');
|
|
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 WPCrmUser($customer->hashcode, $customer->email);
|
|
}
|
|
self::$user->setInfo($customer);
|
|
}
|
|
|
|
/**
|
|
* 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():
|
|
throw $e;
|
|
default:
|
|
Utils::log($e->getMessage(), LogLevel::NOTICE());
|
|
throw $e;
|
|
}
|
|
} catch (CrmException $e) {
|
|
Utils::log($e->getMessage(), LogLevel::EMERG());
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Boot the php session if needed
|
|
*
|
|
* @return void
|
|
*/
|
|
private static function bootSessionIfNeeded()
|
|
{
|
|
if (!session_id() && !self::$sessionDestroyed) {
|
|
session_start();
|
|
}
|
|
if (
|
|
isset($_SESSION[self::$sessionKey]) and
|
|
isset($_SESSION['lastActivity']) and
|
|
// 15 minutes session
|
|
($_SESSION['lastActivity'] + (15 * 60)) < time()
|
|
) {
|
|
self::$sessionDestroyed = true;
|
|
unset($_SESSION[self::$sessionKey]);
|
|
} else {
|
|
$_SESSION['lastActivity'] = time();
|
|
}
|
|
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 array|null
|
|
*/
|
|
public static function getUserFromTable(string $hashcode): ?array
|
|
{
|
|
return self::getWpDb()->get_row(
|
|
self::getWpDb()->prepare(
|
|
'SELECT * FROM `ldc_wp_customers` WHERE `hashcode` = %s',
|
|
[
|
|
'hashcode' => $hashcode
|
|
]
|
|
),
|
|
'ARRAY_A'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get a customer from table by an email
|
|
*
|
|
* @param string $email The customer email
|
|
*
|
|
* @return array|null
|
|
*/
|
|
public static function getUserFromTableByEmail(string $email): ?array
|
|
{
|
|
return self::getWpDb()->get_row(
|
|
self::getWpDb()->prepare(
|
|
'SELECT * FROM `ldc_wp_customers` WHERE `email` = %s',
|
|
[
|
|
'email' => $email
|
|
]
|
|
),
|
|
'ARRAY_A'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get a customer from table by an email
|
|
*
|
|
* @param string $uuid The customer transaction uuid
|
|
*
|
|
* @return array|null
|
|
*/
|
|
public static function getUserFromTableByUuid(string $uuid): ?array
|
|
{
|
|
return self::getWpDb()->get_row(
|
|
self::getWpDb()->prepare(
|
|
'SELECT * FROM `ldc_wp_customers` WHERE `uuid` = %s',
|
|
[
|
|
'uuid' => $uuid
|
|
]
|
|
),
|
|
'ARRAY_A'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Save or update the user to the table
|
|
*
|
|
* @return void
|
|
*/
|
|
private static function saveOrUpdateUserToTable()
|
|
{
|
|
if (is_string(self::$user->hashcode) and self::getUserFromTable(self::$user->hashcode)) {
|
|
self::query(
|
|
'UPDATE `ldc_wp_customers` SET `email` = %s, `uuid` = %s WHERE `hashcode` = %s',
|
|
[
|
|
'email' => self::$user->email,
|
|
'uuid' => self::$user->uuidToken,
|
|
'hashcode' => self::$user->hashcode
|
|
]
|
|
);
|
|
} else {
|
|
self::query(
|
|
'INSERT INTO `ldc_wp_customers`(hashcode, email, uuid) VALUES (%s, %s, %s)',
|
|
[
|
|
'hashcode' => self::$user->hashcode,
|
|
'email' => self::$user->email,
|
|
'uuid' => self::$user->uuidToken
|
|
]
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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);
|
|
}
|
|
}
|