Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.
   1  <?php
   2  
   3  /**

   4   * Represents a language and defines localizable string formatting and

   5   * other functions, as well as the localized messages for HTML Purifier.

   6   */
   7  class HTMLPurifier_Language
   8  {
   9  
  10      /**

  11       * ISO 639 language code of language. Prefers shortest possible version.

  12       * @type string

  13       */
  14      public $code = 'en';
  15  
  16      /**

  17       * Fallback language code.

  18       * @type bool|string

  19       */
  20      public $fallback = false;
  21  
  22      /**

  23       * Array of localizable messages.

  24       * @type array

  25       */
  26      public $messages = array();
  27  
  28      /**

  29       * Array of localizable error codes.

  30       * @type array

  31       */
  32      public $errorNames = array();
  33  
  34      /**

  35       * True if no message file was found for this language, so English

  36       * is being used instead. Check this if you'd like to notify the

  37       * user that they've used a non-supported language.

  38       * @type bool

  39       */
  40      public $error = false;
  41  
  42      /**

  43       * Has the language object been loaded yet?

  44       * @type bool

  45       * @todo Make it private, fix usage in HTMLPurifier_LanguageTest

  46       */
  47      public $_loaded = false;
  48  
  49      /**

  50       * @type HTMLPurifier_Config

  51       */
  52      protected $config;
  53  
  54      /**

  55       * @type HTMLPurifier_Context

  56       */
  57      protected $context;
  58  
  59      /**

  60       * @param HTMLPurifier_Config $config

  61       * @param HTMLPurifier_Context $context

  62       */
  63      public function __construct($config, $context)
  64      {
  65          $this->config  = $config;
  66          $this->context = $context;
  67      }
  68  
  69      /**

  70       * Loads language object with necessary info from factory cache

  71       * @note This is a lazy loader

  72       */
  73      public function load()
  74      {
  75          if ($this->_loaded) {
  76              return;
  77          }
  78          $factory = HTMLPurifier_LanguageFactory::instance();
  79          $factory->loadLanguage($this->code);
  80          foreach ($factory->keys as $key) {
  81              $this->$key = $factory->cache[$this->code][$key];
  82          }
  83          $this->_loaded = true;
  84      }
  85  
  86      /**

  87       * Retrieves a localised message.

  88       * @param string $key string identifier of message

  89       * @return string localised message

  90       */
  91      public function getMessage($key)
  92      {
  93          if (!$this->_loaded) {
  94              $this->load();
  95          }
  96          if (!isset($this->messages[$key])) {
  97              return "[$key]";
  98          }
  99          return $this->messages[$key];
 100      }
 101  
 102      /**

 103       * Retrieves a localised error name.

 104       * @param int $int error number, corresponding to PHP's error reporting

 105       * @return string localised message

 106       */
 107      public function getErrorName($int)
 108      {
 109          if (!$this->_loaded) {
 110              $this->load();
 111          }
 112          if (!isset($this->errorNames[$int])) {
 113              return "[Error: $int]";
 114          }
 115          return $this->errorNames[$int];
 116      }
 117  
 118      /**

 119       * Converts an array list into a string readable representation

 120       * @param array $array

 121       * @return string

 122       */
 123      public function listify($array)
 124      {
 125          $sep      = $this->getMessage('Item separator');
 126          $sep_last = $this->getMessage('Item separator last');
 127          $ret = '';
 128          for ($i = 0, $c = count($array); $i < $c; $i++) {
 129              if ($i == 0) {
 130              } elseif ($i + 1 < $c) {
 131                  $ret .= $sep;
 132              } else {
 133                  $ret .= $sep_last;
 134              }
 135              $ret .= $array[$i];
 136          }
 137          return $ret;
 138      }
 139  
 140      /**

 141       * Formats a localised message with passed parameters

 142       * @param string $key string identifier of message

 143       * @param array $args Parameters to substitute in

 144       * @return string localised message

 145       * @todo Implement conditionals? Right now, some messages make

 146       *     reference to line numbers, but those aren't always available

 147       */
 148      public function formatMessage($key, $args = array())
 149      {
 150          if (!$this->_loaded) {
 151              $this->load();
 152          }
 153          if (!isset($this->messages[$key])) {
 154              return "[$key]";
 155          }
 156          $raw = $this->messages[$key];
 157          $subst = array();
 158          $generator = false;
 159          foreach ($args as $i => $value) {
 160              if (is_object($value)) {
 161                  if ($value instanceof HTMLPurifier_Token) {
 162                      // factor this out some time

 163                      if (!$generator) {
 164                          $generator = $this->context->get('Generator');
 165                      }
 166                      if (isset($value->name)) {
 167                          $subst['$'.$i.'.Name'] = $value->name;
 168                      }
 169                      if (isset($value->data)) {
 170                          $subst['$'.$i.'.Data'] = $value->data;
 171                      }
 172                      $subst['$'.$i.'.Compact'] =
 173                      $subst['$'.$i.'.Serialized'] = $generator->generateFromToken($value);
 174                      // a more complex algorithm for compact representation

 175                      // could be introduced for all types of tokens. This

 176                      // may need to be factored out into a dedicated class

 177                      if (!empty($value->attr)) {
 178                          $stripped_token = clone $value;
 179                          $stripped_token->attr = array();
 180                          $subst['$'.$i.'.Compact'] = $generator->generateFromToken($stripped_token);
 181                      }
 182                      $subst['$'.$i.'.Line'] = $value->line ? $value->line : 'unknown';
 183                  }
 184                  continue;
 185              } elseif (is_array($value)) {
 186                  $keys = array_keys($value);
 187                  if (array_keys($keys) === $keys) {
 188                      // list

 189                      $subst['$'.$i] = $this->listify($value);
 190                  } else {
 191                      // associative array

 192                      // no $i implementation yet, sorry

 193                      $subst['$'.$i.'.Keys'] = $this->listify($keys);
 194                      $subst['$'.$i.'.Values'] = $this->listify(array_values($value));
 195                  }
 196                  continue;
 197              }
 198              $subst['$' . $i] = $value;
 199          }
 200          return strtr($raw, $subst);
 201      }
 202  }
 203  
 204  // vim: et sw=4 sts=4