See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401]
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 /** 18 * Lang import controller 19 * 20 * @package tool_langimport 21 * @copyright 2014 Dan Poltawski <dan@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace tool_langimport; 26 27 use moodle_url; 28 29 defined('MOODLE_INTERNAL') || die(); 30 require_once($CFG->libdir.'/filelib.php'); 31 require_once($CFG->libdir.'/componentlib.class.php'); 32 33 /** 34 * Lang import controller 35 * 36 * @package tool_langimport 37 * @copyright 2014 Dan Poltawski <dan@moodle.com> 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 class controller { 41 /** @var array list of informational messages */ 42 public $info; 43 /** @var array list of error messages */ 44 public $errors; 45 /** @var \lang_installer */ 46 private $installer; 47 /** @var array languages available on the remote server */ 48 public $availablelangs; 49 50 /** 51 * Constructor. 52 */ 53 public function __construct() { 54 make_temp_directory(''); 55 make_upload_directory('lang'); 56 57 $this->info = array(); 58 $this->errors = array(); 59 $this->installer = new \lang_installer(); 60 61 $this->availablelangs = $this->installer->get_remote_list_of_languages(); 62 } 63 64 /** 65 * Redirect to the specified url, outputting any required messages. 66 * 67 * @param moodle_url $url 68 */ 69 public function redirect(moodle_url $url): void { 70 if ($this->info) { 71 $info = implode('<br />', $this->info); 72 \core\notification::success($info); 73 } 74 75 if ($this->errors) { 76 $info = implode('<br />', $this->errors); 77 \core\notification::error($info); 78 } 79 80 redirect($url); 81 } 82 83 /** 84 * Install language packs provided 85 * 86 * @param string|array $langs array of langcodes or individual langcodes 87 * @param bool $updating true if updating the langpacks 88 * @return int false if an error encountered or 89 * @throws \moodle_exception when error is encountered installing langpack 90 */ 91 public function install_languagepacks($langs, $updating = false) { 92 global $CFG; 93 94 $this->installer->set_queue($langs); 95 $results = $this->installer->run(); 96 97 $updatedpacks = 0; 98 99 foreach ($results as $langcode => $langstatus) { 100 switch ($langstatus) { 101 case \lang_installer::RESULT_DOWNLOADERROR: 102 $a = new \stdClass(); 103 $a->url = $this->installer->lang_pack_url($langcode); 104 $a->dest = $CFG->dataroot.'/lang'; 105 $this->errors[] = get_string('remotedownloaderror', 'error', $a); 106 throw new \moodle_exception('remotedownloaderror', 'error', '', $a); 107 break; 108 case \lang_installer::RESULT_INSTALLED: 109 $updatedpacks++; 110 if ($updating) { 111 event\langpack_updated::event_with_langcode($langcode)->trigger(); 112 $this->info[] = get_string('langpackupdated', 'tool_langimport', $langcode); 113 } else { 114 $this->info[] = get_string('langpackinstalled', 'tool_langimport', $langcode); 115 event\langpack_imported::event_with_langcode($langcode)->trigger(); 116 } 117 break; 118 case \lang_installer::RESULT_UPTODATE: 119 $this->info[] = get_string('langpackuptodate', 'tool_langimport', $langcode); 120 break; 121 } 122 } 123 124 return $updatedpacks; 125 } 126 127 /** 128 * Uninstall language pack 129 * 130 * @param string $lang language code 131 * @return bool true if language succesfull installed 132 */ 133 public function uninstall_language($lang) { 134 global $CFG; 135 136 $lang = clean_param($lang, PARAM_LANG); 137 if ($lang === '') { 138 // Do not allow uninstallation of invalid languages. 139 // Note: PARAM_LANG returns an empty string for invalid validation. 140 return false; 141 } 142 143 if ($lang === 'en') { 144 // Never allow removal of the default langauge. 145 return false; 146 } 147 148 $dest1 = $CFG->dataroot.'/lang/'.$lang; 149 $dest2 = $CFG->dirroot.'/lang/'.$lang; 150 $rm1 = false; 151 $rm2 = false; 152 if (file_exists($dest1)) { 153 $rm1 = remove_dir($dest1); 154 } 155 if (file_exists($dest2)) { 156 $rm2 = remove_dir($dest2); 157 } 158 159 if ($rm1 or $rm2) { 160 // Set the default site language to en if the deleted language pack is the default site language. 161 if ($CFG->lang === $lang) { 162 set_config('lang', 'en'); 163 // Fix the user's current language to the default site language. 164 fix_current_language($CFG->lang); 165 } 166 $this->info[] = get_string('langpackremoved', 'tool_langimport', $lang); 167 event\langpack_removed::event_with_langcode($lang)->trigger(); 168 return true; 169 } else { // Nothing deleted, possibly due to permission error. 170 $this->errors[] = get_string('langpacknotremoved', 'tool_langimport', $lang); 171 return false; 172 } 173 } 174 175 /** 176 * Updated all install language packs with the latest found on servre 177 * 178 * @return bool true if languages succesfully updated. 179 */ 180 public function update_all_installed_languages() { 181 global $CFG; 182 183 if (!$availablelangs = $this->installer->get_remote_list_of_languages()) { 184 $this->errors[] = get_string('cannotdownloadlanguageupdatelist', 'error'); 185 return false; 186 } 187 188 $md5array = array(); // Convert to (string)langcode => (string)md5. 189 foreach ($availablelangs as $alang) { 190 $md5array[$alang[0]] = $alang[1]; 191 } 192 193 // Filter out unofficial packs. 194 $currentlangs = array_keys(get_string_manager()->get_list_of_translations(true)); 195 $updateablelangs = array(); 196 foreach ($currentlangs as $clang) { 197 if (!array_key_exists($clang, $md5array)) { 198 $this->info[] = get_string('langpackupdateskipped', 'tool_langimport', $clang); 199 continue; 200 } 201 $dest1 = $CFG->dataroot.'/lang/'.$clang; 202 $dest2 = $CFG->dirroot.'/lang/'.$clang; 203 204 if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')) { 205 $updateablelangs[] = $clang; 206 } 207 } 208 209 // Filter out packs that have the same md5 key. 210 $neededlangs = array(); 211 foreach ($updateablelangs as $ulang) { 212 if (!$this->is_installed_lang($ulang, $md5array[$ulang])) { 213 $neededlangs[] = $ulang; 214 } 215 } 216 217 try { 218 $updated = $this->install_languagepacks($neededlangs, true); 219 } catch (\moodle_exception $e) { 220 $this->errors[] = 'An exception occurred while installing language packs: ' . $e->getMessage(); 221 return false; 222 } 223 224 if ($updated) { 225 $this->info[] = get_string('langupdatecomplete', 'tool_langimport'); 226 // The strings have been changed so we need to purge their cache to ensure users see the changes. 227 get_string_manager()->reset_caches(); 228 } else { 229 $this->info[] = get_string('nolangupdateneeded', 'tool_langimport'); 230 } 231 232 return true; 233 } 234 235 /** 236 * checks the md5 of the zip file, grabbed from download.moodle.org, 237 * against the md5 of the local language file from last update 238 * @param string $lang language code 239 * @param string $md5check md5 to check 240 * @return bool true if installed 241 */ 242 public function is_installed_lang($lang, $md5check) { 243 global $CFG; 244 $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5'; 245 if (file_exists($md5file)) { 246 return (file_get_contents($md5file) == $md5check); 247 } 248 return false; 249 } 250 251 /** 252 * Returns the URL where a given language pack can be downloaded 253 * 254 * Alternatively, if the parameter is empty, returns URL of the page with the 255 * list of all available language packs. 256 * 257 * @param string $langcode language code like 'cs' or empty for unknown 258 * @return string URL 259 */ 260 public function lang_pack_url($langcode = '') { 261 return $this->installer->lang_pack_url($langcode); 262 } 263 264 /** 265 * Schedule installation of the given language packs asynchronously via ad hoc task. 266 * 267 * @param string|array $langs array of langcodes or individual langcodes 268 */ 269 public function schedule_languagepacks_installation($langs): void { 270 global $USER; 271 272 $task = new \tool_langimport\task\install_langpacks(); 273 $task->set_userid($USER->id); 274 $task->set_custom_data([ 275 'langs' => $langs, 276 ]); 277 278 \core\task\manager::queue_adhoc_task($task, true); 279 280 $this->info[] = get_string('installscheduled', 'tool_langimport'); 281 } 282 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body