Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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  defined('MOODLE_INTERNAL') || die();
  28  require_once($CFG->libdir.'/filelib.php');
  29  require_once($CFG->libdir.'/componentlib.class.php');
  30  
  31  /**
  32   * Lang import controller
  33   *
  34   * @package    tool_langimport
  35   * @copyright  2014 Dan Poltawski <dan@moodle.com>
  36   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  37   */
  38  class controller {
  39      /** @var array list of informational messages */
  40      public $info;
  41      /** @var array  list of error messages */
  42      public $errors;
  43      /** @var \lang_installer */
  44      private $installer;
  45      /** @var array languages available on the remote server */
  46      public $availablelangs;
  47  
  48      /**
  49       * Constructor.
  50       */
  51      public function __construct() {
  52          make_temp_directory('');
  53          make_upload_directory('lang');
  54  
  55          $this->info = array();
  56          $this->errors = array();
  57          $this->installer = new \lang_installer();
  58  
  59          $this->availablelangs = $this->installer->get_remote_list_of_languages();
  60      }
  61  
  62      /**
  63       * Install language packs provided
  64       *
  65       * @param string|array $langs array of langcodes or individual langcodes
  66       * @param bool $updating true if updating the langpacks
  67       * @return int false if an error encountered or
  68       * @throws \moodle_exception when error is encountered installing langpack
  69       */
  70      public function install_languagepacks($langs, $updating = false) {
  71          global $CFG;
  72  
  73          $this->installer->set_queue($langs);
  74          $results = $this->installer->run();
  75  
  76          $updatedpacks = 0;
  77  
  78          foreach ($results as $langcode => $langstatus) {
  79              switch ($langstatus) {
  80                  case \lang_installer::RESULT_DOWNLOADERROR:
  81                      $a       = new \stdClass();
  82                      $a->url  = $this->installer->lang_pack_url($langcode);
  83                      $a->dest = $CFG->dataroot.'/lang';
  84                      $this->errors[] = get_string('remotedownloaderror', 'error', $a);
  85                      throw new \moodle_exception('remotedownloaderror', 'error', $a);
  86                      break;
  87                  case \lang_installer::RESULT_INSTALLED:
  88                      $updatedpacks++;
  89                      if ($updating) {
  90                          event\langpack_updated::event_with_langcode($langcode)->trigger();
  91                          $this->info[] = get_string('langpackupdated', 'tool_langimport', $langcode);
  92                      } else {
  93                          $this->info[] = get_string('langpackinstalled', 'tool_langimport', $langcode);
  94                          event\langpack_imported::event_with_langcode($langcode)->trigger();
  95                      }
  96                      break;
  97                  case \lang_installer::RESULT_UPTODATE:
  98                      $this->info[] = get_string('langpackuptodate', 'tool_langimport', $langcode);
  99                      break;
 100              }
 101          }
 102  
 103          return $updatedpacks;
 104      }
 105  
 106      /**
 107       * Uninstall language pack
 108       *
 109       * @param string $lang language code
 110       * @return bool true if language succesfull installed
 111       */
 112      public function uninstall_language($lang) {
 113          global $CFG;
 114  
 115          $dest1 = $CFG->dataroot.'/lang/'.$lang;
 116          $dest2 = $CFG->dirroot.'/lang/'.$lang;
 117          $rm1 = false;
 118          $rm2 = false;
 119          if (file_exists($dest1)) {
 120              $rm1 = remove_dir($dest1);
 121          }
 122          if (file_exists($dest2)) {
 123              $rm2 = remove_dir($dest2);
 124          }
 125  
 126          if ($rm1 or $rm2) {
 127              $this->info[] = get_string('langpackremoved', 'tool_langimport', $lang);
 128              event\langpack_removed::event_with_langcode($lang)->trigger();
 129              return true;
 130          } else {    // Nothing deleted, possibly due to permission error.
 131              $this->errors[] = get_string('langpacknotremoved', 'tool_langimport', $lang);
 132              return false;
 133          }
 134      }
 135  
 136      /**
 137       * Updated all install language packs with the latest found on servre
 138       *
 139       * @return bool true if languages succesfully updated.
 140       */
 141      public function update_all_installed_languages() {
 142          global $CFG;
 143  
 144          if (!$availablelangs = $this->installer->get_remote_list_of_languages()) {
 145              $this->errors[] = get_string('cannotdownloadlanguageupdatelist', 'error');
 146              return false;
 147          }
 148  
 149          $md5array = array();    // Convert to (string)langcode => (string)md5.
 150          foreach ($availablelangs as $alang) {
 151              $md5array[$alang[0]] = $alang[1];
 152          }
 153  
 154          // Filter out unofficial packs.
 155          $currentlangs = array_keys(get_string_manager()->get_list_of_translations(true));
 156          $updateablelangs = array();
 157          foreach ($currentlangs as $clang) {
 158              if (!array_key_exists($clang, $md5array)) {
 159                  $this->info[] = get_string('langpackupdateskipped', 'tool_langimport', $clang);
 160                  continue;
 161              }
 162              $dest1 = $CFG->dataroot.'/lang/'.$clang;
 163              $dest2 = $CFG->dirroot.'/lang/'.$clang;
 164  
 165              if (file_exists($dest1.'/langconfig.php') || file_exists($dest2.'/langconfig.php')) {
 166                  $updateablelangs[] = $clang;
 167              }
 168          }
 169  
 170          // Filter out packs that have the same md5 key.
 171          $neededlangs = array();
 172          foreach ($updateablelangs as $ulang) {
 173              if (!$this->is_installed_lang($ulang, $md5array[$ulang])) {
 174                  $neededlangs[] = $ulang;
 175              }
 176          }
 177  
 178          try {
 179              $updated = $this->install_languagepacks($neededlangs, true);
 180          } catch (\moodle_exception $e) {
 181              $this->errors[] = 'An exception occurred while installing language packs: ' . $e->getMessage();
 182              return false;
 183          }
 184  
 185          if ($updated) {
 186              $this->info[] = get_string('langupdatecomplete', 'tool_langimport');
 187              // The strings have been changed so we need to purge their cache to ensure users see the changes.
 188              get_string_manager()->reset_caches();
 189          } else {
 190              $this->info[] = get_string('nolangupdateneeded', 'tool_langimport');
 191          }
 192  
 193          return true;
 194      }
 195  
 196      /**
 197       * checks the md5 of the zip file, grabbed from download.moodle.org,
 198       * against the md5 of the local language file from last update
 199       * @param string $lang language code
 200       * @param string $md5check md5 to check
 201       * @return bool true if installed
 202       */
 203      public function is_installed_lang($lang, $md5check) {
 204          global $CFG;
 205          $md5file = $CFG->dataroot.'/lang/'.$lang.'/'.$lang.'.md5';
 206          if (file_exists($md5file)) {
 207              return (file_get_contents($md5file) == $md5check);
 208          }
 209          return false;
 210      }
 211  
 212      /**
 213       * Returns the URL where a given language pack can be downloaded
 214       *
 215       * Alternatively, if the parameter is empty, returns URL of the page with the
 216       * list of all available language packs.
 217       *
 218       * @param string $langcode language code like 'cs' or empty for unknown
 219       * @return string URL
 220       */
 221      public function lang_pack_url($langcode = '') {
 222          return $this->installer->lang_pack_url($langcode);
 223      }
 224  }