Commit c611c0ea authored by Sumesh S's avatar Sumesh S

#2 - Port module to support drupal 9.

parent fdfd9e7d
README
======
## Zendesk Remote Authentication
The zendesk module allows you to integrate your drupal site with the zendesk
customer support system (http://www.zendesk.com)
---
Zendesk allows external authentication. This means that your Drupal site can serve
as authentication service. This way customers have a seamless experience without
having to log in in both the drupal site and the zendesk support system.
Installation is easy:
**Installation is easy:**
- install the module
- configure your zendesk account (go to 'Settings - Security - Single Sign-On')
* Enable the "JSON Web Token" strategy.
* insert the remote authentication url: http://yoursite.com/services/zendesk
* optionally you can insert your logout url: http://yoursite.com/logout
* Enable the "JSON Web Token" strategy.
* insert the remote authentication url: http://yoursite.com/services/zendesk
* optionally you can insert your logout url: http://yoursite.com/logout
- go to admin/config/people/zendesk and fill in the url of your zendesk support page (e.g. http://yourdomain.zendesk.com) together with the secret key
Local Development
=================
Zendesk remote authentication does not require your site to be public.
## Local Development
Zendesk remote authentication does not require your site to be public.
## Zendesk PHP library
Zendesk PHP library
===================
This module depends on the Zendesk PHP library. For ease of use, this library is included with the module in the lib directory.
For more information on this library, please visit: http://code.google.com/p/zendesk-php-lib
=================
---
Originally developed for 6.x by twom <http://drupal.org/user/25564>
Ported to Drupal 7.x by markwk <http://drupal.org/user/1094790>
Ported to Drupal 9.x by sumeshsr <http://drupal.org/user/3516919>
......@@ -14,6 +14,6 @@
}
],
"require": {
"zendesk/zendesk_api_client_php": "dev-master"
"zendesk/zendesk_api_client_php": "2.2.11"
}
}
\ No newline at end of file
zendesk_api_token: 'Your API Token'
zendesk_api_mail: ''
zendesk_subdomain: ''
zendesk_url':
zendesk_jwt_shared_secret: 'Your secret key'
zendesk_api_sync_users': ''
......
......@@ -6,7 +6,7 @@ use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\ConfigFormBase;
/**
* Configure zendesk settings for this site.
* Zendesk settings for this site.
*/
class ZendeskAdminForm extends ConfigFormBase {
......@@ -20,7 +20,7 @@ class ZendeskAdminForm extends ConfigFormBase {
/**
* Implements \Drupal\Core\Form\FormInterface::getFormID().
*/
public function getFormID() {
public function getFormId() {
return 'zendesk_admin_form';
}
......@@ -42,19 +42,12 @@ class ZendeskAdminForm extends ConfigFormBase {
'#default_value' => $config->get('zendesk_url'),
];
$form['zendesk']['zendesk_api']['zendesk_subdomain'] = [
'#type' => 'textfield',
'#title' => t('Zendesk subdomain'),
'#default_value' => $config->get('zendesk_subdomain'),
'#description' => t('The subdomain of your zendesk page: if your zendesk is http://subdomain.zendesk.com, then you have to fil in "subdomain".'),
];
$form['zendesk']['zendesk_api']['zendesk_api_token'] = [
'#type' => 'textfield',
'#required' => TRUE,
'#description' => 'The zendesk API token.',
'#title' => t('Zendesk API Token'),
'#description' => t('Use the http://www.yourdomain.com/agent/admin/api/settings page in your zendesk configuration page. (Go to Account -> Channels)'),
'#default_value' => $config->get('zendesk_api_token'),
'#suffix' => t('Use the http://www.yourdomain.com/agent/#/admin/channels page in your zendesk configuration page. (Go to Account -> Channels'),
];
$form['zendesk']['zendesk_api']['zendesk_api_mail'] = [
......@@ -78,13 +71,13 @@ class ZendeskAdminForm extends ConfigFormBase {
$form['zendesk']['zendesk_permissions']['zendesk_roles'] = [
'#type' => 'checkboxes',
'#title' => t('Authenticate only for specific roles'),
'#default_value' => $config->get('zendesk_roles'),
'#default_value' => $config->get('zendesk_roles') ?? [],
'#options' => $role_options,
'#description' => t('Select which roles may be authenticated for zendesk. If you select no roles, all authenticated drupal users will be authenticated for Zendesk.'),
];
$form['zendesk']['zendesk_permissions']['zendesk_no_permission_page'] = [
'#type' => 'textfield',
'#type' => 'url',
'#title' => t('No permission page'),
'#default_value' => $config->get('zendesk_no_permission_page'),
'#description' => t('To what pages do you want to redirect user that have no permission to access Zendesk.'),
......@@ -94,19 +87,18 @@ class ZendeskAdminForm extends ConfigFormBase {
}
/**
* {@inheritdoc}c.
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('zendesk.settings')
->set('zendesk_url', $form_state->getValue('zendesk_url'))
->set('zendesk_subdomain', $form_state->getValue('zendesk_subdomain'))
->set('zendesk_api_token', $form_state->getValue('zendesk_api_token'))
->set('zendesk_api_mail', $form_state->getValue('zendesk_api_mail'))
->set('zendesk_roles', $form_state->getValue('zendesk_roles'))
->set('zendesk_no_permission_page', $form_state->getValue('zendesk_no_permission_page'))
->save();
parent::submitForm($form, $form_state);
$config = $this->config('zendesk.settings');
$config->set('zendesk_url', $form_state->getValue('zendesk_url'));
$config->set('zendesk_api_token', $form_state->getValue('zendesk_api_token'));
$config->set('zendesk_api_mail', $form_state->getValue('zendesk_api_mail'));
$config->set('zendesk_roles', $form_state->getValue('zendesk_roles'));
$config->set('zendesk_no_permission_page', $form_state->getValue('zendesk_no_permission_page'));
$config->save();
return parent::submitForm($form, $form_state);
}
}
<?php
namespace Drupal\zendesk\Utils;
/**
* The Zendesk Helper.
*/
class ZendeskHelper {
/**
* Converts and signs a PHP object or array into a JWT string.
*
* Taken from PEAR::JWT.
*
* @param object|array $payload
* PHP object or array.
* @param string $key
* The secret key.
*
* @return string
* A signed JWT.
*/
public function jwtEncode($payload, $key) {
$header = [
'typ' => 'JWT',
'alg' => 'HS256',
];
$segments = [];
$segments[] = $this->urlSafeB64Encode(json_encode($header));
$segments[] = $this->urlSafeB64Encode(json_encode($payload));
$signing_input = implode('.', $segments);
$signature = hash_hmac('sha256', $signing_input, $key, TRUE);
$segments[] = $this->urlSafeB64Encode($signature);
return implode('.', $segments);
}
/**
* Encodes the given data with urlsafe base64.
*
* A base64 encoded string is made urlsafe by replacing '+' with '-',
* '/' with '_', and removing '='.
*
* Taken from PEAR::JWT.
*
* @param string $data
* The data to encode.
*
* @return string
* The encoded string.
*/
public function urlSafeB64Encode($data) {
$b64 = base64_encode($data);
return str_replace(['+', '/', '\r', '\n', '='], ['-', '_'], $b64);
}
}
name: Zendesk
name: Zendesk Remote Authentication
description: "Main module that handle Zendesk's API"
core_version_requirement: ^8.8 || ^9
core_version_requirement: ^8 || ^9
package: Zendesk
configure: zendesk.zendesk_admin
configure: zendesk_admin
type: module
zendesk.admin_settings:
title: 'Zendesk settings'
description: 'Configure Drupal settings to communicate with Zendesk'
route_name: zendesk_admin
parent: 'system.admin_config_system'
......@@ -3,54 +3,7 @@
/**
* @file
* The Zendesk module helps you to interact with zendesk using Drupal.
*
* Authors:
* Sumesh S (contact.sumeshsr@gmail.com)
*/
use Zendesk\API\Client as ZendeskAPI;
/**
* Implements hook_permission().
*/
function zendesk_permission() {
return [
'configure zendesk' => [
'title' => t('Configure Zendesk'),
'description' => t('Configure Drupal settings to communicate with Zendesk.'),
],
];
}
/**
* Initialization of the zendesk library.
*/
function zendesk_initialize_library() {
$config = Drupal::config('zendesk.settings');
$api_key = $config->get('zendesk_api_token');
$user = $config->get('zendesk_api_mail');
$subdomain = $config->get('zendesk_subdomain');
$client = new ZendeskAPI($subdomain, $user);
$client->setAuth('token', $api_key);
return $client;
}
/**
* Check if the user may be be authenticated or synced with zendesk.
*/
function zendesk_user_has_access($account) {
$zendesk_roles = \Drupal::config('zendesk.settings')->get('zendesk_roles');
if (!array_sum($zendesk_roles)) {
// No roles are set, give access.
return TRUE;
}
else {
$keys = array_keys($account->getRoles);
foreach ($keys as $key) {
if ($zendesk_roles[$key] > 0) {
return TRUE;
}
}
}
return FALSE;
}
administer zendesk:
title: 'Administer Zendesk'
description: 'Configure the Drupal settings to communicate with Zendesk.'
......@@ -3,4 +3,4 @@ zendesk_admin:
defaults:
_form: '\Drupal\zendesk\Form\ZendeskAdminForm'
requirements:
_permission: 'configure zendesk'
_permission: 'administer zendesk'
services:
zendesk.helper:
class: Drupal\zendesk\Utils\ZendeskHelper
arguments: ['@config.factory']
logger.channel.zendesk:
parent: logger.channel_base
arguments: ['zendesk']
<?php
/**
* @file
* Contains \Drupal\zendesk\Controller\ZendeskSSOController.
*/
namespace Drupal\zendesk_sso\Controller;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Url;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\zendesk\Utils\ZendeskHelper;
/**
* Controller routines for zendesk routes.
*/
class ZendeskSSOController extends ControllerBase {
/**
* Zendesk Manager Service.
*
* @var \Drupal\zendesk\ZendeskManager
*/
protected $zendeskManager;
/**
* Injects ZendeskManager Service.
*/
public static function create(ContainerInterface $container) {
return new static($container->get('zendesk.manager'));
}
/**
* Remote authentication script.
*
......@@ -36,37 +20,40 @@ class ZendeskSSOController extends ControllerBase {
* @see https://support.zendesk.com/entries/23675367
*/
public function sso() {
// Check if anonymous, if so redirect to login with destination the path where
// he comes from.
$account = \Drupal::currentUser();
// Redirect anonymous user to login with destination.
$account = $this->currentUser();
if ($account->id()) {
// Check if user role is allowed to be authenticated.
if (zendesk_user_has_access($account)) {
$account = \Drupal::currentUser();
if (\Drupal::service('zendesk_user.manager')->hasAccess($account)) {
$token = array(
$token = [
'jti' => sha1($account->id() . \Drupal::time()->getRequestTime() . rand()),
'iat' => \Drupal::time()->getRequestTime(),
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'external_id' => $account->id(),
);
];
$key = \Drupal::config('zendesk.settings')
->get('zendesk_jwt_shared_secret');
$jwt = zendesk_jwt_encode($token, $key);
$jwt = ZendeskHelper::jwtEncode($token, $key);
// Redirect
// Redirect.
$url = \Drupal::config('zendesk.settings')->get('zendesk_url') . '/access/jwt';
return new RedirectResponse(url($url, array('query' => array('jwt' => $jwt))));
$redirect_url = Url::fromUri($url, ['query' => ['jwt' => $jwt]]);
return new TrustedRedirectResponse($redirect_url->toString());
}
else {
return new RedirectResponse(url(Drupal::config('zendesk.settings')
->get('zendesk_no_permission_page')));
return new RedirectResponse(Url::fromUri(Drupal::config('zendesk.settings')
->get('zendesk_no_permission_page')->toString()));
}
}
else {
return new RedirectResponse(url('user', array('query' => array('destination' => 'services/zendesk'))));
$redirect_url = Url::fromUri('internal:/user/login', ['query' => ['destination' => 'services/zendesk']], ['absolute' => TRUE]);
return new RedirectResponse($redirect_url->toString());
}
}
......
......@@ -5,10 +5,6 @@
* The Zendesk module helps you to interact with zendesk using Drupal.
*/
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\zendesk;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Form\FormStateInterface;
/**
......@@ -17,24 +13,24 @@ use Drupal\Core\Form\FormStateInterface;
function zendesk_sso_form_zendesk_admin_form_alter(array &$form, FormStateInterface $form_state) {
$config = \Drupal::config('zendesk.settings');
$form['zendesk']['zendesk_sso'] = array(
$form['zendesk']['zendesk_sso'] = [
'#type' => 'fieldset',
'#title' => 'SSO configuration',
);
$form['zendesk']['zendesk_sso']['zendesk_jwt_shared_secret'] = array(
];
$form['zendesk']['zendesk_sso']['zendesk_jwt_shared_secret'] = [
'#type' => 'textfield',
'#required' => TRUE,
'#description' => 'The zendesk SSO secret key.',
'#default_value' => $config->get('zendesk_jwt_shared_secret'),
'#suffix' => t('Use the http://www.yourdomain.com/agent/#/admin/security page in your zendesk configuration page. (Go to Account -> Security)'),
);
];
$form['zendesk']['zendesk_sso']['zendesk_api_sync_users'] = array(
$form['zendesk']['zendesk_sso']['zendesk_api_sync_users'] = [
'#type' => 'checkbox',
'#title' => t('Synchronize the Drupal users with Zendesk'),
'#default_value' => $config->get('zendesk_api_sync_users'),
'#description' => t('When accounts are created in your drupal site, updated and delete, push these changes to Zendesk.'),
);
];
// We need tu save those values. So we add our own custom submit handler.
$form['#submit'][] = 'zendesk_admin_zendesk_sso_submit';
}
......@@ -42,63 +38,17 @@ function zendesk_sso_form_zendesk_admin_form_alter(array &$form, FormStateInterf
/**
* Submit callback.
*
* @see zendesk_sso_form_zendesk_admin_form_alter().
* @param array $form
* Nested array of form elements that comprise the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @param array $form
* @param FormStateInterface $form_state
* @see zendesk_sso_form_zendesk_admin_form_alter()
*/
function zendesk_admin_zendesk_sso_submit(array &$form, FormStateInterface $form_state) {
\Drupal::config('zendesk.settings')
\Drupal::getContainer()->get('config.factory')
->getEditable('zendesk.settings')
->set('zendesk_jwt_shared_secret', $form_state->getValue('zendesk_jwt_shared_secret'))
->set('zendesk_api_sync_users', $form_state->getValue('zendesk_api_sync_users'))
->save();
}
/**
* Converts and signs a PHP object or array into a JWT string.
*
* Taken from PEAR::JWT.
*
* @param $payload
* PHP object or array.
* @param $key
* The secret key.
*
* @return
* A signed JWT.
*/
function zendesk_jwt_encode($payload, $key) {
$header = array(
'typ' => 'JWT',
'alg' => 'HS256'
);
$segments = array();
$segments[] = zendesk_urlsafeb64_encode(json_encode($header));
$segments[] = zendesk_urlsafeb64_encode(json_encode($payload));
$signing_input = implode('.', $segments);
$signature = hash_hmac('sha256', $signing_input, $key, TRUE);
$segments[] = zendesk_urlsafeb64_encode($signature);
return implode('.', $segments);
}
/**
* Encodes the given data with urlsafe base64.
*
* A base64 encoded string is made urlsafe by replacing '+' with '-',
* '/' with '_', and removing '='.
*
* Taken from PEAR::JWT.
*
* @param $data
* The data to encode.
*
* @return
* The encoded string.
*/
function zendesk_urlsafeb64_encode($data) {
$b64 = base64_encode($data);
return str_replace(array('+', '/', '\r', '\n', '='), array('-', '_'), $b64);
}
<?php
namespace Drupal\zendesk_users;
use Drupal\Core\Database\Connection;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Psr\Log\LoggerInterface;
use Zendesk\API\HttpClient as ZendeskAPI;
/**
* The Zendesk Users Service.
*/
class ZendeskUsers {
/**
* The database object.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The config factory.
*
* @var \Drupal\Core\Config\ConfigFactoryInterface
*/
protected $configFactory;
/**
* The logger.
*
* @var \Psr\Log\LoggerInterface
*/
protected $logger;
/**
* The zendesk library client.
*
* @var \Zendesk\API\HttpClient
*/
protected $zendeskClient;
/**
* Constructs a new DrupaliseMe object.
*
* @param \Drupal\Core\Database\Connection $connection
* Base Database API class.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* Interface for classes that manage a set of enabled modules.
* @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
* Defines the interface for a configuration object factory.
* @param \Psr\Log\LoggerInterface $logger
* The logger.
*/
public function __construct(Connection $connection, ModuleHandlerInterface $module_handler, ConfigFactoryInterface $config_factory, LoggerInterface $logger) {
$this->database = $connection;
$this->moduleHandler = $module_handler;
$this->config = $config_factory->get('zendesk.settings');
$this->logger = $logger;
$this->zendeskClient = $this->initLibrary();
}
/**
* Initialize the API Call.
*/
protected function initLibrary() {
$token = $this->config->get('zendesk_api_token');
$user = $this->config->get('zendesk_api_mail');
$domain = parse_url($this->config->get('zendesk_url'));
$client = new ZendeskAPI('', $user, $domain['scheme'], $domain['host']);
$client->setAuth('basic', [
'username' => $user,
'token' => $token,
]);
return $client;
}
/**
* Creates a user in zendesk.
*/
public function createUser(AccountInterface $account) {
if ($this->config->get('zendesk_api_sync_users') && $this->hasAccess($account)) {
$data = [
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'role' => 'end-user',
];
if ($this->config->get('zendesk_authed_user')) {
$data['user']['verified'] = TRUE;
}
// Invoke a alter call to allow other modules to pass data to ZenDesk.
$this->moduleHandler->alter(['zendesk_user', 'zendesk_user_update'], $data, $account);
// Make the call.
$result = $this->zendeskClient->users()->create($data);
if (!empty($result->error)) {
// Try to handle special case where a user can be on zendesk's side, but
// not recorded on our table.
if ($result->error == 'RecordInvalid' && $result->details->email[0]->description == 'Email: ' . $account->getEmail() . ' is already being used by another user') {
return $this->syncUserBack($account);
}
$this->logger->error($result->description . ': ' . print_r($result->details, TRUE));
return FALSE;
}
else {
$this->database->insert('zendesk_users')
->fields([
'uid' => $account->id(),
'zid' => $result->user->id,
])
->execute();
return $result->user->id;
}
}
}
/**
* Syncs back the user ata from zendesk.
*/
public function syncUserBack(AccountInterface $account) {
// Look for the user.
$result = $this->zendeskClient->users()->search($account->getEmail());
if (isset($result->users[0]->id)) {
$this->database->insert('zendesk_users')
->fields([
'uid' => $account->id(),
'zid' => $result->users[0]->id,
])
->execute();
return $result->users[0]->id;
}
else {
return FALSE;
}
}
/**
* Updates the user data on zendesk.
*/
public function updateUser(AccountInterface $account) {
if ($this->config->get('zendesk_api_sync_users') && $this->hasAccess($account)) {
if ($user_id = $this->getZendeskUserId($account->id())) {
$data = [
'id' => $user_id,
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'role' => 'end-user',
];
// Invoke a alter call to allow other modules to pass data to ZenDesk.
$this->moduleHandler->alter(['zendesk_user', 'zendesk_user_update'], $data, $account);
// Make the call.
$this->zendeskClient->users()->update($user_id, $data);
}
}
}
/**
* Delete the user from zendesk.
*/
public function deleteUser(AccountInterface $account) {
if ($this->config->get('zendesk_api_sync_users') && $user_id = $this->getZendeskUserId($account->id())) {
// Make the call.
$this->zendeskClient->users()->delete($user_id);
// Delete user entry from the zendesk users table.
$this->database->delete('zendesk_users', ['uid' => $account->id()])->execute();
}
}
/**
* Helper function to retrieve zendesk id of the user.
*/
public function getZendeskUserId(int $uid) {
$result = $this->database->select('zendesk_users', 'zu')
->fields('zu', ['uid', 'zid'])
->condition('zu.uid', $uid, '=')
->execute();
$rows = $result->fetchAll();
if (count($rows) <> 0) {
foreach ($rows as $user) {
return $user->zid;
}
}
else {
return FALSE;
}
}
/**
* Checks if the user has access based on config.
*/
public function hasAccess($account) {
$zendesk_roles = $this->config->get('zendesk_roles');
if (!array_sum($zendesk_roles)) {
// No roles are set, give access.
return TRUE;
}
else {
$keys = array_keys($account->getRoles);
foreach ($keys as $key) {
if ($zendesk_roles[$key] > 0) {
return TRUE;
}
}
}
return FALSE;
}
}
<?php
/**
* @file
* Hooks provided by the Zendesk Users module.
*/
/**
* Alter the user data on the fly, when a user is created/updated.
*
* NOTE: This hook only works if the zendesk user synchronization is enabled.
* /admin/config/system/zendesk.
*
* @param array $data
* Zendesk userdata.
* @param \Drupal\Core\Session\AccountInterface $account
* Object of the user.
*/
function hook_zendesk_user(array &$data, \Drupal\Core\Session\AccountInterface $account) {
}
......@@ -21,6 +21,7 @@ function zendesk_users_schema() {
],
'zid' => [
'type' => 'int',
'size' => 'big',
'unsigned' => TRUE,
'not null' => 0,
'default' => 0,
......
......@@ -32,13 +32,16 @@ function zendesk_users_form_zendesk_admin_form_alter(array &$form, FormStateInte
/**
* Submit callback.
*
* @see zendesk_sso_form_zendesk_admin_form_alter()
*
* @param array $form
* Nested array of form elements that comprise the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @see zendesk_sso_form_zendesk_admin_form_alter()
*/
function zendesk_admin_zendesk_users_submit(array &$form, FormStateInterface $form_state) {
\Drupal::config('zendesk.settings')
\Drupal::getContainer()->get('config.factory')
->getEditable('zendesk.settings')
->set('zendesk_authed_user', $form_state->getValue('zendesk_authed_user'))
->save();
}
......@@ -47,149 +50,19 @@ function zendesk_admin_zendesk_users_submit(array &$form, FormStateInterface $fo
* Implements hook_ENTITY_TYPE_insert() for user entities.
*/
function zendesk_user_insert(AccountInterface $account) {
if (Drupal::config('zendesk.settings')->get('zendesk_api_sync_users') && zendesk_user_has_access($account)) {
zendesk_users_create_user($account);
}
\Drupal::service('zendesk_user.manager')->createUser($account);
}
/**
* Implements hook_ENTITY_TYPE_update() for user entities.
*/
function zendesk_users_user_update(AccountInterface $account) {
if (Drupal::config('zendesk.settings')->get('zendesk_api_sync_users') && zendesk_user_has_access($account)) {
if ($user_id = _zendesk_users_get_user($account->id())) {
$data = [
'id' => $user_id,
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'role' => 'end-user',
];
// Invoke a alter call to allow other modules to pass data to ZenDesk.
\Drupal::moduleHandler()
->alter(['zendesk_user', 'zendesk_user_update'], $data, $account);
// Make the call.
$client = zendesk_initialize_library();
$client->users()->update($data);
}
}
\Drupal::service('zendesk_user.manager')->updateUser($account);
}
/**
* Implements hook_ENTITY_TYPE_delete() for user entities.
*/
function zendesk_users_user_delete(AccountInterface $account) {
if (Drupal::config('zendesk.settings')->get('zendesk_api_sync_users')) {
if ($user_id = _zendesk_users_get_user($account->id())) {
$data = [
'id' => $user_id,
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'suspended' => TRUE,
];
// Alter call to omitted since we are destroying the User object.
// Make the call.
$client = zendesk_initialize_library();
$client->users()->delete($data);
}
}
}
/**
* Create a user on Zendesk's side.
*
* @param object $account
* The Drupal user object that we want to create on zendesk.
*
* @return mixed
* The zendesk's user id if succeeded, FALSE otherwise.
*/
function zendesk_users_create_user(AccountInterface $account) {
$client = zendesk_initialize_library();
$data = [
'name' => $account->getDisplayName(),
'email' => $account->getEmail(),
'role' => 'end-user',
];
if (\Drupal::config('zendesk.settings')->get('zendesk_authed_user')) {
$data['user']['verified'] = TRUE;
}
// Invoke a alter call to allow other modules to pass data to ZenDesk.
\Drupal::moduleHandler()
->alter(['zendesk_user', 'zendesk_user_update'], $data, $account);
// Make the call.
$result = $client->users()->create($data);
if (!empty($result->error)) {
// Try to handle special case where a user can be on zendesk's side, but
// not recorded on our table.
if ($result->error == 'RecordInvalid' && $result->details->email[0]->description == 'Email: ' . $account->getEmail() . ' is already being used by another user') {
return zendesk_users_sync_user_back($account);
}
\Drupal::logger('zendesk_users')->error($result->description . ': ' . print_r($result->details, 1));
return FALSE;
}
else {
db_insert('zendesk_users')
->fields([
'uid' => $account->id(),
'zid' => $result->user->id,
])
->execute();
return $result->user->id;
}
}
/**
* Try to sync user from zendesk on drupal side.
*
* If a user already exist on zendesk's side but not our the drupal side, add
* it in our database.
*
* @param \Drupal\Core\Session\AccountInterface $account
* An object containing the user account.
*
* @return mixed
* Zendesk's user ID if succeeded, FALSE otherwise.
*/
function zendesk_users_sync_user_back(AccountInterface $account) {
// Look for the user.
$client = zendesk_initialize_library();
$result = $client->users()->search($account->getEmail());
if (isset($result->users[0]->id)) {
db_insert('zendesk_users')
->fields([
'uid' => $account->id(),
'zid' => $result->users[0]->id,
])
->execute();
return $result->users[0]->id;
}
else {
return FALSE;
}
}
/**
* Helper function to retrieve zendesk id of the user.
*/
function _zendesk_users_get_user($uid) {
$result = db_select('zendesk_users', 'zu')
->fields('zu', ['uid', 'zid'])
->condition('zu.uid', $uid, '=')
->execute();
if ($result->rowCount() <> 0) {
foreach ($result as $user) {
return $user->zid;
}
}
else {
return FALSE;
}
\Drupal::service('zendesk_user.manager')->deleteUser($account);
}
services:
zendesk_user.manager:
class: \Drupal\zendesk_users\ZendeskUser
arguments: ['@database', '@module_handler','@config.factory', '@logger.channel.zendesk']
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment