Example #1
0
 /**
  * parseInternal
  * @param $mapping
  * @param $until
  * @return void
  * @throws CatchableException
  * @throws \Exception
  */
 private function parseInternal($mapping, $until)
 {
     $mappingLength = strlen($mapping);
     $currentMapping = '';
     $inQuote = false;
     $closingParenthesisFound = false;
     for ($i = 0; $i < $mappingLength; $i++) {
         $char = $mapping[$i];
         $atEnd = $i + 1 == $mappingLength;
         $nextChar = $atEnd ? null : $mapping[$i + 1];
         if ($char == '\\') {
             if ($atEnd) {
                 $this->throwMappingException('An escape character "\\" must either be escaped or not at the end of a mapping', $mapping, $i);
             }
             //Add the next character since we are escaping it
             $currentMapping .= $nextChar;
             $i++;
             //Skip the next character
             continue;
         }
         if ($inQuote) {
             if ($char == '"') {
                 if (!($atEnd || $nextChar == '+' || $nextChar == '.' || $until == self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS && ($nextChar == ')' || $nextChar == ','))) {
                     $this->throwMappingException('A closing quote "\\"" must either be followed by the end of the mapping, a closing parenthesis, a plus, a "," or a .', $mapping, $i);
                 }
                 $inQuote = false;
                 if (is_numeric($currentMapping)) {
                     $object = new Number($currentMapping);
                 } else {
                     $object = new String($currentMapping);
                 }
                 $this->addToCurrentMethod(new Method(new RawValue($object)));
                 $currentMapping = '';
                 continue;
             }
             $currentMapping .= $char;
             continue;
         }
         if ($char == '"') {
             if ($currentMapping != '') {
                 $this->throwMappingException('A beginning quote "\\"" must be at the beginning of a mapping', $mapping, $i);
             }
             $inQuote = true;
             continue;
         }
         if ($char == '(') {
             /** @type Method[] $parameters */
             $parameters = [];
             $i++;
             //Offset for opening parenthesis
             $subMapping = substr($mapping, $i);
             if ($subMapping == '') {
                 $this->throwMappingException('There are more opening parenthesis than closing parenthesis', $mapping, $i);
             }
             while (strlen($subMapping) > 0) {
                 $parse = new Parser();
                 $parse->setOriginalMapping($this->getOriginalMapping());
                 $parse->parseInternal($subMapping, self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS);
                 $parameter = $parse->getMethods();
                 $isLastParameter = substr($subMapping, $parse->getLastIndex(), 1) == ')';
                 if (!$isLastParameter || $parse->getLastIndex() > 0) {
                     $parameters[] = $parameter;
                 }
                 $i += $parse->getLastIndex() + 1;
                 $subMapping = substr($subMapping, $parse->getLastIndex() + 1);
                 if ($isLastParameter) {
                     $i -= 1;
                     break;
                     //Found closing parenthesis
                 }
             }
             $method = new Method($currentMapping);
             $method->setParameters($parameters);
             $method->setRawMapping($mapping);
             $method->setRawMappingIndex($i);
             $this->addToCurrentMethod($method);
             $currentMapping = '';
             continue;
         }
         if ($char == ')') {
             if ($until != self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS) {
                 $this->throwMappingException('There are more closing parenthesis than opening parenthesis', $mapping, $i);
             }
             $closingParenthesisFound = true;
             $this->setLastIndex($i);
             break;
         }
         if ($char == ',') {
             if ($until != self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS) {
                 $this->throwMappingException('Commas are only allowed inside of parameters for methods', $mapping, $i);
             }
             $closingParenthesisFound = true;
             $this->setLastIndex($i);
             break;
         }
         if ($char == '+') {
             $method = new Method($currentMapping);
             $method->setRawMapping($mapping);
             $method->setRawMappingIndex($i);
             $this->addToCurrentMethod($method);
             $this->finishCurrentMethod();
             //Reset mapping/object for next part
             $currentMapping = '';
             continue;
         }
         if ($char == '.') {
             $method = new Method($currentMapping);
             $method->setRawMapping($mapping);
             $method->setRawMappingIndex($i);
             $this->addToCurrentMethod($method);
             $currentMapping = '';
             continue;
         }
         $currentMapping .= $char;
     }
     if (!$closingParenthesisFound && $until == self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS) {
         $this->throwMappingException('There are more opening parenthesis than closing parenthesis', $mapping, $i);
     }
     if ($inQuote) {
         $this->throwMappingException('There is no matching closing quote to an opening quote', $mapping, $mappingLength);
     }
     $method = new Method($currentMapping);
     $method->setRawMapping($mapping);
     $method->setRawMappingIndex($i);
     $this->addToCurrentMethod($method);
     $this->finishCurrentMethod();
 }
Example #2
0
 /**
  * parse
  * @param string $mapping
  * @return mixed
  */
 public function parse($mapping)
 {
     $parser = new Parser();
     $methods = $parser->parse($mapping);
     foreach ($methods as $method) {
         $currentObject = $this->getOriginalObject();
         do {
             $method->setCurrentObject($currentObject);
             $method->setOriginalObject($this->getOriginalObject());
             $method->setOriginalMapping($mapping);
             $currentObject = $method->call();
             $method = $method->getNextMethod();
         } while (!is_null($method));
         $this->addToTotalOutput($currentObject);
     }
     return $this->getTotalOutput();
 }