/**
  * {@inheritdoc}
  */
 public function addRestriction($restriction, $condition, $isComputed = false)
 {
     if ($isComputed) {
         throw new \LogicException('The HAVING restrictions is not supported yet.');
     }
     if ($this->currentExpr === null) {
         // this is the first item in a group
         $this->currentExpr = $restriction;
     } else {
         // other items
         if ($condition === FilterUtility::CONDITION_OR) {
             if ($this->currentExpr instanceof Expr\Orx) {
                 $this->currentExpr->add($restriction);
             } else {
                 $this->currentExpr = $this->qb->expr()->orX($this->currentExpr, $restriction);
             }
         } else {
             if ($this->currentExpr instanceof Expr\Andx) {
                 $this->currentExpr->add($restriction);
             } else {
                 $this->currentExpr = $this->qb->expr()->andX($this->currentExpr, $restriction);
             }
         }
     }
 }
예제 #2
0
 public function addFilterCondition(Composite $sub, QueryBuilder $query)
 {
     $unique = time();
     $q = new Comparison('a.name', Comparison::EQ, '?' . $unique);
     $query->setParameter($unique, $this->attribute);
     $sub->add($q);
 }
예제 #3
0
 /**
  * Add new condition to remove ace by share scope
  *
  * @param QueryBuilder $qb
  * @param Composite    $expr
  * @param string       $scope
  *
  * @throws UnknownShareScopeException
  */
 protected function addExprByShareScope(QueryBuilder $qb, Composite $expr, $scope)
 {
     if ($scope === Share::SHARE_SCOPE_USER) {
         $expr->add($qb->expr()->eq('asid.username', 'true'));
     } elseif ($scope === Share::SHARE_SCOPE_BUSINESS_UNIT) {
         $expr->add($qb->expr()->like('asid.identifier', $qb->expr()->literal('Oro\\\\Bundle\\\\OrganizationBundle\\\\Entity\\\\BusinessUnit%')));
     } else {
         throw new UnknownShareScopeException($scope);
     }
 }
 /**
  * Recursively takes the specified criteria and adds too the expression.
  *
  * The criteria is defined in an array notation where each item in the list
  * represents a comparison <fieldName, operator, value>. The operator maps to
  * comparison methods located in ExpressionBuilder. The key in the array can
  * be used to identify grouping of comparisons.
  *
  * @example
  * $criteria = array(
  *      'or' => array(
  *          array('field1', 'like', '%field1Value%'),
  *          array('field2', 'like', '%field2Value%')
  *      ),
  *      'and' => array(
  *          array('field3', 'eq', 3),
  *          array('field4', 'eq', 'four')
  *      ),
  *      array('field5', 'neq', 5)
  * );
  *
  * $qb = new QueryBuilder();
  * addCriteria($qb, $qb->expr()->andX(), $criteria);
  * echo $qb->getSQL();
  *
  * // Result:
  * // SELECT *
  * // FROM tableName
  * // WHERE ((field1 LIKE '%field1Value%') OR (field2 LIKE '%field2Value%'))
  * // AND ((field3 = '3') AND (field4 = 'four'))
  * // AND (field5 <> '5')
  *
  * @param QueryBuilder $qb
  * @param Composite $expr
  * @param array $criteria
  */
 private static function _addCriteria($qb, Composite $expr, array $criteria)
 {
     if (count($criteria)) {
         foreach ($criteria as $expression => $comparison) {
             list($field, $operator, $value) = $comparison;
             // MINIMUM VALIDATION (to prevent silly access to database) - BEGIN
             if (is_string($operator)) {
                 if (!in_array($operator, ['and', 'or', 'like', 'eq', 'ne', 'lt', 'le', 'gt', 'ge', 'in', 'out'])) {
                     throw new \Exception('RQL: Operator not supported!');
                 }
                 if (!in_array($operator, ['and', 'or']) && is_null($value)) {
                     throw new \Exception('RQL: Value cannot be empty!');
                 }
                 if (in_array($operator, ['like', 'eq', 'ne', 'lt', 'le', 'gt', 'ge']) && is_array($value)) {
                     throw new \Exception('RQL: Value type cannot be Array!');
                 }
                 if ($operator == 'like' && !is_string($value)) {
                     throw new \Exception('RQL: Value type must be String!');
                 }
                 if ($operator == 'like' && ($value == 'true()' || $value == 'false()')) {
                     throw new \Exception('RQL: Value type cannot be boolean!');
                 }
                 if (in_array($operator, ['lt', 'le', 'gt', 'ge']) && !is_numeric($value)) {
                     throw new \Exception('RQL: Value type must be Numeric!');
                 }
                 if (in_array($operator, ['like', 'eq', 'ne', 'lt', 'le', 'gt', 'ge']) && trim($value) == '') {
                     throw new \Exception('RQL: Value cannot be an empty String/Number!');
                 }
                 if (in_array($operator, ['in', 'out']) && !is_array($value)) {
                     throw new \Exception('RQL: Value type must be Array!');
                 }
                 if (in_array($operator, ['in', 'out']) && count($value) == 0) {
                     throw new \Exception('RQL: Value type cannot be an empty Array!');
                 }
                 if (in_array($operator, ['in', 'out'])) {
                     foreach ($value as $v) {
                         if (is_array($v)) {
                             throw new \Exception('RQL: Value cannot be a multidimensional Array!');
                         }
                         if (is_null($v)) {
                             throw new \Exception('RQL: Value cannot have null Array elements!');
                         }
                         if (trim($v) == '') {
                             throw new \Exception('RQL: Value cannot have empty Array elements!');
                         }
                         if ($v == 'null()') {
                             throw new \Exception('RQL: Value cannot have null Array elements!');
                         }
                     }
                 }
             }
             // MINIMUM VALIDATION - END
             if ($expression === 'and') {
                 $expr->add(self::_addCriteria($qb, $qb->expr()->andX(), $comparison));
             } else {
                 if ($expression === 'or') {
                     $expr->add(self::_addCriteria($qb, $qb->expr()->orX(), $comparison));
                 } else {
                     switch ($operator) {
                         case 'like':
                             $field = 'LOWER(' . $field . ')';
                             if ($value == 'null()') {
                                 $expr->add($qb->expr()->isNull($field));
                             } elseif ($value == 'empty()') {
                                 $value = $qb->expr()->literal('');
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } else {
                                 $value = $qb->expr()->literal(strtolower($value));
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             }
                             break;
                         case 'eq':
                             if ($value == 'null()') {
                                 $expr->add($qb->expr()->isNull($field));
                             } elseif ($value == 'true()') {
                                 $value = $qb->expr()->literal(TRUE);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } elseif ($value == 'false()') {
                                 $value = $qb->expr()->literal(FALSE);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } elseif ($value == 'empty()') {
                                 $value = $qb->expr()->literal('');
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } else {
                                 $value = $qb->expr()->literal($value);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             }
                             break;
                         case 'ne':
                             $operator = 'neq';
                             if ($value == 'null()') {
                                 $expr->add($qb->expr()->isNotNull($field));
                             } elseif ($value == 'true()') {
                                 $value = $qb->expr()->literal(TRUE);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } elseif ($value == 'false()') {
                                 $value = $qb->expr()->literal(FALSE);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } elseif ($value == 'empty()') {
                                 $value = $qb->expr()->literal('');
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             } else {
                                 $value = $qb->expr()->literal($value);
                                 $expr->add($qb->expr()->{$operator}($field, $value));
                             }
                             break;
                         case 'lt':
                             $value = $qb->expr()->literal($value);
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         case 'le':
                             $operator = 'lte';
                             $value = $qb->expr()->literal($value);
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         case 'gt':
                             $value = $qb->expr()->literal($value);
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         case 'ge':
                             $operator = 'gte';
                             $value = $qb->expr()->literal($value);
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         case 'in':
                             array_walk($value, function (&$v) {
                                 if ($v == 'true()') {
                                     $v = $qb->expr()->literal(TRUE);
                                 } elseif ($v == 'false()') {
                                     $v = $qb->expr()->literal(FALSE);
                                 } elseif ($v == 'empty()') {
                                     $v = $qb->expr()->literal('');
                                 } else {
                                     $v = $qb->expr()->literal($v);
                                 }
                             });
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         case 'out':
                             $operator = 'notIn';
                             array_walk($value, function (&$v) {
                                 if ($v == 'true()') {
                                     $v = $qb->expr()->literal(TRUE);
                                 } elseif ($v == 'false()') {
                                     $v = $qb->expr()->literal(FALSE);
                                 } elseif ($v == 'empty()') {
                                     $v = $qb->expr()->literal('');
                                 } else {
                                     $v = $qb->expr()->literal($v);
                                 }
                             });
                             $expr->add($qb->expr()->{$operator}($field, $value));
                             break;
                         default:
                             $value = $qb->expr()->literal($value);
                             $expr->add($qb->expr()->{$operator}($field, $value));
                     }
                 }
             }
         }
     }
     return $expr;
 }
예제 #5
0
 /**
  * @param Composite      $expressions
  * @param                $filterCondition
  *
  * @param QueryBuilder   $queryBuilder
  *
  * @throws \Netdudes\DataSourceryBundle\DataSource\Driver\Doctrine\Exception\ColumnNotFoundException
  * @throws \Exception
  */
 protected function addExpressionsForFilterCondition(Composite $expressions, FilterCondition $filterCondition, QueryBuilder $queryBuilder)
 {
     // Build an unique token name for parameter substitution
     $token = $this->buildUniqueToken($filterCondition, $queryBuilder);
     $filterMethod = $filterCondition->getMethod();
     // Add the filtering statement
     $value = $filterCondition->getValue();
     // Flag to not insert the parameter if the logic requires it
     $ignoreParameter = false;
     // Depending on the filter type, create a condition
     $condition = $this->buildCondition($filterCondition, $token, $queryBuilder);
     $expressions->add($condition);
     // Modify the value if needed
     if ($filterMethod == FilterCondition::METHOD_STRING_LIKE) {
         $value = str_replace('*', '%', $filterCondition->getValue());
     }
     // Ignore value if needed
     if ($filterMethod == FilterCondition::METHOD_IN && count($filterCondition->getValue()) <= 0 || $filterMethod == FilterCondition::METHOD_IS_NULL) {
         $ignoreParameter = true;
     }
     // Insert the value substituting the token
     if (!$ignoreParameter) {
         $queryBuilder->setParameter($token, $value);
     }
 }
예제 #6
0
 /**
  * @param array $criteria
  * @param Expr\Composite $expr
  * @throws \InvalidArgumentException
  */
 protected function populate(array $criteria, Expr\Composite $expr)
 {
     if ($this->isComparison($criteria)) {
         $expr->add($this->normalizeComparison($criteria));
         return;
     }
     foreach ($criteria as $operatorOrField => $comparisonOrValue) {
         if (!$this->isOperator($operatorOrField)) {
             if ($this->isComparison($comparisonOrValue)) {
                 $comparison = $this->normalizeComparison($comparisonOrValue);
             } else {
                 if (!$this->isField($operatorOrField)) {
                     if (is_int($operatorOrField) && is_array($comparisonOrValue)) {
                         $this->populate($comparisonOrValue, $expr);
                         continue;
                     }
                     throw new \InvalidArgumentException(sprintf('Criteria format is invalid; "%s" is not a valid field for "%s" value', $operatorOrField, is_object($comparisonOrValue) ? get_class($comparisonOrValue) : print_r($comparisonOrValue, true)));
                 }
                 $operator = is_array($comparisonOrValue) ? static::IN : static::EQUAL;
                 $comparison = $this->{$operator}($operatorOrField, $comparisonOrValue);
             }
             $expr->add($comparison);
         } elseif ($this->isComposite($operatorOrField)) {
             $operator = $this->normalizeOperator($operatorOrField);
             $composite = $this->{$operator}();
             $this->populate($comparisonOrValue, $composite);
             $expr->add($composite);
         } else {
             $operator = $this->normalizeOperator($operatorOrField);
             $composite = $this->getDefaultComposite();
             $this->populate($comparisonOrValue, $composite);
             $expr->add($this->{$operator}($composite));
         }
     }
 }
 private function processFilter(ExpressionManager $expressionManager, Expr\Composite $compositeExpr, QueryBuilder $qb, DoctrineQueryBuilderParametersBinder $binder, Filter $filter)
 {
     $name = $filter->getProperty();
     $fieldName = $expressionManager->getDqlPropertyName($name);
     if (in_array($filter->getComparator(), array(Filter::COMPARATOR_IS_NULL, Filter::COMPARATOR_IS_NOT_NULL))) {
         // these are sort of 'special case'
         $compositeExpr->add($qb->expr()->{$filter->getComparator()}($fieldName));
     } else {
         $value = $filter->getValue();
         $comparatorName = $filter->getComparator();
         if (!$this->isUsefulInFilter($filter->getComparator(), $filter->getValue()) || !$this->isUsefulFilter($expressionManager, $name, $value)) {
             return;
         }
         // when "IN" is used in conjunction with TO_MANY type of relation,
         // then we will treat it in a special way and generate "MEMBER OF" queries
         // instead
         $isAdded = false;
         if ($expressionManager->isAssociation($name)) {
             $mapping = $expressionManager->getMapping($name);
             if (in_array($comparatorName, array(Filter::COMPARATOR_IN, Filter::COMPARATOR_NOT_IN)) && in_array($mapping['type'], array(CMI::ONE_TO_MANY, CMI::MANY_TO_MANY))) {
                 $statements = array();
                 foreach ($value as $id) {
                     $statements[] = sprintf((Filter::COMPARATOR_NOT_IN == $comparatorName ? 'NOT ' : '') . '?%d MEMBER OF %s', $binder->getNextIndex(), $expressionManager->getDqlPropertyName($name));
                     $binder->bind($this->convertValue($expressionManager, $name, $id));
                 }
                 if (Filter::COMPARATOR_IN == $comparatorName) {
                     $compositeExpr->add(call_user_func_array(array($qb->expr(), 'orX'), $statements));
                 } else {
                     $compositeExpr->addMultiple($statements);
                 }
                 $isAdded = true;
             }
         }
         if (!$isAdded) {
             if (is_array($value) && count($value) != count($value, \COUNT_RECURSIVE)) {
                 // must be "OR-ed" ( multi-dimensional array )
                 $orStatements = array();
                 foreach ($value as $orFilter) {
                     if (!$this->isUsefulInFilter($orFilter['comparator'], $orFilter['value']) || !$this->isUsefulFilter($expressionManager, $name, $orFilter['value'])) {
                         continue;
                     }
                     if (in_array($orFilter['comparator'], array(Filter::COMPARATOR_IN, Filter::COMPARATOR_NOT_IN))) {
                         $orStatements[] = $qb->expr()->{$orFilter['comparator']}($fieldName);
                     } else {
                         $orStatements[] = $qb->expr()->{$orFilter['comparator']}($fieldName, '?' . $binder->getNextIndex());
                     }
                     $binder->bind($orFilter['value']);
                 }
                 $compositeExpr->add(call_user_func_array(array($qb->expr(), 'orX'), $orStatements));
             } else {
                 $compositeExpr->add($qb->expr()->{$comparatorName}($fieldName, '?' . $binder->getNextIndex()));
                 $binder->bind($this->convertValue($expressionManager, $name, $value));
             }
         }
     }
 }