3 // This file is part of Moodle - http://moodle.org/
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.
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/>.
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
24 * Locally, language packs are saved into $CFG->dataroot/lang/
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();
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();
57 $notice_error = array();
59 if (($mode == INSTALLATION_OF_SELECTED_LANG
) and confirm_sesskey() and !empty($pack)) {
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
:
70 $a->url
= $installer->lang_pack_url($langcode);
71 $a->dest
= $CFG->dataroot
.'/lang';
72 print_error('remotedownloaderror', 'error', 'langimport.php', $a);
74 case lang_installer
::RESULT_INSTALLED
:
75 $notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
77 case lang_installer
::RESULT_UPTODATE
:
78 $notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
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',
93 echo $OUTPUT->footer();
96 } else if (confirm_sesskey()) {
97 $dest1 = $CFG->dataroot
.'/lang/'.$uninstalllang;
98 $dest2 = $CFG->dirroot
.'/lang/'.$uninstalllang;
101 if (file_exists($dest1)){
102 $rm1 = remove_dir($dest1);
104 if (file_exists($dest2)){
105 $rm2 = remove_dir($dest2);
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
) {
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);
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) {
161 // delete old directories
162 $dest1 = $CFG->dataroot
.'/lang/'.$pack;
163 $dest2 = $CFG->dirroot
.'/lang/'.$pack;
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]);
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]);
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
:
190 $a->url
= $installer->lang_pack_url($langcode);
191 $a->dest
= $CFG->dataroot
.'/lang';
192 print_error('remotedownloaderror', 'error', 'langimport.php', $a);
194 case lang_installer
::RESULT_INSTALLED
:
196 $notice_ok[] = get_string('langpackinstalled', 'admin', $langcode);
198 case lang_installer
::RESULT_UPTODATE
:
199 $notice_ok[] = get_string('langpackuptodate', 'admin', $langcode);
205 $notice_ok[] = get_string('langupdatecomplete','admin');
207 $notice_ok[] = get_string('nolangupdateneeded','admin');
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)) {
225 if (!isset($installedlangs[$parent])) {
226 $missingparents[$installedlang] = $parent;
230 $installer = new lang_installer();
232 if ($availablelangs = $installer->get_remote_list_of_languages()) {
236 $availablelangs = array();
237 echo $OUTPUT->box_start();
238 print_string('remotelangnotavailable', 'admin', $CFG->dataroot
.'/lang/');
239 echo $OUTPUT->box_end();
243 $info = implode('<br />', $notice_ok);
244 echo $OUTPUT->notification($info, 'notifysuccess');
248 $info = implode('<br />', $notice_error);
249 echo $OUTPUT->notification($info, 'notifyproblem');
252 if ($missingparents) {
253 foreach ($missingparents as $l=>$parent) {
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');
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
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();
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
334 function is_installed_lang($lang, $md5check) {
336 $md5file = $CFG->dataroot
.'/lang/'.$lang.'/'.$lang.'.md5';
337 if (file_exists($md5file)){
338 return (file_get_contents($md5file) == $md5check);