public function extract()
 {
     $catalogue = new MessageCatalogue();
     $collection = $this->router instanceof I18nRouter ? $this->router->getOriginalRouteCollection() : $this->router->getRouteCollection();
     foreach ($collection->all() as $name => $route) {
         if ($this->routeExclusionStrategy->shouldExcludeRoute($name, $route)) {
             continue;
         }
         ///////////////////////////////////////
         // Begin customizations
         $meaning = "Route Controller and method: " . $route->getDefault('_controller');
         // set a default value
         // prefix with zikula module url if requested
         if ($route->hasDefault('_zkModule')) {
             $zkNoBundlePrefix = $route->getOption('zkNoBundlePrefix');
             if (!isset($zkNoBundlePrefix) || !$zkNoBundlePrefix) {
                 $meaning = "This is a route from the " . $route->getDefault('_zkModule') . "Bundle and will include a translated prefix.";
             }
         }
         // End customizations
         ///////////////////////////////////////
         $message = new Message($name, $this->domain);
         $message->setDesc($route->getPath());
         if (isset($meaning)) {
             $message->setMeaning($meaning);
         }
         $catalogue->add($message);
     }
     return $catalogue;
 }
 /**
  * @param Message $message
  * @return Boolean
  */
 public function has(Message $message)
 {
     if (!$this->hasDomain($message->getDomain())) {
         return false;
     }
     return $this->getDomain($message->getDomain())->has($message->getId());
 }
 public function extract()
 {
     $catalogue = new MessageCatalogue();
     foreach ($this->i18nLoader->extract($this->router->getRouteCollection()) as $name => $route) {
         $message = new Message($name, $this->domain);
         $message->setDesc($route->getPattern());
         $catalogue->add($message);
     }
     return $catalogue;
 }
 public static function getTranslationMessages()
 {
     $messages = array();
     foreach (self::$choices as $trans) {
         $message = new Message($trans);
         $message->addSource(new FileSource(__FILE__, 13));
         $messages[] = $message;
     }
     return $messages;
 }
 public function testExtractFormModel()
 {
     $expected = new MessageCatalogue();
     $path = __DIR__ . '/Fixture/MyFormModel.php';
     $message = new Message('form.label.choice.foo');
     $message->addSource(new FileSource($path, 13));
     $expected->add($message);
     $message = new Message('form.label.choice.bar');
     $message->addSource(new FileSource($path, 13));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('MyFormModel.php'));
 }
 public function testExtractTemplate()
 {
     $expected = new MessageCatalogue();
     $path = __DIR__ . '/Fixture/template.html.php';
     $message = new Message('foo.bar');
     $message->addSource(new FileSource($path, 1));
     $expected->add($message);
     $message = new Message('baz', 'moo');
     $message->setDesc('Foo Bar');
     $message->addSource(new FileSource($path, 3));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('template.html.php'));
 }
 public function testExtract()
 {
     $expected = new MessageCatalogue();
     $message = new Message('security.authentication_error.foo', 'authentication');
     $message->setDesc('%foo% is invalid.');
     $message->addSource(new FileSource(__DIR__ . '/Fixture/MyAuthException.php', 31));
     $expected->add($message);
     $message = new Message('security.authentication_error.bar', 'authentication');
     $message->setDesc('An authentication error occurred.');
     $message->addSource(new FileSource(__DIR__ . '/Fixture/MyAuthException.php', 35));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('MyAuthException.php'));
 }
 public function testExtractValidationMessages()
 {
     $fileSourceFactory = $this->getFileSourceFactory();
     $fixtureSplInfo = new \SplFileInfo(__DIR__ . '/Fixture/MyEntity.php');
     $expected = new MessageCatalogue();
     $message = new Message('entity.default');
     $message->addSource($fileSourceFactory->create($fixtureSplInfo, 15));
     $expected->add($message);
     $message = new Message('entity.custom-domain', 'custom-domain');
     $message->addSource($fileSourceFactory->create($fixtureSplInfo, 22));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('MyEntity.php'));
 }
 public function testDumpStructureWithMetadata()
 {
     $catalogue = new MessageCatalogue();
     $catalogue->setLocale('en');
     $message = new Message('foo.bar.baz');
     $message->setDesc('Foo');
     $catalogue->add($message);
     $message = new Message('foo.bar.moo');
     $message->setMeaning('Bar');
     $catalogue->add($message);
     $message = new Message('foo.baz');
     $catalogue->add($message);
     $this->assertEquals($this->getOutput('structure_with_metadata'), $this->dump($catalogue, 'messages'));
 }
 public function extract()
 {
     $catalogue = new MessageCatalogue();
     $collection = $this->router instanceof I18nRouter ? $this->router->getOriginalRouteCollection() : $this->router->getRouteCollection();
     foreach ($collection->all() as $name => $route) {
         if ($this->routeExclusionStrategy->shouldExcludeRoute($name, $route)) {
             continue;
         }
         $message = new Message($name, $this->domain);
         $message->setDesc($route->getPath());
         $catalogue->add($message);
     }
     return $catalogue;
 }
示例#11
0
 public function testExtractTemplate()
 {
     $expected = new MessageCatalogue();
     $fileSourceFactory = $this->getFileSourceFactory();
     $fixtureSplInfo = new \SplFileInfo(__DIR__ . '/Fixture/template.html.php');
     $message = new Message('foo.bar');
     $message->addSource($fileSourceFactory->create($fixtureSplInfo, 1));
     $expected->add($message);
     $message = new Message('baz', 'moo');
     $message->setDesc('Foo Bar');
     $message->addSource($fileSourceFactory->create($fixtureSplInfo, 3));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('template.html.php'));
 }
 public function testGet()
 {
     $catalogue = new MessageCatalogue();
     $catalogue->add($message = Message::create('foo'));
     $this->assertTrue($catalogue->hasDomain('messages'));
     $this->assertSame($message, $catalogue->get('foo'));
 }
    public function testCdataOutput()
    {
        $dumper = $this->getDumper();
        $catalogue = new MessageCatalogue();
        $catalogue->add(Message::create('foo')->setLocaleString('<bar>')->setDesc('<baz>'));
        $expected = <<<EOF
<?xml version="1.0" encoding="utf-8"?>
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:jms="urn:jms:translation" version="1.2">
  <file source-language="en" target-language="" datatype="plaintext" original="not.available">
    <header>
      <tool tool-id="JMSTranslationBundle" tool-name="JMSTranslationBundle" tool-version="1.1.0-DEV"/>
      <note>The source node in most cases contains the sample message as written by the developer. If it looks like a dot-delimitted string such as "form.label.firstname", then the developer has not provided a default message.</note>
    </header>
    <body>
      <trans-unit id="0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" resname="foo">
        <source><![CDATA[<baz>]]></source>
        <target state="new"><![CDATA[<bar>]]></target>
      </trans-unit>
    </body>
  </file>
</xliff>

EOF;
        $this->assertEquals($expected, $dumper->dump($catalogue, 'messages'));
    }
 /**
  * Converts Symfony's message catalogue to the catalogue of this
  * bundle.
  *
  * @param mixed $resource
  * @param string $locale
  * @param string $domain
  * @return MessageCatalogue
  */
 public function load($resource, $locale, $domain = 'messages')
 {
     $catalogue = new MessageCatalogue();
     $catalogue->setLocale($locale);
     foreach ($this->loader->load($resource, $locale, $domain)->all($domain) as $id => $message) {
         $catalogue->add(Message::create($id, $domain)->setLocaleString($message)->setNew(false));
     }
     return $catalogue;
 }
示例#15
0
 public function enterNode(\Twig_NodeInterface $node, \Twig_Environment $env)
 {
     $this->stack[] = $node;
     if ($node instanceof \Twig_Node_Expression_Function) {
         $name = $node->getAttribute('name');
         if (in_array($name, $this->methodNames)) {
             $args = $node->getNode('arguments');
             switch ($name) {
                 case '_n':
                 case '_fn':
                     $id = $args->getNode(0)->getAttribute('value') . '|' . $args->getNode(1)->getAttribute('value');
                     break;
                 default:
                 case '__f':
                 case '__':
                     $id = $args->getNode(0)->getAttribute('value');
                     break;
             }
             // obtain translation domain from composer file
             $composerPath = str_replace($this->file->getRelativePathname(), '', $this->file->getPathname());
             if (isset(self::$domainCache[$composerPath])) {
                 $domain = self::$domainCache[$composerPath];
             } else {
                 $scanner = new Scanner();
                 $scanner->scan(array($composerPath), 1);
                 $metaData = $scanner->getModulesMetaData(true);
                 $domains = array_keys($metaData);
                 if (isset($domains[0])) {
                     $domain = strtolower($domains[0]);
                     // cache result of file lookup
                     self::$domainCache[$composerPath] = $domain;
                 } else {
                     $domain = 'messages';
                 }
             }
             $domainNode = array_search($name, $this->methodNames);
             $domain = $args->hasNode($domainNode) ? $args->getNode($domainNode)->getAttribute('value') : $domain;
             $message = new Message($id, $domain);
             $message->addSource(new FileSource((string) $this->file, $node->getLine()));
             $this->catalogue->add($message);
         }
     }
     return $node;
 }
示例#16
0
 public function enterNode(\PHPParser_Node $node)
 {
     if (!$node instanceof \PHPParser_Node_Scalar_String) {
         return;
     }
     $id = $node->value;
     if (preg_match('/(\\.\\.|\\.\\.\\.)/', $id)) {
         return;
     }
     if (preg_match('/^http/', $id)) {
         return;
     }
     if (preg_match('/.*\\./', $id)) {
         $domain = 'messages';
         $message = new Message($id, $domain);
         $message->addSource(new FileSource((string) $this->file, $node->getLine()));
         $this->catalogue->add($message);
     }
 }
示例#17
0
 public function testExtractWithSimpleTestFixtures()
 {
     $expected = array();
     $basePath = __DIR__ . '/Fixture/SimpleTest/';
     $fileSourceFactory = new FileSourceFactory('faux');
     // Controller
     $message = new Message('controller.foo');
     $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'Controller/DefaultController.php'), 27));
     $message->setDesc('Foo');
     $expected['controller.foo'] = $message;
     // Form Model
     $expected['form.foo'] = new Message('form.foo');
     $expected['form.bar'] = new Message('form.bar');
     // Templates
     foreach (array('php', 'twig') as $engine) {
         $message = new Message($engine . '.foo');
         $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'Resources/views/' . $engine . '_template.html.' . $engine), 1));
         $expected[$engine . '.foo'] = $message;
         $message = new Message($engine . '.bar');
         $message->setDesc('Bar');
         $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'Resources/views/' . $engine . '_template.html.' . $engine), 3));
         $expected[$engine . '.bar'] = $message;
         $message = new Message($engine . '.baz');
         $message->setMeaning('Baz');
         $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'Resources/views/' . $engine . '_template.html.' . $engine), 5));
         $expected[$engine . '.baz'] = $message;
         $message = new Message($engine . '.foo_bar');
         $message->setDesc('Foo');
         $message->setMeaning('Bar');
         $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'Resources/views/' . $engine . '_template.html.' . $engine), 7));
         $expected[$engine . '.foo_bar'] = $message;
     }
     // File with global namespace.
     $message = new Message('globalnamespace.foo');
     $message->addSource($fileSourceFactory->create(new \SplFileInfo($basePath . 'GlobalNamespace.php'), 27));
     $message->setDesc('Bar');
     $expected['globalnamespace.foo'] = $message;
     $actual = $this->extract(__DIR__ . '/Fixture/SimpleTest')->getDomain('messages')->all();
     asort($expected);
     asort($actual);
     $this->assertEquals($expected, $actual);
 }
 public function testLoadWithSymfonyFormat()
 {
     $loader = new XliffLoader();
     $expected = new MessageCatalogue();
     $expected->setLocale('en');
     $expected->add(Message::create('foo1')->setDesc('foo1')->setLocaleString('bar')->setNew(false));
     $expected->add(Message::create('foo2')->setDesc('foo2')->setLocaleString('bar')->setNew(false));
     $expected->add(Message::create('foo3')->setDesc('foo3')->setLocaleString('bar')->setNew(false));
     $expected->add(Message::create('foo4')->setDesc('foo4')->setLocaleString('bar')->setNew(false));
     $this->assertEquals($expected, $loader->load(__DIR__ . '/Symfony/xliff/old_format.xml', 'en'));
 }
 public function testExtract()
 {
     $expected = new MessageCatalogue();
     $path = __DIR__ . '/Fixture/MyFormType.php';
     $message = new Message('bar');
     $message->addSource(new FileSource($path, 36));
     $expected->add($message);
     $message = new Message('form.states.empty_value');
     $message->setDesc('Please select a state');
     $message->addSource(new FileSource($path, 37));
     $expected->add($message);
     $message = new Message('form.label.lastname');
     $message->setDesc('Lastname');
     $message->addSource(new FileSource($path, 33));
     $expected->add($message);
     $message = new Message('form.label.firstname');
     $message->addSource(new FileSource($path, 30));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('MyFormType.php'));
 }
 public function testCompareWithMultipleDomains()
 {
     $current = new MessageCatalogue();
     $current->add(Message::create('foo')->setLocaleString('bar'));
     $current->add(Message::create('bar', 'routes')->setLocaleString('baz'));
     $new = new MessageCatalogue();
     $new->add(new Message('foo'));
     $new->add(new Message('bar'));
     $expected = new ChangeSet(array(new Message('bar')), array(Message::create('bar', 'routes')->setLocaleString('baz')));
     $comparator = new CatalogueComparator();
     $this->assertEquals($expected, $comparator->compare($current, $new));
 }
 public function visitPhpFile(\SplFileInfo $file, MessageCatalogue $catalogue, array $ast)
 {
     $this->catalogue = $catalogue;
     // Traverse document to assemble class name
     $traverser = new \PHPParser_NodeTraverser();
     $traverser->addVisitor($this);
     $traverser->traverse($ast);
     if ($this->annotated) {
         // Get annotations for the class
         $annotationDriver = new Annotation(new DoctrineAnnotationReader());
         $manager = new Manager();
         $manager->addDriver($annotationDriver, -1);
         $metadata = $manager->getMetadata($this->parsedClassName);
         // Save messages for title
         foreach ($metadata->getFields() as $field) {
             $mappedField = $metadata->getFieldMapping($field);
             if ((!isset($mappedField['visible']) || $mappedField['visible']) && isset($mappedField['title'])) {
                 $message = new Message($mappedField['title']);
                 $message->addSource(new FileSource((string) $file));
                 $catalogue->add($message);
             }
         }
     }
 }
 public function load($resource, $locale, $domain = 'messages')
 {
     $previous = libxml_use_internal_errors(true);
     if (false === ($doc = simplexml_load_file($resource))) {
         libxml_use_internal_errors($previous);
         $libxmlError = libxml_get_last_error();
         throw new RuntimeException(sprintf('Could not load XML-file "%s": %s', $resource, $libxmlError->message));
     }
     libxml_use_internal_errors($previous);
     $doc->registerXPathNamespace('xliff', 'urn:oasis:names:tc:xliff:document:1.2');
     //        $doc->registerXPathNamespace('jms', 'urn:jms:translation');
     //        $hasReferenceFiles = in_array('urn:jms:translation', $doc->getNamespaces(true));
     $catalogue = new MessageCatalogue();
     $catalogue->setLocale($locale);
     foreach ($doc->xpath('//xliff:trans-unit') as $trans) {
         $id = ($resName = (string) $trans->attributes()->resname) ? $resName : (string) $trans->source;
         $m = Message::create($id, $domain)->setDesc((string) $trans->source)->setLocaleString((string) $trans->target);
         $catalogue->add($m);
         //            if ($hasReferenceFiles) {
         //                foreach ($trans->xpath('./jms:reference-file') as $file) {
         //                    $line = (string) $file->attributes()->line;
         //                    $column = (string) $file->attributes()->column;
         //                    $m->addSource(new FileSource(
         //                        (string) $file,
         //                        $line ? (integer) $line : null,
         //                        $column ? (integer) $column : null
         //                    ));
         //                }
         //            }
         if ($meaning = (string) $trans->attributes()->extradata) {
             if (0 === strpos($meaning, 'Meaning: ')) {
                 $meaning = substr($meaning, 9);
             }
             $m->setMeaning($meaning);
         }
         if (!($state = (string) $trans->target->attributes()->state) || 'new' !== $state) {
             $m->setNew(false);
         }
     }
     return $catalogue;
 }
示例#23
0
 /**
  * This test is used to check if translation from subscriber classes and even closures
  * are correctly extracted
  */
 public function testExtractWithWithSubscriberAndListener()
 {
     $expected = new MessageCatalogue();
     $path = __DIR__ . '/Fixture/MyFormTypeWithSubscriberAndListener.php';
     $pathSubscriber = __DIR__ . '/Fixture/MyFormSubscriber.php';
     $message = new Message('form.label.lastname');
     $message->setDesc('Lastname');
     $message->addSource(new FileSource($path, 36));
     $expected->add($message);
     $message = new Message('form.label.firstname');
     $message->addSource(new FileSource($path, 33));
     $expected->add($message);
     $message = new Message('form.label.password');
     $message->addSource(new FileSource($pathSubscriber, 37));
     $expected->add($message);
     $message = new Message('form.label.password_repeated');
     $message->setDesc('Repeat password');
     $message->addSource(new FileSource($pathSubscriber, 40));
     $expected->add($message);
     $message = new Message('form.label.zip', 'address');
     $message->setDesc('ZIP');
     $message->addSource(new FileSource($path, 51));
     $expected->add($message);
     $message = new Message('form.error.password_mismatch', 'validators');
     $message->setDesc('The entered passwords do not match');
     $message->addSource(new FileSource($pathSubscriber, 42));
     $expected->add($message);
     $catalogue = $this->extract('MyFormTypeWithSubscriberAndListener.php');
     //Merge with the subscriber catalogue
     $catalogue->merge($this->extract('MyFormSubscriber.php'));
     $this->assertEquals($expected, $catalogue);
 }
 public function enterNode(\PHPParser_Node $node)
 {
     if (!$node instanceof \PHPParser_Node_Expr_MethodCall || !is_string($node->name) || 'trans' !== strtolower($node->name) && 'transchoice' !== strtolower($node->name)) {
         $this->previousNode = $node;
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if (null !== ($docComment = $this->getDocCommentForNode($node))) {
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } else {
                 if ($annot instanceof Desc) {
                     $desc = $annot->text;
                 } else {
                     if ($annot instanceof Meaning) {
                         $meaning = $annot->text;
                     }
                 }
             }
         }
     }
     if ($ignore) {
         return;
     }
     if (!$node->args[0]->value instanceof \PHPParser_Node_Scalar_String) {
         $message = sprintf('Can only extract the translation id from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
         if ($this->logger) {
             $this->logger->err($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $id = $node->args[0]->value->value;
     $index = 'trans' === strtolower($node->name) ? 2 : 3;
     if (isset($node->args[$index])) {
         if (!$node->args[$index]->value instanceof \PHPParser_Node_Scalar_String) {
             $message = sprintf('Can only extract the translation domain from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
             if ($this->logger) {
                 $this->logger->err($message);
                 return;
             }
             throw new RuntimeException($message);
         }
         $domain = $node->args[$index]->value->value;
     } else {
         $domain = 'messages';
     }
     $message = new Message($id, $domain);
     $message->setDesc($desc);
     $message->setMeaning($meaning);
     $message->addSource(new FileSource((string) $this->file, $node->getLine()));
     $this->catalogue->add($message);
 }
 /**
  * @param Node $node
  */
 public function enterNode(Node $node)
 {
     if (!$node instanceof Node\Stmt\Throw_ || !$node->expr instanceof Node\Expr\New_) {
         $this->previousNode = $node;
         return;
     }
     $exceptionClass = $node->expr->class->parts[0];
     if (!in_array(strtolower($exceptionClass), array_map('strtolower', $this->exceptionsToExtractFrom))) {
         $this->previousNode = $node;
         return;
     }
     $node = $node->expr;
     $ignore = false;
     $desc = $meaning = null;
     if (null !== ($docComment = $this->getDocCommentForNode($node))) {
         if ($docComment instanceof Doc) {
             $docComment = $docComment->getText();
         }
         foreach ($this->docParser->parse($docComment, 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } elseif ($annot instanceof Desc) {
                 $desc = $annot->text;
             } elseif ($annot instanceof Meaning) {
                 $meaning = $annot->text;
             }
         }
     }
     if (!$node->args[0]->value instanceof String_) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Can only extract the translation id from a scalar string, but got "%s". Please refactor your code to make it extractable, or add the doc comment /** @Ignore */ to this code element (in %s on line %d).', get_class($node->args[0]->value), $this->file, $node->args[0]->value->getLine());
         if ($this->logger) {
             $this->logger->error($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $id = $node->args[0]->value->value;
     $message = new Message($id, $this->defaultDomain);
     $message->setDesc($desc);
     $message->setMeaning($meaning);
     $message->addSource($this->fileSourceFactory->create($this->file, $node->getLine()));
     $this->catalogue->add($message);
 }
 /**
  * @param string $id
  * @param string $domain
  */
 private function addMessage($id, $domain)
 {
     $message = new Message($id, $domain);
     //        $this->logger->debug(sprintf('extract: %s - domain:%s', $id, $domain));
     $trace = debug_backtrace(false);
     if (isset($trace[1]['file'])) {
         $message->addSource(new FileSource($trace[1]['file']));
     }
     $this->catalogue->add($message);
 }
示例#27
0
 /**
  * Get the catalogue used for the structure tests
  *
  * @return MessageCatalogue
  */
 protected function getStructureCatalogue()
 {
     $catalogue = new MessageCatalogue();
     $catalogue->setLocale('en');
     $message = new Message('foo.bar.baz');
     $message->addSource(new FileSource('/z/order/test', 1, 2));
     $message->addSource(new FileSource('bar/baz', 1, 2));
     $message->addSource(new FileSource('bar/baz', 1, 5));
     $message->addSource(new FileSource('/a/b/c/foo/bar', 1, 2));
     $catalogue->add($message);
     return $catalogue;
 }
 public function testEmbeddedTemplate()
 {
     $expected = new MessageCatalogue();
     $path = __DIR__ . '/Fixture/embedded_template.html.twig';
     $message = new Message('foo');
     $message->addSource(new FileSource($path, 3));
     $expected->add($message);
     $this->assertEquals($expected, $this->extract('embedded_template.html.twig'));
 }
 /**
  * @param string $id
  * @param string $source
  * @param null|string $domain
  * @param null|string $desc
  * @param null|string $meaning
  */
 private function addToCatalogue($id, $source, $domain = null, $desc = null, $meaning = null)
 {
     if (null === $domain) {
         $message = new Message($id);
     } else {
         $message = new Message($id, $domain);
     }
     $message->addSource($source);
     if ($desc) {
         $message->setDesc($desc);
     }
     if ($meaning) {
         $message->setMeaning($meaning);
     }
     $this->catalogue->add($message);
 }
 public function enterNode(\PHPParser_Node $node)
 {
     if ($node instanceof \PHPParser_Node_Stmt_Namespace) {
         $this->namespace = implode('\\', $node->name->parts);
         return;
     }
     if ($node instanceof \PHPParser_Node_Stmt_Class) {
         $name = '' === $this->namespace ? $node->name : $this->namespace . '\\' . $node->name;
         if (!class_exists($name)) {
             return;
         }
         $ref = new \ReflectionClass($name);
         if (!$ref->isSubclassOf('Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') && $ref->name !== 'Symfony\\Component\\Security\\Core\\Exception\\AuthenticationException') {
             return;
         }
         if (!$ref->hasMethod('getMessageKey')) {
             return;
         }
         $this->inAuthException = true;
         return;
     }
     if (!$this->inAuthException) {
         return;
     }
     if ($node instanceof \PHPParser_Node_Stmt_ClassMethod) {
         if ('getmessagekey' === strtolower($node->name)) {
             $this->inGetMessageKey = true;
         }
         return;
     }
     if (!$this->inGetMessageKey) {
         return;
     }
     if (!$node instanceof \PHPParser_Node_Stmt_Return) {
         return;
     }
     $ignore = false;
     $desc = $meaning = null;
     if ($docComment = $node->getDocComment()) {
         foreach ($this->docParser->parse($docComment->getText(), 'file ' . $this->file . ' near line ' . $node->getLine()) as $annot) {
             if ($annot instanceof Ignore) {
                 $ignore = true;
             } else {
                 if ($annot instanceof Desc) {
                     $desc = $annot->text;
                 } else {
                     if ($annot instanceof Meaning) {
                         $meaning = $annot->text;
                     }
                 }
             }
         }
     }
     if (!$node->expr instanceof \PHPParser_Node_Scalar_String) {
         if ($ignore) {
             return;
         }
         $message = sprintf('Could not extract id from return value, expected scalar string but got %s (in %s on line %d).', get_class($node->expr), $this->file, $node->expr->getLine());
         if ($this->logger) {
             $this->logger->err($message);
             return;
         }
         throw new RuntimeException($message);
     }
     $message = Message::create($node->expr->value, $this->domain)->setDesc($desc)->setMeaning($meaning)->addSource(new FileSource((string) $this->file, $node->expr->getLine()));
     $this->catalogue->add($message);
 }