PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/web/admin/langimport.php

https://github.com/dhamma-dev/SEA
PHP | 387 lines | 291 code | 46 blank | 50 comment | 63 complexity | 7119aa0ad4e88cb84e0e43bed7af6978 MD5 | raw file
  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/2.0/
  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 core
  25. * @copyright 2005 Yu Zhang
  26. * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  27. */
  28. require_once(dirname(dirname(__FILE__)).'/config.php');
  29. require_once($CFG->libdir.'/adminlib.php');
  30. require_once($CFG->libdir.'/filelib.php');
  31. require_once($CFG->libdir.'/componentlib.class.php');
  32. $thisversion = '2.0'; // TODO this information should be taken from version.php or similar source
  33. admin_externalpage_setup('langimport');
  34. if (!empty($CFG->skiplangupgrade)) {
  35. echo $OUTPUT->header();
  36. echo $OUTPUT->box(get_string('langimportdisabled', 'admin'));
  37. echo $OUTPUT->footer();
  38. die;
  39. }
  40. $mode = optional_param('mode', 0, PARAM_INT); // action
  41. $pack = optional_param('pack', array(), PARAM_SAFEDIR); // pack to install
  42. $uninstalllang = optional_param('uninstalllang', '', PARAM_LANG); // installed pack to uninstall
  43. $confirm = optional_param('confirm', 0, PARAM_BOOL); // uninstallation confirmation
  44. define('INSTALLATION_OF_SELECTED_LANG', 2);
  45. define('DELETION_OF_SELECTED_LANG', 4);
  46. define('UPDATE_ALL_LANG', 5);
  47. //reset and diagnose lang cache permissions
  48. remove_dir($CFG->dataroot.'/cache/languages');
  49. if (file_exists($CFG->dataroot.'/cache/languages')) {
  50. print_error('cannotdeletelangcache', 'error');
  51. }
  52. get_string_manager()->reset_caches();
  53. $notice_ok = array();
  54. $notice_error = array();
  55. if (($mode == INSTALLATION_OF_SELECTED_LANG) and confirm_sesskey() and !empty($pack)) {
  56. set_time_limit(0);
  57. make_upload_directory('temp');
  58. make_upload_directory('lang');
  59. if (is_array($pack)) {
  60. $packs = $pack;
  61. } else {
  62. $packs = array($pack);
  63. }
  64. foreach ($packs as $pack) {
  65. if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion, $pack.'.zip', 'languages.md5', 'lang')) {
  66. $status = $cd->install();
  67. switch ($status) {
  68. case COMPONENT_ERROR:
  69. if ($cd->get_error() == 'remotedownloaderror') {
  70. $a = new stdClass();
  71. $a->url = 'http://download.moodle.org/langpack/'.$thisversion.'/'.$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');
  76. }
  77. break;
  78. case COMPONENT_INSTALLED:
  79. $notice_ok[] = get_string('langpackinstalled','admin',$pack);
  80. if ($parentlang = get_parent_language($pack)) {
  81. // install also parent pack if specified
  82. if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion,
  83. $parentlang.'.zip', 'languages.md5', 'lang')) {
  84. $cd->install();
  85. }
  86. }
  87. break;
  88. case COMPONENT_UPTODATE:
  89. break;
  90. }
  91. } else {
  92. echo $OUTPUT->notification('Had an unspecified error with the component installer, sorry.');
  93. }
  94. }
  95. }
  96. if ($mode == DELETION_OF_SELECTED_LANG and !empty($uninstalllang)) {
  97. if ($uninstalllang == 'en') {
  98. $notice_error[] = 'English language pack can not be uninstalled';
  99. } else if (!$confirm and confirm_sesskey()) {
  100. echo $OUTPUT->header();
  101. echo $OUTPUT->confirm(get_string('uninstallconfirm', 'admin', $uninstalllang),
  102. 'langimport.php?mode='.DELETION_OF_SELECTED_LANG.'&uninstalllang='.$uninstalllang.'&confirm=1',
  103. 'langimport.php');
  104. echo $OUTPUT->footer();
  105. die;
  106. } else if (confirm_sesskey()) {
  107. $dest1 = $CFG->dataroot.'/lang/'.$uninstalllang;
  108. $dest2 = $CFG->dirroot.'/lang/'.$uninstalllang;
  109. $rm1 = false;
  110. $rm2 = false;
  111. if (file_exists($dest1)){
  112. $rm1 = remove_dir($dest1);
  113. }
  114. if (file_exists($dest2)){
  115. $rm2 = remove_dir($dest2);
  116. }
  117. if ($rm1 or $rm2) {
  118. $notice_ok[] = get_string('langpackremoved','admin');
  119. } else { //nothing deleted, possibly due to permission error
  120. $notice_error[] = 'An error has occurred, language pack is not completely uninstalled, please check file permissions';
  121. }
  122. }
  123. }
  124. if ($mode == UPDATE_ALL_LANG) {
  125. set_time_limit(0);
  126. if (!$availablelangs = get_remote_list_of_languages()) {
  127. print_error('cannotdownloadlanguageupdatelist', 'error');
  128. }
  129. $md5array = array(); // (string)langcode => (string)md5
  130. foreach ($availablelangs as $alang) {
  131. $md5array[$alang[0]] = $alang[1];
  132. }
  133. // filter out unofficial packs
  134. $currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
  135. $updateablelangs = array();
  136. foreach ($currentlangs as $clang) {
  137. if (!array_key_exists($clang, $md5array)) {
  138. $notice_ok[] = get_string('langpackupdateskipped', 'admin', $clang);
  139. continue;
  140. }
  141. $dest1 = $CFG->dataroot.'/lang/'.$clang;
  142. $dest2 = $CFG->dirroot.'/lang/'.$clang;
  143. if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')){
  144. $updateablelangs[] = $clang;
  145. }
  146. }
  147. // then filter out packs that have the same md5 key
  148. $neededlangs = array(); // all the packs that needs updating
  149. foreach ($updateablelangs as $ulang) {
  150. if (!is_installed_lang($ulang, $md5array[$ulang])) {
  151. $neededlangs[] = $ulang;
  152. }
  153. }
  154. make_upload_directory('temp');
  155. make_upload_directory('lang');
  156. $updated = false; // any packs updated?
  157. foreach ($neededlangs as $pack) {
  158. if ($pack == 'en') {
  159. continue;
  160. }
  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. continue;
  170. }
  171. }
  172. if (file_exists($dest2)) {
  173. if (!remove_dir($dest2)) {
  174. $notice_error[] = 'Could not delete old directory '.$dest2.', update of '.$pack.' failed, please check permissions.';
  175. continue;
  176. }
  177. }
  178. // copy and unzip new version
  179. if ($cd = new component_installer('http://download.moodle.org', 'langpack/'.$thisversion, $pack.'.zip', 'languages.md5', 'lang')) {
  180. $status = $cd->install();
  181. switch ($status) {
  182. case COMPONENT_ERROR:
  183. if ($cd->get_error() == 'remotedownloaderror') {
  184. $a = new stdClass();
  185. $a->url = 'http://download.moodle.org/langpack/'.$thisversion.'/'.$pack.'.zip';
  186. $a->dest = $CFG->dataroot.'/lang';
  187. print_error($cd->get_error(), 'error', 'langimport.php', $a);
  188. } else {
  189. print_error($cd->get_error(), 'error', 'langimport.php');
  190. }
  191. break;
  192. case COMPONENT_UPTODATE:
  193. // should not get here
  194. break;
  195. case COMPONENT_INSTALLED:
  196. $notice_ok[] = get_string('langpackupdated', 'admin', $pack);
  197. $updated = true;
  198. break;
  199. }
  200. }
  201. }
  202. if ($updated) {
  203. $notice_ok[] = get_string('langupdatecomplete','admin');
  204. } else {
  205. $notice_ok[] = get_string('nolangupdateneeded','admin');
  206. }
  207. }
  208. get_string_manager()->reset_caches();
  209. echo $OUTPUT->header();
  210. echo $OUTPUT->heading(get_string('langimport', 'admin'));
  211. $installedlangs = get_string_manager()->get_list_of_translations(true);
  212. $missingparents = array();
  213. foreach ($installedlangs as $installedlang => $unused) {
  214. $parent = get_parent_language($installedlang);
  215. if (empty($parent) or ($parent === 'en')) {
  216. continue;
  217. }
  218. if (!isset($installedlangs[$parent])) {
  219. $missingparents[$installedlang] = $parent;
  220. }
  221. }
  222. if ($availablelangs = get_remote_list_of_languages()) {
  223. $remote = true;
  224. } else {
  225. $remote = false;
  226. $availablelangs = array();
  227. echo $OUTPUT->box_start();
  228. print_string('remotelangnotavailable', 'admin', $CFG->dataroot.'/lang/');
  229. echo $OUTPUT->box_end();
  230. }
  231. if ($notice_ok) {
  232. $info = implode('<br />', $notice_ok);
  233. echo $OUTPUT->notification($info, 'notifysuccess');
  234. }
  235. if ($notice_error) {
  236. $info = implode('<br />', $notice_error);
  237. echo $OUTPUT->notification($info, 'notifyproblem');
  238. }
  239. if ($missingparents) {
  240. foreach ($missingparents as $l=>$parent) {
  241. $a = new stdClass();
  242. $a->lang = $installedlangs[$l];
  243. $a->parent = $parent;
  244. foreach ($availablelangs as $alang) {
  245. if ($alang[0] == $parent) {
  246. $shortlang = $alang[0];
  247. $a->parent = $alang[2].' ('.$shortlang.')';
  248. }
  249. }
  250. $info = get_string('missinglangparent', 'admin', $a);
  251. echo $OUTPUT->notification($info, 'notifyproblem');
  252. }
  253. }
  254. echo $OUTPUT->box_start();
  255. echo html_writer::start_tag('table');
  256. echo html_writer::start_tag('tr');
  257. // list of installed languages
  258. $url = new moodle_url('/admin/langimport.php', array('mode' => DELETION_OF_SELECTED_LANG));
  259. echo html_writer::start_tag('td', array('valign' => 'top'));
  260. echo html_writer::start_tag('form', array('id' => 'uninstallform', 'action' => $url->out(), 'method' => 'post'));
  261. echo html_writer::start_tag('fieldset');
  262. echo html_writer::label(get_string('installedlangs','admin'), 'uninstalllang');
  263. echo html_writer::empty_tag('br');
  264. echo html_writer::select($installedlangs, 'uninstalllang', '', false, array('size' => 15));
  265. echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
  266. echo html_writer::empty_tag('br');
  267. echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('uninstall','admin')));
  268. echo html_writer::end_tag('fieldset');
  269. echo html_writer::end_tag('form');
  270. if ($remote) {
  271. $url = new moodle_url('/admin/langimport.php', array('mode' => UPDATE_ALL_LANG));
  272. echo html_writer::start_tag('form', array('id' => 'updateform', 'action' => $url->out(), 'method' => 'post'));
  273. echo html_writer::tag('fieldset', html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('updatelangs','admin'))));
  274. echo html_writer::end_tag('form');
  275. }
  276. echo html_writer::end_tag('td');
  277. // list of available languages
  278. $options = array();
  279. foreach ($availablelangs as $alang) {
  280. if (!empty($alang[0]) and trim($alang[0]) !== 'en' and !is_installed_lang($alang[0], $alang[1])) {
  281. $options[$alang[0]] = $alang[2].' ('.$alang[0].')';
  282. }
  283. }
  284. if (!empty($options)) {
  285. echo html_writer::start_tag('td', array('valign' => 'top'));
  286. $url = new moodle_url('/admin/langimport.php', array('mode' => INSTALLATION_OF_SELECTED_LANG));
  287. echo html_writer::start_tag('form', array('id' => 'installform', 'action' => $url->out(), 'method' => 'post'));
  288. echo html_writer::start_tag('fieldset');
  289. echo html_writer::label(get_string('availablelangs','install'), 'pack');
  290. echo html_writer::empty_tag('br');
  291. echo html_writer::select($options, 'pack[]', '', false, array('size' => 15, 'multiple' => 'multiple'));
  292. echo html_writer::empty_tag('input', array('type' => 'hidden', 'name' => 'sesskey', 'value' => sesskey()));
  293. echo html_writer::empty_tag('br');
  294. echo html_writer::empty_tag('input', array('type' => 'submit', 'value' => get_string('install','admin')));
  295. echo html_writer::end_tag('fieldset');
  296. echo html_writer::end_tag('form');
  297. echo html_writer::end_tag('td');
  298. }
  299. echo html_writer::end_tag('tr');
  300. echo html_writer::end_tag('table');
  301. echo $OUTPUT->box_end();
  302. echo $OUTPUT->footer();
  303. die();
  304. ////////////////////////////////////////////////////////////////////////////////
  305. // Local functions /////////////////////////////////////////////////////////////
  306. ////////////////////////////////////////////////////////////////////////////////
  307. /**
  308. * checks the md5 of the zip file, grabbed from download.moodle.org,
  309. * against the md5 of the local language file from last update
  310. * @param string $lang
  311. * @param string $md5check
  312. * @return bool
  313. */
  314. function is_installed_lang($lang, $md5check) {
  315. global $CFG;
  316. $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
  317. if (file_exists($md5file)){
  318. return (file_get_contents($md5file) == $md5check);
  319. }
  320. return false;
  321. }
  322. /**
  323. * Returns the list of available language packs from download.moodle.org
  324. *
  325. * @return array|bool false if can not download
  326. */
  327. function get_remote_list_of_languages() {
  328. $source = 'http://download.moodle.org/langpack/2.0/languages.md5';
  329. $availablelangs = array();
  330. if ($content = download_file_content($source)) {
  331. $alllines = explode("\n", $content);
  332. foreach($alllines as $line) {
  333. if (!empty($line)){
  334. $availablelangs[] = explode(',', $line);
  335. }
  336. }
  337. return $availablelangs;
  338. } else {
  339. return false;
  340. }
  341. }