rc-1.0.x-dev/src/Services/RcUser.php

src/Services/RcUser.php
<?php

namespace Drupal\rc\Services;

use ATDev\RocketChat\Chat;
use ATDev\RocketChat\Users\User;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Logger\LoggerChannelFactory;

/**
 * Class RcUser.
 */
class RcUser extends RcAuth {

  /**
   * @var object
   */
  protected object $user;

  /**
   * The module configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  protected $config;


  /**
   * The logging service.
   *
   * @var \Psr\Log\LoggerInterface
   */
  protected $logger;

  /**
   * @param \Drupal\Core\Config\ConfigFactory $config_factory
   *
   * @param \Drupal\Core\Logger\LoggerChannelFactory $logger_factory
   *   The logging service.   *.
   */
  public function __construct(
    ConfigFactory $config_factory,
    LoggerChannelFactory $logger_factory) {
    $this->config = $config_factory->get('rc.settings');
    $this->logger = $logger_factory->get('rc');
    parent::__construct($config_factory);
  }

  /**
   * Login user with Rocket Chat account credentials.
   *
   * @param string $userName
   * @param string $password
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function login(string $userName = NULL, string $password = NULL) {
    if ($userName && $password) {

      // Set the Rocket Chat server URL.
      Chat::setUrl($this->url());

      // Login user.
      $result = Chat::login($userName, $password);

      if ($result) {
        return $result;
      }

      // Log the error if there is no results.
      $error = Chat::getError();
      $this->logger->error('Rocket chat error while login: ' . $error);
    }

  }

  /**
   * Get the auth token using username.
   * This method is handy when the Rocket Chat ID is not saved in the user
   * object.
   *
   * @param $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function getAuthTokenByName($user) {

    // Validate the username as required by RC account name limitations.
    $userName = $this->validateUsername($user->getDisplayName());

    // User the hashed user password as the RC account password.
    $password = $user->getPassword();

    // Set the Rocket Chat server URL.
    Chat::setUrl($this->url());

    // Get the personal auth token.
    $result = RcChat::authToken($userName, $password, TRUE);

    if ($result) {

      // Retuen the auth token if exist.
      return $result;
    }
    // Log the error.
    $error = Chat::getError();
    $this->logger->error('Rocket chat error while getting authToken: ' . $error);

  }

  /**
   * Login to Rocket Chat server with admin account saved in configurations.
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function loginRcAdmin() {
    return $this->login($this->user(), $this->secret());
  }

  /**
   * Convert username to an acceptable Rocket Chat account name.
   *
   * @param string $userName
   *
   * @return array|string|string[]|null
   */
  public function validateUsername(string $userName) {
    // Replacing spaces and special character with dashes as Rocket Chat does
    // not accept them in the username.
    return preg_replace("![^a-z0-9]+!i", "-", $userName);

  }

  /**
   * Login to Rocket Chat server using user account.
   *
   * @param object $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|null
   */
  public function loginUserByName(object $user): User|bool|null {

    // Validate the username.
    $userName = $this->validateUsername($user->getDisplayName());

    // Use user hashed password as the password of RC account.
    $password = $user->getPassword();

    return $this->login($userName, $password);

  }

  /**
   * Get the saved Rocket chat ID from the field_ricd field in the user object.
   *
   * @param object $user
   *
   * @return mixed
   */
  public function getRcIdFromField(object $user) {
    return $user->field_rcid->value;

  }

  /**
   * Get Rocket Chat account information using username from user object.
   *
   * @param object $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function userInfoByName(object $user = NULL) {
    if ($user) {

      // Login to Rocket Chat server using Admin account.
      if ($this->loginRcAdmin()) {

        $rcUser = new User($this->validateUsername($user->getDisplayName()));

        // Get account information.
        $result = $rcUser->info();

        if ($result) {

          // Return info if exists.
          return $result;
        }

        // Handling output with messages.
        $this->logger->error('Rocket chat error: ' . $rcUser->getError());
      }
    }
  }

  /**
   * Get account information using RC account ID field from user object.
   *
   * @param object|null $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function userInfoById(object $user = NULL) {
    if ($user) {

      // Get the Rocket Chat account Id from field.
      $rcId = $this->getRcIdFromField($user);
      if ($rcId) {

        // Login to Rocket Chat server as admin.
        if ($this->loginRcAdmin()) {

          $rcUser = new User($rcId);

          // Get account information if exists.
          $result = $rcUser->info();

          if ($result) {
            return $result;
          }

          // Log the error.
          $this->logger->error('Rocket chat error: ' . $rcUser->getError());
        }
      }
    }

  }

  /**
   * Check if Rocket Chat account exists for the user using the Rocket Chat
   * Account ID if exists, and if not it checks by the username.
   *
   * @param $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function checkIfUserExist($user) {

    // Get account info using field_rcid field from user object.
    $userInfoById = $this->userInfoById($user);
    if ($userInfoById) {

      return $userInfoById;

    }

    // If no results, try getting account information by username.
    $userInfoByName = $this->userInfoByName($user);
    if ($userInfoByName) {

      return $userInfoByName;
    }

  }

  /**
   * This method creates the chat account, set the Rocket Chat account ID & the
   * token and saves it to the user entity.
   * The $save variable is used to save the user object, this is helpful when
   * using Drupal CRUD hooks as the preprocessors should not be used with
   * $entity->save() which leads to infinite loop.
   *
   * @param object $user
   * @param bool|null $save
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function createUser(object $user, bool $save = NULL) {
    // Login in with Rocket chat admin to create new user.
    if ($this->loginRcAdmin()) {

      // Check if Rocket Chat account exists.
      $checkIfUserExist = $this->checkIfUserExist($user);

      // If Rocket Chat account does not exist.
      if (!$checkIfUserExist) {

        // Initiate the Rocket Chat account creation.
        $rcUser = new User();

        // Get the mapped fields. This method is separated to allow maximum
        // flexibility that contains the minimum fields requirements of Rocket
        // Chat account and allow mapping for custom fields.
        $this->fieldMapping($user, $rcUser);

        // Create the Rocket Chat account.
        $result = $rcUser->create();

        if ($result) {
          // Set the Rocket Chat ID in the field.
          $rcId = $result->getUserId();
          $user->field_rcid->value = $rcId;

          // Set the personal access token field.
          $token = $result->generatePersonalAccessToken("mypersonaltoken", TRUE);
          if (!$token) {
            $token = $result
              ->regeneratePersonalAccessToken("mypersonaltoken");
          }

          $user->field_rc_token->value = $token;

          // Invoke custom hook.
          \Drupal::moduleHandler()->invokeAll('rc_create_user', [$user]);

          // Log the successful creation of the Rocket Chat account.
          $this->logger->info('New chat account of user ' . $user->getDisplayName() . ' is created');

          // Save Drupal user object.
          if ($save) {
            $user->save();
          }

          return $result;
        }

        // Log error.
        $this->logger->error('Rocket Chat error while creating user: ' . $rcUser->getError());

      }

      // If user exists continue to get the Rocket chat ID and personal access
      // token fields.
      // Set the Rocket Chat ID in the field.
      $user->field_rcid->value = $checkIfUserExist->getUserId();

      // Get and save the personal access token.
      if ($checkIfUserExist->getPersonalAccessTokens()) {

        // Set the personal access token.
        $user->field_rc_token->value = $checkIfUserExist
          ->regeneratePersonalAccessToken("mypersonaltoken", TRUE);
      }
      else {
        $user->field_rc_token->value = $checkIfUserExist
          ->generatePersonalAccessToken("mypersonaltoken");
      }

      // Save Drupal user object.
      if ($save) {
        $user->save();
      }

      return $checkIfUserExist;
    }
  }

  /**
   * This method updates the chat account, the token and saves it to
   * the user entity.
   * The $save variable is used to save the user object, this is helpful when
   * using Drupal CRUD hooks as the preprocessors should not be used with
   * $entity->save() which leads to infinite loop.
   *
   * @param object $user
   * @param bool|null $save
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function updateUser(object $user, bool $save = NULL) {

    // Check if user exists.
    $checkIfUserExist = $this->checkIfUserExist($user->original ? $user->original : $user);
    if ($checkIfUserExist) {

      // Login as Rocket Chat admin.
      if ($this->loginRcAdmin()) {

        // Get the RC account ID from RC server.
        $rcId = $checkIfUserExist->getUserId();

        // Initiate update process.
        $rcUser = new User($rcId);

        // Get the mapped fields. This method is separated to allow maximum
        // flexibility that contains the minimum fields requirements of Rocket
        // Chat account and allow mapping for custom fields.
        $this->fieldMapping($user, $rcUser);

        // Update Rocket Chat account.
        $result = $rcUser->update();

        // Log error and return if there is an error.
        if (!$result) {
          $error = $rcUser->getError();
          $this->logger->error('Rocket Chat error while updating user: ' . $error);

          return;
        }

        // Set the Rocket Chat ID field if it does not exist.
        if (!$user->field_rcid->value) {
          $user->field_rcid->value = $rcId;
        }

        // Set the personal token field if it does not exist.
        if (!$user->field_rc_token->value) {

          // Generate token.
          $token = $result->generatePersonalAccessToken('mypersonaltoken', TRUE);

          // If no result, regenerate the token.
          if (!$token) {
            $token = $result->regeneratePersonalAccessToken("mypersonaltoken");
          }

          // Set personal access token field.
          $user->field_rc_token->value = $token;
        }

        // Invoke custom hook.
        \Drupal::moduleHandler()->invokeAll('rc_update_user', [$result, $user]);

        // Log successful account update.
        $this->logger->info('Chat account for user ' . $user->getDisplayName() . ' is updated');

        // Save user entity.
        if ($save) {
          $user->save();
        }

        return $result;
      }
    }

  }

  /**
   * Delete Rocket chat account.
   *
   * @param object $user
   *
   * @return \ATDev\RocketChat\Users\User|bool|void
   */
  public function deleteUser(object $user) {

    // Check if RC account exits.
    $checkIfUserExist = $this->checkIfUserExist($user);

    if ($checkIfUserExist) {

      // Get the RC account ID.
      $rcId = $checkIfUserExist->getUserId();

      // Initiate RC account deletion.
      $rcUser = new User($rcId);

      // Delete RC account.
      $result = $rcUser->delete();

      // Log erros and return.
      if (!$result) {
        // Log the error.
        $error = $rcUser->getError();
        $this->logger->error('Rocket chat error: ' . $error);

        return;
      }

      return $result;
    }

  }

  /**
   * Helper method to map Drupal user fields to Rocket Chat account fields.
   * The main benefit is that it maps mandatory fields by default and allows to
   * map custom fields of Drupal user entity to the Rocket chat account custom
   * fields.
   *
   * @param object $user
   * @param object $rcUser
   *
   * @return object
   */
  public function fieldMapping(object $user, object &$rcUser) {
    // Preparing the data from the $user object, this is a basic mapping to user
    // entity fields.
    $displayName = $user->getDisplayName();
    $name = $this->validateUsername($displayName);

    // Setting the matching data to the rcUser object.
    $rcUser->setName($displayName);
    $rcUser->setUsername($name);
    $rcUser->setPassword($user->getPassword());
    $rcUser->setEmail($user->getEmail());

    // Map user roles, and set Rocket Chat admin role to Drupal users with
    // Administrator role.
    if ($this->config->get('user.add_admin_role')) {
      if (in_array('administrator', $user->getRoles())) {
        $rcUser->setRoles(['admin']);
      }
      else {
        $rcUser->setRoles(['user']);
      }
    }

    // Map the user status to Rocket Chat account status.
    if ($user->isActive()) {
      $rcUser->setActive(TRUE);
      $rcUser->setVerified(TRUE);
    }
    else {
      $rcUser->setActive(FALSE);
      $rcUser->setVerified(FALSE);
    }

    // Invoke hook_field_mapping invoke to update field.
    \Drupal::moduleHandler()->invokeAll('field_mapping_rc_alter', [$user, $rcUser]);
    return $rcUser;
  }

  /**
   * Get the personal access token from field_rc_token.
   *
   * @param object $user
   *
   * @return mixed
   */
  public function getPersonalAccessToken(object $user) {
    return $user->field_rc_token->value;

  }

  /**
   * Generate personal access token for Rocket Chat account and save it to user
   * object.
   *
   * @param object $user
   *
   * @return string|void
   */
  public function generatePersonalAccessToken(object $user) {

    // Login to Rocket Chat server by  username.
    if ($this->loginUserByName($user)) {

      // Initiate personal access token generation.
      $rcUser = Chat::me();

      // Generate the personal access token.
      $token = $rcUser->generatePersonalAccessToken("mypersonaltoken", TRUE);

      // Log errors in no results.
      if (!$token) {
        $this->logger->error('Rocket chat error: ' . $rcUser->getError());
      }
      else {

        // Set the token value to field in user object.
        $user->field_rc_token->value = $token;
        return $token;
      }
    }

    // If login is not successful, show an error.
    else {
      \Drupal::messenger()->addError('Couldn\'t generate an access token, Contact your system administrator.');
    }

  }

  /**
   * Re-generate personal access token for Rocket Chat account and save it to
   * user object.
   *
   * @param object $user
   *
   * @return string|void
   */
  public function reGeneratePersonalAccessToken(object $user) {

    // Login to Rocket Chat server by username.
    if ($this->loginUserByName($user)) {

      // Initiate the personal access token regeneration.
      $rcUser = Chat::me();

      // Regenerate the personal access token.
      $token = $rcUser->regeneratePersonalAccessToken("mypersonaltoken");

      // Log errors in no results.
      if (!$token) {

        // Try generating the token.
        $token = $rcUser->generatePersonalAccessToken("mypersonaltoken", TRUE);

        // If still no result, log errors.
        if (!$token) {
          $this->logger->error('Rocket chat error: ' . $rcUser->getError());
          return;
        }
      }

      // Set the token value to field in user object.
      $user->field_rc_token->value = $token;
      return $token;
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc