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

   1  <?php
   2  
   3  namespace Sabberworm\CSS\Value;
   4  
   5  use Sabberworm\CSS\Parsing\ParserState;
   6  use Sabberworm\CSS\Parsing\UnexpectedEOFException;
   7  use Sabberworm\CSS\Parsing\UnexpectedTokenException;
   8  
   9  class CalcFunction extends CSSFunction
  10  {
  11      /**
  12       * @var int
  13       */
  14      const T_OPERAND = 1;
  15  
  16      /**
  17       * @var int
  18       */
  19      const T_OPERATOR = 2;
  20  
  21      /**
  22       * @return CalcFunction
  23       *
  24       * @throws UnexpectedTokenException
  25       * @throws UnexpectedEOFException
  26       */
  27      public static function parse(ParserState $oParserState)
  28      {
  29          $aOperators = ['+', '-', '*', '/'];
  30          $sFunction = trim($oParserState->consumeUntil('(', false, true));
  31          $oCalcList = new CalcRuleValueList($oParserState->currentLine());
  32          $oList = new RuleValueList(',', $oParserState->currentLine());
  33          $iNestingLevel = 0;
  34          $iLastComponentType = null;
  35          while (!$oParserState->comes(')') || $iNestingLevel > 0) {
  36              $oParserState->consumeWhiteSpace();
  37              if ($oParserState->comes('(')) {
  38                  $iNestingLevel++;
  39                  $oCalcList->addListComponent($oParserState->consume(1));
  40                  $oParserState->consumeWhiteSpace();
  41                  continue;
  42              } elseif ($oParserState->comes(')')) {
  43                  $iNestingLevel--;
  44                  $oCalcList->addListComponent($oParserState->consume(1));
  45                  $oParserState->consumeWhiteSpace();
  46                  continue;
  47              }
  48              if ($iLastComponentType != CalcFunction::T_OPERAND) {
  49                  $oVal = Value::parsePrimitiveValue($oParserState);
  50                  $oCalcList->addListComponent($oVal);
  51                  $iLastComponentType = CalcFunction::T_OPERAND;
  52              } else {
  53                  if (in_array($oParserState->peek(), $aOperators)) {
  54                      if (($oParserState->comes('-') || $oParserState->comes('+'))) {
  55                          if (
  56                              $oParserState->peek(1, -1) != ' '
  57                              || !($oParserState->comes('- ')
  58                                  || $oParserState->comes('+ '))
  59                          ) {
  60                              throw new UnexpectedTokenException(
  61                                  " {$oParserState->peek()} ",
  62                                  $oParserState->peek(1, -1) . $oParserState->peek(2),
  63                                  'literal',
  64                                  $oParserState->currentLine()
  65                              );
  66                          }
  67                      }
  68                      $oCalcList->addListComponent($oParserState->consume(1));
  69                      $iLastComponentType = CalcFunction::T_OPERATOR;
  70                  } else {
  71                      throw new UnexpectedTokenException(
  72                          sprintf(
  73                              'Next token was expected to be an operand of type %s. Instead "%s" was found.',
  74                              implode(', ', $aOperators),
  75                              $oVal
  76                          ),
  77                          '',
  78                          'custom',
  79                          $oParserState->currentLine()
  80                      );
  81                  }
  82              }
  83              $oParserState->consumeWhiteSpace();
  84          }
  85          $oList->addListComponent($oCalcList);
  86          $oParserState->consume(')');
  87          return new CalcFunction($sFunction, $oList, ',', $oParserState->currentLine());
  88      }
  89  }