Exemple #1
0
 protected function parseArguments(TokenIterator $tokens)
 {
     $operator = NULL;
     $conditions = [];
     while ($token = $tokens->nextToken()) {
         if ($tokens->isCurrent(self::TOK_LOGIC)) {
             if ($operator !== NULL && $operator !== $tokens->currentValue()) {
                 throw new Kdyby\Aop\ParserException('Unexpected operator ' . $tokens->currentValue() . '. If you wanna combine them, you must wrap them in brackets.');
             }
             $operator = $tokens->currentValue();
             continue;
         } elseif ($tokens->isCurrent('(')) {
             if ($conditions || $tokens->isNext('(')) {
                 $conditions[] = $this->parseArguments($tokens);
             }
             continue;
         }
         if ($tokens->isCurrent(')')) {
             break;
         }
         $left = self::sanitizeArgumentExpression(self::nextValue($tokens, [self::TOK_IDENTIFIER, self::TOK_STRING], self::TOK_WHITESPACE), $tokens->currentToken());
         $tokens->nextToken();
         $comparator = self::nextValue($tokens, [self::TOK_OPERATOR, self::TOK_LOGIC, ')'], self::TOK_WHITESPACE);
         if ($tokens->isCurrent(self::TOK_LOGIC, ')')) {
             $tokens->position -= 1;
             $conditions[] = [$left, Matcher\Criteria::EQ, new PhpLiteral("TRUE")];
             continue;
         }
         if ($tokens->isCurrent('in', 'nin', 'matches')) {
             $tokens->nextUntil(self::TOK_IDENTIFIER, self::TOK_STRING, '(');
             if ($tokens->isNext('(')) {
                 $tokens->nextToken();
                 // (
                 $right = [];
                 while ($token = $tokens->nextToken()) {
                     if ($tokens->isCurrent(')')) {
                         break;
                     } elseif ($tokens->isCurrent(self::TOK_IDENTIFIER, self::TOK_STRING)) {
                         $right[] = self::sanitizeArgumentExpression($tokens->currentValue(), $token);
                     } elseif (!$tokens->isCurrent(',', self::TOK_WHITESPACE)) {
                         throw new Kdyby\Aop\ParserException('Unexpected token ' . $token[Tokenizer::TYPE]);
                     }
                 }
                 if (empty($right)) {
                     throw new Kdyby\Aop\ParserException("Argument for {$comparator} cannot be an empty array.");
                 }
                 $conditions[] = [$left, $comparator, $right];
                 continue;
             }
         }
         $tokens->nextToken();
         $right = self::sanitizeArgumentExpression(self::nextValue($tokens, [self::TOK_IDENTIFIER, self::TOK_STRING], self::TOK_WHITESPACE), $tokens->currentToken());
         $conditions[] = [$left, $comparator, $right];
     }
     if (!$conditions) {
         if ($tokens->isCurrent(')')) {
             $tokens->nextToken();
         }
         return NULL;
     }
     try {
         if ($operator === ',') {
             $operator = Matcher\Criteria::TYPE_AND;
         }
         $criteria = new Matcher\Criteria($operator ?: Matcher\Criteria::TYPE_AND);
         foreach ($conditions as $condition) {
             if ($condition instanceof Matcher\Criteria) {
                 $criteria->where($condition);
             } else {
                 $criteria->where($condition[0], $condition[1], $condition[2]);
             }
         }
     } catch (Kdyby\Aop\InvalidArgumentException $e) {
         throw new Kdyby\Aop\ParserException('Invalid arguments', 0, $e);
     }
     if ($tokens->isCurrent(')')) {
         $tokens->nextToken();
     }
     return $criteria;
 }