<?php
|
namespace JVBase\integrations;
|
|
use JVBase\meta\Meta;
|
use JVBase\meta\Sanitizer;
|
use JVBase\registrar\Registrar;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
trait SyncToUser
|
{
|
use SyncTo, SyncHelpers, UserConnection;
|
|
public function addSaveUser():void
|
{
|
if (empty($this->syncUsers)) {
|
return;
|
}
|
if (!has_action('profile_update', [$this, 'handleUpdateUser'])) {
|
add_action('profile_update', [$this, 'handleUpdateUser'], 20, 1);
|
}
|
if (!has_action('user_register', [$this, 'handleUpdateUser'])) {
|
add_action('user_register', [$this, 'handleUpdateUser'], 20, 1);
|
}
|
}
|
public function removeSaveUser():void
|
{
|
if (empty($this->syncUsers)) {
|
return;
|
}
|
remove_action('profile_update', [$this, 'handleUpdateUser'], 20);
|
remove_action('user_register', [$this, 'handleUpdateUser'], 20);
|
}
|
protected function handleUpdateUser(int $userID):void
|
{
|
$user = $this->getOrCreateUser($userID);
|
if (!$user) {
|
return;
|
}
|
|
$fields = $this->getSyncFields($userID, 'user');
|
if (!empty($fields["_{$this->service_name}_item_id"])) {
|
return;
|
}
|
|
$this->removeSaveUser();
|
$this->handleTheSaveUser($userID);
|
$this->addSaveUser();
|
}
|
|
protected function getOrCreateUser(int $userID):string|false
|
{
|
$user = get_userdata($userID);
|
if (!$user || is_wp_error($user)) {
|
return false;
|
}
|
$role = jvbUserRole($userID);
|
if (!in_array(jvbNoBase($role), $this->syncUsers)) {
|
return false;
|
}
|
$fields = $this->getSyncFields($userID, 'user');
|
if (!empty($fields["_{$this->service_name}_item_id"])) {
|
return $fields["_{$this->service_name}_item_id"];
|
}
|
|
$meta = Meta::forUser($userID);
|
$serviceUserID = $this->searchServiceForUser($user->user_email??'');
|
if ($serviceUserID) {
|
$meta->set("{$this->service_name}_item_id", $serviceUserID);
|
return $serviceUserID;
|
}
|
|
$created = $this->createServiceUser($userID, $fields);
|
if ($created) {
|
return $created;
|
}
|
return false;
|
}
|
public function searchServiceForUser(string $email):string|false
|
{
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
|
return false;
|
}
|
return $this->handleEmailSearch($email);
|
}
|
|
/**
|
* Searches for existing user from sanitized email
|
* @param string $email
|
* @return string|false The found service's User ID or false on failure
|
*/
|
abstract public function handleEmailSearch(string $email):string|false;
|
|
public function createServiceUser(int $userID, array $fields):string|false
|
{
|
$checked = $this->validateUserFields($userID, $fields);
|
$response = $this->handleCreateUser($checked);
|
if ($response['success'] && !empty($response['data'])) {
|
$meta = Meta::forUser($userID);
|
$meta->set("{$this->service_name}_item_id", $response['data']['id']);
|
}
|
return $response['success'] ? $response['data']['id']??false : false;
|
}
|
|
protected function validateUserFields(int $userID, array $fields):array|false
|
{
|
foreach ($fields as $f => $v) {
|
$v = match ($f) {
|
'email' => filter_var($v, FILTER_SANITIZE_EMAIL),
|
'phone' => Sanitizer::sanitizePhone($v),
|
default => sanitize_text_field($v),
|
};
|
if (empty($v) && in_array($f, $this->requiredUserFields())) {
|
return false;
|
}
|
$fields[$f] = $v;
|
}
|
return $fields;
|
}
|
protected function requiredUserFields():array
|
{
|
return [];
|
}
|
|
/**
|
* @param array $data User Data
|
* @return array The created user ID or false on failure
|
*/
|
abstract protected function handleCreateUser(array $data):array;
|
|
/**
|
* @param int $userID
|
* @return void
|
*/
|
protected function handleTheSaveUser(int $userID):void
|
{
|
error_log('==== ['.$this->title.']::handleTheSaveUser ====');
|
//TODO: This is likely only for stuff like customers.
|
//If we have multiple stores connected, we may have to queue operations to update every connection's customer account if they made an order with that store
|
$role = jvbUserRole($userID);
|
$registrar = Registrar::getInstance($role);
|
if (!$registrar || !$registrar->hasIntegration($this->service_name)) {
|
return;
|
}
|
|
$this->queueOperation(self::$syncTo, [
|
'users' => [$userID],
|
]);
|
}
|
|
public function addDeleteUser():void
|
{
|
if (!has_action('delete_user', [$this, 'handleDeleteTerm'])) {
|
add_action('delete_user', [$this, 'handleDeleteTerm']);
|
}
|
}
|
public function removeDeleteUser():void
|
{
|
remove_action('delete_user', [$this, 'handleDeleteTerm']);
|
}
|
public function handleDeleteUser(int $userID):void
|
{
|
if (!$this->canSync['delete']) {
|
return;
|
}
|
|
$fields = $this->getSyncFields($userID, 'user');
|
if (empty($fields["_{$this->service_name}_item_id"])) {
|
return;
|
}
|
JVB()->queue()->add(
|
self::$deleteFrom,
|
0,
|
[
|
'fields' => [$userID => $fields],
|
'service' => $this->service_name,
|
'type' => 'user'
|
]
|
);
|
}
|
}
|