diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md
index c95fc1b84ade7..0a4e6a924beff 100644
--- a/src/Symfony/Component/Validator/CHANGELOG.md
+++ b/src/Symfony/Component/Validator/CHANGELOG.md
@@ -126,7 +126,8 @@ CHANGELOG
}
}
```
-
+ * Add Latitude and Longitude Constraints
+
7.3
---
diff --git a/src/Symfony/Component/Validator/Constraints/Latitude.php b/src/Symfony/Component/Validator/Constraints/Latitude.php
new file mode 100644
index 0000000000000..9e92c5133ee1a
--- /dev/null
+++ b/src/Symfony/Component/Validator/Constraints/Latitude.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
+final class Latitude extends Constraint
+{
+ public const INVALID_LATITUDE_ERROR = '2f01c7bf-43ec-487c-a173-bcc305d3bbd1';
+
+ protected const ERROR_NAMES = [
+ self::INVALID_LATITUDE_ERROR => 'INVALID_LATITUDE_ERROR',
+ ];
+
+ public function __construct(
+ public string $mode = 'strict',
+ public string $message = 'This value must contain valid latitude coordinates.',
+ ?array $groups = null,
+ mixed $payload = null,
+ ) {
+ parent::__construct(null, $groups, $payload);
+ }
+}
diff --git a/src/Symfony/Component/Validator/Constraints/LatitudeValidator.php b/src/Symfony/Component/Validator/Constraints/LatitudeValidator.php
new file mode 100644
index 0000000000000..9e37bd45a25aa
--- /dev/null
+++ b/src/Symfony/Component/Validator/Constraints/LatitudeValidator.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Exception\UnexpectedValueException;
+
+final class LatitudeValidator extends ConstraintValidator
+{
+ public function validate(mixed $value, Constraint $constraint): void
+ {
+ if (!$constraint instanceof Latitude) {
+ throw new UnexpectedTypeException($constraint, Latitude::class);
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!\is_scalar($value) && !$value instanceof \Stringable) {
+ throw new UnexpectedValueException($value, 'string');
+ }
+
+ // Accept only strings or numbers
+ if (!\is_string($value) && !is_numeric($value)) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $value)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!preg_match('/^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?)$/', (string) $value)) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $value)
+ ->setCode(Latitude::INVALID_LATITUDE_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/src/Symfony/Component/Validator/Constraints/Longitude.php b/src/Symfony/Component/Validator/Constraints/Longitude.php
new file mode 100644
index 0000000000000..d2e9f5a7377d5
--- /dev/null
+++ b/src/Symfony/Component/Validator/Constraints/Longitude.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+
+#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
+final class Longitude extends Constraint
+{
+ public const INVALID_LONGITUDE_ERROR = '2984c3a9-702d-40bb-b53e-74d81de37ea2';
+
+ protected const ERROR_NAMES = [
+ self::INVALID_LONGITUDE_ERROR => 'INVALID_LONGITUDE_ERROR',
+ ];
+
+ public function __construct(
+ public string $mode = 'strict',
+ public string $message = 'This value must contain valid longitude coordinates.',
+ ?array $groups = null,
+ mixed $payload = null,
+ ) {
+ parent::__construct(null, $groups, $payload);
+ }
+}
diff --git a/src/Symfony/Component/Validator/Constraints/LongitudeValidator.php b/src/Symfony/Component/Validator/Constraints/LongitudeValidator.php
new file mode 100644
index 0000000000000..48080f4e60463
--- /dev/null
+++ b/src/Symfony/Component/Validator/Constraints/LongitudeValidator.php
@@ -0,0 +1,51 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\Validator\Constraints;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+use Symfony\Component\Validator\Exception\UnexpectedTypeException;
+use Symfony\Component\Validator\Exception\UnexpectedValueException;
+
+final class LongitudeValidator extends ConstraintValidator
+{
+ public function validate(mixed $value, Constraint $constraint): void
+ {
+ if (!$constraint instanceof Longitude) {
+ throw new UnexpectedTypeException($constraint, Longitude::class);
+ }
+
+ if (null === $value || '' === $value) {
+ return;
+ }
+
+ if (!\is_scalar($value) && !$value instanceof \Stringable) {
+ throw new UnexpectedValueException($value, 'string');
+ }
+
+ // Accept only strings or numbers
+ if (!\is_string($value) && !is_numeric($value)) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', $value)
+ ->addViolation();
+
+ return;
+ }
+
+ if (!preg_match('/^[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/', (string) $value)) {
+ $this->context->buildViolation($constraint->message)
+ ->setParameter('{{ value }}', '"'.$value.'"')
+ ->setCode(Longitude::INVALID_LONGITUDE_ERROR)
+ ->addViolation();
+ }
+ }
+}
diff --git a/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf b/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf
index 9f53b1afe35c3..c617e4e0bd4b9 100644
--- a/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf
+++ b/src/Symfony/Component/Validator/Resources/translations/validators.af.xlf
@@ -470,6 +470,14 @@
This value is not a valid Twig template.
Hierdie waarde is nie 'n geldige Twig-sjabloon nie.
+
+ This value must contain valid latitude coordinates.
+ This value must contain valid latitude coordinates.
+
+
+ This value must contain valid longitude coordinates.
+ This value must contain valid longitude coordinates.
+