From d53eba1fc48531776bdada721b86a0b6d4f663f8 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Thu, 30 Jan 2025 13:49:40 +0100
Subject: [PATCH 01/13] [#3503330] Expose items_per_page as configuration

---
 modules/render/src/Plugin/Action/Views.php    | 37 ++++++++++++++++++-
 modules/render/tests/src/Kernel/ViewsTest.php |  1 +
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index cd34873bf..dc087e286 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -11,6 +11,7 @@ use Drupal\Core\Render\RendererInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
 use Drupal\views\Entity\View;
+use Drupal\views\Views as ViewsService;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -52,6 +53,7 @@ class Views extends RenderElementActionBase {
       'view_id' => '',
       'display_id' => 'default',
       'arguments' => '',
+      'items_per_page' => NULL,
     ] + parent::defaultConfiguration();
   }
 
@@ -88,6 +90,14 @@ class Views extends RenderElementActionBase {
       '#weight' => -30,
       '#required' => FALSE,
     ];
+    $form['items_per_page'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Items per page'),
+      '#default_value' => $this->configuration['items_per_page'],
+      '#weight' => -30,
+      '#required' => FALSE,
+    ];
+
     return parent::buildConfigurationForm($form, $form_state);
   }
 
@@ -99,6 +109,7 @@ class Views extends RenderElementActionBase {
     $this->configuration['view_id'] = $form_state->getValue('view_id');
     $this->configuration['display_id'] = $form_state->getValue('display_id');
     $this->configuration['arguments'] = $form_state->getValue('arguments');
+    $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
   }
 
   /**
@@ -134,14 +145,26 @@ class Views extends RenderElementActionBase {
    * {@inheritdoc}
    */
   protected function doBuild(array &$build): void {
-    $args = [$this->getViewId(), $this->getDisplayId()];
+    $view = ViewsService::getView($this->getViewId());
+    $view->setDisplay($this->getDisplayId());
+
+    $args = [];
     foreach (explode('/', $this->getArguments()) as $argument) {
       if ($argument !== '') {
         $args[] = $argument;
       }
     }
+    $view->setArguments($args);
+
+    $itemsPerPage = $this->getItemsPerPage();
+    if (!empty($itemsPerPage)) {
+      $view->setItemsPerPage((int) $itemsPerPage);
+    }
 
-    $build = views_embed_view(...$args);
+    $view->preExecute();
+    $view->execute();
+
+    $build = $view->buildRenderable();
 
     $markup = $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
       return $this->renderer->render($build);
@@ -197,4 +220,14 @@ class Views extends RenderElementActionBase {
     return trim((string) $this->tokenService->replaceClear($this->configuration['arguments']));
   }
 
+  /**
+   * Get the configured items per page.
+   *
+   * @return string
+   *   The items per page.
+   */
+  protected function getItemsPerPage(): string {
+    return trim((string) $this->tokenService->replaceClear($this->configuration['items_per_page']));
+  }
+
 }
diff --git a/modules/render/tests/src/Kernel/ViewsTest.php b/modules/render/tests/src/Kernel/ViewsTest.php
index 50c3a32aa..2afde2c9c 100644
--- a/modules/render/tests/src/Kernel/ViewsTest.php
+++ b/modules/render/tests/src/Kernel/ViewsTest.php
@@ -29,6 +29,7 @@ class ViewsTest extends RenderActionsTestBase {
       'view_id' => 'test_view',
       'display_id' => 'default',
       'arguments' => '',
+      'items_per_page' => '3',
       'token_name' => '',
       'name' => '',
       'weight' => '100',
-- 
GitLab


From 99825cf7ab01c09b4d89788016a47348378fa5e8 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Tue, 4 Feb 2025 15:05:25 +0100
Subject: [PATCH 02/13] [#3503330] Implement PR remarks

---
 modules/render/src/Plugin/Action/Views.php | 41 ++++++----------------
 1 file changed, 10 insertions(+), 31 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index dc087e286..7f110449b 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -2,13 +2,11 @@
 
 namespace Drupal\eca_render\Plugin\Action;
 
-use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\Markup as RenderMarkup;
 use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Render\RendererInterface;
-use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
 use Drupal\views\Entity\View;
 use Drupal\views\Views as ViewsService;
@@ -82,6 +80,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['display_id'],
       '#weight' => -40,
       '#required' => FALSE,
+      '#eca_token_reference' => TRUE,
     ];
     $form['arguments'] = [
       '#type' => 'textarea',
@@ -89,6 +88,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['arguments'],
       '#weight' => -30,
       '#required' => FALSE,
+      '#eca_token_reference' => TRUE,
     ];
     $form['items_per_page'] = [
       '#type' => 'number',
@@ -96,6 +96,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['items_per_page'],
       '#weight' => -30,
       '#required' => FALSE,
+      '#eca_token_reference' => TRUE,
     ];
 
     return parent::buildConfigurationForm($form, $form_state);
@@ -112,40 +113,15 @@ class Views extends RenderElementActionBase {
     $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
-    $result = AccessResult::forbidden();
-    $view_id = $this->getViewId();
-    if ($view_id !== '') {
-      $view = View::load($view_id);
-      if ($view && $view->status()) {
-        $viewExecutable = $view->getExecutable();
-        $display_id = $this->getDisplayId();
-        $display = NULL;
-        if ($display_id !== '') {
-          if ($viewExecutable->setDisplay($display_id)) {
-            $display = $viewExecutable->getDisplay();
-          }
-        }
-        else {
-          $viewExecutable->initDisplay();
-          $display = $viewExecutable->getDisplay();
-        }
-        if ($display !== NULL) {
-          $result = AccessResult::allowedIf($display->access($account));
-        }
-      }
-    }
-    return $return_as_object ? $result : $result->isAllowed();
-  }
-
   /**
    * {@inheritdoc}
    */
   protected function doBuild(array &$build): void {
     $view = ViewsService::getView($this->getViewId());
+    if (!$view || !$view->access($this->getDisplayId())) {
+      return;
+    }
+
     $view->setDisplay($this->getDisplayId());
 
     $args = [];
@@ -165,6 +141,9 @@ class Views extends RenderElementActionBase {
     $view->execute();
 
     $build = $view->buildRenderable();
+    if (empty($build)) {
+      return;
+    }
 
     $markup = $this->renderer->executeInRenderContext(new RenderContext(), function () use (&$build) {
       return $this->renderer->render($build);
-- 
GitLab


From a0aaab6e9620930f3574b4490467950c00af0ee3 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Tue, 4 Feb 2025 15:52:13 +0100
Subject: [PATCH 03/13] [#3503330] Re-add access check

---
 modules/render/src/Plugin/Action/Views.php | 32 ++++++++++++++++++++++
 1 file changed, 32 insertions(+)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index 7f110449b..f6ea175d0 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -2,11 +2,13 @@
 
 namespace Drupal\eca_render\Plugin\Action;
 
+use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\BubbleableMetadata;
 use Drupal\Core\Render\Markup as RenderMarkup;
 use Drupal\Core\Render\RenderContext;
 use Drupal\Core\Render\RendererInterface;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
 use Drupal\views\Entity\View;
 use Drupal\views\Views as ViewsService;
@@ -113,6 +115,36 @@ class Views extends RenderElementActionBase {
     $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
   }
 
+    /**
+   * {@inheritdoc}
+   */
+  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $result = AccessResult::forbidden();
+    $view_id = $this->getViewId();
+    if ($view_id !== '') {
+      $view = View::load($view_id);
+      if ($view && $view->status()) {
+        $viewExecutable = $view->getExecutable();
+        $display_id = $this->getDisplayId();
+        $display = NULL;
+        if ($display_id !== '') {
+          if ($viewExecutable->setDisplay($display_id)) {
+            $display = $viewExecutable->getDisplay();
+          }
+        }
+        else {
+          $viewExecutable->initDisplay();
+          $display = $viewExecutable->getDisplay();
+        }
+        if ($display !== NULL) {
+          $result = AccessResult::allowedIf($display->access($account));
+        }
+      }
+    }
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+
   /**
    * {@inheritdoc}
    */
-- 
GitLab


From c31137ce93bbd0264f5e3de606d18bc23b0bf2a1 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Tue, 4 Feb 2025 15:57:43 +0100
Subject: [PATCH 04/13] [#(3503330] Apply code styling

---
 modules/render/src/Plugin/Action/Views.php | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index f6ea175d0..d341f461d 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -115,7 +115,7 @@ class Views extends RenderElementActionBase {
     $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
   }
 
-    /**
+  /**
    * {@inheritdoc}
    */
   public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
@@ -144,7 +144,6 @@ class Views extends RenderElementActionBase {
     return $return_as_object ? $result : $result->isAllowed();
   }
 
-
   /**
    * {@inheritdoc}
    */
-- 
GitLab


From c06ac7dfe11a1db682f5ce44108e46b8736eeca6 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sat, 29 Mar 2025 16:35:27 +0100
Subject: [PATCH 05/13] [#3503330] Refactor config value retrieval

---
 modules/render/src/Plugin/Action/Views.php | 50 ++++++++--------------
 1 file changed, 19 insertions(+), 31 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index d341f461d..03ae48144 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -93,7 +93,7 @@ class Views extends RenderElementActionBase {
       '#eca_token_reference' => TRUE,
     ];
     $form['items_per_page'] = [
-      '#type' => 'number',
+      '#type' => 'textfield',
       '#title' => $this->t('Items per page'),
       '#default_value' => $this->configuration['items_per_page'],
       '#weight' => -30,
@@ -125,7 +125,7 @@ class Views extends RenderElementActionBase {
       $view = View::load($view_id);
       if ($view && $view->status()) {
         $viewExecutable = $view->getExecutable();
-        $display_id = $this->getDisplayId();
+        $display_id = $this->getConfigValue('display_id');
         $display = NULL;
         if ($display_id !== '') {
           if ($viewExecutable->setDisplay($display_id)) {
@@ -149,21 +149,21 @@ class Views extends RenderElementActionBase {
    */
   protected function doBuild(array &$build): void {
     $view = ViewsService::getView($this->getViewId());
-    if (!$view || !$view->access($this->getDisplayId())) {
+    if (!$view || !$view->access($this->getConfigValue('display_id'))) {
       return;
     }
 
-    $view->setDisplay($this->getDisplayId());
+    $view->setDisplay($this->getConfigValue('display_id'));
 
     $args = [];
-    foreach (explode('/', $this->getArguments()) as $argument) {
+    foreach (explode('/', $this->getConfigValue('arguments')) as $argument) {
       if ($argument !== '') {
         $args[] = $argument;
       }
     }
     $view->setArguments($args);
 
-    $itemsPerPage = $this->getItemsPerPage();
+    $itemsPerPage = $this->getConfigValue('items_per_page');
     if (!empty($itemsPerPage)) {
       $view->setItemsPerPage((int) $itemsPerPage);
     }
@@ -211,33 +211,21 @@ class Views extends RenderElementActionBase {
   }
 
   /**
-   * Get the configured display ID.
-   *
-   * @return string
-   *   The display ID.
+   * Retrieve a configuration value.
+   * 
+   * @param string $key
+   *   The configuration key.
+   * 
+   * @return mixed
+   *   The value of the token or the exact same key.
    */
-  protected function getDisplayId(): string {
-    return trim((string) $this->tokenService->replaceClear($this->configuration['display_id']));
-  }
-
-  /**
-   * Get the configured Views arguments.
-   *
-   * @return string
-   *   The arguments, multiple arguments are separated by "/".
-   */
-  protected function getArguments(): string {
-    return trim((string) $this->tokenService->replaceClear($this->configuration['arguments']));
-  }
+  protected function getConfigValue(string $key) {
+    $token = trim((string) $this->configuration[$key]);
+    if (!$this->tokenService->hasTokenData($token)) {
+      return $token;
+    }
 
-  /**
-   * Get the configured items per page.
-   *
-   * @return string
-   *   The items per page.
-   */
-  protected function getItemsPerPage(): string {
-    return trim((string) $this->tokenService->replaceClear($this->configuration['items_per_page']));
+    return $this->tokenService->getTokenData($token);
   }
 
 }
-- 
GitLab


From d5fd877ecf48e1a051444cb768506e03cb3b5180 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sat, 29 Mar 2025 16:36:38 +0100
Subject: [PATCH 06/13] [#3503330] Add separate Views-action for pagination
 alteration

---
 .../src/Plugin/Action/ViewsSetPagination.php  | 120 ++++++++++++++++++
 1 file changed, 120 insertions(+)
 create mode 100644 modules/views/src/Plugin/Action/ViewsSetPagination.php

diff --git a/modules/views/src/Plugin/Action/ViewsSetPagination.php b/modules/views/src/Plugin/Action/ViewsSetPagination.php
new file mode 100644
index 000000000..b3823cd2b
--- /dev/null
+++ b/modules/views/src/Plugin/Action/ViewsSetPagination.php
@@ -0,0 +1,120 @@
+<?php
+
+namespace Drupal\eca_views\Plugin\Action;
+
+use Drupal\Core\Access\AccessResult;
+use Drupal\Core\Annotation\Action;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\eca\Plugin\Action\ConfigurableActionBase;
+use Drupal\eca\Plugin\DataType\DataTransferObject;
+use Drupal\eca_views\Event\ViewsBase;
+
+/**
+ * Set a views pagination values.
+ *
+ * @Action(
+ *   id = "eca_views_set_pagination_values",
+ *   label = @Translation("Views: Set pagination values"),
+ *   eca_version_introduced = "2.1.3"
+ * )
+ */
+class ViewsSetPagination extends ConfigurableActionBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration(): array {
+    return [
+      'items_per_page' => '',
+      'offset' => '',
+    ] + parent::defaultConfiguration();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state): array {
+    $form = parent::buildConfigurationForm($form, $form_state);
+
+    $form['items_per_page'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Items per page'),
+      '#default_value' => $this->configuration['items_per_page'],
+      '#weight' => -30,
+      '#eca_token_replacement' => TRUE,
+    ];
+
+    $form['offset'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Offset'),
+      '#default_value' => $this->configuration['offset'],
+      '#weight' => -20,
+      '#eca_token_replacement' => TRUE,
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state): void {
+    parent::submitConfigurationForm($form, $form_state);
+
+    $this->configuration['items_per_page'] = $form_state->getValue('items_per_page');
+    $this->configuration['offset'] = $form_state->getValue('offset');
+  }
+
+  /**
+   * @inheritDoc
+   */
+  public function execute(mixed $object = NULL): void {
+    $event = $this->getEvent();
+    if (!($event instanceof ViewsBase)) {
+      return;
+    }
+
+    $pager = $event->getView()->getPager();
+    if ($value = $this->getValue('items_per_page')) {
+      $pager?->setItemsPerPage($value);
+    }
+
+    if ($value = $this->getValue('offset')) {
+      $pager?->setOffset($value);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
+    $result = AccessResult::forbidden();
+    $event = $this->getEvent();
+    if ($event instanceof ViewsBase) {
+      $result = AccessResult::allowed();
+    }
+
+    return $return_as_object ? $result : $result->isAllowed();
+  }
+
+  /**
+   * Retrieve the value of the configuration item.
+   *
+   * @param string $key
+   *   The key of the config item.
+   *
+   * @return string
+   *   Returns the replaced token or the actual value.
+   */
+  protected function getValue(string $key): string {
+    $token = trim((string) $this->configuration[$key]);
+    $value = $this->tokenService->getOrReplace($token);
+    if ($value instanceof DataTransferObject) {
+      return $value->getValue();
+    }
+
+    return $value;
+  }
+
+}
-- 
GitLab


From c16e0b98fea7aea4b51be267788780efec386301 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sat, 29 Mar 2025 16:38:42 +0100
Subject: [PATCH 07/13] [#3503330] Change default value to empty string

---
 modules/render/src/Plugin/Action/Views.php | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index 03ae48144..b3c2b9970 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -53,7 +53,7 @@ class Views extends RenderElementActionBase {
       'view_id' => '',
       'display_id' => 'default',
       'arguments' => '',
-      'items_per_page' => NULL,
+      'items_per_page' => '',
     ] + parent::defaultConfiguration();
   }
 
-- 
GitLab


From 33e2d0fd284befa61e49187239ee5de4f84d800e Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sat, 29 Mar 2025 16:41:22 +0100
Subject: [PATCH 08/13] [#3503330] Add update-hook to eca_render module

---
 modules/render/eca_render.install | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 modules/render/eca_render.install

diff --git a/modules/render/eca_render.install b/modules/render/eca_render.install
new file mode 100644
index 000000000..ae2716a0f
--- /dev/null
+++ b/modules/render/eca_render.install
@@ -0,0 +1,13 @@
+<?php
+
+/**
+ * @file
+ * ECA Render install file.
+ */
+
+/**
+ * Update existing models.
+ */
+function eca_render_update_8001(): void {
+  \Drupal::service('eca.update')->updateAllModels();
+}
-- 
GitLab


From aeeb65f90d225c2f3f54ce99cba5e725c8834f68 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sun, 30 Mar 2025 13:37:53 +0200
Subject: [PATCH 09/13] [#3503330] Resolve phpcs and phpstan errors

---
 modules/render/src/Plugin/Action/Views.php            |  4 ++--
 .../views/src/Plugin/Action/ViewsSetPagination.php    | 11 +++++------
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index b3c2b9970..ab80e6b7c 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -212,10 +212,10 @@ class Views extends RenderElementActionBase {
 
   /**
    * Retrieve a configuration value.
-   * 
+   *
    * @param string $key
    *   The configuration key.
-   * 
+   *
    * @return mixed
    *   The value of the token or the exact same key.
    */
diff --git a/modules/views/src/Plugin/Action/ViewsSetPagination.php b/modules/views/src/Plugin/Action/ViewsSetPagination.php
index b3823cd2b..43ebfa5f5 100644
--- a/modules/views/src/Plugin/Action/ViewsSetPagination.php
+++ b/modules/views/src/Plugin/Action/ViewsSetPagination.php
@@ -3,7 +3,6 @@
 namespace Drupal\eca_views\Plugin\Action;
 
 use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Annotation\Action;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\Action\ConfigurableActionBase;
@@ -67,7 +66,7 @@ class ViewsSetPagination extends ConfigurableActionBase {
   }
 
   /**
-   * @inheritDoc
+   * {@inheritdoc}
    */
   public function execute(mixed $object = NULL): void {
     $event = $this->getEvent();
@@ -76,12 +75,12 @@ class ViewsSetPagination extends ConfigurableActionBase {
     }
 
     $pager = $event->getView()->getPager();
-    if ($value = $this->getValue('items_per_page')) {
-      $pager?->setItemsPerPage($value);
+    if ($pager && ($value = $this->getValue('items_per_page'))) {
+      $pager->setItemsPerPage($value);
     }
 
-    if ($value = $this->getValue('offset')) {
-      $pager?->setOffset($value);
+    if ($pager && ($value = $this->getValue('offset'))) {
+      $pager->setOffset($value);
     }
   }
 
-- 
GitLab


From 291a02f6d5ba6af73cf1dbdaf901f1dfe9366faf Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Sun, 30 Mar 2025 13:44:41 +0200
Subject: [PATCH 10/13] [#3503330] Resolve phpcs and phpstan errors

---
 .../views/src/Plugin/Action/ViewsSetPagination.php    | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/modules/views/src/Plugin/Action/ViewsSetPagination.php b/modules/views/src/Plugin/Action/ViewsSetPagination.php
index 43ebfa5f5..4d33652c5 100644
--- a/modules/views/src/Plugin/Action/ViewsSetPagination.php
+++ b/modules/views/src/Plugin/Action/ViewsSetPagination.php
@@ -8,6 +8,7 @@ use Drupal\Core\Session\AccountInterface;
 use Drupal\eca\Plugin\Action\ConfigurableActionBase;
 use Drupal\eca\Plugin\DataType\DataTransferObject;
 use Drupal\eca_views\Event\ViewsBase;
+use Drupal\views\Plugin\views\pager\PagerPluginBase;
 
 /**
  * Set a views pagination values.
@@ -75,11 +76,15 @@ class ViewsSetPagination extends ConfigurableActionBase {
     }
 
     $pager = $event->getView()->getPager();
-    if ($pager && ($value = $this->getValue('items_per_page'))) {
+    if (!($pager instanceof PagerPluginBase)) {
+      return;
+    }
+
+    if ($value = $this->getValue('items_per_page')) {
       $pager->setItemsPerPage($value);
     }
 
-    if ($pager && ($value = $this->getValue('offset'))) {
+    if ($value = $this->getValue('offset')) {
       $pager->setOffset($value);
     }
   }
@@ -90,7 +95,7 @@ class ViewsSetPagination extends ConfigurableActionBase {
   public function access($object, ?AccountInterface $account = NULL, $return_as_object = FALSE) {
     $result = AccessResult::forbidden();
     $event = $this->getEvent();
-    if ($event instanceof ViewsBase) {
+    if ($event instanceof ViewsBase && ($event->getView()->getPager() instanceof PagerPluginBase)) {
       $result = AccessResult::allowed();
     }
 
-- 
GitLab


From 1b39297bcd2b09d5aa213945987fd06a7c3d3b03 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Thu, 10 Apr 2025 11:52:49 +0200
Subject: [PATCH 11/13] [#3503330] Allow exposed_input to be injected in the
 query

---
 .../views/src/Plugin/Action/ViewsQuery.php    | 51 ++++++++++++++++++-
 src/Plugin/ECA/PluginFormTrait.php            |  4 ++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/modules/views/src/Plugin/Action/ViewsQuery.php b/modules/views/src/Plugin/Action/ViewsQuery.php
index 67aedd496..70c32e0a6 100644
--- a/modules/views/src/Plugin/Action/ViewsQuery.php
+++ b/modules/views/src/Plugin/Action/ViewsQuery.php
@@ -10,10 +10,12 @@ use Drupal\Core\TypedData\ListDataDefinition;
 use Drupal\Core\TypedData\Plugin\DataType\ItemList;
 use Drupal\eca\Plugin\Action\ConfigurableActionBase;
 use Drupal\eca\Plugin\ECA\PluginFormTrait;
+use Drupal\eca\Service\YamlParser;
 use Drupal\views\Entity\View;
 use Drupal\views\Plugin\views\display\DisplayPluginBase;
 use Drupal\views\Plugin\views\query\Sql;
 use Drupal\views\ViewExecutable;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Run views query.
@@ -21,14 +23,24 @@ use Drupal\views\ViewExecutable;
  * @Action(
  *   id = "eca_views_query",
  *   label = @Translation("Views: Execute query"),
- *   description = @Translation("Use a View to execute a query and store the results in a token that contains an indexed list of the results. Despite the type of view that you use, always get the complete entities obtained by the view. You can access the entity properties using the token style."),
- *   eca_version_introduced = "1.0.0"
+ *   description = @Translation("Use a View to execute a query and store the
+ *   results in a token that contains an indexed list of the results. Despite
+ *   the type of view that you use, always get the complete entities obtained
+ *   by the view. You can access the entity properties using the token
+ *   style."), eca_version_introduced = "1.0.0"
  * )
  */
 class ViewsQuery extends ConfigurableActionBase {
 
   use PluginFormTrait;
 
+  /**
+   * The YAML parser.
+   *
+   * @var \Drupal\eca\Service\YamlParser
+   */
+  protected YamlParser $yamlParser;
+
   /**
    * The executable view.
    *
@@ -36,6 +48,16 @@ class ViewsQuery extends ConfigurableActionBase {
    */
   protected ViewExecutable $view;
 
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): static {
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->yamlParser = $container->get('eca.service.yaml_parser');
+
+    return $instance;
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -90,6 +112,7 @@ class ViewsQuery extends ConfigurableActionBase {
       'view_id' => '',
       'display_id' => 'default',
       'arguments' => '',
+      'exposed_input' => '',
     ] + parent::defaultConfiguration();
   }
 
@@ -136,6 +159,13 @@ class ViewsQuery extends ConfigurableActionBase {
       '#maxlength' => 512,
       '#weight' => -30,
     ];
+    $form['exposed_input'] = [
+      '#type' => 'textarea',
+      '#title' => $this->t('Exposed input'),
+      '#default_value' => $this->configuration['exposed_input'],
+      '#description' => $this->t('Provide the values for the exposed filters. Data should be set using YAML format, for example <em>myfilter: "My value"</em>. When using tokens and YAML altogether, make sure that tokens are wrapped as a string. Example: <em>myfilter: "[node:title]"</em>'),
+    ];
+
     return parent::buildConfigurationForm($form, $form_state);
   }
 
@@ -147,6 +177,7 @@ class ViewsQuery extends ConfigurableActionBase {
     $this->configuration['view_id'] = $form_state->getValue('view_id');
     $this->configuration['display_id'] = $form_state->getValue('display_id');
     $this->configuration['arguments'] = $form_state->getValue('arguments');
+    $this->configuration['exposed_input'] = $form_state->getValue('exposed_input');
     parent::submitConfigurationForm($form, $form_state);
   }
 
@@ -190,6 +221,7 @@ class ViewsQuery extends ConfigurableActionBase {
       }
     }
     $this->view->setArguments($args);
+    $this->view->setExposedInput($this->getExposedInput());
 
     return $this->view->getDisplay();
   }
@@ -228,6 +260,21 @@ class ViewsQuery extends ConfigurableActionBase {
     return trim((string) $this->tokenService->replaceClear($this->configuration['arguments']));
   }
 
+  /**
+   * Get the configured Views exposed input.
+   *
+   * @return array
+   *   The exposed input.
+   */
+  protected function getExposedInput(): array {
+    $exposedInput = $this->configuration['exposed_input'];
+    if (empty($exposedInput)) {
+      return [];
+    }
+
+    return (array) $this->yamlParser->parse($exposedInput);
+  }
+
   /**
    * Extracts the entities out of the executed View query.
    *
diff --git a/src/Plugin/ECA/PluginFormTrait.php b/src/Plugin/ECA/PluginFormTrait.php
index 0836e6ba2..db15de3d8 100644
--- a/src/Plugin/ECA/PluginFormTrait.php
+++ b/src/Plugin/ECA/PluginFormTrait.php
@@ -3,6 +3,7 @@
 namespace Drupal\eca\Plugin\ECA;
 
 use Drupal\Core\Render\Element;
+use Drupal\Core\TypedData\Plugin\DataType\StringData;
 use Drupal\eca\Plugin\DataType\DataTransferObject;
 
 /**
@@ -45,6 +46,9 @@ trait PluginFormTrait {
     if ($value instanceof DataTransferObject) {
       $value = $value->getValue();
     }
+    if ($value instanceof StringData) {
+      $value = $value->getCastedValue();
+    }
     return is_scalar($value) ? (string) $value : $default;
   }
 
-- 
GitLab


From 7862d96f68cc638f08363f45bd4d5bbde33b6386 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Thu, 10 Apr 2025 14:34:24 +0200
Subject: [PATCH 12/13] [#3503330] Use token replacement for config values

---
 modules/render/src/Plugin/Action/Views.php | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index ab80e6b7c..d9c3d9410 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -82,7 +82,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['display_id'],
       '#weight' => -40,
       '#required' => FALSE,
-      '#eca_token_reference' => TRUE,
+      '#eca_token_replacement' => TRUE,
     ];
     $form['arguments'] = [
       '#type' => 'textarea',
@@ -90,7 +90,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['arguments'],
       '#weight' => -30,
       '#required' => FALSE,
-      '#eca_token_reference' => TRUE,
+      '#eca_token_replacement' => TRUE,
     ];
     $form['items_per_page'] = [
       '#type' => 'textfield',
@@ -98,7 +98,7 @@ class Views extends RenderElementActionBase {
       '#default_value' => $this->configuration['items_per_page'],
       '#weight' => -30,
       '#required' => FALSE,
-      '#eca_token_reference' => TRUE,
+      '#eca_token_replacement' => TRUE,
     ];
 
     return parent::buildConfigurationForm($form, $form_state);
@@ -207,6 +207,7 @@ class Views extends RenderElementActionBase {
     if ($view_id === '_eca_token') {
       $view_id = $this->getTokenValue('view_id', '');
     }
+
     return trim((string) $view_id);
   }
 
@@ -216,16 +217,11 @@ class Views extends RenderElementActionBase {
    * @param string $key
    *   The configuration key.
    *
-   * @return mixed
-   *   The value of the token or the exact same key.
+   * @return string
+   *   The value of the token.
    */
-  protected function getConfigValue(string $key) {
-    $token = trim((string) $this->configuration[$key]);
-    if (!$this->tokenService->hasTokenData($token)) {
-      return $token;
-    }
-
-    return $this->tokenService->getTokenData($token);
+  protected function getConfigValue(string $key): string {
+    return trim((string) $this->tokenService->replaceClear($this->configuration[$key]));
   }
 
 }
-- 
GitLab


From 672413a62961af5ffc8a1e1ad7e6f5b3d3f33b22 Mon Sep 17 00:00:00 2001
From: Jasper Lammens <jasper.lammens@dropsolid.com>
Date: Thu, 10 Apr 2025 14:34:45 +0200
Subject: [PATCH 13/13] [#3503330] Remove duplicate existence check

---
 modules/render/src/Plugin/Action/Views.php | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/modules/render/src/Plugin/Action/Views.php b/modules/render/src/Plugin/Action/Views.php
index d9c3d9410..3407e6c93 100644
--- a/modules/render/src/Plugin/Action/Views.php
+++ b/modules/render/src/Plugin/Action/Views.php
@@ -149,10 +149,6 @@ class Views extends RenderElementActionBase {
    */
   protected function doBuild(array &$build): void {
     $view = ViewsService::getView($this->getViewId());
-    if (!$view || !$view->access($this->getConfigValue('display_id'))) {
-      return;
-    }
-
     $view->setDisplay($this->getConfigValue('display_id'));
 
     $args = [];
-- 
GitLab