public function testDictionaryCompiler() { vfsStream::setup('root'); $dic = <<<DIC <fig:dictionary xmlns:fig="http://figdice.org/" language="fr"> <entry key="foo">bar</entry> <entry key="David">Bowie</entry> </fig:dictionary> DIC; $vDicFile = vfsStream::newFile('en/dic.xml')->at(vfsStreamWrapper::getRoot()); $vDicFile->withContent($dic); $target = vfsStream::url('root/Dictionary/en/dic.xml.php'); $compilationResult = Dictionary::compile(vfsStream::url($vDicFile->path()), $target); $this->assertTrue($compilationResult); $this->assertFileExists($target); $this->assertEquals('a:2:{s:3:"foo";s:3:"bar";s:5:"David";s:5:"Bowie";}', file_get_contents($target)); // Test the loading of a pre-compiled dictionary: $view = new View(); // Indicate where the source dictionary is located $view->setTranslationPath(vfsStream::url('root')); // Indicate where the compiled dictionaries are located. $view->setTempPath(vfsStream::url('root')); $viewString = <<<ENDTEMPLATE <fig:template> <fig:dictionary file="dic.xml" /> <fig:trans key="David"/> </fig:template> ENDTEMPLATE; $view->loadString($viewString); $view->setLanguage('en'); $this->assertEquals('Bowie', trim($view->render())); }
/** * Loads a language XML file, to be used within the current view. * * If a Temp path was specified in the View, * we try to compile (serialize) the XML key-value collection and store * the serialized form in a 'Dictionary/(langcode)' subfolder of the temp path. */ private function fig_dictionary() { //If a @source attribute is specified, //it means that when the target (view's language) is the same as @source, //then don't bother loading dictionary file, nor translating: just render the tag's children. $file = $this->attributes['file']; $filename = $this->getView()->getTranslationPath() . '/' . $this->getView()->getLanguage() . '/' . $file; $name = $this->getAttribute('name', null); $source = $this->getAttribute('source', null); $dictionary = new Dictionary($filename, $source); if ($this->getView()->getLanguage() == '' || $source == $this->getView()->getLanguage()) { // If the current View does not specify a Language, // or if the dictionary to load is same language as View, // let's not care about i18n. // We will activate i18n only if the dictionary explicitly specifies a source, // which means that we cannot simply rely on contents of the fig:trans tags. // However, we still need to hook the Dictionary object as a placeholder, // so that subsequent trans tag for the given dic name and source will // simply render their contents. $this->getCurrentFile()->addDictionary($dictionary, $name); return ''; } //TODO: Please optimize here: cache the realpath of the loaded dictionaries, //so as not to re-load an already loaded dictionary in same View hierarchy. try { //Determine whether this dictionary was pre-compiled: if ($this->getView()->getTempPath()) { $tmpFile = $this->getView()->getTempPath() . '/' . 'Dictionary' . '/' . $this->getView()->getLanguage() . '/' . $file . '.php'; //If the tmp file already exists, if (file_exists($tmpFile)) { //but is older than the source file, if (filemtime($tmpFile) < filemtime($filename)) { Dictionary::compile($filename, $tmpFile); } } else { Dictionary::compile($filename, $tmpFile); } $dictionary->restore($tmpFile); } else { $dictionary->load(); } } catch (FileNotFoundException $ex) { throw new FileNotFoundException('Translation file not found: file=' . $filename . ', language=' . $this->getView()->getLanguage() . ', source=' . $this->getCurrentFilename(), $this->getCurrentFilename()); } catch (DictionaryDuplicateKeyException $ddkex) { $this->getLogger()->error('Duplicate key: "' . $ddkex->getKey() . '" in dictionary: ' . $ddkex->getFilename()); } //Hook the dictionary to the current file. //(in fact this will bubble up the message as high as possible, ie: //to the highest parent which does not bear a dictionary of same name) $this->getCurrentFile()->addDictionary($dictionary, $name); return ''; }