langimport.php 17.1 KB
Newer Older
skodak's avatar
skodak committed
1
<?php //$Id$
toyomoyo's avatar
toyomoyo committed
2
3
4
5
6
///This file only manages the installation of 1.6 lang packs.
///in downloads.moodle.org, they are store in separate directory /lang16
///in local server, they are stored in $CFG->dataroot/lang
///This helps to avoid confusion.

skodak's avatar
skodak committed
7
    require_once('../config.php');
8
    require_once($CFG->libdir.'/adminlib.php');
9
10
    require_once($CFG->libdir.'/filelib.php');
    require_once($CFG->libdir.'/componentlib.class.php');
11
12

    admin_externalpage_setup('langimport');
skodak's avatar
skodak committed
13

14
15
16
    if (!empty($CFG->skiplangupgrade)) {
        admin_externalpage_print_header();
        print_box(get_string('langimportdisabled', 'admin'));
17
        echo $OUTPUT->footer();
18
19
20
        die;
    }

skodak's avatar
skodak committed
21
    $mode          = optional_param('mode', 0, PARAM_INT);     //phase
22
    $pack          = optional_param('pack', array(), PARAM_FILE);   //pack to install
skodak's avatar
skodak committed
23
24
25
26
27
    $displaylang   = $pack;
    $uninstalllang = optional_param('uninstalllang', '', PARAM_FILE);
    $confirm       = optional_param('confirm', 0, PARAM_BOOL);
    $sitelang      = optional_param('sitelangconfig', '', PARAM_FILE);

toyomoyo's avatar
toyomoyo committed
28
29
30
    define('INSTALLATION_OF_SELECTED_LANG', 2);
    define('DELETION_OF_SELECTED_LANG', 4);
    define('UPDATE_ALL_LANG', 5);
31

32
33
34
35
    $strlang         = get_string('langimport','admin');
    $strlanguage     = get_string('language');
    $strthislanguage = get_string('thislanguage');
    $title           = $strlang;
36

37
38
39
    //reset and diagnose lang cache permissions
    @unlink($CFG->dataroot.'/cache/languages');
    if (file_exists($CFG->dataroot.'/cache/languages')) {
dongsheng's avatar
dongsheng committed
40
        print_error('cannotdeletelangcache', 'error');
41
42
    }
    get_list_of_languages(true); //refresh lang cache
toyomoyo's avatar
toyomoyo committed
43

44
45
46
    $notice_ok     = array();
    $notice_error = array();

toyomoyo's avatar
toyomoyo committed
47
    switch ($mode){
48

toyomoyo's avatar
toyomoyo committed
49
        case INSTALLATION_OF_SELECTED_LANG:    ///installation of selected language pack
50

51
52
            if (confirm_sesskey() and !empty($pack)) {
                set_time_limit(0);
53
54
                @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);    //make it in case it's a fresh install, it might not be there
                @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
55

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
                if (is_array($pack)) {
                    $packs = $pack;
                } else {
                    $packs = array($pack);
                }

                foreach ($packs as $pack) {
                    if ($cd = new component_installer('http://download.moodle.org', 'lang16',
                                                        $pack.'.zip', 'languages.md5', 'lang')) {
                        $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
                        switch ($status) {

                            case COMPONENT_ERROR:
                                if ($cd->get_error() == 'remotedownloaderror') {
                                    $a = new object();
                                    $a->url = 'http://download.moodle.org/lang16/'.$pack.'.zip';
                                    $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');
76
77
78
79
80
                                }
                            break;

                            case COMPONENT_INSTALLED:
                                $notice_ok[] = get_string('langpackinstalled','admin',$pack);
81
82
83
84
85
86
                                if ($parentlang = get_parent_language($pack)) {
                                    // install also parent pack if specified
                                    if ($cd = new component_installer('http://download.moodle.org', 'lang16', $parentlang.'.zip', 'languages.md5', 'lang')) {
                                        $cd->install();
                                    }
                                }
87
88
89
90
                            break;

                            case COMPONENT_UPTODATE:
                            break;
moodler's avatar
moodler committed
91

92
93
94
                        }
                    } else {
                        notify('Had an unspecified error with the component installer, sorry.');
toyomoyo's avatar
toyomoyo committed
95
96
97
98
99
100
101
                    }
                }
            }
        break;

        case DELETION_OF_SELECTED_LANG:    //delete a directory(ies) containing a lang pack completely

102
103
104
105
106
            if ($uninstalllang == 'en_utf8') {
                $notice_error[] = 'en_utf8 can not be uninstalled!';

            } else if (!$confirm && confirm_sesskey()) {
                admin_externalpage_print_header();
107
                notice_yesno(get_string('uninstallconfirm', 'admin', $uninstalllang),
108
                             'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&amp;uninstalllang='.$uninstalllang.'&amp;confirm=1&amp;sesskey='.sesskey(),
moodler's avatar
moodler committed
109
                             'langimport.php');
110
                echo $OUTPUT->footer();
111
112
                die;

moodler's avatar
moodler committed
113
            } else if (confirm_sesskey()) {
toyomoyo's avatar
toyomoyo committed
114
115
116
117
118
119
120
121
122
123
                $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
                $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
                $rm1 = false;
                $rm2 = false;
                if (file_exists($dest1)){
                    $rm1 = remove_dir($dest1);
                }
                if (file_exists($dest2)){
                    $rm2 = remove_dir($dest2);
                }
124
                get_list_of_languages(true); //refresh lang cache
toyomoyo's avatar
toyomoyo committed
125
126
                //delete the direcotries
                if ($rm1 or $rm2) {
127
                    $notice_ok[] = get_string('langpackremoved','admin');
toyomoyo's avatar
toyomoyo committed
128
                } else {    //nothing deleted, possibly due to permission error
129
                    $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
toyomoyo's avatar
toyomoyo committed
130
131
132
                }
            }
        break;
133

toyomoyo's avatar
toyomoyo committed
134
        case UPDATE_ALL_LANG:    //1 click update for all updatable language packs
135
            set_time_limit(0);
toyomoyo's avatar
toyomoyo committed
136
137
138
139

            //0th pull a list from download.moodle.org,
            //key = langname, value = md5
            $md5array = array();
moodler's avatar
moodler committed
140
            $updated = 0;    //any packs updated?
141
            $alllangs = array_keys(get_list_of_languages(false, true)); //get all available langs
toyomoyo's avatar
toyomoyo committed
142
143
144
            $lang16 = array();   //all the Moodle 1.6 unicode lang packs (updated and not updated)
            $packs = array();    //all the packs that needs updating

145

146
            if (!$availablelangs = get_remote_list_of_languages()) {
dongsheng's avatar
dongsheng committed
147
                print_error('cannotdownloadlanguageupdatelist', 'error');
toyomoyo's avatar
toyomoyo committed
148
            }
149

toyomoyo's avatar
toyomoyo committed
150
151
152
153
154
            //and build an associative array
            foreach ($availablelangs as $alang) {
                $md5array[$alang[0]] = $alang[1];
            }

155
            //filtering out non-16 and unofficial packs
toyomoyo's avatar
toyomoyo committed
156
            foreach ($alllangs as $clang) {
157
158
159
160
                if (!array_key_exists($clang, $md5array)) {
                    $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
                    continue;
                }
toyomoyo's avatar
toyomoyo committed
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
                $dest1 = $CFG->dataroot.'/lang/'.$clang;
                $dest2 = $CFG->dirroot.'/lang/'.$clang;

                if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
                    $lang16[] = $clang;
                }
            }

            //then filter out packs that have the same md5 key
            foreach ($lang16 as $clang) {
                if (!is_installed_lang($clang, $md5array[$clang])){
                    $packs[] = $clang;
                }
            }

176
177
            @mkdir ($CFG->dataroot.'/temp/', $CFG->directorypermissions);
            @mkdir ($CFG->dataroot.'/lang/', $CFG->directorypermissions);
toyomoyo's avatar
toyomoyo committed
178
            foreach ($packs as $pack){    //for each of the remaining in the list, we
toyomoyo's avatar
toyomoyo committed
179
180
181
                if ($pack == 'en_utf8') {    // no update for en_utf8
                    continue;
                }
182

toyomoyo's avatar
toyomoyo committed
183
184
185
186
187
188
189
                //1. delete old director(ies)

                $dest1 = $CFG->dataroot.'/lang/'.$pack;
                $dest2 = $CFG->dirroot.'/lang/'.$pack;
                $rm1 = false;
                $rm2 = false;
                if (file_exists($dest1)) {
190
191
192
193
                    if (!remove_dir($dest1)) {
                        $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
                        continue;
                    }
toyomoyo's avatar
toyomoyo committed
194
195
                }
                if (file_exists($dest2)) {
196
197
198
199
                    if (!remove_dir($dest2)) {
                        $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
                        continue;
                    }
toyomoyo's avatar
toyomoyo committed
200
201
202
203
                }

                //2. copy & unzip into new

moodler's avatar
moodler committed
204
205
                if ($cd = new component_installer('http://download.moodle.org', 'lang16',
                                       $pack.'.zip', 'languages.md5', 'lang')) {
206
                $status = $cd->install(); //returns COMPONENT_(ERROR | UPTODATE | INSTALLED)
moodler's avatar
moodler committed
207
208
                switch ($status) {

209
                    case COMPONENT_ERROR:
210
                        if ($cd->get_error() == 'remotedownloaderror') {
moodler's avatar
moodler committed
211
                            $a = new stdClass();
212
                            $a->url = 'http://download.moodle.org/lang16/'.$pack.'.zip';
moodler's avatar
moodler committed
213
                            $a->dest= $CFG->dataroot.'/lang';
214
                            print_error($cd->get_error(), 'error', "", $a); // not probable
moodler's avatar
moodler committed
215
                        } else {
216
                            print_error($cd->get_error(), 'error'); // not probable
toyomoyo's avatar
toyomoyo committed
217
                        }
moodler's avatar
moodler committed
218
                    break;
219
                    case COMPONENT_UPTODATE:
moodler's avatar
moodler committed
220
221
                        //Print error string or whatever you want to do
                    break;
222
                    case COMPONENT_INSTALLED:
223
                        $notice_ok[] = get_string('langpackupdated', 'admin', $pack);
moodler's avatar
moodler committed
224
225
226
227
                        $updated = true;
                        //Print/do whatever you want
                    break;
                    default:
toyomoyo's avatar
toyomoyo committed
228
                    }
moodler's avatar
moodler committed
229
230
                } else {

toyomoyo's avatar
toyomoyo committed
231
232
233
234
                }
            }

            if ($updated) {
235
                $notice_ok[] = get_string('langupdatecomplete','admin');
toyomoyo's avatar
toyomoyo committed
236
            } else {
237
                $notice_ok[] = get_string('nolangupdateneeded','admin');
toyomoyo's avatar
toyomoyo committed
238
239
240
            }

        break;
241
    }    //close of main switch
242

toyomoyo's avatar
toyomoyo committed
243

244
    admin_externalpage_print_header();
toyomoyo's avatar
toyomoyo committed
245

246
    $installedlangs = get_list_of_languages(true, true);
247

248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
    $missingparents = array();
    $oldlang = isset($SESSION->lang) ? $SESSION->lang : null; // override current lang

    foreach($installedlangs as $l=>$unused) {
        $SESSION->lang = $l;
        $parent = get_string('parentlanguage');
        if ($parent == 'en_utf8') {
            continue;
        }
        if (strpos($parent, '[[') !== false) {
            continue; // no parent
        }
        if (!isset($installedlangs[$parent])) {
            $missingparents[$l] = $parent;
        }
    }
    if (isset($oldlang)) {
        $SESSION->lang = $oldlang;
    } else {
        unset($SESSION->lang);
    }

270
271
272
273
274
275
    if ($availablelangs = get_remote_list_of_languages()) {
        $remote = 1;
    } else {
        $remote = 0;    //flag for reading from remote or local
        $availablelangs = get_local_list_of_languages();
    }
toyomoyo's avatar
toyomoyo committed
276

277
278
279
280
281
    if (!$remote) {
        print_box_start();
        print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
        print_box_end();
    }
toyomoyo's avatar
toyomoyo committed
282

283
284
285
286
    if ($notice_ok) {
        $info = implode('<br />', $notice_ok);
        notify($info, 'notifysuccess');
    }
toyomoyo's avatar
toyomoyo committed
287

288
289
290
291
292
    if ($notice_error) {
        $info = implode('<br />', $notice_error);
        notify($info, 'notifyproblem');
    }

293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    if ($missingparents) {
        foreach ($missingparents as $l=>$parent) {
            $a = new object();
            $a->lang   = $installedlangs[$l];
            $a->parent = $parent;
            foreach ($availablelangs as $alang) {
                if ($alang[0] == $parent) {
                    if (substr($alang[0], -5) == '_utf8') {   //Remove the _utf8 suffix from the lang to show
                        $shortlang = substr($alang[0], 0, -5);
                    } else {
                        $shortlang = $alang[0];
                    }
                    $a->parent = $alang[2].' ('.$shortlang.')';
                }
            }
            $info = get_string('missinglangparent', 'admin', $a);
            notify($info, 'notifyproblem');
        }
    }

313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
    print_box_start();
    echo '<table summary="">';
    echo '<tr><td align="center" valign="top">';
    echo '<form id="uninstallform" action="langimport.php?mode='.DELETION_OF_SELECTED_LANG.'" method="post">';
    echo '<fieldset class="invisiblefieldset">';
    echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';

    /// display installed langs here

    echo '<label for="uninstalllang">'.get_string('installedlangs','admin')."</label><br />\n";
    echo '<select name="uninstalllang" id="uninstalllang" size="15">';
    foreach ($installedlangs as $clang =>$ilang){
        echo '<option value="'.$clang.'">'.$ilang.'</option>';
    }
    echo '</select>';
    echo '<br /><input type="submit" value="'.get_string('uninstall','admin').'" />';
    echo '</fieldset>';
    echo '</form>';

    if ($remote) {
        echo '<form id="updateform" action="langimport.php?mode='.UPDATE_ALL_LANG.'" method="post">';
        echo '<div>';
        echo '<br /><input type="submit" value="'.get_string('updatelangs','admin').'" />';
        echo '</div>';
        echo '</form>';
    }

    /// Display option to change site language

    /// display to be installed langs here

    echo '</td><td align="center" valign="top">';
    //availabe langs table
    $empty = 1;    //something to pring

    /// if this language pack is not already installed, then we allow installation

    echo '<form id="installform" method="post" action="langimport.php?mode='.INSTALLATION_OF_SELECTED_LANG.'">';
    echo '<fieldset class="invisiblefieldset">';
    echo '<input name="sesskey" type="hidden" value="'.sesskey().'" />';
    echo '<label for="pack">'.get_string('availablelangs','admin')."</label><br />\n";
    if ($remote) {
355
        echo '<select name="pack[]" id="pack" size="15" multiple="multiple">';
356
    }
toyomoyo's avatar
toyomoyo committed
357

358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    foreach ($availablelangs as $alang) {
        if ($alang[0] == '') {
            continue;
        }
        if (trim($alang[0]) != "en_utf8") {
            if ($remote) {
                if (substr($alang[0], -5) == '_utf8') {   //Remove the _utf8 suffix from the lang to show
                    $shortlang = substr($alang[0], 0, -5);
                } else {
                    $shortlang = $alang[0];
                }
                if (!is_installed_lang($alang[0], $alang[1])){    //if not already installed
                    echo '<option value="'.$alang[0].'">'.$alang[2].' ('.$shortlang.')</option>';
                }
            } else {    //print list in local format, and instruction to install
                echo '<tr><td>'.$alang[2].'</td><td><a href="http://download.moodle.org/lang16/'.$alang[0].'.zip">'.get_string('download','admin').'</a></td></tr>';
toyomoyo's avatar
toyomoyo committed
374
            }
375
376
377
378
379
380
381
382
383
            $empty = 0;
        }
    }
    if ($remote) {
        echo '</select>';
        echo '<br /><input type="submit" value="'.$THEME->larrow.' '.get_string('install','admin').'" />';
    }
    echo '</fieldset>';
    echo '</form>';
toyomoyo's avatar
toyomoyo committed
384

385
386
387
388
    if ($empty) {
        echo '<br />';
        print_string('nolanguagetodownload','admin');
    }
toyomoyo's avatar
toyomoyo committed
389

390
391
392
    //close available langs table
    echo '</td></tr></table>';
    print_box_end();
toyomoyo's avatar
toyomoyo committed
393

394
    echo $OUTPUT->footer();
395

396
397
    /**
     * Returns a list of available language packs from a
toyomoyo's avatar
toyomoyo committed
398
     * local copy shipped with standard moodle distro
399
     * this is for site that can't download components.
toyomoyo's avatar
toyomoyo committed
400
401
402
403
     * @return array
     */
    function get_local_list_of_languages() {
        global $CFG;
404
        $source = $CFG->dirroot.'/lib/languages.md5';
toyomoyo's avatar
toyomoyo committed
405
        $availablelangs = array();
406
        if ($fp = fopen($source, 'r')) {
toyomoyo's avatar
toyomoyo committed
407
408
409
410
411
412
            while(!feof ($fp)) {
                $availablelangs[] = split(',', fgets($fp,1024));
            }
        }
        return $availablelangs;
    }
413

414
415
    /**
     * checks the md5 of the zip file, grabbed from download.moodle.org,
toyomoyo's avatar
toyomoyo committed
416
417
418
419
420
421
422
423
424
425
426
427
428
     * against the md5 of the local language file from last update
     * @param string $lang
     * @param string $md5check
     * @return bool
     */
    function is_installed_lang($lang, $md5check) {
        global $CFG;
        $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
        if (file_exists($md5file)){
            return (file_get_contents($md5file) == $md5check);
        }
        return false;
    }
429

430
431
432
433
434
435
436
    /**
     * Returns the latest list of available language packs from
     * moodle.org
     * @return array or false if can not download
     */
    function get_remote_list_of_languages() {
        $source = 'http://download.moodle.org/lang16/languages.md5';
437
        $availablelangs = array();
438

439
        if ($content = download_file_content($source)) {
440
            $alllines = split("\n", $content);
441
442
            foreach($alllines as $line) {
                if (!empty($line)){
443
                    $availablelangs[] = split(',', $line);
444
445
                }
            }
446
            return $availablelangs;
447
448

        } else {
449
            return false;
450
451
        }
    }
toyomoyo's avatar
toyomoyo committed
452
?>