MDL-26804 core_string_manager::get_list_of_translations() can use a cache again

This patch reimplements the internal cache that was used to store the
list of available translations in Moodle 1.x. By default, the method
get_list_of_translations() still uses the file
moodledata/cache/languages to store the list of available translations.
The location of that file can be redefined in config.php. The internal
format of the cache file is JSON now (used to be a plain text list).

The patch also fixes a usage of the global $CFG in translation_exists()
methods where the internal property should be used instead.
This commit is contained in:
David Mudrak 2011-03-21 18:33:06 +01:00
parent 92a387b467
commit a9cbd19bff
7 changed files with 67 additions and 17 deletions

View file

@ -53,11 +53,6 @@ define('INSTALLATION_OF_SELECTED_LANG', 2);
define('DELETION_OF_SELECTED_LANG', 4); define('DELETION_OF_SELECTED_LANG', 4);
define('UPDATE_ALL_LANG', 5); define('UPDATE_ALL_LANG', 5);
//reset and diagnose lang cache permissions
remove_dir($CFG->dataroot.'/cache/languages');
if (file_exists($CFG->dataroot.'/cache/languages')) {
print_error('cannotdeletelangcache', 'error');
}
get_string_manager()->reset_caches(); get_string_manager()->reset_caches();
$notice_ok = array(); $notice_ok = array();

View file

@ -10,7 +10,7 @@ if ($hassiteconfig) {
$temp->add(new admin_setting_configselect('lang', get_string('lang', 'admin'), get_string('configlang', 'admin'), current_language(), get_string_manager()->get_list_of_translations())); // $CFG->lang might be set in installer already, default en is in setup.php $temp->add(new admin_setting_configselect('lang', get_string('lang', 'admin'), get_string('configlang', 'admin'), current_language(), get_string_manager()->get_list_of_translations())); // $CFG->lang might be set in installer already, default en is in setup.php
$temp->add(new admin_setting_configcheckbox('langmenu', get_string('langmenu', 'admin'), get_string('configlangmenu', 'admin'), 1)); $temp->add(new admin_setting_configcheckbox('langmenu', get_string('langmenu', 'admin'), get_string('configlangmenu', 'admin'), 1));
$temp->add(new admin_setting_langlist()); $temp->add(new admin_setting_langlist());
$temp->add(new admin_setting_configcheckbox('langcache', get_string('langcache', 'admin'), get_string('configlangcache', 'admin'), 1)); $temp->add(new admin_setting_configcheckbox('langcache', get_string('langcache', 'admin'), get_string('langcache_desc', 'admin'), 1));
$temp->add(new admin_setting_configcheckbox('langstringcache', get_string('langstringcache', 'admin'), get_string('configlangstringcache', 'admin'), 1)); $temp->add(new admin_setting_configcheckbox('langstringcache', get_string('langstringcache', 'admin'), get_string('configlangstringcache', 'admin'), 1));
$temp->add(new admin_setting_configtext('locale', get_string('localetext', 'admin'), get_string('configlocale', 'admin'), '', PARAM_FILE)); $temp->add(new admin_setting_configtext('locale', get_string('localetext', 'admin'), get_string('configlocale', 'admin'), '', PARAM_FILE));
$temp->add(new admin_setting_configselect('latinexcelexport', get_string('latinexcelexport', 'admin'), get_string('configlatinexcelexport', 'admin'), '0', array('0'=>'Unicode','1'=>'Latin'))); $temp->add(new admin_setting_configselect('latinexcelexport', get_string('latinexcelexport', 'admin'), get_string('configlatinexcelexport', 'admin'), '0', array('0'=>'Unicode','1'=>'Latin')));

View file

@ -357,6 +357,13 @@ $CFG->admin = 'admin';
// //
// $CFG->langcacheroot = '/var/www/moodle/htdocs/altcache/lang'; // $CFG->langcacheroot = '/var/www/moodle/htdocs/altcache/lang';
// //
// If $CFG->langcache is enabled (which should always be in production
// environment), Moodle stores the list of available languages in a cache file.
// By default, the file $CFG->dataroot/languages is used. You may wish to
// specify an alternative location of this cache file.
//
// $CFG->langmenucachefile = '/var/www/moodle/htdocs/altcache/languages';
//
// Site default language can be set via standard administration interface. If you // Site default language can be set via standard administration interface. If you
// want to have initial error messages for eventual database connection problems // want to have initial error messages for eventual database connection problems
// localized too, you have to set your language code here. // localized too, you have to set your language code here.

View file

@ -246,7 +246,6 @@ $string['configjabberpassword'] = 'The password to use when connecting to the Ja
$string['configjabberport'] = 'The port to use when connecting to the Jabber server'; $string['configjabberport'] = 'The port to use when connecting to the Jabber server';
$string['configkeeptagnamecase'] = 'Check this if you want tag names to keep the original casing as entered by users who created them'; $string['configkeeptagnamecase'] = 'Check this if you want tag names to keep the original casing as entered by users who created them';
$string['configlang'] = 'Choose a default language for the whole site. Users can override this setting using the language menu or the setting in their personal profile.'; $string['configlang'] = 'Choose a default language for the whole site. Users can override this setting using the language menu or the setting in their personal profile.';
$string['configlangcache'] = 'Cache the language menu. Saves a lot of memory and processing power. If you enable this, the menu takes a few minutes to update after you have added or removed languages.';
$string['configlangstringcache'] = 'Caches all the language strings into compiled files in the data directory. If you are translating Moodle or changing strings in the Moodle source code then you may want to switch this off. Otherwise leave it on to see performance benefits.'; $string['configlangstringcache'] = 'Caches all the language strings into compiled files in the data directory. If you are translating Moodle or changing strings in the Moodle source code then you may want to switch this off. Otherwise leave it on to see performance benefits.';
$string['configlangdir'] = 'Most languages are printed left-to-right, but some, like Arabic and Hebrew, are printed right-to-left.'; $string['configlangdir'] = 'Most languages are printed left-to-right, but some, like Arabic and Hebrew, are printed right-to-left.';
$string['configlanglist'] = 'Leave this blank to allow users to choose from any language you have in this installation of Moodle. However, you can shorten the language menu by entering a comma-separated list of language codes that you want. For example: en,es_es,fr,it'; $string['configlanglist'] = 'Leave this blank to allow users to choose from any language you have in this installation of Moodle. However, you can shorten the language menu by entering a comma-separated list of language codes that you want. For example: en,es_es,fr,it';
@ -632,6 +631,7 @@ $string['jabberport'] = 'Jabber port';
$string['keeptagnamecase'] = 'Keep tag name casing'; $string['keeptagnamecase'] = 'Keep tag name casing';
$string['lang'] = 'Default language'; $string['lang'] = 'Default language';
$string['langcache'] = 'Cache language menu'; $string['langcache'] = 'Cache language menu';
$string['langcache_desc'] = 'Cache the language menu. If enabled, the list of available translations is cached. The cache is automatically refreshed when you install or delete a language pack via the in-built language packs management tool. If you install a new language pack manually, you have to use Purge all caches feature to refresh the cached list.';
$string['langedit'] = 'Language editing'; $string['langedit'] = 'Language editing';
$string['langimport'] = 'Language import utility'; $string['langimport'] = 'Language import utility';
$string['langimportdisabled'] = 'Language import feature has been disabled. You have to update your language packs manually at the file-system level.'; $string['langimportdisabled'] = 'Language import feature has been disabled. You have to update your language packs manually at the file-system level.';

View file

@ -61,7 +61,6 @@ $string['cannotdeletecourse'] = 'You do not have the permission to delete this c
$string['cannotdeletecustomfield'] = 'Error deleting custom field data'; $string['cannotdeletecustomfield'] = 'Error deleting custom field data';
$string['cannotdeletedir'] = 'Cannot delete ({$a})'; $string['cannotdeletedir'] = 'Cannot delete ({$a})';
$string['cannotdeletefile'] = 'Cannot delete this file'; $string['cannotdeletefile'] = 'Cannot delete this file';
$string['cannotdeletelangcache'] = 'Language cache cannot be deleted, please fix permissions in dataroot/cache/languages!';
$string['cannotdeleterole'] = 'It cannot be deleted, because {$a}'; $string['cannotdeleterole'] = 'It cannot be deleted, because {$a}';
$string['cannotdeleterolewithid'] = 'Could not delete role with ID {$a}'; $string['cannotdeleterolewithid'] = 'Could not delete role with ID {$a}';
$string['cannotdeletethisrole'] = 'You cannot delete this role because it is used by the system, or because it is the last role with administrator capabilities.'; $string['cannotdeletethisrole'] = 'You cannot delete this role because it is used by the system, or because it is the last role with administrator capabilities.';

View file

@ -5484,17 +5484,28 @@ function get_string_manager($forcereload=false) {
} }
if ($singleton === null) { if ($singleton === null) {
if (empty($CFG->early_install_lang)) { if (empty($CFG->early_install_lang)) {
if (empty($CFG->langcacheroot)) { if (empty($CFG->langcacheroot)) {
$langcacheroot = $CFG->dataroot . '/cache/lang'; $langcacheroot = $CFG->dataroot . '/cache/lang';
} else { } else {
$langcacheroot = $CFG->langcacheroot; $langcacheroot = $CFG->langcacheroot;
} }
if (empty($CFG->langlist)) { if (empty($CFG->langlist)) {
$translist = array(); $translist = array();
} else { } else {
$translist = explode(',', $CFG->langlist); $translist = explode(',', $CFG->langlist);
} }
$singleton = new core_string_manager($CFG->langotherroot, $CFG->langlocalroot, $langcacheroot, !empty($CFG->langstringcache), $translist);
if (empty($CFG->langmenucachefile)) {
$langmenucache = $CFG->dataroot . '/cache/languages';
} else {
$langmenucache = $CFG->langmenucachefile;
}
$singleton = new core_string_manager($CFG->langotherroot, $CFG->langlocalroot, $langcacheroot,
!empty($CFG->langstringcache), $translist, $langmenucache);
} else { } else {
$singleton = new install_string_manager(); $singleton = new install_string_manager();
} }
@ -5624,22 +5635,26 @@ class core_string_manager implements string_manager {
protected $usediskcache; protected $usediskcache;
/* @var array limit list of translations */ /* @var array limit list of translations */
protected $translist; protected $translist;
/** @var string location of a file that caches the list of available translations */
protected $menucache;
/** /**
* Crate new instance of string manager * Create new instance of string manager
* *
* @param string $otherroot location of downlaoded lang packs - usually $CFG->dataroot/lang * @param string $otherroot location of downlaoded lang packs - usually $CFG->dataroot/lang
* @param string $localroot usually the same as $otherroot * @param string $localroot usually the same as $otherroot
* @param string $cacheroot usually lang dir in cache folder * @param string $cacheroot usually lang dir in cache folder
* @param bool $usediskcache use disk cache * @param bool $usediskcache use disk cache
* @param array $translist limit list of visible translations * @param array $translist limit list of visible translations
* @param string $menucache the location of a file that caches the list of available translations
*/ */
public function __construct($otherroot, $localroot, $cacheroot, $usediskcache, $translist) { public function __construct($otherroot, $localroot, $cacheroot, $usediskcache, $translist, $menucache) {
$this->otherroot = $otherroot; $this->otherroot = $otherroot;
$this->localroot = $localroot; $this->localroot = $localroot;
$this->cacheroot = $cacheroot; $this->cacheroot = $cacheroot;
$this->usediskcache = $usediskcache; $this->usediskcache = $usediskcache;
$this->translist = $translist; $this->translist = $translist;
$this->menucache = $menucache;
} }
/** /**
@ -6007,15 +6022,13 @@ class core_string_manager implements string_manager {
* @return boot true if exists * @return boot true if exists
*/ */
public function translation_exists($lang, $includeall = true) { public function translation_exists($lang, $includeall = true) {
global $CFG;
if (strpos($lang, '_local') !== false) { if (strpos($lang, '_local') !== false) {
// _local packs are not real translations // _local packs are not real translations
return false; return false;
} }
if (!$includeall and !empty($CFG->langlist)) { if (!$includeall and !empty($this->translist)) {
$enabled = explode(',', $CFG->langlist); if (!in_array($lang, $this->translist)) {
if (!in_array($lang, $enabled)) {
return false; return false;
} }
} }
@ -6036,7 +6049,30 @@ class core_string_manager implements string_manager {
$languages = array(); $languages = array();
//TODO: add some translist cache stored in normal cache dir if ($CFG->langcache and is_readable($this->menucache)) {
// try to re-use the cached list of all available languages
$cachedlist = json_decode(file_get_contents($this->menucache), true);
if (is_array($cachedlist) and !empty($cachedlist)) {
// the cache file is restored correctly
if (!$returnall and !empty($this->translist)) {
// return just enabled translations
foreach ($cachedlist as $langcode => $langname) {
if (in_array($langcode, $this->translist)) {
$languages[$langcode] = $langname;
}
}
return $languages;
} else {
// return all translations
return $cachedlist;
}
}
}
// the cached list of languages is not available, let us populate the list
if (!$returnall and !empty($this->translist)) { if (!$returnall and !empty($this->translist)) {
// return only some translations // return only some translations
@ -6080,6 +6116,12 @@ class core_string_manager implements string_manager {
} }
unset($string); unset($string);
} }
if ($CFG->langcache and !empty($this->menucache)) {
// cache the list so that it can be used next time
textlib_get_instance()->asort($languages);
file_put_contents($this->menucache, json_encode($languages));
}
} }
textlib_get_instance()->asort($languages); textlib_get_instance()->asort($languages);
@ -6111,8 +6153,16 @@ class core_string_manager implements string_manager {
global $CFG; global $CFG;
require_once("$CFG->libdir/filelib.php"); require_once("$CFG->libdir/filelib.php");
// clear the on-disk disk with aggregated string files
fulldelete($this->cacheroot); fulldelete($this->cacheroot);
// clear the in-memory cache of loaded strings
$this->cache = array(); $this->cache = array();
// clear the cache containing the list of available translations
// and re-populate it again
fulldelete($this->menucache);
$this->get_list_of_translations(true);
} }
} }

View file

@ -1290,7 +1290,6 @@ function upgrade_language_pack($lang='') {
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED) $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
if ($status == COMPONENT_INSTALLED) { if ($status == COMPONENT_INSTALLED) {
remove_dir($CFG->dataroot.'/cache/languages');
if ($parentlang = get_parent_language($lang)) { if ($parentlang = get_parent_language($lang)) {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $parentlang.'.zip', 'languages.md5', 'lang')) { if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $parentlang.'.zip', 'languages.md5', 'lang')) {
$cd->install(); $cd->install();