diff --git a/admin/code/ModelAdmin.php b/admin/code/ModelAdmin.php index e19dfbbc4..0c8e4c370 100644 --- a/admin/code/ModelAdmin.php +++ b/admin/code/ModelAdmin.php @@ -96,14 +96,18 @@ abstract class ModelAdmin extends LeftAndMain { /** * Initialize the model admin interface. Sets up embedded jquery libraries and requisite plugins. - * - * @todo remove reliance on urlParams */ public function init() { parent::init(); $models = $this->getManagedModels(); - $this->modelClass = (isset($this->urlParams['ModelClass'])) ? $this->urlParams['ModelClass'] : key($models); + + if($this->request->param('ModelClass')) { + $this->modelClass = $this->request->param('ModelClass'); + } else { + reset($models); + $this->modelClass = key($models); + } // security check for valid models if(!array_key_exists($this->modelClass, $models)) { diff --git a/admin/tests/SecurityAdminTest.php b/admin/tests/SecurityAdminTest.php index 86f635869..b024e0500 100644 --- a/admin/tests/SecurityAdminTest.php +++ b/admin/tests/SecurityAdminTest.php @@ -76,7 +76,7 @@ class SecurityAdminTest extends FunctionalTest { $group = $this->objFromFixture('Group', 'admin'); SecurityAdmin::add_hidden_permission('CMS_ACCESS_ReportAdmin'); - $response = $this->get(sprintf('admin/security/EditForm/field/Group/item/%d/edit', $group->ID)); + $response = $this->get(sprintf('admin/security/EditForm/field/Groups/item/%d/edit', $group->ID)); $this->assertContains( 'CMS_ACCESS_SecurityAdmin', diff --git a/forms/gridfield/GridFieldAddNewButton.php b/forms/gridfield/GridFieldAddNewButton.php index 61e135549..2086b5a5b 100644 --- a/forms/gridfield/GridFieldAddNewButton.php +++ b/forms/gridfield/GridFieldAddNewButton.php @@ -6,17 +6,31 @@ * @subpackage gridfield */ class GridFieldAddNewButton implements GridField_HTMLProvider { + protected $targetFragment; - + + protected $buttonName; + + public function setButtonName($name) { + $this->buttonName = $name; + return $this; + } + public function __construct($targetFragment = 'before') { $this->targetFragment = $targetFragment; } - + public function getHTMLFragments($gridField) { + if(!$this->buttonName) { + // provide a default button name, can be changed by calling {@link setButtonName()} on this component + $this->buttonName = _t('GridField.Add', 'Add {name}', array('name' => $gridField->getModelClass())); + } + $data = new ArrayData(array( 'NewLink' => Controller::join_links($gridField->Link('item'), 'new'), - 'ButtonName' => _t('GridField.Add', 'Add {name}', array('name' => $gridField->getModelClass())), + 'ButtonName' => $this->buttonName, )); + return array( $this->targetFragment => $data->renderWith('GridFieldAddNewbutton'), ); diff --git a/i18n/i18n.php b/i18n/i18n.php index c350797f6..2460518a7 100644 --- a/i18n/i18n.php +++ b/i18n/i18n.php @@ -1494,13 +1494,20 @@ class i18n extends Object implements TemplateGlobalProvider { foreach($translators as $name => $translator) { $adapter = $translator->getAdapter(); - // If language table isn't loaded for this locale, get it for each of the modules. - // The method will automatically load fallback languages (the lang for a locale). - if(!$adapter->isAvailable($locale) && !$adapter->isAvailable($lang)) { - // TODO Remove reliance on global state, by refactoring into an i18nTranslatorManager - // which is instanciated by core with a $clean instance variable. + // at this point, we need to ensure the language and locale are loaded + // as include_by_locale() doesn't load a fallback. + + // TODO Remove reliance on global state, by refactoring into an i18nTranslatorManager + // which is instanciated by core with a $clean instance variable. + + if(!$adapter->isAvailable($lang)) { + i18n::include_by_locale($lang, (isset($_GET['flush']))); + } + + if(!$adapter->isAvailable($locale)) { i18n::include_by_locale($locale, (isset($_GET['flush']))); } + $translation = $adapter->translate($entity, $locale); // Return translation only if we found a match thats not the entity itself (Zend fallback) @@ -1568,7 +1575,8 @@ class i18n extends Object implements TemplateGlobalProvider { 'disableNotices' => true, )) ); - + + i18n::include_by_locale('en', isset($_GET['flush'])); i18n::include_by_locale('en_US', isset($_GET['flush'])); } @@ -1919,24 +1927,16 @@ class i18n extends Object implements TemplateGlobalProvider { /** * Includes all available language files for a certain defined locale. - * If the locale is a fully qualified locale (e.g. "en_US" rather than "en"), - * will load the base locale file as well (if available). - * + * * @param string $locale All resources from any module in locale $locale will be loaded * @param Boolean $clean Clean old caches? */ static function include_by_locale($locale, $clean = false) { - $lang = i18n::get_lang_from_locale($locale); - if($clean) { $cache = Zend_Translate::getCache(); if($cache) $cache->clean(Zend_Cache::CLEANING_MODE_ALL); } - // Automatically include fallback language (if applicable) - // TODO Also include custom Zend_Translate routing languages - $selectedLocales = array_unique(array($lang, $locale)); - // Sort modules by inclusion priority, then alphabetically // TODO Should be handled by priority flags within modules $prios = array('sapphire' => 10, 'framework' => 10, 'admin' => 11, 'cms' => 12, 'mysite' => 90); @@ -1959,15 +1959,13 @@ class i18n extends Object implements TemplateGlobalProvider { // Load translations from modules foreach($modules as $module) { - foreach($selectedLocales as $selectedLocale) { - $filename = $adapter->getFilenameForLocale($selectedLocale); - $filepath = "{$module}/lang/" . $filename; + $filename = $adapter->getFilenameForLocale($locale); + $filepath = "{$module}/lang/" . $filename; - if($filename && !file_exists($filepath)) continue; - $adapter->addTranslation( - array('content' => $filepath, 'locale' => $selectedLocale) - ); - } + if($filename && !file_exists($filepath)) continue; + $adapter->addTranslation( + array('content' => $filepath, 'locale' => $locale) + ); } // Load translations from themes @@ -1979,29 +1977,25 @@ class i18n extends Object implements TemplateGlobalProvider { strpos($theme, SSViewer::current_theme()) === 0 && file_exists("{$themesBase}/{$theme}/lang/") ) { - foreach($selectedLocales as $selectedLocale) { - $filename = $adapter->getFilenameForLocale($selectedLocale); - $filepath = "{$themesBase}/{$theme}/lang/" . $filename; - if($filename && !file_exists($filepath)) continue; - $adapter->addTranslation( - array('content' => $filepath, 'locale' => $selectedLocale) - ); - } + $filename = $adapter->getFilenameForLocale($locale); + $filepath = "{$themesBase}/{$theme}/lang/" . $filename; + if($filename && !file_exists($filepath)) continue; + $adapter->addTranslation( + array('content' => $filepath, 'locale' => $locale) + ); } } } // Add empty translations to ensure the locales are "registered" with isAvailable(), // and the next invocation of include_by_locale() doesn't cause a new reparse. - foreach($selectedLocales as $selectedLocale) { - $adapter->addTranslation( - array( - 'content' => array('_' => '_'), - 'locale' => $selectedLocale, - 'usetranslateadapter' => true - ) - ); - } + $adapter->addTranslation( + array( + 'content' => array('_' => '_'), + 'locale' => $locale, + 'usetranslateadapter' => true + ) + ); } } } diff --git a/tests/i18n/i18nTest.php b/tests/i18n/i18nTest.php index 7fe513209..b8adc6f5d 100644 --- a/tests/i18n/i18nTest.php +++ b/tests/i18n/i18nTest.php @@ -484,12 +484,12 @@ class i18nTest extends SapphireTest { i18n::register_translator($translator, 'custom', 11); $this->assertEquals( i18n::_t('i18nTestModule.ENTITY'), - 'i18nTestModule.ENTITY CustomAdapter (en)', + 'i18nTestModule.ENTITY CustomAdapter (en_US)', 'Existing entities overruled by adapter with higher priority' ); $this->assertEquals( i18n::_t('AdapterEntity1', 'AdapterEntity1'), - 'AdapterEntity1 CustomAdapter (en)', + 'AdapterEntity1 CustomAdapter (en_US)', 'New entities only defined in new adapter are detected' ); @@ -501,7 +501,7 @@ class i18nTest extends SapphireTest { i18n::register_translator($translator, 'othercustom_lower_prio', 5); $this->assertEquals( i18n::_t('i18nTestModule.ENTITY'), - 'i18nTestModule.ENTITY CustomAdapter (en)', + 'i18nTestModule.ENTITY CustomAdapter (en_US)', 'Adapter with lower priority loses' ); @@ -513,7 +513,7 @@ class i18nTest extends SapphireTest { i18n::register_translator($translator, 'othercustom_higher_prio', 15); $this->assertEquals( i18n::_t('i18nTestModule.ENTITY'), - 'i18nTestModule.ENTITY OtherCustomAdapter (en)', + 'i18nTestModule.ENTITY OtherCustomAdapter (en_US)', 'Adapter with higher priority wins' );