Skip to content
Snippets Groups Projects
Commit 24c446a8 authored by Mateu Aguiló Bosch's avatar Mateu Aguiló Bosch Committed by Mateu Aguiló Bosch
Browse files

Issue #3155280 by e0ipso: Improve usability in the toolbar integration

parent 0aa0970e
Branches 8.x-0.x
Tags 1.0.0-rc3
No related merge requests found
......@@ -35,17 +35,41 @@ function entity_reference_preview_toolbar_alter(&$items) {
if (!$enabled) {
return;
}
$container = \Drupal::getContainer();
$request = $container
$request = \Drupal::getContainer()
->get('request_stack')
->getCurrentRequest();
$is_previewing = $request
$active_detector = $request
->attributes
->get(PreviewNegotiationSubscriber::IS_PREVIEWING);
$current_status = $is_previewing ? 'previewing' : 'stopped';
->get(PreviewNegotiationSubscriber::ACTIVE_DETECTOR);
$current_status = $active_detector ? 'previewing' : 'stopped';
$has_permission = \Drupal::currentUser()
->hasPermission('request entity_reference_preview preview');
$message = $active_detector === 'rendered_entity'
? 'The preview state is active because you are seeing the latest version of an entity under moderation.'
: 'The preview state is triggered by an external action.';
$controls = [
'#markup' => new TranslatableMarkup('<a href="#" title="' . $message . '">?</a>'),
];
if (!$active_detector || $active_detector === 'cookie') {
$controls = [
'#type' => 'link',
'#title' => new TranslatableMarkup('Change'),
'#url' => Url::fromRoute('entity_reference_preview.controls'),
'#access' => $has_permission,
];
try {
$controls['#url']
->setRouteParameter(
'destination',
Url::createFromRequest($request)->toString()
);
}
catch (ResourceNotFoundException $exception) {
// If the request is 404 we can ignore it.
}
}
$items['preview_controls'] = [
'#type' => 'toolbar_item',
'tab' => [
......@@ -55,7 +79,7 @@ function entity_reference_preview_toolbar_alter(&$items) {
'#attributes' => [
'class' => [
'toolbar-icon',
'preview--' . ($is_previewing ? 'started' : 'stopped'),
'preview--' . ($active_detector ? 'started' : 'stopped'),
],
],
],
......@@ -75,12 +99,7 @@ function entity_reference_preview_toolbar_alter(&$items) {
],
],
],
'link' => [
'#type' => 'link',
'#title' => new TranslatableMarkup('Change'),
'#url' => Url::fromRoute('entity_reference_preview.controls'),
'#access' => $has_permission,
],
'link' => $controls,
],
'#attached' => [
'library' => [
......@@ -91,16 +110,6 @@ function entity_reference_preview_toolbar_alter(&$items) {
'id' => 'entity-reference-preview-controls-tab',
],
];
try {
$items['preview_controls']['tray']['link']['#url']
->setRouteParameter(
'destination',
Url::createFromRequest($request)->toString()
);
}
catch (ResourceNotFoundException $exception) {
// If the request is 404 we can ignore it.
}
}
/**
......
......@@ -14,6 +14,8 @@ final class PreviewNegotiationSubscriber implements EventSubscriberInterface {
const IS_PREVIEWING = '_is_previewing';
const ACTIVE_DETECTOR = '_active_detector';
/**
* The preview detector.
*
......@@ -52,8 +54,9 @@ final class PreviewNegotiationSubscriber implements EventSubscriberInterface {
public function setPreview(GetResponseEvent $event): void {
$request = $event->getRequest();
// Set the global request state in the request object for others to read.
$is_previewing = $this->previewDetector->isPreviewing($request);
$request->attributes->set(static::IS_PREVIEWING, $is_previewing);
$active_detector = $this->previewDetector->activeDetector($request);
$request->attributes->set(static::IS_PREVIEWING, (bool) $active_detector);
$request->attributes->set(static::ACTIVE_DETECTOR, $active_detector);
}
}
......@@ -54,16 +54,36 @@ class PreviewDetectorPluginManager extends DefaultPluginManager implements Fallb
* TRUE if the request is for a preview.
*/
public function isPreviewing(Request $request, array $configuration = []): bool {
return (bool) $this->activeDetector($request, $configuration);
}
/**
* Gets the active detector ID, if any, for the current request.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* The global request object.
* @param array $configuration
* The configuration for the preview detectors.
*
* @return string
* The plugin ID that is triggering the preview state.
*/
public function activeDetector(Request $request, array $configuration = []): ?string {
$instances = array_map(function (array $definition) use ($configuration) {
return $this->createInstance($definition['id'], $configuration);
}, $this->getDefinitions());
// Return true if any of the plugins is true.
return array_reduce(
$instances,
function (bool $detected, PreviewDetectorInterface $detector) use ($request) {
return $detected || $detector->isPreviewing($request);
static function ($detected, PreviewDetectorInterface $detector) use ($request) {
if ($detected) {
return $detected;
}
return $detector->isPreviewing($request)
? $detector->getPluginId()
: NULL;
},
FALSE
NULL
);
}
......
......@@ -38,7 +38,7 @@ class PreviewNegotiationSubscriberTest extends UnitTestCase {
* The data.
*/
public function dataProviderSetPreview() {
return [[TRUE], [FALSE]];
return [['foo'], [NULL]];
}
/**
......@@ -55,10 +55,13 @@ class PreviewNegotiationSubscriberTest extends UnitTestCase {
* @covers ::setPreview
* @dataProvider dataProviderSetPreview
*/
public function testSetPreview($is_previewing) {
public function testSetPreview($active_detector) {
$this->previewDetector
->isPreviewing(Argument::type(Request::class))
->willReturn($is_previewing)
->shouldBecalled($this->once());
$this->previewDetector
->activeDetector(Argument::type(Request::class))
->willReturn($active_detector)
->shouldBecalled($this->once());
$request = new Request();
$event = $this->prophesize(GetResponseEvent::class);
......@@ -66,7 +69,10 @@ class PreviewNegotiationSubscriberTest extends UnitTestCase {
$this->eventSubscriber->setPreview($event->reveal());
$flag = $request->attributes
->get(PreviewNegotiationSubscriber::IS_PREVIEWING);
$this->assertSame($is_previewing, $flag);
$this->assertSame((bool) $active_detector, $flag);
$actual = $request->attributes
->get(PreviewNegotiationSubscriber::ACTIVE_DETECTOR);
$this->assertSame($active_detector, $actual);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment