PageRenderTime 57ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/admin/tool/langimport/index.php

https://bitbucket.org/ngmares/moodle
PHP | 353 lines | 267 code | 42 blank | 44 comment | 48 complexity | e47e4932901c15a69adf929edc72c65f MD5 | raw file
Possible License(s): LGPL-2.1, AGPL-3.0, MPL-2.0-no-copyleft-exception, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. // This file is part of Moodle - http://moodle.org/
  3. //
  4. // Moodle is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // Moodle is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
  16. /**
  17. * Fetches language packages from download.moodle.org server
  18. *
  19. * Language packages are available at http://download.moodle.org/langpack/
  20. * in ZIP format together with a file languages.md5 containing their hashes
  21. * and meta info.
  22. * Locally, language packs are saved into $CFG->dataroot/lang/
  23. *
  24. * @package tool
  25. * @subpackage langimport
  26. * @copyright 2005 Yu Zhang
  27. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  28. */
  29. require(dirname(dirname(dirname(dirname(__FILE__)))) . '/config.php');
  30. require_once($CFG->libdir.'/adminlib.php');
  31. require_once($CFG->libdir.'/filelib.php');
  32. require_once($CFG->libdir.'/componentlib.class.php');
  33. admin_externalpage_setup('toollangimport');
  34. if (empty($CFG->langotherroot)) {
  35. throw new moodle_exception('missingcfglangotherroot', 'tool_langimport');
  36. }
  37. $mode = optional_param('mode', 0, PARAM_INT); // action
  38. $pack = optional_param_array('pack', array(), PARAM_SAFEDIR); // pack to install
  39. $uninstalllang = optional_param('uninstalllang', '', PARAM_LANG); // installed pack to uninstall
  40. $confirm = optional_param('confirm', 0, PARAM_BOOL); // uninstallation confirmation
  41. $purgecaches = optional_param('purgecaches', false, PARAM_BOOL); // explicit caches reset
  42. if ($purgecaches) {
  43. require_sesskey();
  44. get_string_manager()->reset_caches();
  45. redirect($PAGE->url);
  46. }
  47. if (!empty($CFG->skiplangupgrade)) {
  48. echo $OUTPUT->header();
  49. echo $OUTPUT->box(get_string('langimportdisabled', 'tool_langimport'));
  50. echo $OUTPUT->single_button(new moodle_url($PAGE->url, array('purgecaches' => 1)), get_string('purgestringcaches', 'tool_langimport'));
  51. echo $OUTPUT->footer();
  52. die;
  53. }
  54. define('INSTALLATION_OF_SELECTED_LANG', 2);
  55. define('DELETION_OF_SELECTED_LANG', 4);
  56. define('UPDATE_ALL_LANG', 5);
  57. get_string_manager()->reset_caches();
  58. $notice_ok = array();
  59. $notice_error = array();
  60. if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($pack)) {
  61. set_time_limit(0);
  62. make_temp_directory('');
  63. 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', 'index.php', $a);
  73. break;
  74. case lang_installer::RESULT_INSTALLED:
  75. $notice_ok[] = get_string('langpackinstalled', 'tool_langimport', $langcode);
  76. break;
  77. case lang_installer::RESULT_UPTODATE:
  78. $notice_ok[] = get_string('langpackuptodate', 'tool_langimport', $langcode);
  79. break;
  80. }
  81. }
  82. }
  83. if ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
  84. if ($uninstalllang == 'en') {
  85. $notice_error[] = 'English language pack can not be uninstalled';
  86. } else if (!$confirm and confirm_sesskey()) {
  87. echo $OUTPUT->header();
  88. echo $OUTPUT->confirm(get_string('uninstallconfirm', 'tool_langimport', $uninstalllang),
  89. 'index.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
  90. 'index.php');
  91. echo $OUTPUT->footer();
  92. die;
  93. } else if (confirm_sesskey()) {
  94. $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
  95. $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
  96. $rm1 = false;
  97. $rm2 = false;
  98. if (file_exists($dest1)){
  99. $rm1 = remove_dir($dest1);
  100. }
  101. if (file_exists($dest2)){
  102. $rm2 = remove_dir($dest2);
  103. }
  104. if ($rm1 or $rm2) {
  105. $notice_ok[] = get_string('langpackremoved', 'tool_langimport');
  106. } else { //nothing deleted, possibly due to permission error
  107. $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
  108. }
  109. }
  110. }
  111. if ($mode == UPDATE_ALL_LANG) {
  112. set_time_limit(0);
  113. $installer = new lang_installer();
  114. if (!$availablelangs = $installer->get_remote_list_of_languages()) {
  115. print_error('cannotdownloadlanguageupdatelist', 'error');
  116. }
  117. $md5array = array(); // (string)langcode => (string)md5
  118. foreach ($availablelangs as $alang) {
  119. $md5array[$alang[0]] = $alang[1];
  120. }
  121. // filter out unofficial packs
  122. $currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
  123. $updateablelangs = array();
  124. foreach ($currentlangs as $clang) {
  125. if (!array_key_exists($clang, $md5array)) {
  126. $notice_ok[] = get_string('langpackupdateskipped', 'tool_langimport', $clang);
  127. continue;
  128. }
  129. $dest1 = $CFG->dataroot.'/lang/'.$clang;
  130. $dest2 = $CFG->dirroot.'/lang/'.$clang;
  131. if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
  132. $updateablelangs[] = $clang;
  133. }
  134. }
  135. // then filter out packs that have the same md5 key
  136. $neededlangs = array(); // all the packs that needs updating
  137. foreach ($updateablelangs as $ulang) {
  138. if (!is_installed_lang($ulang, $md5array[$ulang])) {
  139. $neededlangs[] = $ulang;
  140. }
  141. }
  142. make_temp_directory('');
  143. make_upload_directory('lang');
  144. // clean-up currently installed versions of the packs
  145. foreach ($neededlangs as $packindex => $pack) {
  146. if ($pack == 'en') {
  147. continue;
  148. }
  149. // delete old directories
  150. $dest1 = $CFG->dataroot.'/lang/'.$pack;
  151. $dest2 = $CFG->dirroot.'/lang/'.$pack;
  152. $rm1 = false;
  153. $rm2 = false;
  154. if (file_exists($dest1)) {
  155. if (!remove_dir($dest1)) {
  156. $notice_error[] = 'Could not delete old directory '.$dest1.', update of '.$pack.' failed, please check permissions.';
  157. unset($neededlangs[$packindex]);
  158. continue;
  159. }
  160. }
  161. if (file_exists($dest2)) {
  162. if (!remove_dir($dest2)) {
  163. $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
  164. unset($neededlangs[$packindex]);
  165. continue;
  166. }
  167. }
  168. }
  169. // install all needed language packs
  170. $installer->set_queue($neededlangs);
  171. $results = $installer->run();
  172. $updated = false; // any packs updated?
  173. foreach ($results as $langcode => $langstatus) {
  174. switch ($langstatus) {
  175. case lang_installer::RESULT_DOWNLOADERROR:
  176. $a = new stdClass();
  177. $a->url = $installer->lang_pack_url($langcode);
  178. $a->dest = $CFG->dataroot.'/lang';
  179. print_error('remotedownloaderror', 'error', 'index.php', $a);
  180. break;
  181. case lang_installer::RESULT_INSTALLED:
  182. $updated = true;
  183. $notice_ok[] = get_string('langpackinstalled', 'tool_langimport', $langcode);
  184. break;
  185. case lang_installer::RESULT_UPTODATE:
  186. $notice_ok[] = get_string('langpackuptodate', 'tool_langimport', $langcode);
  187. break;
  188. }
  189. }
  190. if ($updated) {
  191. $notice_ok[] = get_string('langupdatecomplete', 'tool_langimport');
  192. } else {
  193. $notice_ok[] = get_string('nolangupdateneeded', 'tool_langimport');
  194. }
  195. unset($installer);
  196. }
  197. get_string_manager()->reset_caches();
  198. echo $OUTPUT->header();
  199. echo $OUTPUT->heading(get_string('langimport', 'tool_langimport'));
  200. $installedlangs = get_string_manager()->get_list_of_translations(true);
  201. $missingparents = array();
  202. foreach ($installedlangs as $installedlang => $unused) {
  203. $parent = get_parent_language($installedlang);
  204. if (empty($parent)) {
  205. continue;
  206. }
  207. if (!isset($installedlangs[$parent])) {
  208. $missingparents[$installedlang] = $parent;
  209. }
  210. }
  211. $installer = new lang_installer();
  212. if ($availablelangs = $installer->get_remote_list_of_languages()) {
  213. $remote = true;
  214. } else {
  215. $remote = false;
  216. $availablelangs = array();
  217. echo $OUTPUT->box_start();
  218. print_string('remotelangnotavailable', 'tool_langimport', $CFG->dataroot.'/lang/');
  219. echo $OUTPUT->box_end();
  220. }
  221. if ($notice_ok) {
  222. $info = implode('<br />', $notice_ok);
  223. echo $OUTPUT->notification($info, 'notifysuccess');
  224. }
  225. if ($notice_error) {
  226. $info = implode('<br />', $notice_error);
  227. echo $OUTPUT->notification($info, 'notifyproblem');
  228. }
  229. if ($missingparents) {
  230. foreach ($missingparents as $l=>$parent) {
  231. $a = new stdClass();
  232. $a->lang = $installedlangs[$l];
  233. $a->parent = $parent;
  234. foreach ($availablelangs as $alang) {
  235. if ($alang[0] == $parent) {
  236. $shortlang = $alang[0];
  237. $a->parent = $alang[2].' ('.$shortlang.')';
  238. }
  239. }
  240. $info = get_string('missinglangparent', 'tool_langimport', $a);
  241. echo $OUTPUT->notification($info, 'notifyproblem');
  242. }
  243. }
  244. echo $OUTPUT->box_start();
  245. echo html_writer::start_tag('table');
  246. echo html_writer::start_tag('tr');
  247. // list of installed languages
  248. $url = new moodle_url('/admin/tool/langimport/index.php', array('mode' => DELETION_OF_SELECTED_LANG));
  249. echo html_writer::start_tag('td', array('valign' => 'top'));
  250. echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
  251. echo html_writer::start_tag('fieldset');
  252. echo html_writer::label(get_string('installedlangs', 'tool_langimport'), 'uninstalllang');
  253. echo html_writer::empty_tag('br');
  254. echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
  255. echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
  256. echo html_writer::empty_tag('br');
  257. echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('uninstall', 'tool_langimport')));
  258. echo html_writer::end_tag('fieldset');
  259. echo html_writer::end_tag('form');
  260. if ($remote) {
  261. $url = new moodle_url('/admin/tool/langimport/index.php', array('mode' => UPDATE_ALL_LANG));
  262. echo html_writer::start_tag('form', array('id' => 'updateform', 'action' => $url->out(), 'method' => 'post'));
  263. echo html_writer::tag('fieldset', html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('updatelangs','tool_langimport'))));
  264. echo html_writer::end_tag('form');
  265. }
  266. echo html_writer::end_tag('td');
  267. // list of available languages
  268. $options = array();
  269. foreach ($availablelangs as $alang) {
  270. if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !is_installed_lang($alang[0], $alang[1])) {
  271. $options[$alang[0]] = $alang[2].' ('.$alang[0].')';
  272. }
  273. }
  274. if (!empty($options)) {
  275. echo html_writer::start_tag('td', array('valign' => 'top'));
  276. $url = new moodle_url('/admin/tool/langimport/index.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
  277. echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
  278. echo html_writer::start_tag('fieldset');
  279. echo html_writer::label(get_string('availablelangs','install'), 'pack');
  280. echo html_writer::empty_tag('br');
  281. echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
  282. echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
  283. echo html_writer::empty_tag('br');
  284. echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('install','tool_langimport')));
  285. echo html_writer::end_tag('fieldset');
  286. echo html_writer::end_tag('form');
  287. echo html_writer::end_tag('td');
  288. }
  289. echo html_writer::end_tag('tr');
  290. echo html_writer::end_tag('table');
  291. echo $OUTPUT->box_end();
  292. echo $OUTPUT->footer();
  293. die();
  294. ////////////////////////////////////////////////////////////////////////////////
  295. // Local functions /////////////////////////////////////////////////////////////
  296. ////////////////////////////////////////////////////////////////////////////////
  297. /**
  298. * checks the md5 of the zip file, grabbed from download.moodle.org,
  299. * against the md5 of the local language file from last update
  300. * @param string $lang
  301. * @param string $md5check
  302. * @return bool
  303. */
  304. function is_installed_lang($lang, $md5check) {
  305. global $CFG;
  306. $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
  307. if (file_exists($md5file)){
  308. return (file_get_contents($md5file) == $md5check);
  309. }
  310. return false;
  311. }