MDL-22061 workaround for special handling of parentlanguage string
[moodle.git] / admin / langimport.php
CommitLineData
20207b82 1<?php
3a915b06
PS
2///This file only manages the installation of 2.0 lang packs.
3///in downloads.moodle.org, they are store in separate directory /lang20
6e113a15 4///in local server, they are stored in $CFG->dataroot/lang
5///This helps to avoid confusion.
6
3a915b06
PS
7die('Work in progress, to be replaced by the new language update interface...');
8
636c2c08 9 require_once('../config.php');
6e4dc10f 10 require_once($CFG->libdir.'/adminlib.php');
a7d43f0d 11 require_once($CFG->libdir.'/filelib.php');
12 require_once($CFG->libdir.'/componentlib.class.php');
1ae083e4 13
14 admin_externalpage_setup('langimport');
636c2c08 15
f9a064f9 16 if (!empty($CFG->skiplangupgrade)) {
61ef8f9f 17 echo $OUTPUT->header();
20486a5a 18 echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
73d6f52f 19 echo $OUTPUT->footer();
f9a064f9 20 die;
21 }
22
636c2c08 23 $mode = optional_param('mode', 0, PARAM_INT); //phase
7b7b8b36 24 $pack = optional_param('pack', array(), PARAM_FILE); //pack to install
636c2c08 25 $displaylang = $pack;
26 $uninstalllang = optional_param('uninstalllang', '', PARAM_FILE);
27 $confirm = optional_param('confirm', 0, PARAM_BOOL);
28 $sitelang = optional_param('sitelangconfig', '', PARAM_FILE);
29
6e113a15 30 define('INSTALLATION_OF_SELECTED_LANG', 2);
6e113a15 31 define('DELETION_OF_SELECTED_LANG', 4);
32 define('UPDATE_ALL_LANG', 5);
d6d04971 33
a7d43f0d 34 $strlang = get_string('langimport','admin');
35 $strlanguage = get_string('language');
f62493d8 36 $strthislanguage = get_string('thislanguage', 'langconfig');
a7d43f0d 37 $title = $strlang;
d6d04971 38
0a5ce9dd 39 //reset and diagnose lang cache permissions
40 @unlink($CFG->dataroot.'/cache/languages');
41 if (file_exists($CFG->dataroot.'/cache/languages')) {
4fd532ea 42 print_error('cannotdeletelangcache', 'error');
0a5ce9dd 43 }
44 get_list_of_languages(true); //refresh lang cache
6e113a15 45
a7d43f0d 46 $notice_ok = array();
47 $notice_error = array();
48
6e113a15 49 switch ($mode){
d6d04971 50
6e113a15 51 case INSTALLATION_OF_SELECTED_LANG: ///installation of selected language pack
d6d04971 52
7b7b8b36 53 if (confirm_sesskey() and !empty($pack)) {
54 set_time_limit(0);
c9a433cd 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);
d6d04971 57
7b7b8b36 58 if (is_array($pack)) {
59 $packs = $pack;
60 } else {
61 $packs = array($pack);
62 }
63
64 foreach ($packs as $pack) {
3a915b06 65 if ($cd = new component_installer('http://download.moodle.org', 'lang20',
7b7b8b36 66 $pack.'.zip', 'languages.md5', 'lang')) {
67 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
68 switch ($status) {
69
70 case COMPONENT_ERROR:
71 if ($cd->get_error() == 'remotedownloaderror') {
72 $a = new object();
3a915b06 73 $a->url = 'http://download.moodle.org/lang20/'.$pack.'.zip';
7b7b8b36 74 $a->dest= $CFG->dataroot.'/lang';
dcd68962 75 print_error($cd->get_error(), 'error', 'langimport.php', $a);
7b7b8b36 76 } else {
dcd68962 77 print_error($cd->get_error(), 'error', 'langimport.php');
7b7b8b36 78 }
79 break;
80
81 case COMPONENT_INSTALLED:
82 $notice_ok[] = get_string('langpackinstalled','admin',$pack);
07f67118 83 if ($parentlang = get_parent_language($pack)) {
84 // install also parent pack if specified
3a915b06 85 if ($cd = new component_installer('http://download.moodle.org', 'lang20', $parentlang.'.zip', 'languages.md5', 'lang')) {
07f67118 86 $cd->install();
87 }
88 }
7b7b8b36 89 break;
90
91 case COMPONENT_UPTODATE:
92 break;
1c6f450c 93
7b7b8b36 94 }
95 } else {
8fbce1c8 96 echo $OUTPUT->notification('Had an unspecified error with the component installer, sorry.');
6e113a15 97 }
98 }
99 }
100 break;
101
6e113a15 102 case DELETION_OF_SELECTED_LANG: //delete a directory(ies) containing a lang pack completely
103
3a915b06
PS
104 if ($uninstalllang == 'en') {
105 $notice_error[] = 'en can not be uninstalled!';
a7d43f0d 106
107 } else if (!$confirm && confirm_sesskey()) {
61ef8f9f 108 echo $OUTPUT->header();
414a4a91 109 echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
110 'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
004bd0cc 111 'langimport.php');
73d6f52f 112 echo $OUTPUT->footer();
a7d43f0d 113 die;
114
004bd0cc 115 } else if (confirm_sesskey()) {
6e113a15 116 $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
117 $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
118 $rm1 = false;
119 $rm2 = false;
120 if (file_exists($dest1)){
121 $rm1 = remove_dir($dest1);
122 }
123 if (file_exists($dest2)){
124 $rm2 = remove_dir($dest2);
125 }
0a5ce9dd 126 get_list_of_languages(true); //refresh lang cache
6e113a15 127 //delete the direcotries
128 if ($rm1 or $rm2) {
a7d43f0d 129 $notice_ok[] = get_string('langpackremoved','admin');
6e113a15 130 } else { //nothing deleted, possibly due to permission error
a7d43f0d 131 $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
6e113a15 132 }
133 }
134 break;
d6d04971 135
6e113a15 136 case UPDATE_ALL_LANG: //1 click update for all updatable language packs
7b7b8b36 137 set_time_limit(0);
6e113a15 138
139 //0th pull a list from download.moodle.org,
140 //key = langname, value = md5
6e113a15 141 $md5array = array();
ecb454fe 142 $updated = 0; //any packs updated?
0a5ce9dd 143 $alllangs = array_keys(get_list_of_languages(false, true)); //get all available langs
3a915b06 144 $lang20 = array(); //all the Moodle 1.6 unicode lang packs (updated and not updated)
6e113a15 145 $packs = array(); //all the packs that needs updating
146
28dad8b9 147
a7d43f0d 148 if (!$availablelangs = get_remote_list_of_languages()) {
4fd532ea 149 print_error('cannotdownloadlanguageupdatelist', 'error');
6e113a15 150 }
28dad8b9 151
6e113a15 152 //and build an associative array
153 foreach ($availablelangs as $alang) {
154 $md5array[$alang[0]] = $alang[1];
155 }
156
a7d43f0d 157 //filtering out non-16 and unofficial packs
6e113a15 158 foreach ($alllangs as $clang) {
a7d43f0d 159 if (!array_key_exists($clang, $md5array)) {
160 $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
161 continue;
162 }
6e113a15 163 $dest1 = $CFG->dataroot.'/lang/'.$clang;
164 $dest2 = $CFG->dirroot.'/lang/'.$clang;
165
166 if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
3a915b06 167 $lang20[] = $clang;
6e113a15 168 }
169 }
170
171 //then filter out packs that have the same md5 key
3a915b06 172 foreach ($lang20 as $clang) {
6e113a15 173 if (!is_installed_lang($clang, $md5array[$clang])){
174 $packs[] = $clang;
175 }
176 }
177
c9a433cd 178 @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);
179 @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
6e113a15 180 foreach ($packs as $pack){ //for each of the remaining in the list, we
3a915b06 181 if ($pack == 'en') { // no update for en
ee14d736 182 continue;
183 }
a7d43f0d 184
6e113a15 185 //1. delete old director(ies)
186
187 $dest1 = $CFG->dataroot.'/lang/'.$pack;
188 $dest2 = $CFG->dirroot.'/lang/'.$pack;
189 $rm1 = false;
190 $rm2 = false;
191 if (file_exists($dest1)) {
a7d43f0d 192 if (!remove_dir($dest1)) {
193 $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
194 continue;
195 }
6e113a15 196 }
197 if (file_exists($dest2)) {
a7d43f0d 198 if (!remove_dir($dest2)) {
199 $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
200 continue;
201 }
6e113a15 202 }
203
204 //2. copy & unzip into new
205
3a915b06 206 if ($cd = new component_installer('http://download.moodle.org', 'lang20',
1c6f450c 207 $pack.'.zip', 'languages.md5', 'lang')) {
f85236dc 208 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
1c6f450c 209 switch ($status) {
210
f85236dc 211 case COMPONENT_ERROR:
a7d43f0d 212 if ($cd->get_error() == 'remotedownloaderror') {
1c6f450c 213 $a = new stdClass();
3a915b06 214 $a->url = 'http://download.moodle.org/lang20/'.$pack.'.zip';
1c6f450c 215 $a->dest= $CFG->dataroot.'/lang';
dcd68962 216 print_error($cd->get_error(), 'error', "", $a); // not probable
1c6f450c 217 } else {
dcd68962 218 print_error($cd->get_error(), 'error'); // not probable
6e113a15 219 }
1c6f450c 220 break;
f85236dc 221 case COMPONENT_UPTODATE:
1c6f450c 222 //Print error string or whatever you want to do
223 break;
f85236dc 224 case COMPONENT_INSTALLED:
a7d43f0d 225 $notice_ok[] = get_string('langpackupdated', 'admin', $pack);
1c6f450c 226 $updated = true;
227 //Print/do whatever you want
228 break;
229 default:
6e113a15 230 }
1c6f450c 231 } else {
232
6e113a15 233 }
234 }
235
6e113a15 236 if ($updated) {
a7d43f0d 237 $notice_ok[] = get_string('langupdatecomplete','admin');
6e113a15 238 } else {
a7d43f0d 239 $notice_ok[] = get_string('nolangupdateneeded','admin');
6e113a15 240 }
6e113a15 241
242 break;
a7d43f0d 243 } //close of main switch
d6d04971 244
6e113a15 245
61ef8f9f 246 echo $OUTPUT->header();
6e113a15 247
a7d43f0d 248 $installedlangs = get_list_of_languages(true, true);
d6d04971 249
7b7b8b36 250 $missingparents = array();
251 $oldlang = isset($SESSION->lang) ? $SESSION->lang : null; // override current lang
252
253 foreach($installedlangs as $l=>$unused) {
254 $SESSION->lang = $l;
c9042db5 255 $parent = get_string('parentlanguage', 'langconfig');
c2ed166e 256 if ($parent === 'en') {
7b7b8b36 257 continue;
258 }
7b7b8b36 259 if (!isset($installedlangs[$parent])) {
260 $missingparents[$l] = $parent;
261 }
262 }
263 if (isset($oldlang)) {
264 $SESSION->lang = $oldlang;
265 } else {
266 unset($SESSION->lang);
267 }
268
a7d43f0d 269 if ($availablelangs = get_remote_list_of_languages()) {
270 $remote = 1;
271 } else {
272 $remote = 0; //flag for reading from remote or local
273 $availablelangs = get_local_list_of_languages();
274 }
6e113a15 275
a7d43f0d 276 if (!$remote) {
20486a5a 277 echo $OUTPUT->box_start();
a7d43f0d 278 print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
20486a5a 279 echo $OUTPUT->box_end();
a7d43f0d 280 }
6e113a15 281
a7d43f0d 282 if ($notice_ok) {
283 $info = implode('<br />', $notice_ok);
8fbce1c8 284 echo $OUTPUT->notification($info, 'notifysuccess');
a7d43f0d 285 }
6e113a15 286
a7d43f0d 287 if ($notice_error) {
288 $info = implode('<br />', $notice_error);
8fbce1c8 289 echo $OUTPUT->notification($info, 'notifyproblem');
a7d43f0d 290 }
291
7b7b8b36 292 if ($missingparents) {
293 foreach ($missingparents as $l=>$parent) {
294 $a = new object();
295 $a->lang = $installedlangs[$l];
296 $a->parent = $parent;
297 foreach ($availablelangs as $alang) {
298 if ($alang[0] == $parent) {
3a915b06 299 $shortlang = $alang[0];
7b7b8b36 300 $a->parent = $alang[2].' ('.$shortlang.')';
301 }
302 }
303 $info = get_string('missinglangparent', 'admin', $a);
8fbce1c8 304 echo $OUTPUT->notification($info, 'notifyproblem');
7b7b8b36 305 }
306 }
307
20486a5a 308 echo $OUTPUT->box_start();
a7d43f0d 309 echo '<table summary="">';
310 echo '<tr><td align="center" valign="top">';
311 echo '<form id="uninstallform" action="langimport.php?mode='.DELETION_OF_SELECTED_LANG.'" method="post">';
312 echo '<fieldset class="invisiblefieldset">';
313 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
314
315 /// display installed langs here
316
317 echo '<label for="uninstalllang">'.get_string('installedlangs','admin')."</label><br />\n";
318 echo '<select name="uninstalllang" id="uninstalllang" size="15">';
319 foreach ($installedlangs as $clang =>$ilang){
320 echo '<option value="'.$clang.'">'.$ilang.'</option>';
321 }
322 echo '</select>';
323 echo '<br /><input type="submit" value="'.get_string('uninstall','admin').'" />';
324 echo '</fieldset>';
325 echo '</form>';
326
327 if ($remote) {
328 echo '<form id="updateform" action="langimport.php?mode='.UPDATE_ALL_LANG.'" method="post">';
329 echo '<div>';
330 echo '<br /><input type="submit" value="'.get_string('updatelangs','admin').'" />';
331 echo '</div>';
332 echo '</form>';
333 }
334
335 /// Display option to change site language
336
337 /// display to be installed langs here
338
339 echo '</td><td align="center" valign="top">';
340 //availabe langs table
341 $empty = 1; //something to pring
342
343 /// if this language pack is not already installed, then we allow installation
344
345 echo '<form id="installform" method="post" action="langimport.php?mode='.INSTALLATION_OF_SELECTED_LANG.'">';
346 echo '<fieldset class="invisiblefieldset">';
347 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
348 echo '<label for="pack">'.get_string('availablelangs','admin')."</label><br />\n";
349 if ($remote) {
7b7b8b36 350 echo '<select name="pack[]" id="pack" size="15" multiple="multiple">';
a7d43f0d 351 }
6e113a15 352
a7d43f0d 353 foreach ($availablelangs as $alang) {
354 if ($alang[0] == '') {
355 continue;
356 }
3a915b06 357 if (trim($alang[0]) != "en") {
a7d43f0d 358 if ($remote) {
3a915b06 359 $shortlang = $alang[0];
a7d43f0d 360 if (!is_installed_lang($alang[0], $alang[1])){ //if not already installed
361 echo '<option value="'.$alang[0].'">'.$alang[2].' ('.$shortlang.')</option>';
362 }
363 } else { //print list in local format, and instruction to install
3a915b06 364 echo '<tr><td>'.$alang[2].'</td><td><a href="http://download.moodle.org/lang20/'.$alang[0].'.zip">'.get_string('download','admin').'</a></td></tr>';
6e113a15 365 }
a7d43f0d 366 $empty = 0;
367 }
368 }
369 if ($remote) {
370 echo '</select>';
92e01ab7 371 echo '<br /><input type="submit" value="'.$OUTPUT->larrow().' '.get_string('install','admin').'" />';
a7d43f0d 372 }
373 echo '</fieldset>';
374 echo '</form>';
6e113a15 375
a7d43f0d 376 if ($empty) {
377 echo '<br />';
378 print_string('nolanguagetodownload','admin');
379 }
6e113a15 380
a7d43f0d 381 //close available langs table
382 echo '</td></tr></table>';
20486a5a 383 echo $OUTPUT->box_end();
6e113a15 384
73d6f52f 385 echo $OUTPUT->footer();
d6d04971 386
a7d43f0d 387 /**
388 * Returns a list of available language packs from a
6e113a15 389 * local copy shipped with standard moodle distro
76bd786d 390 * this is for site that can't download components.
6e113a15 391 * @return array
392 */
393 function get_local_list_of_languages() {
394 global $CFG;
a7d43f0d 395 $source = $CFG->dirroot.'/lib/languages.md5';
6e113a15 396 $availablelangs = array();
a7d43f0d 397 if ($fp = fopen($source, 'r')) {
6e113a15 398 while(!feof ($fp)) {
399 $availablelangs[] = split(',', fgets($fp,1024));
400 }
401 }
402 return $availablelangs;
403 }
d6d04971 404
a7d43f0d 405 /**
406 * checks the md5 of the zip file, grabbed from download.moodle.org,
6e113a15 407 * against the md5 of the local language file from last update
408 * @param string $lang
409 * @param string $md5check
410 * @return bool
411 */
412 function is_installed_lang($lang, $md5check) {
413 global $CFG;
414 $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
415 if (file_exists($md5file)){
416 return (file_get_contents($md5file) == $md5check);
417 }
418 return false;
419 }
d6d04971 420
a7d43f0d 421 /**
422 * Returns the latest list of available language packs from
423 * moodle.org
424 * @return array or false if can not download
425 */
426 function get_remote_list_of_languages() {
3a915b06 427 $source = 'http://download.moodle.org/lang20/languages.md5';
6e1cc99d 428 $availablelangs = array();
28dad8b9 429
a7d43f0d 430 if ($content = download_file_content($source)) {
6e1cc99d 431 $alllines = split("\n", $content);
a7d43f0d 432 foreach($alllines as $line) {
433 if (!empty($line)){
6e1cc99d 434 $availablelangs[] = split(',', $line);
28dad8b9 435 }
28dad8b9 436 }
6e1cc99d 437 return $availablelangs;
a7d43f0d 438
439 } else {
6e1cc99d 440 return false;
28dad8b9 441 }
28dad8b9 442 }
20207b82 443