Skip to content

Commit

Permalink
MDL-26804 core_string_manager::get_list_of_translations() can use a c…
Browse files Browse the repository at this point in the history
…ache 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.
  • Loading branch information
mudrd8mz authored and stronk7 committed Mar 28, 2011
1 parent 1a6a148 commit 91a4b3b
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 17 deletions.
5 changes: 0 additions & 5 deletions admin/langimport.php
Expand Up @@ -53,11 +53,6 @@
define('DELETION_OF_SELECTED_LANG', 4);
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();

$notice_ok = array();
Expand Down
2 changes: 1 addition & 1 deletion admin/settings/language.php
Expand Up @@ -10,7 +10,7 @@
$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_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_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')));
Expand Down
7 changes: 7 additions & 0 deletions config-dist.php
Expand Up @@ -357,6 +357,13 @@
//
// $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
// want to have initial error messages for eventual database connection problems
// localized too, you have to set your language code here.
Expand Down
2 changes: 1 addition & 1 deletion lang/en/admin.php
Expand Up @@ -246,7 +246,6 @@
$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['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['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';
Expand Down Expand Up @@ -632,6 +631,7 @@
$string['keeptagnamecase'] = 'Keep tag name casing';
$string['lang'] = 'Default language';
$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['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.';
Expand Down
1 change: 0 additions & 1 deletion lang/en/error.php
Expand Up @@ -61,7 +61,6 @@
$string['cannotdeletecustomfield'] = 'Error deleting custom field data';
$string['cannotdeletedir'] = 'Cannot delete ({$a})';
$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['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.';
Expand Down
66 changes: 58 additions & 8 deletions lib/moodlelib.php
Expand Up @@ -5484,17 +5484,28 @@ function get_string_manager($forcereload=false) {
}
if ($singleton === null) {
if (empty($CFG->early_install_lang)) {

if (empty($CFG->langcacheroot)) {
$langcacheroot = $CFG->dataroot . '/cache/lang';
} else {
$langcacheroot = $CFG->langcacheroot;
}

if (empty($CFG->langlist)) {
$translist = array();
} else {
$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 {
$singleton = new install_string_manager();
}
Expand Down Expand Up @@ -5624,22 +5635,26 @@ class core_string_manager implements string_manager {
protected $usediskcache;
/* @var array limit list of translations */
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 $localroot usually the same as $otherroot
* @param string $cacheroot usually lang dir in cache folder
* @param bool $usediskcache use disk cache
* @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->localroot = $localroot;
$this->cacheroot = $cacheroot;
$this->usediskcache = $usediskcache;
$this->translist = $translist;
$this->menucache = $menucache;
}

/**
Expand Down Expand Up @@ -6007,15 +6022,13 @@ public function get_list_of_languages($lang = NULL, $standard = 'iso6391') {
* @return boot true if exists
*/
public function translation_exists($lang, $includeall = true) {
global $CFG;

if (strpos($lang, '_local') !== false) {
// _local packs are not real translations
return false;
}
if (!$includeall and !empty($CFG->langlist)) {
$enabled = explode(',', $CFG->langlist);
if (!in_array($lang, $enabled)) {
if (!$includeall and !empty($this->translist)) {
if (!in_array($lang, $this->translist)) {
return false;
}
}
Expand All @@ -6036,7 +6049,30 @@ public function get_list_of_translations($returnall = false) {

$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)) {
// return only some translations
Expand Down Expand Up @@ -6080,6 +6116,12 @@ public function get_list_of_translations($returnall = false) {
}
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);
Expand Down Expand Up @@ -6111,8 +6153,16 @@ public function reset_caches() {
global $CFG;
require_once("$CFG->libdir/filelib.php");

// clear the on-disk disk with aggregated string files
fulldelete($this->cacheroot);

// clear the in-memory cache of loaded strings
$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);
}
}

Expand Down
1 change: 0 additions & 1 deletion lib/upgradelib.php
Expand Up @@ -1290,7 +1290,6 @@ function upgrade_language_pack($lang='') {
$status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)

if ($status == COMPONENT_INSTALLED) {
remove_dir($CFG->dataroot.'/cache/languages');
if ($parentlang = get_parent_language($lang)) {
if ($cd = new component_installer('http://download.moodle.org', 'langpack/2.0', $parentlang.'.zip', 'languages.md5', 'lang')) {
$cd->install();
Expand Down

0 comments on commit 91a4b3b

Please sign in to comment.