Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita8f450d

Browse files
committed
Add the twig constraint and its validator
1 parent95d1191 commita8f450d

File tree

5 files changed

+242
-0
lines changed

5 files changed

+242
-0
lines changed

‎src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CHANGELOG
1313
* Add the`Week` constraint
1414
* Add`CompoundConstraintTestCase` to ease testing Compound Constraints
1515
* Add context variable to`WhenValidator`
16+
* Add the`twig` constraint for validating Twig content
1617

1718
7.1
1819
---
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
namespaceSymfony\Component\Validator\Constraints;
13+
14+
useSymfony\Component\Validator\Attribute\HasNamedArguments;
15+
useSymfony\Component\Validator\Constraint;
16+
useSymfony\Component\Validator\Exception\LogicException;
17+
useTwig\Environment;
18+
19+
/**
20+
* @author Mokhtar Tlili <tlili.mokhtar@gmail.com>
21+
*/
22+
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
23+
class Twigextends Constraint
24+
{
25+
publicconstINVALID_TWIG_ERROR ='e7fc55d5-e586-4cc1-924e-d27ee7fcd1b5';
26+
27+
protectedconstERROR_NAMES = [
28+
self::INVALID_TWIG_ERROR =>'INVALID_TWIG_ERROR',
29+
];
30+
31+
#[HasNamedArguments]
32+
publicfunction__construct(
33+
publicstring$message ='This value is not valid Twig.',
34+
?array$groups =null,
35+
mixed$payload =null,
36+
) {
37+
if (!class_exists(Environment::class)) {
38+
thrownewLogicException('The twig/twig library is required to use the Twig constraint. Try running "composer require twig/twig".');
39+
}
40+
41+
parent::__construct(null,$groups,$payload);
42+
}
43+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
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+
namespaceSymfony\Component\Validator\Constraints;
13+
14+
useSymfony\Component\Validator\Constraint;
15+
useSymfony\Component\Validator\ConstraintValidator;
16+
useSymfony\Component\Validator\Exception\UnexpectedTypeException;
17+
useSymfony\Component\Validator\Exception\UnexpectedValueException;
18+
useTwig\Environment;
19+
useTwig\Error\Error;
20+
useTwig\Loader\ArrayLoader;
21+
useTwig\Source;
22+
23+
/**
24+
* @author Mokhtar Tlili <tlili.mokhtar@gmail.com>
25+
*/
26+
class TwigValidatorextends ConstraintValidator
27+
{
28+
publicfunctionvalidate(mixed$value,Constraint$constraint):void
29+
{
30+
if (!$constraintinstanceof Twig) {
31+
thrownewUnexpectedTypeException($constraint, Twig::class);
32+
}
33+
34+
if (null ===$value ||'' ===$value) {
35+
return;
36+
}
37+
38+
if (!\is_scalar($value) && !$valueinstanceof \Stringable) {
39+
thrownewUnexpectedValueException($value,'string');
40+
}
41+
42+
$value = (string)$value;
43+
44+
$prevErrorHandler =set_error_handler(staticfunction ($level,$message,$file,$line)use (&$prevErrorHandler) {
45+
if (\E_USER_DEPRECATED ===$level) {
46+
$templateLine =0;
47+
if (preg_match('/ at line (\d+)[ .]/',$message,$matches)) {
48+
$templateLine =$matches[1];
49+
}
50+
51+
thrownewError($message,$templateLine);
52+
}
53+
54+
return$prevErrorHandler ?$prevErrorHandler($level,$message,$file,$line) :false;
55+
});
56+
57+
try {
58+
$twig =newEnvironment(newArrayLoader([$value]));
59+
$twig->parse($twig->tokenize(newSource($value,'')));
60+
}catch (Error$e) {
61+
$this->context->buildViolation($constraint->message)
62+
->setParameter('{{ error }}',$e->getMessage())
63+
->setParameter('{{ line }}',$e->getTemplateLine())
64+
->setCode(Twig::INVALID_TWIG_ERROR)
65+
->addViolation();
66+
}finally {
67+
restore_error_handler();
68+
}
69+
}
70+
}
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+
namespaceSymfony\Component\Validator\Tests\Constraints;
13+
14+
usePHPUnit\Framework\TestCase;
15+
useSymfony\Component\Validator\Constraints\Twig;
16+
useSymfony\Component\Validator\Mapping\ClassMetadata;
17+
useSymfony\Component\Validator\Mapping\Loader\AttributeLoader;
18+
19+
/**
20+
* @author Mokhtar Tlili <tlili.mokhtar@gmail.com>
21+
*/
22+
class TwigTestextends TestCase
23+
{
24+
publicfunctiontestAttributes()
25+
{
26+
$metadata =newClassMetadata(TwigDummy::class);
27+
$loader =newAttributeLoader();
28+
self::assertTrue($loader->loadClassMetadata($metadata));
29+
30+
[$bConstraint] =$metadata->properties['b']->getConstraints();
31+
self::assertSame('myMessage',$bConstraint->message);
32+
self::assertSame(['Default','TwigDummy'],$bConstraint->groups);
33+
34+
[$cConstraint] =$metadata->properties['c']->getConstraints();
35+
self::assertSame(['my_group'],$cConstraint->groups);
36+
self::assertSame('some attached data',$cConstraint->payload);
37+
}
38+
}
39+
40+
class TwigDummy
41+
{
42+
#[Twig]
43+
private$a;
44+
45+
#[Twig(message:'myMessage')]
46+
private$b;
47+
48+
#[Twig(groups: ['my_group'], payload:'some attached data')]
49+
private$c;
50+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
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+
namespaceSymfony\Component\Validator\Tests\Constraints;
13+
14+
useSymfony\Component\Validator\Constraints\Twig;
15+
useSymfony\Component\Validator\Constraints\TwigValidator;
16+
useSymfony\Component\Validator\Test\ConstraintValidatorTestCase;
17+
18+
/**
19+
* @author Mokhtar Tlili <tlili.mokhtar@gmail.com>
20+
*/
21+
class TwigValidatorTestextends ConstraintValidatorTestCase
22+
{
23+
protectedfunctioncreateValidator():TwigValidator
24+
{
25+
returnnewTwigValidator();
26+
}
27+
28+
/**
29+
* @dataProvider getValidValues
30+
*/
31+
publicfunctiontestTwigIsValid($value)
32+
{
33+
$this->validator->validate($value,newTwig());
34+
35+
$this->assertNoViolation();
36+
}
37+
38+
/**
39+
* @dataProvider getInvalidValues
40+
*/
41+
publicfunctiontestInvalidValues($value,$message,$line)
42+
{
43+
$constraint =newTwig('myMessageTest');
44+
45+
$this->validator->validate($value,$constraint);
46+
47+
$this->buildViolation('myMessageTest')
48+
->setParameter('{{ error }}',$message)
49+
->setParameter('{{ line }}',$line)
50+
->setCode(Twig::INVALID_TWIG_ERROR)
51+
->assertRaised();
52+
}
53+
54+
publicstaticfunctiongetValidValues()
55+
{
56+
return [
57+
['Hello {{ name }}'],
58+
['{% if condition %}Yes{% else %}No{% endif %}'],
59+
['{# Comment #}'],
60+
['Hello {{ "world" | upper }}'],
61+
['{% for i in 1..3 %}Item {{ i }}{% endfor %}'],
62+
];
63+
}
64+
65+
publicstaticfunctiongetInvalidValues()
66+
{
67+
return [
68+
// Invalid syntax example (missing end tag)
69+
['{% if condition %}Oops','Unexpected end of template at line 1.',1],
70+
// Another syntax error example (unclosed variable)
71+
['Hello {{ name','Unexpected token "end of template" ("end of print statement" expected) at line 1.',1],
72+
// Unknown filter error
73+
['Hello {{ name | unknown_filter }}','Unknown "unknown_filter" filter at line 1.',1],
74+
// Invalid variable syntax
75+
['Hello {{ .name }}','Unexpected token "punctuation" of value "." at line 1.',1],
76+
];
77+
}
78+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp