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 311 and 401] [Versions 39 and 401]

   1  <?php
   2  
   3  /**
   4   * SCSSPHP
   5   *
   6   * @copyright 2012-2020 Leaf Corcoran
   7   *
   8   * @license http://opensource.org/licenses/MIT MIT
   9   *
  10   * @link http://scssphp.github.io/scssphp
  11   */
  12  
  13  namespace ScssPhp\ScssPhp;
  14  
  15  use ScssPhp\ScssPhp\Base\Range;
  16  use ScssPhp\ScssPhp\Exception\RangeException;
  17  use ScssPhp\ScssPhp\Node\Number;
  18  
  19  /**
  20   * Utility functions
  21   *
  22   * @author Anthon Pang <anthon.pang@gmail.com>
  23   *
  24   * @internal
  25   */
  26  class Util
  27  {
  28      /**
  29       * Asserts that `value` falls within `range` (inclusive), leaving
  30       * room for slight floating-point errors.
  31       *
  32       * @param string       $name  The name of the value. Used in the error message.
  33       * @param Range        $range Range of values.
  34       * @param array|Number $value The value to check.
  35       * @param string       $unit  The unit of the value. Used in error reporting.
  36       *
  37       * @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin.
  38       *
  39       * @throws \ScssPhp\ScssPhp\Exception\RangeException
  40       */
  41      public static function checkRange($name, Range $range, $value, $unit = '')
  42      {
  43          $val = $value[1];
  44          $grace = new Range(-0.00001, 0.00001);
  45  
  46          if (! \is_numeric($val)) {
  47              throw new RangeException("$name {$val} is not a number.");
  48          }
  49  
  50          if ($range->includes($val)) {
  51              return $val;
  52          }
  53  
  54          if ($grace->includes($val - $range->first)) {
  55              return $range->first;
  56          }
  57  
  58          if ($grace->includes($val - $range->last)) {
  59              return $range->last;
  60          }
  61  
  62          throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit");
  63      }
  64  
  65      /**
  66       * Encode URI component
  67       *
  68       * @param string $string
  69       *
  70       * @return string
  71       */
  72      public static function encodeURIComponent($string)
  73      {
  74          $revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')'];
  75  
  76          return strtr(rawurlencode($string), $revert);
  77      }
  78  
  79      /**
  80       * mb_chr() wrapper
  81       *
  82       * @param int $code
  83       *
  84       * @return string
  85       */
  86      public static function mbChr($code)
  87      {
  88          // Use the native implementation if available, but not on PHP 7.2 as mb_chr(0) is buggy there
  89          if (\PHP_VERSION_ID > 70300 && \function_exists('mb_chr')) {
  90              return mb_chr($code, 'UTF-8');
  91          }
  92  
  93          if (0x80 > $code %= 0x200000) {
  94              $s = \chr($code);
  95          } elseif (0x800 > $code) {
  96              $s = \chr(0xC0 | $code >> 6) . \chr(0x80 | $code & 0x3F);
  97          } elseif (0x10000 > $code) {
  98              $s = \chr(0xE0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F);
  99          } else {
 100              $s = \chr(0xF0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3F)
 101                  . \chr(0x80 | $code >> 6 & 0x3F) . \chr(0x80 | $code & 0x3F);
 102          }
 103  
 104          return $s;
 105      }
 106  
 107      /**
 108       * mb_strlen() wrapper
 109       *
 110       * @param string $string
 111       * @return int
 112       */
 113      public static function mbStrlen($string)
 114      {
 115          // Use the native implementation if available.
 116          if (\function_exists('mb_strlen')) {
 117              return mb_strlen($string, 'UTF-8');
 118          }
 119  
 120          if (\function_exists('iconv_strlen')) {
 121              return (int) @iconv_strlen($string, 'UTF-8');
 122          }
 123  
 124          throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.');
 125      }
 126  
 127      /**
 128       * mb_substr() wrapper
 129       * @param string $string
 130       * @param int $start
 131       * @param null|int $length
 132       * @return string
 133       */
 134      public static function mbSubstr($string, $start, $length = null)
 135      {
 136          // Use the native implementation if available.
 137          if (\function_exists('mb_substr')) {
 138              return mb_substr($string, $start, $length, 'UTF-8');
 139          }
 140  
 141          if (\function_exists('iconv_substr')) {
 142              if ($start < 0) {
 143                  $start = static::mbStrlen($string) + $start;
 144                  if ($start < 0) {
 145                      $start = 0;
 146                  }
 147              }
 148  
 149              if (null === $length) {
 150                  $length = 2147483647;
 151              } elseif ($length < 0) {
 152                  $length = static::mbStrlen($string) + $length - $start;
 153                  if ($length < 0) {
 154                      return '';
 155                  }
 156              }
 157  
 158              return (string)iconv_substr($string, $start, $length, 'UTF-8');
 159          }
 160  
 161          throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.');
 162      }
 163  
 164      /**
 165       * mb_strpos wrapper
 166       * @param string $haystack
 167       * @param string $needle
 168       * @param int $offset
 169       *
 170       * @return int|false
 171       */
 172      public static function mbStrpos($haystack, $needle, $offset = 0)
 173      {
 174          if (\function_exists('mb_strpos')) {
 175              return mb_strpos($haystack, $needle, $offset, 'UTF-8');
 176          }
 177  
 178          if (\function_exists('iconv_strpos')) {
 179              return iconv_strpos($haystack, $needle, $offset, 'UTF-8');
 180          }
 181  
 182          throw new \LogicException('Either mbstring (recommended) or iconv is necessary to use Scssphp.');
 183      }
 184  }