From f4ca2526f5806f759c3d5fea3f30ea0ab02994ff Mon Sep 17 00:00:00 2001
From: Andrew Nuzhdov <mail@answe.ru>
Date: Sun, 14 Apr 2024 00:24:33 +0700
Subject: [PATCH] Added #3318703 code.

---
 src/Entity/ModulesInfo.php                    |  1 +
 src/ModulesInfoService.php                    | 21 ++++++++
 .../ValidateMachineNameConstraint.php         | 21 ++++++++
 ...ValidateMachineNameConstraintValidator.php | 50 +++++++++++++++++++
 4 files changed, 93 insertions(+)
 create mode 100644 src/Plugin/Validation/Constraint/ValidateMachineNameConstraint.php
 create mode 100644 src/Plugin/Validation/Constraint/ValidateMachineNameConstraintValidator.php

diff --git a/src/Entity/ModulesInfo.php b/src/Entity/ModulesInfo.php
index 2032543..9b3008c 100644
--- a/src/Entity/ModulesInfo.php
+++ b/src/Entity/ModulesInfo.php
@@ -88,6 +88,7 @@ class ModulesInfo extends ContentEntityBase {
       ->setRequired(TRUE)
       ->setDescription(t('The module machine name.'))
       ->addConstraint('UniqueField', [])
+      ->addConstraint('ValidateMachineName', [])
       ->addPropertyConstraints('value', ['Regex' => ['pattern' => '/^[a-z0-9_]+$/']])
       ->setDisplayOptions('view', [
         'label' => 'above',
diff --git a/src/ModulesInfoService.php b/src/ModulesInfoService.php
index 8a5c2ef..1e18f49 100644
--- a/src/ModulesInfoService.php
+++ b/src/ModulesInfoService.php
@@ -201,4 +201,25 @@ class ModulesInfoService {
     return FALSE;
   }
 
+  /**
+   * Validates the machine name of module.
+   *
+   * @param string $machine_name
+   *   Machine name.
+   *
+   * @return true|false
+   *   Returns bolean value
+   */
+  public function validateMachineName(string $machine_name) {
+    $uri = 'https://www.drupal.org/project/' . $machine_name;
+    try {
+      $response = $this->httpClient->get($uri, self::HEADERS);
+      return TRUE;
+    }
+    catch (TransferException $e) {
+      if ($e->getCode() == 404) {
+        return FALSE;
+      }
+    }
+  }
 }
diff --git a/src/Plugin/Validation/Constraint/ValidateMachineNameConstraint.php b/src/Plugin/Validation/Constraint/ValidateMachineNameConstraint.php
new file mode 100644
index 0000000..ad83e09
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/ValidateMachineNameConstraint.php
@@ -0,0 +1,21 @@
+<?php
+
+namespace Drupal\modules_info\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Checks if the module machine name exists or not.
+ *
+ * @Constraint(
+ *   id = "ValidateMachineName",
+ *   label = @Translation("Validate Machine Name", context = "Validation"),
+ *   type = "string"
+ * )
+ */
+class ValidateMachineNameConstraint extends Constraint {
+
+  // The message that will be shown if the machine name does not exist.
+  public $validMachineName = 'Machine name %value does not exist.';
+
+}
diff --git a/src/Plugin/Validation/Constraint/ValidateMachineNameConstraintValidator.php b/src/Plugin/Validation/Constraint/ValidateMachineNameConstraintValidator.php
new file mode 100644
index 0000000..c50a617
--- /dev/null
+++ b/src/Plugin/Validation/Constraint/ValidateMachineNameConstraintValidator.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\modules_info\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
+use Drupal\modules_info\ModulesInfoService;
+
+/**
+ * Validates the ValidateMachineName constraint.
+ */
+class ValidateMachineNameConstraintValidator extends ConstraintValidator implements ContainerInjectionInterface{
+  /**
+   * The Module Info Service.
+   *
+   * @var \Drupal\modules_info\ModulesInfoService
+   */
+  protected $moduleInfoService;
+
+  /**
+   * Creates a new ValidateMachineNameConstraintValidator instance.
+   * 
+   * @param \Drupal\modules_info\ModulesInfoService $module_info_service
+   * The Module Info Service.
+   */
+  public function __construct(ModulesInfoService $module_info_service) {
+    $this->moduleInfoService = $module_info_service;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('modules_info.service'),
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($items, Constraint $constraint) {
+    $entity = $items->getEntity();
+    if (!$this->moduleInfoService->validateMachineName($entity->machine_name->value)) {
+      $this->context->addViolation($constraint->validMachineName, ['%value' => $entity->machine_name->value]);
+    }
+  }
+}
-- 
GitLab