Skip to content

Commit

Permalink
Issue #402: Validate URLs entered into field_paragraph_document_link
Browse files Browse the repository at this point in the history
  • Loading branch information
lkmorlan committed Apr 19, 2024
1 parent 12fcc96 commit 1f7908e
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
7 changes: 7 additions & 0 deletions html/modules/custom/bc_dc/bc_dc.module
Original file line number Diff line number Diff line change
Expand Up @@ -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().
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Drupal\bc_dc\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
* Checks that a string is a URL.
*
* @Constraint(
* id = "BcDcUrlConstraint",
* label = @Translation("BCDC URL validator", context = "Validation"),
* type = "string"
* )
*/
class BcDcUrlConstraint extends Constraint {

/**
* Constraint message.
*
* @var string
*/
public $message = 'Enter a valid URL.';

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Drupal\bc_dc\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

/**
* Validates the BcDcUrlConstraint constraint.
*/
class BcDcUrlConstraintValidator extends ConstraintValidator {

/**
* {@inheritdoc}
*/
public function validate(mixed $value, Constraint $constraint): void {
// This will be a string in kernel tests.
if (is_object($value)) {
$url = $value->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);
}
}

}
68 changes: 68 additions & 0 deletions html/modules/custom/bc_dc/tests/src/Kernel/BcDcKernelTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Drupal\Tests\bc_dc\Kernel;

use Drupal\Core\TypedData\DataDefinition;
use Drupal\KernelTests\KernelTestBase;

/**
* Kernel tests.
*
* @group BcDc
*/
class BcDcKernelTest extends KernelTestBase {

/**
* The typed data manager to use.
*
* @var \Drupal\Core\TypedData\TypedDataManager
*/
protected $typedData;

/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->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:[email protected]',
'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);
}
}

}

0 comments on commit 1f7908e

Please sign in to comment.