Merge branch 'MDL-29064_21' of git://github.com/timhunt/moodle into MOODLE_21_STABLE
[moodle.git] / admin / langimport.php
blob4aa614b2193629ad3ede74ec14dad17c3a8fd8b5
1 <?php
3 // This file is part of Moodle - http://moodle.org/
4 //
5 // Moodle is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // Moodle is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
18 /**
19 * Fetches language packages from download.moodle.org server
21 * Language packages are available at http://download.moodle.org/langpack/
22 * in ZIP format together with a file languages.md5 containing their hashes
23 * and meta info.
24 * Locally, language packs are saved into $CFG->dataroot/lang/
26 * @package core
27 * @copyright 2005 Yu Zhang
28 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
31 require_once(dirname(dirname(__FILE__)).'/config.php');
32 require_once($CFG->libdir.'/adminlib.php');
33 require_once($CFG->libdir.'/filelib.php');
34 require_once($CFG->libdir.'/componentlib.class.php');
36 admin_externalpage_setup('langimport');
38 if (!empty($CFG->skiplangupgrade)) {
39 echo $OUTPUT->header();
40 echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
41 echo $OUTPUT->footer();
42 die;
45 $mode = optional_param('mode', 0, PARAM_INT); // action
46 $pack = optional_param('pack', array(), PARAM_SAFEDIR); // pack to install
47 $uninstalllang = optional_param('uninstalllang', '', PARAM_LANG); // installed pack to uninstall
48 $confirm = optional_param('confirm', 0, PARAM_BOOL); // uninstallation confirmation
50 define('INSTALLATION_OF_SELECTED_LANG', 2);
51 define('DELETION_OF_SELECTED_LANG', 4);
52 define('UPDATE_ALL_LANG', 5);
54 get_string_manager()->reset_caches();
56 $notice_ok = array();
57 $notice_error = array();
59 if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($pack)) {
60 set_time_limit(0);
61 make_upload_directory('temp');
62 make_upload_directory('lang');
64 $installer = new lang_installer($pack);
65 $results = $installer->run();
66 foreach ($results as $langcode => $langstatus) {
67 switch ($langstatus) {
68 case lang_installer::RESULT_DOWNLOADERROR:
69 $a = new stdClass();
70 $a->url = $installer->lang_pack_url($langcode);
71 $a->dest = $CFG->dataroot.'/lang';
72 print_error('remotedownloaderror', 'error', 'langimport.php', $a);
73 break;
74 case lang_installer::RESULT_INSTALLED:
75 $notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
76 break;
77 case lang_installer::RESULT_UPTODATE:
78 $notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
79 break;
84 if ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
85 if ($uninstalllang == 'en') {
86 $notice_error[] = 'English language pack can not be uninstalled';
88 } else if (!$confirm and confirm_sesskey()) {
89 echo $OUTPUT->header();
90 echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
91 'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
92 'langimport.php');
93 echo $OUTPUT->footer();
94 die;
96 } else if (confirm_sesskey()) {
97 $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
98 $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
99 $rm1 = false;
100 $rm2 = false;
101 if (file_exists($dest1)){
102 $rm1 = remove_dir($dest1);
104 if (file_exists($dest2)){
105 $rm2 = remove_dir($dest2);
107 if ($rm1 or $rm2) {
108 $notice_ok[] = get_string('langpackremoved','admin');
109 } else { //nothing deleted, possibly due to permission error
110 $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
115 if ($mode == UPDATE_ALL_LANG) {
116 set_time_limit(0);
118 $installer = new lang_installer();
120 if (!$availablelangs = $installer->get_remote_list_of_languages()) {
121 print_error('cannotdownloadlanguageupdatelist', 'error');
123 $md5array = array(); // (string)langcode => (string)md5
124 foreach ($availablelangs as $alang) {
125 $md5array[$alang[0]] = $alang[1];
128 // filter out unofficial packs
129 $currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
130 $updateablelangs = array();
131 foreach ($currentlangs as $clang) {
132 if (!array_key_exists($clang, $md5array)) {
133 $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
134 continue;
136 $dest1 = $CFG->dataroot.'/lang/'.$clang;
137 $dest2 = $CFG->dirroot.'/lang/'.$clang;
139 if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
140 $updateablelangs[] = $clang;
144 // then filter out packs that have the same md5 key
145 $neededlangs = array(); // all the packs that needs updating
146 foreach ($updateablelangs as $ulang) {
147 if (!is_installed_lang($ulang, $md5array[$ulang])) {
148 $neededlangs[] = $ulang;
152 make_upload_directory('temp');
153 make_upload_directory('lang');
155 // clean-up currently installed versions of the packs
156 foreach ($neededlangs as $packindex => $pack) {
157 if ($pack == 'en') {
158 continue;
161 // delete old directories
162 $dest1 = $CFG->dataroot.'/lang/'.$pack;
163 $dest2 = $CFG->dirroot.'/lang/'.$pack;
164 $rm1 = false;
165 $rm2 = false;
166 if (file_exists($dest1)) {
167 if (!remove_dir($dest1)) {
168 $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
169 unset($neededlangs[$packindex]);
170 continue;
173 if (file_exists($dest2)) {
174 if (!remove_dir($dest2)) {
175 $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
176 unset($neededlangs[$packindex]);
177 continue;
182 // install all needed language packs
183 $installer->set_queue($neededlangs);
184 $results = $installer->run();
185 $updated = false; // any packs updated?
186 foreach ($results as $langcode => $langstatus) {
187 switch ($langstatus) {
188 case lang_installer::RESULT_DOWNLOADERROR:
189 $a = new stdClass();
190 $a->url = $installer->lang_pack_url($langcode);
191 $a->dest = $CFG->dataroot.'/lang';
192 print_error('remotedownloaderror', 'error', 'langimport.php', $a);
193 break;
194 case lang_installer::RESULT_INSTALLED:
195 $updated = true;
196 $notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
197 break;
198 case lang_installer::RESULT_UPTODATE:
199 $notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
200 break;
204 if ($updated) {
205 $notice_ok[] = get_string('langupdatecomplete','admin');
206 } else {
207 $notice_ok[] = get_string('nolangupdateneeded','admin');
210 unset($installer);
212 get_string_manager()->reset_caches();
214 echo $OUTPUT->header();
215 echo $OUTPUT->heading(get_string('langimport', 'admin'));
217 $installedlangs = get_string_manager()->get_list_of_translations(true);
219 $missingparents = array();
220 foreach ($installedlangs as $installedlang => $unused) {
221 $parent = get_parent_language($installedlang);
222 if (empty($parent)) {
223 continue;
225 if (!isset($installedlangs[$parent])) {
226 $missingparents[$installedlang] = $parent;
230 $installer = new lang_installer();
232 if ($availablelangs = $installer->get_remote_list_of_languages()) {
233 $remote = true;
234 } else {
235 $remote = false;
236 $availablelangs = array();
237 echo $OUTPUT->box_start();
238 print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
239 echo $OUTPUT->box_end();
242 if ($notice_ok) {
243 $info = implode('<br />', $notice_ok);
244 echo $OUTPUT->notification($info, 'notifysuccess');
247 if ($notice_error) {
248 $info = implode('<br />', $notice_error);
249 echo $OUTPUT->notification($info, 'notifyproblem');
252 if ($missingparents) {
253 foreach ($missingparents as $l=>$parent) {
254 $a = new stdClass();
255 $a->lang = $installedlangs[$l];
256 $a->parent = $parent;
257 foreach ($availablelangs as $alang) {
258 if ($alang[0] == $parent) {
259 $shortlang = $alang[0];
260 $a->parent = $alang[2].' ('.$shortlang.')';
263 $info = get_string('missinglangparent', 'admin', $a);
264 echo $OUTPUT->notification($info, 'notifyproblem');
268 echo $OUTPUT->box_start();
270 echo html_writer::start_tag('table');
271 echo html_writer::start_tag('tr');
273 // list of installed languages
274 $url = new moodle_url('/admin/langimport.php', array('mode' => DELETION_OF_SELECTED_LANG));
275 echo html_writer::start_tag('td', array('valign' => 'top'));
276 echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
277 echo html_writer::start_tag('fieldset');
278 echo html_writer::label(get_string('installedlangs','admin'), 'uninstalllang');
279 echo html_writer::empty_tag('br');
280 echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
281 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
282 echo html_writer::empty_tag('br');
283 echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('uninstall','admin')));
284 echo html_writer::end_tag('fieldset');
285 echo html_writer::end_tag('form');
286 if ($remote) {
287 $url = new moodle_url('/admin/langimport.php', array('mode' => UPDATE_ALL_LANG));
288 echo html_writer::start_tag('form', array('id' => 'updateform', 'action' => $url->out(), 'method' => 'post'));
289 echo html_writer::tag('fieldset', html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('updatelangs','admin'))));
290 echo html_writer::end_tag('form');
292 echo html_writer::end_tag('td');
294 // list of available languages
295 $options = array();
296 foreach ($availablelangs as $alang) {
297 if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !is_installed_lang($alang[0], $alang[1])) {
298 $options[$alang[0]] = $alang[2].' ('.$alang[0].')';
301 if (!empty($options)) {
302 echo html_writer::start_tag('td', array('valign' => 'top'));
303 $url = new moodle_url('/admin/langimport.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
304 echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
305 echo html_writer::start_tag('fieldset');
306 echo html_writer::label(get_string('availablelangs','install'), 'pack');
307 echo html_writer::empty_tag('br');
308 echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
309 echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
310 echo html_writer::empty_tag('br');
311 echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('install','admin')));
312 echo html_writer::end_tag('fieldset');
313 echo html_writer::end_tag('form');
314 echo html_writer::end_tag('td');
317 echo html_writer::end_tag('tr');
318 echo html_writer::end_tag('table');
319 echo $OUTPUT->box_end();
320 echo $OUTPUT->footer();
321 die();
323 ////////////////////////////////////////////////////////////////////////////////
324 // Local functions /////////////////////////////////////////////////////////////
325 ////////////////////////////////////////////////////////////////////////////////
328 * checks the md5 of the zip file, grabbed from download.moodle.org,
329 * against the md5 of the local language file from last update
330 * @param string $lang
331 * @param string $md5check
332 * @return bool
334 function is_installed_lang($lang, $md5check) {
335 global $CFG;
336 $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
337 if (file_exists($md5file)){
338 return (file_get_contents($md5file) == $md5check);
340 return false;