How can I restrict external URLs in link field to allow only certain domains?

drupal.stackexchange https://drupal.stackexchange.com/questions/299950

  •  02-03-2021
  •  | 
  •  

Question

After creating a Link field and use the Link with service icon format, I find out that there is no option to restrict external URLs to external domains that I want

For example, if I only want to allow Twitter links, something like add https://www.twitter.com/*.

Someone already asked here, but it seems that the Advanced Link module is not available for my Drupal version.

With what module and how can I filter my desired URLs in Drupal 9?

Était-ce utile?

La solution

There is a now a new module on drupal.org: Link Allowed Hosts – Will be working on this during the week so next week we can finally restrict the allowed hosts for link fields.

Autres conseils

You need to write your own custom validation contraint and add this constraint to your field.

Docs: https://www.drupal.org/docs/drupal-apis/entity-api/entity-validation-api/providing-a-custom-validation-constraint

I've used that example to create a "force HTTPS" link field constraint

src/Plugin/Validation/Constraint/Https.php

<?php

namespace Drupal\MYMODULE\Plugin\Validation\Constraint;

use Symfony\Component\Validator\Constraint;

/**
 * Checks that the submitted URL is starting with https://
 *
 * @Constraint(
 *   id = "MY_CONSTRAINT_ID",
 *   label = @Translation("Https", context = "Validation"),
 *   type = "string"
 * )
 */
class Https extends Constraint {
  public $notHttps = '%uri is not a secure site (not starting with https://)';
}

src/Plugin/Validation/Constraint/HttpsValidator.php

<?php

namespace Drupal\MYMODULE\Plugin\Validation\Constraint;

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

/**
 * Validates the Https constraint.
 */
class HttpsValidator extends ConstraintValidator {

  /**
   * {@inheritdoc}
   */
  public function validate($items, Constraint $constraint) {
    $item = $items->first();
    if (!isset($item)) {
      return NULL;
    }

    foreach ($items as $item) {
      /* CHANGE THIS, e.g. here you can check for domain names */
      if (strpos($item->uri, 'https://') !== 0) {
        $this->context->addViolation($constraint->notHttps, ['%uri' => $item->uri]);
      }
    }
  }
}

MYMODULE.module

<?php

use Drupal\Core\Entity\EntityTypeInterface;

function MYMODULE_entity_bundle_field_info_alter(&$fields, EntityTypeInterface $entity_type, $bundle) {
  if ($bundle === 'MY_ENTITY_BUNDLE' && $entity_type->id() == 'MY_ENTITY_TYPE') {
    if (isset($fields['MY_FIELD'])) {
      $fields['MY_FIELD']->addConstraint('MY_CONSTRAINT_ID', []);
    }
  }
}

A module exists with that capability, perhaps try https://www.drupal.org/sandbox/wombatbuddy/3183996

Licencié sous: CC-BY-SA avec attribution
Non affilié à drupal.stackexchange
scroll top