From 1f7908ef1fc8a17230bc0019d75ad5b4898139ef Mon Sep 17 00:00:00 2001 From: Liam Morland Date: Fri, 19 Apr 2024 11:01:29 -0400 Subject: [PATCH] Issue #402: Validate URLs entered into field_paragraph_document_link --- html/modules/custom/bc_dc/bc_dc.module | 7 ++ .../Constraint/BcDcUrlConstraint.php | 25 +++++++ .../Constraint/BcDcUrlConstraintValidator.php | 31 +++++++++ .../bc_dc/tests/src/Kernel/BcDcKernelTest.php | 68 +++++++++++++++++++ 4 files changed, 131 insertions(+) create mode 100644 html/modules/custom/bc_dc/src/Plugin/Validation/Constraint/BcDcUrlConstraint.php create mode 100644 html/modules/custom/bc_dc/src/Plugin/Validation/Constraint/BcDcUrlConstraintValidator.php create mode 100644 html/modules/custom/bc_dc/tests/src/Kernel/BcDcKernelTest.php diff --git a/html/modules/custom/bc_dc/bc_dc.module b/html/modules/custom/bc_dc/bc_dc.module index 118e3527..38865fa0 100644 --- a/html/modules/custom/bc_dc/bc_dc.module +++ b/html/modules/custom/bc_dc/bc_dc.module @@ -703,6 +703,13 @@ function bc_dc_cron(): void { \Drupal::service('bc_dc.update_review_status')->updateAll(); } +/** + * Implements hook_entity_type_alter(). + */ +function bc_dc_entity_type_alter(array &$entity_types): void { + $entity_types['paragraph']->addConstraint('BcDcUrlConstraint'); +} + /** * Implements hook_form_FORM_ID_alter(). */ diff --git a/html/modules/custom/bc_dc/src/Plugin/Validation/Constraint/BcDcUrlConstraint.php b/html/modules/custom/bc_dc/src/Plugin/Validation/Constraint/BcDcUrlConstraint.php new file mode 100644 index 00000000..a19f601c --- /dev/null +++ b/html/modules/custom/bc_dc/src/Plugin/Validation/Constraint/BcDcUrlConstraint.php @@ -0,0 +1,25 @@ +field_paragraph_document_link?->value; + } + else { + $url = (string) $value; + } + + // If there is a URL, it must pass parse_url() and the regex. + if ($url && (parse_url($url) === FALSE || !preg_match(',^(//|\\\\|(file|https?|ftps?):),', $url))) { + $this->context->addViolation($constraint->message); + } + } + +} diff --git a/html/modules/custom/bc_dc/tests/src/Kernel/BcDcKernelTest.php b/html/modules/custom/bc_dc/tests/src/Kernel/BcDcKernelTest.php new file mode 100644 index 00000000..69b12731 --- /dev/null +++ b/html/modules/custom/bc_dc/tests/src/Kernel/BcDcKernelTest.php @@ -0,0 +1,68 @@ +enableModules(['bc_dc', 'paragraphs']); + $this->typedData = $this->container->get('typed_data_manager'); + } + + /** + * Test validation constraints. + */ + public function testValidation() { + // Create a definition that specifies some AllowedValues. + $definition = DataDefinition::create('string') + ->addConstraint('BcDcUrlConstraint'); + + // Valid paths. + $paths = [ + 'http://example.com/path', + 'https://example.com/path', + 'ftp://example.com/path', + 'ftps://example.com/path', + 'file:///path/filename.pdf', + '//test/path', + '\\fin.gov.bc.ca\PATH\file_name.pdf', + ]; + foreach ($paths as $path) { + $typed_data = $this->typedData->create($definition, $path); + $violations = $typed_data->validate(); + $this->assertEquals(0, $violations->count(), 'Validation should pass for valid path: ' . $path); + } + + // Invalid paths. + $paths = [ + 'test-path', + 'mailto:example@example.com', + 'tel:+12345678901', + ]; + foreach ($paths as $path) { + $typed_data = $this->typedData->create($definition, $path); + $violations = $typed_data->validate(); + $this->assertEquals(1, $violations->count(), 'Validation should fail for invalid path: ' . $path); + } + } + +}