예제 #1
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;
 }
예제 #2
0
 /**
  * Adds close parenthesis ')'.
  */
 public function closeParenthesis()
 {
     $this->expr->add(new SearchQueryExprOperator(')'));
 }