Skip to content
Snippets Groups Projects
Commit f336230d authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3432084 by alexpott, daniel.bosen: Add link to view content as it is sent to VG Wort

parent 988a6a65
No related branches found
No related tags found
1 merge request!46Add modal to display text sent to VG Wort
Pipeline #129377 passed
parameters:
ignoreErrors:
-
message: """
#^Call to deprecated method loadRevision\\(\\) of class Drupal\\\\Core\\\\Entity\\\\EntityStorageInterface\\:
in drupal\\:10\\.1\\.0 and is removed from drupal\\:11\\.0\\.0\\. Use
\\\\Drupal\\\\Core\\\\Entity\\\\RevisionableStorageInterface\\:\\:loadRevision instead\\.$#
"""
count: 1
path: src/Controller/Overview.php
-
message: "#^\\\\Drupal calls should be avoided in classes, use dependency injection instead$#"
count: 1
......
<?php
namespace Drupal\vgwort\Controller;
use Drupal\Component\Render\PlainTextOutput;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\RevisionableInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Url;
use Drupal\vgwort\EntityJobMapper;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
class MessageTextView extends ControllerBase {
public function __construct(
private readonly EntityJobMapper $jobMapper,
private readonly RendererInterface $renderer,
ConfigFactoryInterface $configFactory,
EntityTypeManagerInterface $entityTypeManager,
) {
$this->configFactory = $configFactory;
$this->entityTypeManager = $entityTypeManager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('vgwort.entity_job_mapper'),
$container->get('renderer'),
$container->get('config.factory'),
$container->get('entity_type.manager'),
);
}
public function __invoke(RouteMatchInterface $route_match, string $entity_type_id, Request $request) {
/** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
$entity = $route_match->getParameter($entity_type_id);
// Use the sent revision if one is available.
if ($entity instanceof RevisionableInterface) {
$revisions_sent = $this->jobMapper->getRevisionsSent($entity);
if ($last_revision_sent_id = array_key_last($revisions_sent)) {
/** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage($entity->getEntityTypeId());
$entity = $storage->loadRevision($last_revision_sent_id);
}
}
$view_mode = $this->config('vgwort.settings')->get("entity_types.{$entity_type_id}.view_mode") ?? 'full';
$content = $this->entityTypeManager
->getViewBuilder($entity->getEntityTypeId())
->view($entity, $view_mode);
$text = PlainTextOutput::renderFromHtml((string) $this->renderer->renderPlain($content));
$build = [];
$build['#title'] = $this->t('VG Wort text for %title', ['%title' => $entity->label()]);
$build['content'] = [
'#prefix' => '<pre>',
'#plain_text' => $text,
'#suffix' => '</pre>',
];
// If not accessed via a modal then provide a button to go to the VG Wort
// tab.
if ($request->query->get('_wrapper_format') !== 'drupal_modal') {
$build['button'] = [
'#type' => 'link',
'#title' => $this->t('Back to VG Wort overview'),
'#url' => Url::fromRoute("entity.{$entity->getEntityTypeId()}.vgwort", [$entity->getEntityTypeId() => $entity->id()]),
'#attributes' => [
'class' => ['button', 'button--small'],
],
];
}
// This page depends on queue information and potentially data on references
// therefore it is not possible to cache this info.
CacheableMetadata::createFromObject($entity)->setCacheMaxAge(0)->applyTo($build);
return $build;
}
}
......@@ -4,6 +4,7 @@ namespace Drupal\vgwort\Controller;
use Drupal\advancedqueue\Job;
use Drupal\advancedqueue\Plugin\views\field\JobState;
use Drupal\Component\Serialization\Json;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Datetime\DateFormatterInterface;
......@@ -43,7 +44,7 @@ class Overview extends ControllerBase {
);
}
public function __invoke(RouteMatchInterface $route_match, $entity_type_id = NULL) {
public function __invoke(RouteMatchInterface $route_match, string $entity_type_id) {
/** @var \Drupal\Core\Entity\FieldableEntityInterface $entity */
$entity = $route_match->getParameter($entity_type_id);
......@@ -52,6 +53,9 @@ class Overview extends ControllerBase {
$build = [];
$build['#title'] = $this->t('VG Wort overview for %title', ['%title' => $entity->label()]);
$build['table'] = $this->buildInfoTable($entity);
$build['#attached'] = [
'library' => ['core/drupal.dialog.ajax'],
];
// This page depends on queue information and potentially data on references
// therefore it is not possible to cache this info.
......@@ -72,8 +76,10 @@ class Overview extends ControllerBase {
if ($entity instanceof RevisionableInterface) {
$revisions_sent = $this->jobMapper->getRevisionsSent($entity);
if ($last_revision_sent_id = array_key_last($revisions_sent)) {
/** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
$storage = $this->entityTypeManager()->getStorage($entity->getEntityTypeId());
/** @var \Drupal\Core\Entity\RevisionableInterface $last_revision_sent */
$last_revision_sent = $this->entityTypeManager()->getStorage($entity->getEntityTypeId())->loadRevision($last_revision_sent_id);
$last_revision_sent = $storage->loadRevision($last_revision_sent_id);
// @todo can we turn this into a link or maybe a date. It might be hard
// to support an entity type.
$participants = $this->participantListManager->getParticipants($last_revision_sent);
......@@ -187,12 +193,27 @@ class Overview extends ControllerBase {
}
// Build the operation links.
$job_url = Url::fromRoute('view.advancedqueue_jobs.page_1', ['arg_0' => 'vgwort']);
$operation_links = [];
$view_text_url = Url::fromRoute("entity.{$entity->getEntityTypeId()}.vgwort.text", [$entity->getEntityTypeId() => $entity->id()]);
$operation_links['view_text'] = [
'title' => $this->t('View text sent'),
'url' => $view_text_url,
'attributes' => [
'class' => ['use-ajax'],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 880,
]),
],
];
$job_url = Url::fromRoute('view.advancedqueue_jobs.page_1', ['arg_0' => 'vgwort']);
$operation_links['queue_admin'] = [
'title' => $this->t('Administer queue'),
'url' => $job_url,
];
$rows[] = [
['data' => $this->t('Operations'), 'header' => TRUE],
[
......
......@@ -6,6 +6,8 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Routing\RouteSubscriberBase;
use Drupal\Core\Routing\RoutingEvents;
use Drupal\vgwort\Controller\MessageTextView;
use Drupal\vgwort\Controller\Overview;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
......@@ -36,10 +38,11 @@ class VGWortRouteSubscriber extends RouteSubscriberBase {
}
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
if ($entity_type->hasLinkTemplate('drupal:vgwort-overview')) {
$path = $entity_type->getLinkTemplate('drupal:vgwort-overview');
$route = new Route(
$entity_type->getLinkTemplate('drupal:vgwort-overview'),
$path,
[
'_controller' => '\Drupal\vgwort\Controller\Overview',
'_controller' => Overview::class,
'entity_type_id' => $entity_type_id,
],
[
......@@ -55,8 +58,13 @@ class VGWortRouteSubscriber extends RouteSubscriberBase {
'_admin_route' => $is_admin,
]
);
$route_name = "entity.$entity_type_id.vgwort";
$collection->add($route_name, $route);
$collection->add("entity.$entity_type_id.vgwort", $route);
// Add a route for text modals.
$text_route = clone $route;
$text_route->setPath($path . '_text');
$text_route->setDefault('_controller', MessageTextView::class);
$collection->add("entity.$entity_type_id.vgwort.text", $text_route);
}
}
}
......
......@@ -204,7 +204,7 @@ class VGWortTest extends BrowserTestBase {
$this->assertSession()->addressEquals('admin/config/system/queues/jobs/vgwort');
$this->getSession()->getDriver()->back();
$this->clickLink('Edit');
$this->submitForm(['body[0][value]' => $this->getRandomGenerator()->paragraphs(30)], 'Save');
$this->submitForm(['body[0][value]' => 'Some random test content for us.' . $this->getRandomGenerator()->paragraphs(30)], 'Save');
$this->assertSession()->elementTextContains('css', '[data-drupal-messages]', 'Resolve all issues below to register this article with VG Wort.');
$this->assertSession()->elementTextContains('css', '[data-drupal-messages]', 'In order to be counted by VG Wort there must be at least one author.');
$this->assertSession()->elementTextNotContains('css', '[data-drupal-messages]', 'The minimum numbers of characters in order to be counted by VG Wort is 1800.');
......@@ -230,6 +230,11 @@ class VGWortTest extends BrowserTestBase {
$this->assertSession()->elementTextContains('css', 'main table', 'Author John Smith');
$this->assertSession()->elementTextContains('css', 'main table', 'Translators Sally FieldBobby Jones');
$this->clickLink('View text sent');
$this->assertSession()->pageTextContains('Some random test content for us.');
$this->clickLink('Back to VG Wort overview');
$this->assertSession()->elementTextContains('css', 'main table', 'Counter ID ' . $node->vgwort_counter_id->value);
// Pretend to process the queue.
$queue = Queue::load('vgwort');
$queue_backend = $queue->getBackend();
......@@ -255,6 +260,7 @@ class VGWortTest extends BrowserTestBase {
'vgwort_translators[0][card_number]' => '',
'vgwort_translators[0][firstname]' => '',
'vgwort_translators[0][surname]' => '',
'body[0][value]' => 'Some different random test content for us.' . $this->getRandomGenerator()->paragraphs(30),
], 'Save');
$this->clickLink('VG Wort');
......@@ -265,6 +271,12 @@ class VGWortTest extends BrowserTestBase {
$this->assertSession()->elementTextContains('css', 'main table tr:nth-child(3) > td:nth-child(2)', 'This has changed since being sent. It is not possible to update this information on VG Wort.');
$this->assertSession()->elementTextContains('css', 'main table tr:nth-child(3) > td:nth-child(2)', 'The current value is: Sally Field');
// Ensure that the text is the one at the time of sending - not how it is
// now.
$this->clickLink('View text sent');
$this->assertSession()->pageTextContains('Some random test content for us.');
$this->assertSession()->pageTextNotContains('Some different random test content for us.');
$this->drupalLogout();
// Ensure access is denied to the VG Wort info tab.
$this->drupalGet('node/1/vgwort');
......
......@@ -66,12 +66,17 @@ class VGWortFieldTest extends WebDriverTestBase {
->save();
$display_repository->getViewDisplay('node', 'article', 'full')
->setComponent($node_field_name)
->setComponent('body', [
'label' => 'hidden',
'type' => 'text_default',
])
->save();
$this->drupalLogin($this->createUser([
'access content',
'create article content',
'edit own article content',
'view vgwort info',
]));
$this->drupalGet('node/add/article');
$card_number = $this->assertSession()->waitForElementVisible('named', ['field', 'field_vg_test[0][card_number]']);
......@@ -89,6 +94,7 @@ class VGWortFieldTest extends WebDriverTestBase {
$this->assertSession()->fieldExists('field_vg_test[0][firstname]')->setValue('Bob');
$this->assertSession()->fieldExists('field_vg_test[0][surname]')->setValue('Jones');
$this->assertSession()->fieldExists('title[0][value]')->setValue('Test node for VGWort');
$this->assertSession()->fieldExists('body[0][value]')->setValue('Some random test content for us.' . $this->getRandomGenerator()->paragraphs(30));
$this->assertSession()->buttonExists('Save')->press();
$this->assertSession()->pageTextContainsOnce('article Test node for VGWort has been created.');
$node = $this->drupalGetNodeByTitle('Test node for VGWort');
......@@ -190,6 +196,12 @@ class VGWortFieldTest extends WebDriverTestBase {
else {
$this->assertSession()->pageTextContainsOnce('This value should be between 10 and 9999999.');
}
// Test the viewing text sent to VG Wort modal works as expected.
$this->drupalGet('node/1/vgwort');
$this->clickLink('View text sent');
$this->assertSession()->waitForText('Some random test content for us.');
$this->assertSession()->pageTextContains('Some random test content for us.');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment