2 ///This file only manages the installation of 2.0 lang packs.
3 ///in downloads.moodle.org, they are store in separate directory /lang20
4 ///in local server, they are stored in $CFG->dataroot/lang
5 ///This helps to avoid confusion.
7 die('Work in progress, to be replaced by the new language update interface...');
9 require_once('../config.php');
10 require_once($CFG->libdir.'/adminlib.php');
11 require_once($CFG->libdir.'/filelib.php');
12 require_once($CFG->libdir.'/componentlib.class.php');
14 admin_externalpage_setup('langimport');
16 if (!empty($CFG->skiplangupgrade)) {
17 echo $OUTPUT->header();
18 echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
19 echo $OUTPUT->footer();
23 $mode = optional_param('mode', 0, PARAM_INT); //phase
24 $pack = optional_param('pack', array(), PARAM_FILE); //pack to install
26 $uninstalllang = optional_param('uninstalllang', '', PARAM_FILE);
27 $confirm = optional_param('confirm', 0, PARAM_BOOL);
28 $sitelang = optional_param('sitelangconfig', '', PARAM_FILE);
30 define('INSTALLATION_OF_SELECTED_LANG', 2);
31 define('DELETION_OF_SELECTED_LANG', 4);
32 define('UPDATE_ALL_LANG', 5);
34 $strlang = get_string('langimport','admin');
35 $strlanguage = get_string('language');
36 $strthislanguage = get_string('thislanguage', 'langconfig');
39 //reset and diagnose lang cache permissions
40 @unlink($CFG->dataroot.'/cache/languages');
41 if (file_exists($CFG->dataroot.'/cache/languages')) {
42 print_error('cannotdeletelangcache', 'error');
44 get_list_of_languages(true); //refresh lang cache
47 $notice_error = array();
51 case INSTALLATION_OF_SELECTED_LANG: ///installation of selected language pack
53 if (confirm_sesskey() and !empty($pack)) {
55 @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions); //make it in case it's a fresh install, it might not be there
56 @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
58 if (is_array($pack)) {
61 $packs = array($pack);
64 foreach ($packs as $pack) {
65 if ($cd = new component_installer('http://download.moodle.org', 'lang20',
66 $pack.'.zip', 'languages.md5', 'lang')) {
67 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
71 if ($cd->get_error() == 'remotedownloaderror') {
73 $a->url = 'http://download.moodle.org/lang20/'.$pack.'.zip';
74 $a->dest= $CFG->dataroot.'/lang';
75 print_error($cd->get_error(), 'error', 'langimport.php', $a);
77 print_error($cd->get_error(), 'error', 'langimport.php');
81 case COMPONENT_INSTALLED:
82 $notice_ok[] = get_string('langpackinstalled','admin',$pack);
83 if ($parentlang = get_parent_language($pack)) {
84 // install also parent pack if specified
85 if ($cd = new component_installer('http://download.moodle.org', 'lang20', $parentlang.'.zip', 'languages.md5', 'lang')) {
91 case COMPONENT_UPTODATE:
96 echo $OUTPUT->notification('Had an unspecified error with the component installer, sorry.');
102 case DELETION_OF_SELECTED_LANG: //delete a directory(ies) containing a lang pack completely
104 if ($uninstalllang == 'en') {
105 $notice_error[] = 'en can not be uninstalled!';
107 } else if (!$confirm && confirm_sesskey()) {
108 echo $OUTPUT->header();
109 echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
110 'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
112 echo $OUTPUT->footer();
115 } else if (confirm_sesskey()) {
116 $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
117 $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
120 if (file_exists($dest1)){
121 $rm1 = remove_dir($dest1);
123 if (file_exists($dest2)){
124 $rm2 = remove_dir($dest2);
126 get_list_of_languages(true); //refresh lang cache
127 //delete the direcotries
129 $notice_ok[] = get_string('langpackremoved','admin');
130 } else { //nothing deleted, possibly due to permission error
131 $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
136 case UPDATE_ALL_LANG: //1 click update for all updatable language packs
139 //0th pull a list from download.moodle.org,
140 //key = langname, value = md5
142 $updated = 0; //any packs updated?
143 $alllangs = array_keys(get_list_of_languages(false, true)); //get all available langs
144 $lang20 = array(); //all the Moodle 1.6 unicode lang packs (updated and not updated)
145 $packs = array(); //all the packs that needs updating
148 if (!$availablelangs = get_remote_list_of_languages()) {
149 print_error('cannotdownloadlanguageupdatelist', 'error');
152 //and build an associative array
153 foreach ($availablelangs as $alang) {
154 $md5array[$alang[0]] = $alang[1];
157 //filtering out non-16 and unofficial packs
158 foreach ($alllangs as $clang) {
159 if (!array_key_exists($clang, $md5array)) {
160 $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
163 $dest1 = $CFG->dataroot.'/lang/'.$clang;
164 $dest2 = $CFG->dirroot.'/lang/'.$clang;
166 if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
171 //then filter out packs that have the same md5 key
172 foreach ($lang20 as $clang) {
173 if (!is_installed_lang($clang, $md5array[$clang])){
178 @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);
179 @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
180 foreach ($packs as $pack){ //for each of the remaining in the list, we
181 if ($pack == 'en') { // no update for en
185 //1. delete old director(ies)
187 $dest1 = $CFG->dataroot.'/lang/'.$pack;
188 $dest2 = $CFG->dirroot.'/lang/'.$pack;
191 if (file_exists($dest1)) {
192 if (!remove_dir($dest1)) {
193 $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
197 if (file_exists($dest2)) {
198 if (!remove_dir($dest2)) {
199 $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
204 //2. copy & unzip into new
206 if ($cd = new component_installer('http://download.moodle.org', 'lang20',
207 $pack.'.zip', 'languages.md5', 'lang')) {
208 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
211 case COMPONENT_ERROR:
212 if ($cd->get_error() == 'remotedownloaderror') {
214 $a->url = 'http://download.moodle.org/lang20/'.$pack.'.zip';
215 $a->dest= $CFG->dataroot.'/lang';
216 print_error($cd->get_error(), 'error', "", $a); // not probable
218 print_error($cd->get_error(), 'error'); // not probable
221 case COMPONENT_UPTODATE:
222 //Print error string or whatever you want to do
224 case COMPONENT_INSTALLED:
225 $notice_ok[] = get_string('langpackupdated', 'admin', $pack);
227 //Print/do whatever you want
237 $notice_ok[] = get_string('langupdatecomplete','admin');
239 $notice_ok[] = get_string('nolangupdateneeded','admin');
243 } //close of main switch
246 echo $OUTPUT->header();
248 $installedlangs = get_list_of_languages(true, true);
250 $missingparents = array();
251 $oldlang = isset($SESSION->lang) ? $SESSION->lang : null; // override current lang
253 foreach($installedlangs as $l=>$unused) {
255 $parent = get_string('parentlanguage', 'langconfig');
256 if ($parent == 'en') {
259 if (strpos($parent, '[[') !== false) {
260 continue; // no parent
262 if (!isset($installedlangs[$parent])) {
263 $missingparents[$l] = $parent;
266 if (isset($oldlang)) {
267 $SESSION->lang = $oldlang;
269 unset($SESSION->lang);
272 if ($availablelangs = get_remote_list_of_languages()) {
275 $remote = 0; //flag for reading from remote or local
276 $availablelangs = get_local_list_of_languages();
280 echo $OUTPUT->box_start();
281 print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
282 echo $OUTPUT->box_end();
286 $info = implode('<br />', $notice_ok);
287 echo $OUTPUT->notification($info, 'notifysuccess');
291 $info = implode('<br />', $notice_error);
292 echo $OUTPUT->notification($info, 'notifyproblem');
295 if ($missingparents) {
296 foreach ($missingparents as $l=>$parent) {
298 $a->lang = $installedlangs[$l];
299 $a->parent = $parent;
300 foreach ($availablelangs as $alang) {
301 if ($alang[0] == $parent) {
302 $shortlang = $alang[0];
303 $a->parent = $alang[2].' ('.$shortlang.')';
306 $info = get_string('missinglangparent', 'admin', $a);
307 echo $OUTPUT->notification($info, 'notifyproblem');
311 echo $OUTPUT->box_start();
312 echo '<table summary="">';
313 echo '<tr><td align="center" valign="top">';
314 echo '<form id="uninstallform" action="langimport.php?mode='.DELETION_OF_SELECTED_LANG.'" method="post">';
315 echo '<fieldset class="invisiblefieldset">';
316 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
318 /// display installed langs here
320 echo '<label for="uninstalllang">'.get_string('installedlangs','admin')."</label><br />\n";
321 echo '<select name="uninstalllang" id="uninstalllang" size="15">';
322 foreach ($installedlangs as $clang =>$ilang){
323 echo '<option value="'.$clang.'">'.$ilang.'</option>';
326 echo '<br /><input type="submit" value="'.get_string('uninstall','admin').'" />';
331 echo '<form id="updateform" action="langimport.php?mode='.UPDATE_ALL_LANG.'" method="post">';
333 echo '<br /><input type="submit" value="'.get_string('updatelangs','admin').'" />';
338 /// Display option to change site language
340 /// display to be installed langs here
342 echo '</td><td align="center" valign="top">';
343 //availabe langs table
344 $empty = 1; //something to pring
346 /// if this language pack is not already installed, then we allow installation
348 echo '<form id="installform" method="post" action="langimport.php?mode='.INSTALLATION_OF_SELECTED_LANG.'">';
349 echo '<fieldset class="invisiblefieldset">';
350 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
351 echo '<label for="pack">'.get_string('availablelangs','admin')."</label><br />\n";
353 echo '<select name="pack[]" id="pack" size="15" multiple="multiple">';
356 foreach ($availablelangs as $alang) {
357 if ($alang[0] == '') {
360 if (trim($alang[0]) != "en") {
362 $shortlang = $alang[0];
363 if (!is_installed_lang($alang[0], $alang[1])){ //if not already installed
364 echo '<option value="'.$alang[0].'">'.$alang[2].' ('.$shortlang.')</option>';
366 } else { //print list in local format, and instruction to install
367 echo '<tr><td>'.$alang[2].'</td><td><a href="http://download.moodle.org/lang20/'.$alang[0].'.zip">'.get_string('download','admin').'</a></td></tr>';
374 echo '<br /><input type="submit" value="'.$OUTPUT->larrow().' '.get_string('install','admin').'" />';
381 print_string('nolanguagetodownload','admin');
384 //close available langs table
385 echo '</td></tr></table>';
386 echo $OUTPUT->box_end();
388 echo $OUTPUT->footer();
391 * Returns a list of available language packs from a
392 * local copy shipped with standard moodle distro
393 * this is for site that can't download components.
396 function get_local_list_of_languages() {
398 $source = $CFG->dirroot.'/lib/languages.md5';
399 $availablelangs = array();
400 if ($fp = fopen($source, 'r')) {
402 $availablelangs[] = split(',', fgets($fp,1024));
405 return $availablelangs;
409 * checks the md5 of the zip file, grabbed from download.moodle.org,
410 * against the md5 of the local language file from last update
411 * @param string $lang
412 * @param string $md5check
415 function is_installed_lang($lang, $md5check) {
417 $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
418 if (file_exists($md5file)){
419 return (file_get_contents($md5file) == $md5check);
425 * Returns the latest list of available language packs from
427 * @return array or false if can not download
429 function get_remote_list_of_languages() {
430 $source = 'http://download.moodle.org/lang20/languages.md5';
431 $availablelangs = array();
433 if ($content = download_file_content($source)) {
434 $alllines = split("\n", $content);
435 foreach($alllines as $line) {
437 $availablelangs[] = split(',', $line);
440 return $availablelangs;