support-2.0.x-dev/modules/support_ticket/src/Form/RevisionOverviewForm.php
modules/support_ticket/src/Form/RevisionOverviewForm.php
<?php
namespace Drupal\support_ticket\Form;
use Drupal\Component\Utility\SafeMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManager;
use Drupal\Core\Form\FormBase;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
/**
* Provides a form for revision overview page.
*/
class RevisionOverviewForm extends FormBase {
use StringTranslationTrait;
/**
* The entity manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityManager;
/**
* The current user service.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The date service.
*
* @var \Drupal\Core\Datetime\DateFormatter
*/
protected $date;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Wrapper object for simple configuration.
*
* Wrapper object for writing/reading simple
* configuration from support_ticket.settings.yml.
*
* @var config
*/
protected $config;
/**
* Constructs a RevisionOverviewForm object.
*
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityManager
* The entity manager.
* @param \Drupal\Core\Session\AccountInterface $currentUser
* The current user.
* @param \Drupal\Core\Datetime\DateFormatter $date
* The date service.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
*/
public function __construct(EntityTypeManagerInterface $entityManager, AccountInterface $currentUser, DateFormatter $date, RendererInterface $renderer) {
$this->entityManager = $entityManager;
$this->currentUser = $currentUser;
$this->date = $date;
$this->renderer = $renderer;
$this->config = $this->config('support_ticket.settings');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('entity_type.manager'),
$container->get('current_user'),
$container->get('date.formatter'),
$container->get('renderer')
);
}
/**
* {@inheritdoc}
*/
public function getFormId(): string {
return 'revision_overview_form';
}
/**
* {@inheritdoc}
*
* @throws \Exception
*/
public function buildForm(array $form, FormStateInterface $form_state, $support_ticket = NULL) {
$account = $this->currentUser;
$support_ticket_store = $this->entityManager->getStorage('support_ticket');
$type = $support_ticket->getType();
$vids = array_reverse($support_ticket_store->revisionIds($support_ticket));
$revision_count = count($vids);
$build = [
'#title' => $this->t('Revisions for %title',
['%title' => $support_ticket->label()]
),
'stid' => [
'#type' => 'hidden',
'#value' => $support_ticket->stid->value,
],
];
$table_header = [
'revision' => $this->t('Revision'),
'operations' => $this->t('Operations'),
];
// Allow comparisons only if there are 2 or more revisions.
if ($revision_count > 1) {
$table_header += [
'select_column_one' => '',
'select_column_two' => '',
];
}
$rev_revert_perm = $account->hasPermission("revert $type revisions") ||
$account->hasPermission('revert all revisions') ||
$account->hasPermission('administer support tickets');
$rev_delete_perm = $account->hasPermission("delete $type revisions") ||
$account->hasPermission('delete all revisions') ||
$account->hasPermission('administer support tickets');
$revert_permission = $rev_revert_perm && $support_ticket->access('update');
$delete_permission = $rev_delete_perm && $support_ticket->access('delete');
// Contains the table listing the revisions.
$build['support_ticket_revisions_table'] = [
'#type' => 'table',
'#header' => $table_header,
'#attributes' => ['class' => ['diff-revisions']],
];
$build['support_ticket_revisions_table']['#attached']['library'][] = 'diff/diff.general';
$build['support_ticket_revisions_table']['#attached']['drupalSettings']['diffRevisionRadios'] = $this->config->get('general_settings.radio_behavior');
// Add rows to the table.
foreach ($vids as $vid) {
if ($revision = $support_ticket_store->loadRevision($vid)) {
// Markup for revision log.
if ($revision->revision_log->value != '') {
$revision_log = '<p class="revision-log">' . Xss::filter($revision->revision_log->value) . '</p>';
}
else {
$revision_log = '';
}
// Username to be rendered.
$username = [
'#theme' => 'username',
'#account' => $revision->uid->entity,
];
$revision_date = $this->date->format($revision->getRevisionCreationTime(), 'short');
// Default revision.
if ($revision->isDefaultRevision()) {
$date_username_markup = $this->t('!date by !username',
[
'!date' => $this->l(
$revision_date,
Url::fromRoute('entity.support_ticket.canonical',
['support_ticket' => $support_ticket->id()]
)
),
'!username' => $this->renderer->render($username),
],
);
$row = [
'revision' => [
'#markup' => $date_username_markup . $revision_log,
],
'operations' => [
'#markup' => '%placeholder',
['%placeholder' => $this->t('current revision')]
,
],
'#attributes' => [
'class' => ['revision-current'],
],
];
// Allow comparisons only if there are 2 or more revisions.
if ($revision_count > 1) {
$row += [
'select_column_one' => [
'#type' => 'radio',
'#title_display' => 'invisible',
'#name' => 'radios_left',
'#return_value' => $vid,
'#default_value' => FALSE,
],
'select_column_two' => [
'#type' => 'radio',
'#title_display' => 'invisible',
'#name' => 'radios_right',
'#default_value' => $vid,
'#return_value' => $vid,
],
];
}
}
else {
$route_params = [
'support_ticket' => $support_ticket->id(),
'support_ticket_revision' => $vid,
];
// Add links based on permissions.
if ($revert_permission) {
$links['revert'] = [
'title' => $this->t('Revert'),
'url' => Url::fromRoute('support_ticket.revision_revert_confirm', $route_params),
];
}
if ($delete_permission) {
$links['delete'] = [
'title' => $this->t('Delete'),
'url' => Url::fromRoute('support_ticket.revision_delete_confirm', $route_params),
];
}
$date_username_markup = $this->t('!date by !username',
[
'!date' => $this->l($revision_date, Url::fromRoute('entity.support_ticket.revision', $route_params)),
'!username' => $this->renderer->render($username),
],
);
// Here we don't have to deal with 'only one revision' case because
// if there's only one revision it will also be the default one,
// entering on the first branch of this if else statement.
$row = [
'revision' => [
'#markup' => $date_username_markup . $revision_log,
],
'select_column_one' => [
'#type' => 'radio',
'#title_display' => 'invisible',
'#name' => 'radios_left',
'#return_value' => $vid,
'#default_value' => $vids[1] ?? FALSE,
],
'select_column_two' => [
'#type' => 'radio',
'#title_display' => 'invisible',
'#name' => 'radios_right',
'#return_value' => $vid,
'#default_value' => FALSE,
],
'operations' => [
'#type' => 'operations',
'#links' => $links,
],
];
}
// Add the row to the table.
$build['support_ticket_revisions_table'][] = $row;
}
}
// Allow comparisons only if there are 2 or more revisions.
if ($revision_count > 1) {
$build['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Compare'),
'#attributes' => [
'class' => [
'diff-button',
],
],
];
}
return $build;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state): void {
$input = $form_state->getUserInput();
$vid_left = $input['radios_left'];
$vid_right = $input['radios_right'];
if ($vid_left == $vid_right || !$vid_left || !$vid_right) {
// @todo Radio-boxes selection resets if there are errors.
$form_state->setErrorByName('support_ticket_revisions_table',
$this->t('Select different revisions to compare.')
);
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state): void {
$input = $form_state->getUserInput();
$vid_left = $input['radios_left'];
$vid_right = $input['radios_right'];
$stid = $input['stid'];
// Always place the older revision on the left side of the comparison
// and the newer revision on the right side (however revisions can be
// compared both ways if we manually change the order of the parameters).
if ($vid_left > $vid_right) {
$aux = $vid_left;
$vid_left = $vid_right;
$vid_right = $aux;
}
// Builds the redirect Url.
$redirect_url = Url::fromRoute(
'support_ticket.revisions_diff',
[
'support_ticket' => $stid,
'left_vid' => $vid_left,
'right_vid' => $vid_right,
]
);
$form_state->setRedirectUrl($redirect_url);
}
}
