Merge branch 'MDL-27174_MOODLE_19_STABLE' of git://github.com/nebgor/moodle into...
[moodle.git] / admin / langimport.php
blobbcffb56f04dd1837d631f1a80673eb7ab85d29a4
1 <?php //$Id$
2 ///This file only manages the installation of 1.6 lang packs.
3 ///in downloads.moodle.org, they are store in separate directory /lang16
4 ///in local server, they are stored in $CFG->dataroot/lang
5 ///This helps to avoid confusion.
7 require_once('../config.php');
8 require_once($CFG->libdir.'/adminlib.php');
9 require_once($CFG->libdir.'/filelib.php');
10 require_once($CFG->libdir.'/componentlib.class.php');
12 admin_externalpage_setup('langimport');
14 if (!empty($CFG->skiplangupgrade)) {
15 admin_externalpage_print_header();
16 print_box(get_string('langimportdisabled', 'admin'));
17 print_footer();
18 die;
21 $mode = optional_param('mode', 0, PARAM_INT); //phase
22 $pack = optional_param('pack', array(), PARAM_FILE); //pack to install
23 $displaylang = $pack;
24 $uninstalllang = optional_param('uninstalllang', '', PARAM_FILE);
25 $confirm = optional_param('confirm', 0, PARAM_BOOL);
26 $sitelang = optional_param('sitelangconfig', '', PARAM_FILE);
28 define('INSTALLATION_OF_SELECTED_LANG', 2);
29 define('DELETION_OF_SELECTED_LANG', 4);
30 define('UPDATE_ALL_LANG', 5);
32 $strlang = get_string('langimport','admin');
33 $strlanguage = get_string('language');
34 $strthislanguage = get_string('thislanguage');
35 $title = $strlang;
37 //reset and diagnose lang cache permissions
38 @unlink($CFG->dataroot.'/cache/languages');
39 if (file_exists($CFG->dataroot.'/cache/languages')) {
40 error('Language cache can not be deleted, please fix permissions in dataroot/cache/languages!');
42 get_list_of_languages(true); //refresh lang cache
44 $notice_ok = array();
45 $notice_error = array();
47 switch ($mode){
49 case INSTALLATION_OF_SELECTED_LANG: ///installation of selected language pack
51 if (confirm_sesskey() and !empty($pack)) {
52 set_time_limit(0);
53 @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions); //make it in case it's a fresh install, it might not be there
54 @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
56 if (is_array($pack)) {
57 $packs = $pack;
58 } else {
59 $packs = array($pack);
62 foreach ($packs as $pack) {
63 if ($cd = new component_installer('http://download.moodle.org', 'lang16',
64 $pack.'.zip', 'languages.md5', 'lang')) {
65 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
66 switch ($status) {
68 case COMPONENT_ERROR:
69 if ($cd->get_error() == 'remotedownloaderror') {
70 $a = new object();
71 $a->url = 'http://download.moodle.org/lang16/'.$pack.'.zip';
72 $a->dest= $CFG->dataroot.'/lang';
73 print_error($cd->get_error(), 'error', 'langimport.php', $a);
74 } else {
75 print_error($cd->get_error(), 'error', 'langimport.php');
77 break;
79 case COMPONENT_INSTALLED:
80 $notice_ok[] = get_string('langpackinstalled','admin',$pack);
81 break;
83 case COMPONENT_UPTODATE:
84 break;
87 } else {
88 notify('Had an unspecified error with the component installer, sorry.');
92 break;
94 case DELETION_OF_SELECTED_LANG: //delete a directory(ies) containing a lang pack completely
96 if ($uninstalllang == 'en_utf8') {
97 $notice_error[] = 'en_utf8 can not be uninstalled!';
99 } else if (!$confirm && confirm_sesskey()) {
100 admin_externalpage_print_header();
101 notice_yesno(get_string('uninstallconfirm', 'admin', $uninstalllang),
102 'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&amp;uninstalllang='.$uninstalllang.'&amp;confirm=1&amp;sesskey='.sesskey(),
103 'langimport.php');
104 print_footer();
105 die;
107 } else if (confirm_sesskey()) {
108 $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
109 $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
110 $rm1 = false;
111 $rm2 = false;
112 if (file_exists($dest1)){
113 $rm1 = remove_dir($dest1);
115 if (file_exists($dest2)){
116 $rm2 = remove_dir($dest2);
118 get_list_of_languages(true); //refresh lang cache
119 //delete the direcotries
120 if ($rm1 or $rm2) {
121 $notice_ok[] = get_string('langpackremoved','admin');
122 } else { //nothing deleted, possibly due to permission error
123 $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
126 break;
128 case UPDATE_ALL_LANG: //1 click update for all updatable language packs
129 set_time_limit(0);
131 //0th pull a list from download.moodle.org,
132 //key = langname, value = md5
133 $md5array = array();
134 $updated = 0; //any packs updated?
135 $alllangs = array_keys(get_list_of_languages(false, true)); //get all available langs
136 $lang16 = array(); //all the Moodle 1.6 unicode lang packs (updated and not updated)
137 $packs = array(); //all the packs that needs updating
140 if (!$availablelangs = get_remote_list_of_languages()) {
141 print_error('cannotdownloadlanguageupdatelist');
144 //and build an associative array
145 foreach ($availablelangs as $alang) {
146 $md5array[$alang[0]] = $alang[1];
149 //filtering out non-16 and unofficial packs
150 foreach ($alllangs as $clang) {
151 if (!array_key_exists($clang, $md5array)) {
152 $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
153 continue;
155 $dest1 = $CFG->dataroot.'/lang/'.$clang;
156 $dest2 = $CFG->dirroot.'/lang/'.$clang;
158 if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
159 $lang16[] = $clang;
163 //then filter out packs that have the same md5 key
164 foreach ($lang16 as $clang) {
165 if (!is_installed_lang($clang, $md5array[$clang])){
166 $packs[] = $clang;
170 @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);
171 @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
172 foreach ($packs as $pack){ //for each of the remaining in the list, we
173 if ($pack == 'en_utf8') { // no update for en_utf8
174 continue;
177 //1. delete old director(ies)
179 $dest1 = $CFG->dataroot.'/lang/'.$pack;
180 $dest2 = $CFG->dirroot.'/lang/'.$pack;
181 $rm1 = false;
182 $rm2 = false;
183 if (file_exists($dest1)) {
184 if (!remove_dir($dest1)) {
185 $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
186 continue;
189 if (file_exists($dest2)) {
190 if (!remove_dir($dest2)) {
191 $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
192 continue;
196 //2. copy & unzip into new
198 if ($cd = new component_installer('http://download.moodle.org', 'lang16',
199 $pack.'.zip', 'languages.md5', 'lang')) {
200 $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
201 switch ($status) {
203 case COMPONENT_ERROR:
204 if ($cd->get_error() == 'remotedownloaderror') {
205 $a = new stdClass();
206 $a->url = 'http://download.moodle.org/lang16/'.$pack.'.zip';
207 $a->dest= $CFG->dataroot.'/lang';
208 print_error($cd->get_error(), 'error', "", $a); // not probable
209 } else {
210 print_error($cd->get_error(), 'error'); // not probable
212 break;
213 case COMPONENT_UPTODATE:
214 //Print error string or whatever you want to do
215 break;
216 case COMPONENT_INSTALLED:
217 $notice_ok[] = get_string('langpackupdated', 'admin', $pack);
218 $updated = true;
219 //Print/do whatever you want
220 break;
221 default:
223 } else {
228 if ($updated) {
229 $notice_ok[] = get_string('langupdatecomplete','admin');
230 } else {
231 $notice_ok[] = get_string('nolangupdateneeded','admin');
234 break;
235 } //close of main switch
238 admin_externalpage_print_header();
240 $installedlangs = get_list_of_languages(true, true);
242 $missingparents = array();
243 $oldlang = isset($SESSION->lang) ? $SESSION->lang : null; // override current lang
245 foreach($installedlangs as $l=>$unused) {
246 $SESSION->lang = $l;
247 $parent = get_string('parentlanguage');
248 if ($parent == 'en_utf8') {
249 continue;
251 if (empty($parent) || strpos($parent, '[[') !== false) {
252 continue; // no parent
254 if (!isset($installedlangs[$parent])) {
255 $missingparents[$l] = $parent;
258 if (isset($oldlang)) {
259 $SESSION->lang = $oldlang;
260 } else {
261 unset($SESSION->lang);
264 if ($availablelangs = get_remote_list_of_languages()) {
265 $remote = 1;
266 } else {
267 $remote = 0; //flag for reading from remote or local
268 $availablelangs = get_local_list_of_languages();
271 if (!$remote) {
272 print_box_start();
273 print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
274 print_box_end();
277 if ($notice_ok) {
278 $info = implode('<br />', $notice_ok);
279 notify($info, 'notifysuccess');
282 if ($notice_error) {
283 $info = implode('<br />', $notice_error);
284 notify($info, 'notifyproblem');
287 if ($missingparents) {
288 foreach ($missingparents as $l=>$parent) {
289 $a = new object();
290 $a->lang = $installedlangs[$l];
291 $a->parent = $parent;
292 foreach ($availablelangs as $alang) {
293 if ($alang[0] == $parent) {
294 if (substr($alang[0], -5) == '_utf8') { //Remove the _utf8 suffix from the lang to show
295 $shortlang = substr($alang[0], 0, -5);
296 } else {
297 $shortlang = $alang[0];
299 $a->parent = $alang[2].' ('.$shortlang.')';
302 $info = get_string('missinglangparent', 'admin', $a);
303 notify($info, 'notifyproblem');
307 print_box_start();
308 echo '<table summary="">';
309 echo '<tr><td align="center" valign="top">';
310 echo '<form id="uninstallform" action="langimport.php?mode='.DELETION_OF_SELECTED_LANG.'" method="post">';
311 echo '<fieldset class="invisiblefieldset">';
312 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
314 /// display installed langs here
316 echo '<label for="uninstalllang">'.get_string('installedlangs','admin')."</label><br />\n";
317 echo '<select name="uninstalllang" id="uninstalllang" size="15">';
318 foreach ($installedlangs as $clang =>$ilang){
319 echo '<option value="'.$clang.'">'.$ilang.'</option>';
321 echo '</select>';
322 echo '<br /><input type="submit" value="'.get_string('uninstall','admin').'" />';
323 echo '</fieldset>';
324 echo '</form>';
326 if ($remote) {
327 echo '<form id="updateform" action="langimport.php?mode='.UPDATE_ALL_LANG.'" method="post">';
328 echo '<div>';
329 echo '<br /><input type="submit" value="'.get_string('updatelangs','admin').'" />';
330 echo '</div>';
331 echo '</form>';
334 /// Display option to change site language
336 /// display to be installed langs here
338 echo '</td><td align="center" valign="top">';
339 //availabe langs table
340 $empty = 1; //something to pring
342 /// if this language pack is not already installed, then we allow installation
344 echo '<form id="installform" method="post" action="langimport.php?mode='.INSTALLATION_OF_SELECTED_LANG.'">';
345 echo '<fieldset class="invisiblefieldset">';
346 echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
347 echo '<label for="pack">'.get_string('availablelangs','admin')."</label><br />\n";
348 if ($remote) {
349 echo '<select name="pack[]" id="pack" size="15" multiple="multiple">';
352 foreach ($availablelangs as $alang) {
353 if ($alang[0] == '') {
354 continue;
356 if (trim($alang[0]) != "en_utf8") {
357 if ($remote) {
358 if (substr($alang[0], -5) == '_utf8') { //Remove the _utf8 suffix from the lang to show
359 $shortlang = substr($alang[0], 0, -5);
360 } else {
361 $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/lang16/'.$alang[0].'.zip">'.get_string('download','admin').'</a></td></tr>';
369 $empty = 0;
372 if ($remote) {
373 echo '</select>';
374 echo '<br /><input type="submit" value="'.$THEME->larrow.' '.get_string('install','admin').'" />';
376 echo '</fieldset>';
377 echo '</form>';
379 if ($empty) {
380 echo '<br />';
381 print_string('nolanguagetodownload','admin');
384 //close available langs table
385 echo '</td></tr></table>';
386 print_box_end();
388 admin_externalpage_print_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.
394 * @return array
396 function get_local_list_of_languages() {
397 global $CFG;
398 $source = $CFG->dirroot.'/lib/languages.md5';
399 $availablelangs = array();
400 if ($fp = fopen($source, 'r')) {
401 while(!feof ($fp)) {
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
413 * @return bool
415 function is_installed_lang($lang, $md5check) {
416 global $CFG;
417 $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
418 if (file_exists($md5file)){
419 return (file_get_contents($md5file) == $md5check);
421 return false;
425 * Returns the latest list of available language packs from
426 * moodle.org
427 * @return array or false if can not download
429 function get_remote_list_of_languages() {
430 $source = 'http://download.moodle.org/lang16/languages.md5';
431 $availablelangs = array();
433 if ($content = download_file_content($source)) {
434 $alllines = split("\n", $content);
435 foreach($alllines as $line) {
436 if (!empty($line)){
437 $availablelangs[] = split(',', $line);
440 return $availablelangs;
442 } else {
443 return false;