From 281d5003662d8b2974c3856fa3d21e4e70c64207 Mon Sep 17 00:00:00 2001 From: Andrei Sozonov Date: Sun, 18 Dec 2016 19:38:59 +0000 Subject: [PATCH] custom constraints message extractor (#423) --- Resources/config/services.xml | 4 + .../File/ConstraintMessageExtractor.php | 152 ++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 Translation/Extractor/File/ConstraintMessageExtractor.php diff --git a/Resources/config/services.xml b/Resources/config/services.xml index 4358f077..5ae7c495 100644 --- a/Resources/config/services.xml +++ b/Resources/config/services.xml @@ -15,6 +15,7 @@ JMS\TranslationBundle\Translation\Extractor\File\FormExtractor JMS\TranslationBundle\Translation\Extractor\File\ValidationExtractor JMS\TranslationBundle\Translation\Extractor\File\AuthenticationMessagesExtractor + JMS\TranslationBundle\Translation\Extractor\File\ConstraintMessageExtractor JMS\TranslationBundle\Translation\Loader\Symfony\XliffLoader JMS\TranslationBundle\Translation\Loader\XliffLoader @@ -115,6 +116,9 @@ + + + diff --git a/Translation/Extractor/File/ConstraintMessageExtractor.php b/Translation/Extractor/File/ConstraintMessageExtractor.php new file mode 100644 index 00000000..bdf34269 --- /dev/null +++ b/Translation/Extractor/File/ConstraintMessageExtractor.php @@ -0,0 +1,152 @@ +traverser = new NodeTraverser(); + $this->traverser->addVisitor($this); + } + + /** + * @param Node $node + * @return void + */ + public function enterNode(Node $node) + { + if ($node instanceof Node\Stmt\Namespace_) { + if (isset($node->name)) { + $this->namespace = implode('\\', $node->name->parts); + } + + return; + } + + if (!$node instanceof Node\Stmt\Class_) { + return; + } + + $name = '' === $this->namespace ? $node->name : $this->namespace.'\\'.$node->name; + + if ($node instanceof Node\Stmt\Class_) { + if (!class_exists($name)) { + return; + } + $ref = new \ReflectionClass($name); + if (!$ref->isSubclassOf('Symfony\Component\Validator\Constraint')) { + return; + } else { + $constraint = $ref->newInstance(); + /** @var Constraint $constraint */ + $this->extractFromConstraint($constraint); + } + } + } + + /** + * @param \SplFileInfo $file + * @param MessageCatalogue $catalogue + * @param array $ast + */ + public function visitPhpFile(\SplFileInfo $file, MessageCatalogue $catalogue, array $ast) + { + $this->file = $file; + $this->namespace = ''; + $this->catalogue = $catalogue; + $this->traverser->traverse($ast); + } + + /** + * @param array $nodes + * @return void + */ + public function beforeTraverse(array $nodes) + { + } + + /** + * @param Node $node + * @return void + */ + public function leaveNode(Node $node) + { + } + + /** + * @param array $nodes + * @return void + */ + public function afterTraverse(array $nodes) + { + } + + /** + * @param \SplFileInfo $file + * @param MessageCatalogue $catalogue + */ + public function visitFile(\SplFileInfo $file, MessageCatalogue $catalogue) + { + } + + /** + * @param \SplFileInfo $file + * @param MessageCatalogue $catalogue + * @param \Twig_Node $ast + */ + public function visitTwigFile(\SplFileInfo $file, MessageCatalogue $catalogue, \Twig_Node $ast) + { + } + + /** + * @param Constraint $constraint + */ + private function extractFromConstraint(Constraint $constraint) + { + $ref = new \ReflectionClass($constraint); + + $properties = $ref->getProperties(); + + foreach ($properties as $property) { + $propName = $property->getName(); + + // If the property ends with 'Message' + if (strtolower(substr($propName, -1 * strlen('Message'))) === 'message') { + $message = new Message($constraint->{$propName}, 'validators'); + $this->catalogue->add($message); + } + } + } +} \ No newline at end of file