πŸ‡ΊπŸ‡ΈUnited States @phillamb168

Account created on 28 February 2006, over 18 years ago
#

Recent comments

πŸ‡ΊπŸ‡ΈUnited States phillamb168

I needed this functionality as well. I modified the functionality on PreviewLinkController::preview() so that it:
1. checks entity->status->value to see if it's published
2. if published, calls the sessiontokencontroller and removes the tokens (to avoid redirect loops)
3. redirects to the new entity URL.

I'm pasting in the patch file while I figure out how to submit a patch - it's been a while so I need to remember how to do it.

diff --git a/preview_link.services.yml b/preview_link.services.yml
index 5f11fab..af709ef 100644
--- a/preview_link.services.yml
+++ b/preview_link.services.yml
@@ -51,6 +51,22 @@ services:
     arguments: ['@entity_type.manager']
     tags:
       - { name: event_subscriber }
+  preview_link.session_token_controller:
+    class: Drupal\preview_link\Controller\PreviewLinkSessionTokenController
+    arguments:
+      - '@string_translation'
+      - '@messenger'
+      - '@tempstore.private'
+  preview_link.controller:
+    class: Drupal\preview_link\Controller\PreviewLinkController
+    arguments:
+      - '@entity_type.manager'
+      - '@tempstore.private'
+      - '@config.factory'
+      - '@preview_link.message'
+      - '@messenger'
+      - '@preview_link.hook_helper'
+      - '@preview_link.session_token_controller'
   logger.channel.preview_link:
     parent: logger.channel_base
     arguments: [ 'preview_link' ]
diff --git a/src/Controller/PreviewLinkController.php b/src/Controller/PreviewLinkController.php
index d4cf5f3..8acd37c 100644
--- a/src/Controller/PreviewLinkController.php
+++ b/src/Controller/PreviewLinkController.php
@@ -15,11 +15,15 @@ use Drupal\Core\TempStore\PrivateTempStoreFactory;
 use Drupal\preview_link\PreviewLinkHookHelper;
 use Drupal\preview_link\PreviewLinkMessageInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Drupal\preview_link\Controller\PreviewLinkSessionTokenController;
+
 
 /**
  * Preview link controller to view any entity.
  */
 class PreviewLinkController extends ControllerBase {
+  protected PreviewLinkSessionTokenController $sessionTokenController;
 
   /**
    * PreviewLinkController constructor.
@@ -44,10 +48,12 @@ class PreviewLinkController extends ControllerBase {
     protected PreviewLinkMessageInterface $previewLinkMessages,
     MessengerInterface $messenger,
     protected PreviewLinkHookHelper $hookHelper,
+    PreviewLinkSessionTokenController $sessionTokenController
   ) {
     $this->entityTypeManager = $entityTypeManager;
     $this->configFactory = $configFactory;
     $this->messenger = $messenger;
+    $this->sessionTokenController = $sessionTokenController;
   }
 
   /**
@@ -60,7 +66,8 @@ class PreviewLinkController extends ControllerBase {
       $container->get('config.factory'),
       $container->get('preview_link.message'),
       $container->get('messenger'),
-      $container->get('preview_link.hook_helper')
+      $container->get('preview_link.hook_helper'),
+      $container->get('preview_link.session_token_controller')
     );
   }
 
@@ -75,12 +82,18 @@ class PreviewLinkController extends ControllerBase {
    * @return array
    *   A render array for previewing the entity.
    */
-  public function preview(RouteMatchInterface $routeMatch, string $preview_token): array {
+  public function preview(RouteMatchInterface $routeMatch, string $preview_token): array|RedirectResponse {
     // Accessing the controller will bind the Preview Link token to the session.
     $this->claimToken($preview_token);
 
     $entity = $this->resolveEntity($routeMatch);
-
+    // Is the entity published?
+    $is_published = $entity->status->value;
+    if ($is_published && $routeMatch->getRouteName() !== $entity->getEntityType()->getLinkTemplate('canonical')) {
+      // Redirect to the published node.
+      $this->sessionTokenController->removeTokens();
+      return new RedirectResponse($entity->toUrl()->toString());
+    }
     $config = $this->configFactory->get('preview_link.settings');
     if (in_array($config->get('display_message'), ['always'], TRUE)) {
       // Reset static cache so our hook_entity_access is always re-evaluated.
πŸ‡ΊπŸ‡ΈUnited States phillamb168

Poking on this one - would be good to get it in, I had a similar issue and the patch resolved it for me.

πŸ‡ΊπŸ‡ΈUnited States phillamb168

I figured this out - it's actually pretty easy. On your local machine, run the drush command. Then what I did was:

create a new directory in the project root `ckeditor-plugins`
copy the `ckeditor5` directory from `web/libraries` (or wherever your docroot is) to this folder.
Your directory structure should now look like this:
/composer.json
/composer.lock
/web/libraries/ckeditor5/plugins/media-embed/build/media-embed.js (there are a lot of other files in /web/libraries/ckeditor5 but that's the important one)
/ckeditor-plugins/ckeditor5/plugins/media-embed/ (again lots of other files here)

You'll want to get composer to handle the copy of course - I added the following to my composer.json file:

    "scripts": {
        "post-update-cmd": [
            "cp -R ckeditor-plugins/ckeditor5 web/libraries/ckeditor5"
        ],  
        "post-install-cmd": [
            "cp -R ckeditor-plugins/ckeditor5 web/libraries/ckeditor5"
        ]
    }, 

Your 'scripts' section may look slightly different - just add those two cp commands as necessary.

πŸ‡ΊπŸ‡ΈUnited States phillamb168

@elusivemind thank you for this. One issue I'm experiencing: on Pantheon, we're not allowed to run drush commands that modify libraries because the filesystem is read-only. I thus need to have the media-embed part of ckeditor5 installed via composer. I'm digging into the docs for the ckeditor5 core side of things, but do you have any leads on how to install the requirement without having to run the drush command?

Production build 0.71.5 2024