/**
  * @param string $itemName The property name
  * @param SearchQueryExpr $value The sub query
  * @return string
  */
 protected function processSubQueryValue($itemName, SearchQueryExpr $value)
 {
     if ($value->isEmpty()) {
         return '';
     }
     $result = $this->processExpr($value, $itemName);
     if ($value->isComplex()) {
         $result = sprintf('(%s)', $result);
     }
     return $result;
 }
示例#2
0
 /**
  * Arranges the given search expression before it can be converted to its string representation
  * As IMAP SEARCH command uses prefixed OR operator in its search expressions we need to prepare
  * our search expression before it will be converted to a string.
  * Examples:
  *    'val1 OR val2' need to be changed to 'OR val1 val2'
  *    'val1 OR val2 OR val3' need to be changed to 'OR val1 OR val2 val3'
  *    'NOT val1 OR val2' need to be changed to 'OR NOT val1 val2'
  *
  * @param SearchQueryExpr $expr The search expression
  * @return SearchQueryExpr
  */
 protected function arrangeExpr(SearchQueryExpr $expr)
 {
     // Make a clone of the expression and find out OR operators
     $result = new SearchQueryExpr();
     $orOperatorPositions = array();
     $i = 0;
     foreach ($expr as $item) {
         if ($item instanceof SearchQueryExprOperator) {
             $result->add($item);
             if ($item->getName() === 'OR') {
                 $orOperatorPositions[] = $i;
             }
         } elseif ($item instanceof SearchQueryExpr) {
             $result->add($this->arrangeExpr($item));
         } else {
             /** @var SearchQueryExprValueBase $item */
             $value = $item->getValue();
             if ($value instanceof SearchQueryExpr) {
                 $item->setValue($this->arrangeExpr($value));
             }
             $result->add($item);
         }
         $i++;
     }
     // Arrange OR operators is any
     foreach ($orOperatorPositions as $orPos) {
         $i = $orPos - 1;
         $parenthesisCounter = 0;
         while ($i >= 0) {
             $item = $result[$i];
             if ($item instanceof SearchQueryExprOperator) {
                 /** @var SearchQueryExprOperator $item */
                 switch ($item->getName()) {
                     case '(':
                         $parenthesisCounter--;
                         break;
                     case ')':
                         $parenthesisCounter++;
                         break;
                 }
             } elseif ($parenthesisCounter === 0) {
                 $this->moveOperator($result, $orPos, $this->correctNewPositionOfOperatorIfNeeded($result, $i));
                 break;
             }
             $i--;
         }
         if ($i === -1 && $parenthesisCounter === 0) {
             $this->moveOperator($result, $orPos, 0);
         }
     }
     return $result;
 }
 /**
  * {@inheritdoc}
  */
 protected function processSubQueryValue($itemName, SearchQueryExpr $value)
 {
     if ($value->isEmpty()) {
         return '';
     }
     if ($itemName !== null) {
         $keyword = $this->getKeyword($itemName);
         if (!$keyword) {
             throw new \InvalidArgumentException(sprintf('Unsupported property "%s".', $itemName));
         }
         $result = sprintf('%s%s', $keyword, $this->getNameValueDelimiter());
     } else {
         $result = '';
     }
     $expr = $this->processExpr($value);
     $result .= $value->isComplex() ? sprintf('(%s)', $expr) : $expr;
     return $result;
 }
示例#4
0
 private function andOperatorIfNeeded()
 {
     $exprItems = $this->expr->getItems();
     $lastIndex = count($exprItems) - 1;
     if ($lastIndex != -1) {
         $lastItem = $exprItems[$lastIndex];
         if (!$lastItem instanceof SearchQueryExprOperator || $lastItem instanceof SearchQueryExprOperator && $lastItem->getName() == ')') {
             $this->andOperator();
         }
     }
 }