social_auth-8.x-2.x-dev/social_auth.module
social_auth.module
<?php
/**
* @file
* Allows login using different social networking services.
*/
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\Core\Utility\Error;
/**
* Implements hook_theme().
*/
function social_auth_theme() {
return [
'login_with' => [
'variables' => ['networks' => NULL, 'destination' => NULL],
],
];
}
/**
* Implements hook_preprocess_HOOK().
*/
function social_auth_preprocess_login_with(&$variables) {
$request = \Drupal::request();
$variables['destination'] = $request->get('destination', $variables['destination']);
$variables['base_path'] = base_path();
$variables['#cache'] = ['contexts' => ['url.query_args:destination']];
}
/**
* Implements hook_ENTITY_TYPE_delete().
*/
function social_auth_user_delete(EntityInterface $account) {
try {
$storage = \Drupal::entityTypeManager()
->getStorage('social_auth');
/** @var \Drupal\social_auth\Entity\SocialAuth[] $socialAuthUser */
$users = $storage->loadByProperties([
'user_id' => $account->id(),
]);
if ($users) {
$storage->delete($users);
}
$storage->resetCache([$account->id()]);
}
catch (\Exception $e) {
\Drupal::logger('social_auth')
->error('Could not delete Social Auth users for user @uid. Error @error', [
'@uid' => $account->id(),
'@error' => $e->getMessage(),
]);
}
}
/**
* Implements hook_entity_extra_field_info().
*/
function social_auth_entity_extra_field_info() {
$fields['user']['user']['form']['social_auth'] = [
'label' => t('Social authentications'),
'description' => t('Social Auth form element.'),
'weight' => 5,
];
return $fields;
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function social_auth_form_user_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// If the for is the user edit form, not user register form or others.
// @see https://www.drupal.org/node/2854977
if ($form_id == 'user_form') {
$current_user = Drupal::currentUser();
if (_social_auth_can_grant_permission($current_user)) {
// Add a button to authorize twitter auto posting.
try {
$form += _social_auth_user_edit_form($current_user);
}
catch (Exception $e) {
Error::logException(\Drupal::logger('social_auth'), $e);
}
}
}
}
/**
* Check if the user is allowed to view own social auths.
*
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*
* @return bool
* The user can see this user social auths.
*/
function _social_auth_can_grant_permission(AccountInterface $current_user): bool {
$routeMatch = Drupal::service('current_route_match');
// If the current user id is the same as the user id of parameter.
if ($current_user->id() == $routeMatch->getParameter('user')->id()) {
return TRUE;
}
return FALSE;
}
/**
* Creates elements to the user edit form.
*
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
*
* @return array
* The elements to add to the user edit form.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function _social_auth_user_edit_form(AccountInterface $current_user): array {
/** @var \Drupal\social_post\Entity\SocialPost[] $accounts */
$accounts = _social_auth_get_accounts_by_uid($current_user->id());
$networks = _social_auth_get_networks();
$form['social_auth'] = [
'#type' => 'details',
'#title' => t('Social Authentications'),
'#open' => TRUE,
];
$form['social_auth']['accounts'] = [
'#type' => 'table',
'#header' => [
t('Status'),
t('Network'),
t('Provider User ID'),
t('Operations'),
],
'#empty' => t('You have not added any accounts yet.'),
];
foreach ($networks as $network_plugin_id => $network) {
$form['social_auth']['accounts'][$network_plugin_id]['status'] = [
'#markup' => '',
];
$form['social_auth']['accounts'][$network_plugin_id]['network'] = [
'#markup' => $network['network']->getShortName(),
];
$form['social_auth']['accounts'][$network_plugin_id]['screen_name'] = [
'#markup' => '-',
];
$form['social_auth']['accounts'][$network_plugin_id]['operations'] = [
'#type' => 'operations',
'#links' => [
'authenticate' => [
'title' => t('Authenticate'),
'url' => Url::fromUserInput($network['network']->getRedirectUrl([
'query' => [
'destination' => Url::fromRoute('<current>', [], [])->toString(),
],
])->toString()),
],
],
];
foreach ($accounts as $account) {
$plugin_id = $account->hasField("plugin_id") && !$account->get("plugin_id")->isEmpty() ? $account->get("plugin_id")->first()->getValue()['value'] : t('Broken/Missing');
if ($network_plugin_id === $plugin_id) {
$provider_user_id = $account->hasField("provider_user_id") && !$account->get("provider_user_id")->isEmpty() ? $account->get("provider_user_id")->first()->getValue()['value'] : t('Broken/Missing');
$form['social_auth']['accounts'][$network_plugin_id]['status'] = [
'#type' => 'html_tag',
'#tag' => 'span',
'#value' => $networks[$plugin_id]['access_token_expired'] ? '⚠️⌛' : '✔️',
'#attributes' => [
'title' => $networks[$plugin_id]['access_token_expired'] ? t('Access token expired') : t('Connected'),
],
];
$form['social_auth']['accounts'][$network_plugin_id]['screen_name'] = [
'#markup' => $provider_user_id,
];
$form['social_auth']['accounts'][$network_plugin_id]['operations']['#links']['delete'] = [
'title' => t('Delete'),
'url' => Url::fromRoute('entity.social_auth.delete_form',
[
'social_auth' => $account->id(),
]
),
];
}
}
}
return $form;
}
/**
* Gets the accounts associated to the Drupal user.
*
* @param int $user_id
* The user id.
*
* @return \Drupal\Core\Entity\EntityInterface[]
* Accounts associated to the user id.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
function _social_auth_get_accounts_by_uid(int $user_id): array {
$entity_query = Drupal::entityTypeManager()->getStorage('social_auth')->getAggregateQuery();
$result = $entity_query
->condition('user_id', $user_id)
->aggregate('id', 'MAX')
->groupBy('plugin_id')
->accessCheck(TRUE)
->execute();
$accounts = [];
foreach ($result as $distinct_entities) {
$accounts[] = $distinct_entities['id_max'];
}
return $result ? Drupal::entityTypeManager()->getStorage('social_auth')->loadMultiple($accounts) : [];
}
/**
* Gets the networks defined.
*
* @return array
* Array of network plugins.
*
* @throws \Drupal\Component\Plugin\Exception\PluginException
*/
function _social_auth_get_networks(): array {
/** @var \Drupal\social_api\Plugin\NetworkManager $network_manager */
$network_manager = \Drupal::service('plugin.network.manager');
/** @var \Drupal\social_auth\SocialAuthDataHandler $data_handler */
$data_handler = \Drupal::service('social_auth.data_handler');
$networks = [];
foreach ($network_manager->getDefinitions() as $definition) {
$networks[$definition['id']]['network'] = $network_manager->createInstance($definition['id']);
$data_handler->setSessionPrefix($definition['id']);
if ($access_token = $data_handler->get('access_token')) {
$networks[$definition['id']]['access_token_expired'] = $access_token->getExpires() < (new DrupalDateTime())->getTimestamp();
$networks[$definition['id']]['access_token'] = $access_token;
}
else {
$networks[$definition['id']]['access_token_expired'] = TRUE;
}
}
return $networks;
}
