Skip to content

Commit f9e3400

Browse files
committed
Add Longitude Validator
1 parent 39c5025 commit f9e3400

File tree

4 files changed

+219
-0
lines changed

4 files changed

+219
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
use Symfony\Component\Validator\Constraint;
15+
16+
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
17+
final class Longitude extends Constraint
18+
{
19+
public const INVALID_LONGITUDE_ERROR = '2984c3a9-702d-40bb-b53e-74d81de37ea2';
20+
21+
protected const ERROR_NAMES = [
22+
self::INVALID_LONGITUDE_ERROR => 'INVALID_LONGITUDE_ERROR',
23+
];
24+
25+
public function __construct(
26+
public string $mode = 'strict',
27+
public string $message = 'This value must contain valid longitude coordinates.',
28+
?array $groups = null,
29+
mixed $payload = null
30+
) {
31+
parent::__construct([], $groups, $payload);
32+
}
33+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Constraints;
13+
14+
use Symfony\Component\Validator\Constraint;
15+
use Symfony\Component\Validator\ConstraintValidator;
16+
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
17+
use Symfony\Component\Validator\Exception\UnexpectedValueException;
18+
19+
final class LongitudeValidator extends ConstraintValidator
20+
{
21+
public function validate(mixed $value, Constraint $constraint): void
22+
{
23+
if (!$constraint instanceof Longitude) {
24+
throw new UnexpectedTypeException($constraint, Longitude::class);
25+
}
26+
27+
if (null === $value || '' === $value) {
28+
return;
29+
}
30+
31+
if (!\is_scalar($value) && !$value instanceof \Stringable) {
32+
throw new UnexpectedValueException($value, 'string');
33+
}
34+
35+
// Accept only strings or numbers
36+
if (!is_string($value) && !is_numeric($value)) {
37+
$this->context->buildViolation($constraint->message)
38+
->setParameter('{{ value }}', $value)
39+
->addViolation();
40+
return;
41+
}
42+
43+
if (!preg_match('/^[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/', (string) $value)) {
44+
$this->context->buildViolation($constraint->message)
45+
->setParameter('{{ value }}', '"'.$value.'"')
46+
->setCode(Longitude::INVALID_LONGITUDE_ERROR)
47+
->addViolation();
48+
}
49+
}
50+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Constraints;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Validator\Constraints\Longitude;
16+
use Symfony\Component\Validator\Mapping\ClassMetadata;
17+
use Symfony\Component\Validator\Mapping\Loader\AttributeLoader;
18+
19+
class LongitudeTest extends TestCase
20+
{
21+
public function testAttributes()
22+
{
23+
$metadata = new ClassMetadata(LongitudeDummy::class);
24+
$loader = new AttributeLoader();
25+
self::assertTrue($loader->loadClassMetadata($metadata));
26+
27+
[$bConstraint] = $metadata->properties['b']->getConstraints();
28+
self::assertSame('myMessage', $bConstraint->message);
29+
self::assertSame(['Default', 'LongitudeDummy'], $bConstraint->groups);
30+
31+
[$cConstraint] = $metadata->properties['c']->getConstraints();
32+
self::assertSame(['my_group'], $cConstraint->groups);
33+
}
34+
}
35+
36+
class LongitudeDummy
37+
{
38+
#[Longitude]
39+
private $a;
40+
41+
#[Longitude(message: 'myMessage')]
42+
private $b;
43+
44+
#[Longitude(groups: ['my_group'])]
45+
private $c;
46+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Constraints;
13+
14+
use Symfony\Component\Validator\Constraints\Longitude;
15+
use Symfony\Component\Validator\Constraints\LongitudeValidator;
16+
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;
17+
18+
class LongitudeValidatorTest extends ConstraintValidatorTestCase
19+
{
20+
protected function createValidator(): LongitudeValidator
21+
{
22+
return new LongitudeValidator();
23+
}
24+
25+
/**
26+
* @dataProvider getValidValues
27+
*/
28+
public function testLongitudeIsValid($value)
29+
{
30+
$this->validator->validate($value, new Longitude());
31+
32+
$this->assertNoViolation();
33+
}
34+
35+
/**
36+
* @dataProvider getInvalidValues
37+
*/
38+
public function testInvalidValues($value)
39+
{
40+
$constraint = new Longitude(message: 'myMessageTest');
41+
42+
$this->validator->validate($value, $constraint);
43+
44+
$this->buildViolation('myMessageTest')
45+
->setParameter('{{ value }}', '"'.$value.'"')
46+
->setCode(Longitude::INVALID_LONGITUDE_ERROR)
47+
->assertRaised();
48+
}
49+
50+
public static function getValidValues()
51+
{
52+
return [
53+
[null],
54+
[''],
55+
['0'],
56+
[0],
57+
['180'],
58+
[180],
59+
['-180'],
60+
[-180],
61+
['179.9999'],
62+
[-179.9999],
63+
['90'],
64+
['-90'],
65+
['45.123456'],
66+
['+45.0'],
67+
['+0'],
68+
['+180.0'],
69+
['-0.0'],
70+
];
71+
}
72+
73+
public static function getInvalidValues()
74+
{
75+
return [
76+
['180.0001'],
77+
['-180.0001'],
78+
['200'],
79+
[-200],
80+
['abc'],
81+
['--45'],
82+
['+'],
83+
[' '],
84+
['+180.1'],
85+
['-181'],
86+
['1,23'],
87+
['179,999'],
88+
];
89+
}
90+
}

0 commit comments

Comments
 (0)