Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 401 and 402] [Versions 401 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   * CLI customlang import tool.
  19   *
  20   * @package    tool_customlang
  21   * @copyright  2020 Ferran Recio <ferran@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  
  25  use tool_customlang\local\importer;
  26  use core\output\notification;
  27  
  28  define('CLI_SCRIPT', true);
  29  
  30  require(__DIR__ . '/../../../../config.php');
  31  require_once($CFG->dirroot.'/'.$CFG->admin.'/tool/customlang/locallib.php');
  32  require_once("$CFG->libdir/clilib.php");
  33  
  34  $usage =
  35  "Import lang customization.
  36  
  37  It can get a single file or a folder.
  38  If no lang is provided it will try to infere from the filename
  39  
  40  Options:
  41  --lang                  The target language (will get from filename if not provided)
  42  --source=path           File or folder of the custom lang files (zip or php files)
  43  --mode                  What string should be imported. Options are:
  44                              - all: all string will be imported (default)
  45                              - new: only string with no previous customisation
  46                              - update: only strings already modified
  47  --checkin               Save strings to the language pack
  48  -h, --help              Print out this help
  49  
  50  Examples:
  51  \$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --lang=en --source=customlangs.zip
  52  
  53  \$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --source=/tmp/customlangs --checkin
  54  
  55  \$ sudo -u www-data /usr/bin/php admin/tool/customlang/cli/import.php --lang=en --source=/tmp/customlangs
  56  
  57  ";
  58  
  59  list($options, $unrecognized) = cli_get_params(
  60      [
  61          'help' => false,
  62          'lang' => false,
  63          'source' => false,
  64          'mode' => 'all',
  65          'checkin' => false,
  66      ],
  67      ['h' => 'help']
  68  );
  69  
  70  if ($unrecognized) {
  71      $unrecognized = implode("\n  ", $unrecognized);
  72      cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
  73  }
  74  
  75  if ($options['help']) {
  76      cli_write($usage);
  77      exit(0);
  78  }
  79  
  80  $source = $options['source'] ?? null;
  81  $lang = $options['lang'] ?? null;
  82  $modeparam = $options['mode'] ?? 'all';
  83  $checkin = $options['checkin'] ?? false;
  84  
  85  $modes = [
  86      'all' => importer::IMPORTALL,
  87      'update' => importer::IMPORTUPDATE,
  88      'new' => importer::IMPORTNEW,
  89  ];
  90  if (!isset($modes[$modeparam])) {
  91      cli_error(get_string('climissingmode', 'tool_customlang'));
  92  }
  93  $mode = $modes[$modeparam];
  94  
  95  if (empty($source)) {
  96      $source = $CFG->dataroot.'/temp/customlang';
  97  }
  98  
  99  if (!file_exists($source)) {
 100      cli_error(get_string('climissingsource', 'tool_customlang'));
 101  }
 102  
 103  // Emulate normal session - we use admin account by default.
 104  cron_setup_user();
 105  
 106  // Get the file list.
 107  $files = [];
 108  $langfiles = [];
 109  
 110  if (is_file($source)) {
 111      $files[] = $source;
 112  }
 113  if (is_dir($source)) {
 114      $filelist = glob("$source/*");
 115      foreach ($filelist as $filename) {
 116          $files[] = "$filename";
 117      }
 118  }
 119  
 120  $countfiles = 0;
 121  foreach ($files as $filepath) {
 122      // Try to get the lang.
 123      $filelang = $lang;
 124      // Get component from filename.
 125      $pathparts = pathinfo($filepath);
 126      $filename = $pathparts['filename'];
 127      $extension = $pathparts['extension'];
 128      if ($extension == 'zip') {
 129          if (!$filelang) {
 130              // Try to get the lang from the filename.
 131              if (strrpos($filename, 'customlang_') === 0) {
 132                  $parts = explode('_', $filename);
 133                  if (!empty($parts[1])) {
 134                      $filelang = $parts[1];
 135                  }
 136              }
 137          }
 138      } else if ($extension != 'php') {
 139          // Ignore any other file extension.
 140          continue;
 141      }
 142      if (empty($filelang)) {
 143          cli_error(get_string('climissinglang', 'tool_customlang'));
 144      }
 145      if (!isset($langfiles[$filelang])) {
 146          $langfiles[$filelang] = [];
 147      }
 148      $langfiles[$filelang][] = $filepath;
 149      $countfiles ++;
 150  }
 151  
 152  if (!$countfiles) {
 153      cli_error(get_string('climissingfiles', 'tool_customlang'));
 154  }
 155  
 156  foreach ($langfiles as $lng => $files) {
 157      $importer = new importer($lng, $mode);
 158      $storedfiles = [];
 159      $fs = get_file_storage();
 160  
 161      cli_heading(get_string('clifiles', 'tool_customlang', $lng));
 162  
 163      // If we intend to check in any changes, we must first check them out.
 164      if ($checkin) {
 165          cli_writeln(get_string('checkout', 'tool_customlang'));
 166  
 167          $progressbar = new progress_bar();
 168          $progressbar->create();
 169  
 170          tool_customlang_utils::checkout($lng, $progressbar);
 171      }
 172  
 173      foreach ($files as $file) {
 174          // Generate a valid stored_file from this file.
 175          $record = (object)[
 176              'filearea' => 'draft',
 177              'component' => 'user',
 178              'filepath' => '/',
 179              'itemid'   => file_get_unused_draft_itemid(),
 180              'license'  => $CFG->sitedefaultlicense,
 181              'author'   => '',
 182              'filename' => clean_param(basename($file), PARAM_FILE),
 183              'contextid' => \context_user::instance($USER->id)->id,
 184              'userid' => $USER->id,
 185          ];
 186          cli_writeln($file);
 187          $storedfiles[] = $fs->create_file_from_pathname($record, $file);
 188      }
 189      cli_writeln("");
 190  
 191      // Import files.
 192      cli_heading(get_string('cliimporting', 'tool_customlang', $modeparam));
 193      $importer->import($storedfiles);
 194      // Display logs.
 195      $log = $importer->get_log();
 196      if (empty($log)) {
 197          cli_problem(get_string('clinolog', 'tool_customlang', $lng));
 198      }
 199      foreach ($log as $message) {
 200          if ($message->errorlevel == notification::NOTIFY_ERROR) {
 201              cli_problem($message->get_message());
 202          } else {
 203              cli_writeln($message->get_message());
 204          }
 205      }
 206      // Do the checkin if necessary.
 207      if ($checkin) {
 208          tool_customlang_utils::checkin($lng);
 209          cli_writeln(get_string('savecheckin', 'tool_customlang'));
 210      }
 211      cli_writeln("");
 212  }
 213  
 214  exit(0);