Example #1
0
 public function testItemAt()
 {
     $parse = new Parse(new Map(['abc', 'def', 'abc']));
     $actual = $parse->parse('itemAt("1")');
     $this->assertEquals("def", $actual->getValue());
 }
Example #2
0
 /**
  * parseInternal
  * @param $mapping
  * @param $until
  * @return ObjectInterface
  * @throws CatchableException
  * @throws \Exception
  */
 private function parseInternal($mapping, $until)
 {
     $mappingLength = strlen($mapping);
     $totalOutput = null;
     $currentMapping = '';
     $inQuote = false;
     $currentObject = $this->getOriginalObject();
     $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)) {
                     $currentObject = new Number($currentMapping);
                 } else {
                     $currentObject = new String($currentMapping);
                 }
                 $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 Parsable[] $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 Parse($currentObject);
                 $parameter = $parse->parseInternal($subMapping, self::UNTIL_CLOSING_COMMA_OR_CLOSING_PARENTHESIS);
                 $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) {
                     break;
                     //Found closing parenthesis
                 }
             }
             $currentObject = $this->call($mapping, $i, $currentObject, $currentMapping, $parameters);
             $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 == '+') {
             $currentObject = $this->call($mapping, $i, $currentObject, $currentMapping);
             $this->addToTotalOutput($currentObject);
             //Reset mapping/object for next part
             $currentMapping = '';
             $currentObject = $this->getOriginalObject();
             continue;
         }
         if ($char == '.') {
             $currentObject = $this->call($mapping, $i, $currentObject, $currentMapping);
             $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);
     }
     $currentObject = $this->call($mapping, $i, $currentObject, $currentMapping);
     $this->addToTotalOutput($currentObject);
     return $this->getTotalOutput();
 }