drupalorg-1.0.x-dev/src/UserService.php
src/UserService.php
<?php
namespace Drupal\drupalorg;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\node\NodeInterface;
use Drupal\user\UserInterface;
/**
* User related helper methods.
*/
class UserService {
/**
* The database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected Connection $connection;
/**
* An instance of the entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* Project service.
*
* @var \Drupal\drupalorg\ProjectService
*/
protected ProjectService $projectService;
/**
* Construct method.
*
* @param \Drupal\Core\Database\Connection $connection
* The database connection.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
* Entity type manager service.
* @param \Drupal\drupalorg\ProjectService $projectService
* Project service.
*/
public function __construct(Connection $connection, EntityTypeManagerInterface $entityTypeManager, ProjectService $projectService) {
$this->connection = $connection;
$this->entityTypeManager = $entityTypeManager;
$this->projectService = $projectService;
}
/**
* Retrieve user by username.
*
* @param string $username
* Drupal username.
*
* @return \Drupal\user\UserInterface|null
* User entity or null.
*/
public function getUserByUsername(string $username): ?UserInterface {
$users = $this->getUsersByUsername([$username]);
return !empty($users) ? array_shift($users) : NULL;
}
/**
* Retrieve users by name.
*
* @param string[] $usernames
* List of usernames.
*
* @return \Drupal\user\UserInterface[]|null
* User entity or null.
*/
public function getUsersByUsername(array $usernames): ?array {
return $this->getUsersBy('name', $usernames);
}
/**
* Retrieve user by git username.
*
* @param string $username
* Git username.
*
* @return \Drupal\user\UserInterface|null
* User entity or null.
*/
public function getUserByGitUsername(string $username): ?UserInterface {
$users = $this->getUsersByGitUsername([$username]);
return !empty($users) ? array_shift($users) : NULL;
}
/**
* Retrieve users by git username.
*
* @param string[] $usernames
* List of git usernames.
*
* @return \Drupal\user\UserInterface[]|null
* User entity or null.
*/
public function getUsersByGitUsername(array $usernames): ?array {
return $this->getUsersBy('field_git_username', $usernames);
}
/**
* Generic function to get users by a certain value on a given field.
*
* @param string $field
* Name of the field.
* @param array $values
* List of values for the field.
*
* @return \Drupal\user\UserInterface[]|null
* List of users matching the criteria or null.
*/
protected function getUsersBy($field, array $values): ?array {
$ids = $this->entityTypeManager->getStorage('user')->getQuery()
->accessCheck(FALSE)
->condition($field, $values, 'IN')
->execute();
if (!empty($ids)) {
return $this->entityTypeManager->getStorage('user')->loadMultiple($ids);
}
return NULL;
}
/**
* List of node types that shared accounts can use.
*
* @return string[]
* List of node types.
*/
public function sharedAccountAllowedNodeTypes() {
$project_types = $this->projectService->projectNodeTypes();
return array_merge(['organization', 'casestudy', 'event'], $project_types);
}
/**
* Returns whether a given user account is shared.
*
* @param \Drupal\user\UserInterface $user
* User to check.
*
* @return bool
* Account is a shared one or not.
*/
public function isSharedAccount(UserInterface $user) {
return (bool) $user->get('field_shared_account_for_an_org')->value;
}
/**
* Returns the GitLab ID for the given user.
*
* @param \Drupal\user\UserInterface|\Drupal\Core\Session\AccountInterface $user
* User to check.
*
* @return int|null
* GitLab ID of the user or null.
*/
public function getGitLabUserId(UserInterface|AccountInterface $user) {
$query = $this->connection
->select('drupalorg_gitlab_users', 'gu')
->condition('gu.uid', $user->id())
->fields('gu');
$info = $query->execute()->fetchAssoc();
return $info['gitlab_user_id'] ?? NULL;
}
/**
* Returns the git username of a user.
*
* @param \Drupal\user\UserInterface $user
* User to check.
*
* @return string|null
* Git username or null.
*/
public function getGitUsername(UserInterface $user) {
return !empty($user->get('field_git_username')->getValue()) ?
$user->get('field_git_username')->getValue()[0]['value'] :
NULL;
}
/**
* Calculates and returns a no-reply address for the given user.
*
* @param \Drupal\user\UserInterface $user
* User to check.
* @param bool $only_email
* Whether to return only the email or the full address.
*
* @return string
* Email address or full address for the user.
*/
public function getNoReplyAddress(UserInterface $user, $only_email = TRUE) {
// Calculate the no-reply email so as not to expose PII.
$username = $this->getGitUsername($user) ?? $user->getAccountName();
$gitlab_user_id = $this->getGitLabUserId($user);
// Format 1 (GITLAB_USER_ID-GIT_USERNAME@users.noreply.drupalcode.org).
if ($gitlab_user_id) {
$email = $gitlab_user_id . '-' . $username . '@users.noreply.drupalcode.org';
}
// Format 2 (USERNAME@UID.no-reply.drupal.org).
else {
$email = $user->getAccountName() . '@' . $user->id() . '.no-reply.drupal.org';
}
if ($only_email) {
return $email;
}
return $username . ' <' . $email . '>';
}
/**
* Checks whether a user is shared and can access a certain node for editing.
*
* @param \Drupal\user\UserInterface $user
* User to check.
* @param \Drupal\node\NodeInterface $node
* Node to check.
*
* @return bool
* Whether the user can edit the node or not.
*/
public function isAccountAllowedToEditNode(UserInterface $user, NodeInterface $node) {
if (
$this->isSharedAccount($user) &&
!in_array($node->bundle(), $this->sharedAccountAllowedNodeTypes())
) {
return FALSE;
}
return TRUE;
}
/**
* Checks whether a user is shared and can access a certain node for creation.
*
* @param \Drupal\user\UserInterface $user
* User to check.
* @param string $entity_type
* Node type to check.
*
* @return bool
* Whether the user can edit the node or not.
*/
public function isAccountAllowedToCreateNode(UserInterface $user, string $entity_type) {
if (
$this->isSharedAccount($user) &&
!in_array($entity_type, $this->sharedAccountAllowedNodeTypes())
) {
return FALSE;
}
return TRUE;
}
/**
* Get the projects maintained by an user.
*
* @param \Drupal\user\UserInterface $user
* User to get the projects from.
*
* @return array
* Array of project ids and machine_names that the user is maintainer of.
*/
public function getProjectMaintained(UserInterface $user): array {
$query = $this->connection
->select('drupalorg_project_maintainer', 'pm')
->condition('pm.uid', $user->id())
->fields('pm');
return $query->execute()->fetchAllAssoc('nid');
}
}
