From d3b0e7239ed6e49624c2af3f9ea16d750b462c01 Mon Sep 17 00:00:00 2001
From: Oleksandr Pozharskyi <o.pozharskyi@dev-branch.com>
Date: Sat, 25 Jan 2025 14:30:13 +0200
Subject: [PATCH] Issue #3500169: Skip validations

---
 fapi_validation.services.yml            |  5 +++--
 src/FapiValidationValidatorsManager.php | 28 +++++++++++++++++++++++--
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/fapi_validation.services.yml b/fapi_validation.services.yml
index ed3c432..b23ee65 100644
--- a/fapi_validation.services.yml
+++ b/fapi_validation.services.yml
@@ -2,8 +2,9 @@ services:
   plugin.manager.fapi_validation_validators:
     class: Drupal\fapi_validation\FapiValidationValidatorsManager
     parent: default_plugin_manager
-    # tags:
-    #   - {name: event_subscriber}
+    arguments:
+      - '@config.factory'
+      - '@current_user'
   plugin.manager.fapi_validation_filters:
     class: Drupal\fapi_validation\FapiValidationFiltersManager
     parent: default_plugin_manager
diff --git a/src/FapiValidationValidatorsManager.php b/src/FapiValidationValidatorsManager.php
index 310f754..75f44f8 100644
--- a/src/FapiValidationValidatorsManager.php
+++ b/src/FapiValidationValidatorsManager.php
@@ -3,7 +3,9 @@
 namespace Drupal\fapi_validation;
 
 use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\fapi_validation\Exception\ValidatorException;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\DefaultPluginManager;
@@ -26,8 +28,18 @@ class FapiValidationValidatorsManager extends DefaultPluginManager {
    *   Cache backend instance to use.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
    *   The module handler to invoke the alter hook with.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
+   *   The config factory.
+   * @param \Drupal\Core\Session\AccountInterface $currentUser
+   *   The current user.
    */
-  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+  public function __construct(
+    \Traversable $namespaces,
+    CacheBackendInterface $cache_backend,
+    ModuleHandlerInterface $module_handler,
+    protected readonly ConfigFactoryInterface $configFactory,
+    protected readonly AccountInterface $currentUser
+  ) {
     $this->alterInfo('fapi_validation_validators_info');
     $this->setCacheBackend($cache_backend, 'fapi_validation_validators');
 
@@ -64,7 +76,15 @@ class FapiValidationValidatorsManager extends DefaultPluginManager {
    * @throws \Drupal\fapi_validation\Exception\ValidatorException
    */
   public function validate(array &$element, FormStateInterface $form_state) {
-    // If element is empty and not required, by pass rule validation.
+    // If the bypass config is true and the user has appropriate permissions, bypass validation.
+    $config = $this->configFactory->getEditable('fapi_validation.settings');
+    $bypass_config = $config->get('bypass');
+    $current_user = $this->currentUser;
+    if ($bypass_config && $current_user->hasPermission('bypass fapi validations')) {
+      return;
+    }
+
+    // If element is empty and not required, bypass rule validation.
     $value = !isset($element['#value']) || trim($element['#value']) === '';
     if (!$element['#required'] && $value) {
       return;
@@ -80,6 +100,10 @@ class FapiValidationValidatorsManager extends DefaultPluginManager {
         throw new ValidatorException("Invalid validator name '{$validator->getName()}'.");
       }
 
+      if ($bypass_config && $current_user->hasPermission("bypass {$validator->getName()} fapi validation")) {
+        return;
+      }
+
       $plugin = $this->getDefinition($validator->getName());
       $instance = $this->createInstance($plugin['id']);
 
-- 
GitLab