@@ -307,3 +307,114 @@ also relative URLs that contain no protocol (e.g. ``//example.com``).
307307 ]));
308308 }
309309 }
310+
311+ ``requireTld ``
312+ ~~~~~~~~~~~~~~
313+
314+ **type **: ``boolean `` **default **: ``false ``
315+
316+ .. versionadded :: 7.1
317+
318+ The ``requiredTld `` option was introduced in Symfony 7.1.
319+
320+ By default, URLs like ``https://aaa `` or ``https://foobar `` are considered valid
321+ because they are tecnically correct according to the `URL spec `_. If you set this option
322+ to ``true ``, the host part of the URL will have to include a TLD (top-level domain
323+ name): e.g. ``https://example.com `` will be valid but ``https://example `` won't.
324+
325+ .. note ::
326+
327+ This constraint does not validate that the given TLD value is included in
328+ the `list of official top-level domains `_ (because that list is growing
329+ continuously and it's hard to keep track of it).
330+
331+ ``tldMessage ``
332+ ~~~~~~~~~~~~~~
333+
334+ **type **: ``string `` **default **: ``This URL does not contain a TLD. ``
335+
336+ .. versionadded :: 7.1
337+
338+ The ``tldMessage `` option was introduced in Symfony 7.1.
339+
340+ This message is shown if the ``requireTld `` option is set to ``true `` and the URL
341+ does not contain at least one TLD.
342+
343+ You can use the following parameters in this message:
344+
345+ =============== ==============================================================
346+ Parameter Description
347+ =============== ==============================================================
348+ ``{{ value }} `` The current (invalid) value
349+ ``{{ label }} `` Corresponding form field label
350+ =============== ==============================================================
351+
352+ .. configuration-block ::
353+
354+ .. code-block :: php-attributes
355+
356+ // src/Entity/Website.php
357+ namespace App\Entity;
358+
359+ use Symfony\Component\Validator\Constraints as Assert;
360+
361+ class Website
362+ {
363+ #[Assert\Url(
364+ requireTld: true,
365+ tldMessage: 'Add at least one TLD to the {{ value }} URL.',
366+ )]
367+ protected string $homepageUrl;
368+ }
369+
370+ .. code-block :: yaml
371+
372+ # config/validator/validation.yaml
373+ App\Entity\Website :
374+ properties :
375+ homepageUrl :
376+ - Url :
377+ requireTld : true
378+ tldMessage : Add at least one TLD to the {{ value }} URL.
379+
380+ .. code-block :: xml
381+
382+ <!-- config/validator/validation.xml -->
383+ <?xml version =" 1.0" encoding =" UTF-8" ?>
384+ <constraint-mapping xmlns =" http://symfony.com/schema/dic/constraint-mapping"
385+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
386+ xsi : schemaLocation =" http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd" >
387+
388+ <class name =" App\Entity\Website" >
389+ <property name =" homepageUrl" >
390+ <constraint name =" Url" >
391+ <option name =" requireTld" >true</option >
392+ <option name =" tldMessage" >Add at least one TLD to the {{ value }} URL.</option >
393+ </constraint >
394+ </property >
395+ </class >
396+ </constraint-mapping >
397+
398+ .. code-block :: php
399+
400+ // src/Entity/Website.php
401+ namespace App\Entity;
402+
403+ use Symfony\Component\Validator\Constraints as Assert;
404+ use Symfony\Component\Validator\Mapping\ClassMetadata;
405+
406+ class Website
407+ {
408+ // ...
409+
410+ public static function loadValidatorMetadata(ClassMetadata $metadata): void
411+ {
412+ $metadata->addPropertyConstraint('homepageUrl', new Assert\Url([
413+ 'requireTld' => true,
414+ 'tldMessage' => 'Add at least one TLD to the {{ value }} URL.',
415+ ]));
416+ }
417+ }
418+
419+ .. _`URL spec` : https://datatracker.ietf.org/doc/html/rfc1738
420+ .. _`list of official top-level domains` : https://en.wikipedia.org/wiki/List_of_Internet_top-level_domains
0 commit comments