rc-1.0.x-dev/src/Plugin/Block/RcBaseBlock.php
src/Plugin/Block/RcBaseBlock.php
<?php
namespace Drupal\rc\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Cache\Cache;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\rc\Services\RcUser;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Abstract Class as a base for RC blocks.
*/
abstract class RcBaseBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected AccountInterface $account;
/**
* The rc.user service.
*
* @var \Drupal\rc\Services\RcUser
*/
protected RcUser $rcUser;
/**
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected EntityTypeManagerInterface $entityTypeManager;
/**
* Constructs a new RcBaseBlock instance.
*
* @param array $configuration
* The plugin configuration, i.e. an array with configuration values keyed
* by configuration option name. The special key 'context' may be used to
* initialize the defined contexts by setting it to an array of context
* values keyed by context names.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
* @param \Drupal\rc\Services\RcUser $rcUser
* The rc.user service.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountInterface $account, RcUser $rcUser, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->account = $account;
$this->rcUser = $rcUser;
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user'),
$container->get('rc.user'),
$container->get('entity_type.manager')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration(): array {
return [
'width' => '350px',
'height' => '100vh',
'visibility_web' => FALSE,
'visibility_mobile' => FALSE,
'embedded' => TRUE,
'open_new_window' => FALSE,
'new_window_width' => 400,
'new_window_height' => 700,
];
}
/**
* {@inheritdoc}
*/
public function getCacheContexts(): array {
return Cache::mergeContexts(parent::getCacheContexts(), ['user']);
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state): array {
$form = parent::blockForm($form, $form_state);
$config = $this->getConfiguration();
// Getting Rocket Chat config to generate server URL.
$serverUrl = $this->rcUser->url();
$form['#tree'] = TRUE;
$form['block_options'] = [
'#type' => 'details',
'#title' => $this->t('Basic configuration'),
'#open' => TRUE,
'#attributes' => [
'id' => 'rc-basic-config',
],
];
$form['block_options']['url'] = [
'#type' => 'textfield',
'#title' => $this->t('iFrame URL'),
'#description' => $this->t('The inner URL to be imbedded in as an iFrame.'),
'#maxlength' => 255,
'#size' => 64,
'#default_value' => $config['url'] ?? '/directory/channels',
'#field_prefix' => $serverUrl,
];
$form['block_options']['width'] = [
'#type' => 'textfield',
'#title' => $this->t('iFrame width'),
'#description' => $this->t('The width of the iFrame in pixel or percent "200px" or "100%".'),
'#maxlength' => 255,
'#size' => 40,
'#default_value' => $config['width'] ?? '100%',
];
$form['block_options']['height'] = [
'#type' => 'textfield',
'#title' => $this->t('iFrame height'),
'#description' => $this->t('The height of the iFrame. in pixel or percent "200px" or "100%"'),
'#maxlength' => 255,
'#size' => 40,
'#default_value' => $config['height'] ?? '100vh',
];
$form['block_options']['visibility_web'] = [
'#type' => 'checkbox',
'#title' => $this->t('show a deep link to open chat app using "https://go.rocket.chat"'),
'#description' => $this->t('If checked, it shows a direct link to the chat website.'),
'#default_value' => $config['visibility_web'] ?? FALSE,
];
$form['block_options']['visibility_mobile'] = [
'#type' => 'checkbox',
'#title' => $this->t('show a deep link to open chat app using "rocketchat://"'),
'#description' => $this->t('If checked, it shows a direct link to open the chat mobile app.'),
'#default_value' => $config['visibility_mobile'] ?? FALSE,
];
$form['block_options']['embedded'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show the embedded version of the chat inside the iFrame'),
'#description' => $this->t('If checked, it will show the embedded version of the chat inside the iFrame.'),
'#default_value' => $config['embedded'] ?? TRUE,
];
$form['window_options'] = [
'#type' => 'details',
'#title' => $this->t('New window options'),
'#open' => TRUE,
];
$form['window_options']['open_new_window'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show a button to open the chat in a new window.'),
'#description' => $this->t('If checked, it will show a button link to open the chat in a new window.'),
'#default_value' => $config['open_new_window'] ?? FALSE,
'#attributes' => [
'id' => 'rc-window-options',
],
];
$form['window_options']['new_window_width'] = [
'#type' => 'textfield',
'#title' => $this->t('New window width'),
'#description' => $this->t('The width of the new window. Insert the number without px, vh...etc.'),
'#maxlength' => 255,
'#size' => 40,
'#default_value' => $config['new_window_width'] ?? '400',
'#states' => [
'visible' => [
'#rc-window-options' => ['checked' => TRUE],
],
],
];
$form['window_options']['new_window_height'] = [
'#type' => 'textfield',
'#title' => $this->t('New window height'),
'#description' => $this->t('The height of the new window. Insert the number without px, vh...etc.'),
'#maxlength' => 255,
'#size' => 40,
'#default_value' => $config['height'] ?? '700',
'#states' => [
'visible' => [
'#rc-window-options' => ['checked' => TRUE],
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
parent::blockSubmit($form, $form_state);
$values = $form_state->getValues();
$this->configuration['url'] = $values['block_options']['url'];
$this->configuration['server_url'] = $this->rcUser->url();
$this->configuration['width'] = strip_tags($values['block_options']['width']);
$this->configuration['height'] = strip_tags($values['block_options']['height']);
$this->configuration['visibility_web'] = $values['block_options']['visibility_web'];
$this->configuration['visibility_mobile'] = $values['block_options']['visibility_mobile'];
$this->configuration['embedded'] = $values['block_options']['embedded'];
$this->configuration['open_new_window'] = $values['window_options']['open_new_window'];
$this->configuration['new_window_width'] = strip_tags($values['window_options']['new_window_width']);
$this->configuration['new_window_height'] = strip_tags($values['window_options']['new_window_height']);
}
/**
* {@inheritdoc}
*/
public function build(): array {
$build = [];
$user = $this->getUserById($this->account->id());
$token = $this->validateRcUserToken($user) ?? NULL;
if (empty($token)) {
return $build;
}
// Get resume token from field.
$config = $this->getConfiguration();
// Get the authToken.
$authToken = $this->rcUser->getAuthTokenByName($user);
// Get the server URL.
$serverUrl = $this->rcUser->url();
// Set the host to be used by deep linking ULRs.
$host = preg_replace("(^https?://)", "", $serverUrl);
$build['#theme'] = 'rc_user_block';
$build['#url'] = $serverUrl . $config['url'] . ($config['embedded'] ? '?layout=embedded' : '');
$build['#server_url'] = $serverUrl;
$build['#token'] = $authToken;
$build['#width'] = $config['width'];
$build['#height'] = $config['height'];
$build['#web'] = $config['visibility_web'] ? 'https://go.rocket.chat/auth?host=' . $host . '&resumeToken=' . $token : NULL;
$build['#mobile'] = $config['visibility_mobile'] ? 'rocketchat://auth?host=' . $host . '&resumeToken=' . $token : NULL;
$build['#open_new_window'] = $config['open_new_window'];
$build['#new_window_width'] = $config['new_window_width'];
$build['#new_window_height'] = $config['new_window_height'];
return $build;
}
public function getUserById(int $userId): ?\Drupal\Core\Entity\EntityInterface {
return $this->entityTypeManager
->getStorage('user')
->load( $this->account->id());
}
public function validateRcUserToken(object $user) {
if (!$user || !$user->field_rcid->value) {
return NULL;
}
// Get the personal auth token.
$token = $user->field_rc_token->value;
if (!$token) {
$token = $this->rcUser->reGeneratePersonalAccessToken($user);
if ($token) {
$user->field_rc_token->value = $token;
$user->save();
}
else {
return NULL;
}
}
return $token;
}
}
