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' ] ); } }