Merge remote-tracking branch 'origin/3.1'

This commit is contained in:
Ingo Schommer 2013-06-02 20:25:32 +02:00
commit f855c146d5
5 changed files with 82 additions and 15 deletions

View File

@ -71,10 +71,21 @@ class i18nTextCollector extends Object {
* @uses DataObject->collectI18nStatics() * @uses DataObject->collectI18nStatics()
* *
* @param array $restrictToModules * @param array $restrictToModules
* @param array $mergeWithExisting Merge new master strings with existing ones
* already defined in language files, rather than replacing them. This can be useful
* for long-term maintenance of translations across releases, because it allows
* "translation backports" to older releases without removing strings these older releases
* still rely on.
*/ */
public function run($restrictToModules = null) { public function run($restrictToModules = null, $mergeWithExisting = false) {
//Debug::message("Collecting text...", false); $entitiesByModule = $this->collect($restrictToModules, $mergeWithExisting);
// Write each module language file
if($entitiesByModule) foreach($entitiesByModule as $module => $entities) {
$this->getWriter()->write($entities, $this->defaultLocale, $this->baseSavePath . '/' . $module);
}
}
public function collect($restrictToModules = null, $mergeWithExisting = false) {
$modules = scandir($this->basePath); $modules = scandir($this->basePath);
$themeFolders = array(); $themeFolders = array();
@ -137,7 +148,31 @@ class i18nTextCollector extends Object {
$entitiesByModule[$othermodule][$fullName] = $spec; $entitiesByModule[$othermodule][$fullName] = $spec;
unset($entitiesByModule[$module][$fullName]); unset($entitiesByModule[$module][$fullName]);
} }
} }
// Optionally merge with existing master strings
// TODO Support all defined source formats through i18n::get_translators().
// Currently not possible because adapter instances can't be fully reset through the Zend API,
// meaning master strings accumulate across modules
if($mergeWithExisting) {
$adapter = Injector::inst()->get('i18nRailsYamlAdapter');
$masterFile = "{$this->basePath}/{$module}/lang/"
. $adapter->getFilenameForLocale($this->defaultLocale);
if(!file_exists($masterFile)) continue;
$adapter->addTranslation(array(
'content' => $masterFile,
'locale' => $this->defaultLocale
));
$entitiesByModule[$module] = array_merge(
array_map(
// Transform each master string from scalar value to array of strings
function($v) {return array($v);},
$adapter->getMessages($this->defaultLocale)
),
$entitiesByModule[$module]
);
}
} }
// Restrict modules we update to just the specified ones (if any passed) // Restrict modules we update to just the specified ones (if any passed)
@ -147,10 +182,11 @@ class i18nTextCollector extends Object {
} }
} }
// Write each module language file return $entitiesByModule;
if($entitiesByModule) foreach($entitiesByModule as $module => $entities) { }
$this->getWriter()->write($entities, $this->defaultLocale, $this->baseSavePath . '/' . $module);
} public function write($module, $entities) {
$this->getWriter()->write($entities, $this->defaultLocale, $this->baseSavePath . '/' . $module);
} }
/** /**

View File

@ -10,6 +10,12 @@ class i18nTextCollectorTask extends BuildTask {
protected $description = " protected $description = "
Traverses through files in order to collect the 'entity master tables' Traverses through files in order to collect the 'entity master tables'
stored in each module. stored in each module.
Parameters:
- locale: Sets default locale
- writer: Custom writer class (defaults to i18nTextCollector_Writer_RailsYaml)
- module: One or more modules to limit collection (comma-separated)
- merge: Merge new strings with existing ones already defined in language files (default: FALSE)
"; ";
public function init() { public function init() {
@ -32,6 +38,6 @@ class i18nTextCollectorTask extends BuildTask {
$writer = $request->getVar('writer'); $writer = $request->getVar('writer');
if($writer) $c->setWriter(new $writer()); if($writer) $c->setWriter(new $writer());
$restrictModules = ($request->getVar('module')) ? explode(',', $request->getVar('module')) : null; $restrictModules = ($request->getVar('module')) ? explode(',', $request->getVar('module')) : null;
return $c->run($restrictModules); return $c->run($restrictModules, (bool)$request->getVar('merge'));
} }
} }

View File

@ -15,8 +15,8 @@ class FileTest extends SapphireTest {
$parser = new ShortcodeParser(); $parser = new ShortcodeParser();
$parser->register('file_link', array('File', 'link_shortcode_handler')); $parser->register('file_link', array('File', 'link_shortcode_handler'));
$fileShortcode = sprintf('[file_link id=%d]', $testFile->ID); $fileShortcode = sprintf('[file_link,id=%d]', $testFile->ID);
$fileEnclosed = sprintf('[file_link id=%d]Example Content[/file_link]', $testFile->ID); $fileEnclosed = sprintf('[file_link,id=%d]Example Content[/file_link]', $testFile->ID);
$fileShortcodeExpected = $testFile->Link(); $fileShortcodeExpected = $testFile->Link();
$fileEnclosedExpected = sprintf( $fileEnclosedExpected = sprintf(
@ -27,11 +27,11 @@ class FileTest extends SapphireTest {
$testFile->delete(); $testFile->delete();
$fileShortcode = '[file_link id="-1"]'; $fileShortcode = '[file_link,id="-1"]';
$fileEnclosed = '[file_link id="-1"]Example Content[/file_link]'; $fileEnclosed = '[file_link,id="-1"]Example Content[/file_link]';
$this->assertEquals('', $parser->parse('[file_link]'), 'Test that invalid ID attributes are not parsed.'); $this->assertEquals('', $parser->parse('[file_link]'), 'Test that invalid ID attributes are not parsed.');
$this->assertEquals('', $parser->parse('[file_link id="text"]')); $this->assertEquals('', $parser->parse('[file_link,id="text"]'));
$this->assertEquals('', $parser->parse('[file_link]Example Content[/file_link]')); $this->assertEquals('', $parser->parse('[file_link]Example Content[/file_link]'));
if(class_exists('ErrorPage')) { if(class_exists('ErrorPage')) {

View File

@ -1,3 +1,4 @@
<% _t('i18nTestModule.MAINTEMPLATE',"Main Template") %> <% _t('i18nTestModule.MAINTEMPLATE',"Main Template") %>
$Layout $Layout
lonely _t() call that should be ignored lonely _t() call that should be ignored
<% _t('i18nTestModule.NEWENTITY',"Not stored in master file yet") %>

View File

@ -538,6 +538,30 @@ YAML;
Config::inst()->update('SSViewer', 'theme', $theme); Config::inst()->update('SSViewer', 'theme', $theme);
} }
public function testCollectMergesWithExisting() {
$defaultlocal = i18n::default_locale();
$local = i18n::get_locale();
i18n::set_locale('en_US');
i18n::set_default_locale('en_US');
$c = new i18nTextCollector();
$c->setWriter(new i18nTextCollector_Writer_Php());
$c->basePath = $this->alternateBasePath;
$c->baseSavePath = $this->alternateBaseSavePath;
$entitiesByModule = $c->collect(null, true /* merge */);
$this->assertArrayHasKey(
'i18nTestModule.ENTITY',
$entitiesByModule['i18ntestmodule'],
'Retains existing entities'
);
$this->assertArrayHasKey(
'i18nTestModule.NEWENTITY',
$entitiesByModule['i18ntestmodule'],
'Adds new entities'
);
}
public function testCollectFromFilesystemAndWriteMasterTables() { public function testCollectFromFilesystemAndWriteMasterTables() {
$defaultlocal = i18n::default_locale(); $defaultlocal = i18n::default_locale();