Ejemplo n.º 1
0
 /**
  * @param string|array $filter Filter for querying records by
  * @param array        $params Filter replacement parameters
  *
  * @return array
  * @throws \DreamFactory\Core\Exceptions\BadRequestException
  */
 protected static function buildFilterArray($filter, $params = null)
 {
     if (empty($filter)) {
         return [];
     }
     if (is_array($filter)) {
         // assume client knows correct usage of Mongo query language
         return static::toMongoObjects($filter);
     }
     // handle logical operators first
     $logicalOperators = DbLogicalOperators::getDefinedConstants();
     foreach ($logicalOperators as $logicalOp) {
         if (DbLogicalOperators::NOT_STR === $logicalOp) {
             // NOT(a = 1)  or NOT (a = 1)format
             if (0 === stripos($filter, $logicalOp . '(') || 0 === stripos($filter, $logicalOp . '(')) {
                 $parts = trim(substr($filter, 3));
                 $parts = static::buildFilterArray($parts, $params);
                 return [static::localizeOperator($logicalOp) => $parts];
             }
         } else {
             // (a = 1) AND (b = 2) format
             $paddedOp = ') ' . $logicalOp . ' (';
             if (false !== ($pos = stripos($filter, $paddedOp))) {
                 $left = trim(substr($filter, 0, $pos));
                 $right = trim(substr($filter, $pos + strlen($paddedOp)));
                 $left = static::buildFilterArray($left, $params);
                 $right = static::buildFilterArray($right, $params);
                 return [static::localizeOperator($logicalOp) => [$left, $right]];
             }
             // (a = 1)AND(b = 2) format
             $paddedOp = ')' . $logicalOp . '(';
             if (false !== ($pos = stripos($filter, $paddedOp))) {
                 $left = trim(substr($filter, 0, $pos));
                 $right = trim(substr($filter, $pos + strlen($paddedOp)));
                 $left = static::buildFilterArray($left, $params);
                 $right = static::buildFilterArray($right, $params);
                 return [static::localizeOperator($logicalOp) => [$left, $right]];
             }
         }
     }
     $filter = trim(trim($filter, '()'));
     // the rest should be comparison operators
     // Note: order matters here!
     $sqlOperators = DbComparisonOperators::getParsingOrder();
     foreach ($sqlOperators as $sqlOp) {
         $paddedOp = static::padOperator($sqlOp);
         if (false !== ($pos = stripos($filter, $paddedOp))) {
             $field = trim(substr($filter, 0, $pos));
             $negate = false;
             if (false !== strpos($field, ' ')) {
                 $parts = explode(' ', $field);
                 if (count($parts) > 2 || 0 !== strcasecmp($parts[1], trim(DbLogicalOperators::NOT_STR))) {
                     // invalid field side of operator
                     throw new BadRequestException('Invalid or unparsable field in filter request.');
                 }
                 $field = $parts[0];
                 $negate = true;
             }
             $value = trim(substr($filter, $pos + strlen($paddedOp)));
             if (DbComparisonOperators::requiresValueList($sqlOp)) {
                 $value = trim($value, '()[]');
                 $parsed = [];
                 foreach (explode(',', $value) as $each) {
                     $parsed[] = static::determineValue($each, $field, $params);
                 }
                 $value = $parsed;
             } elseif (DbComparisonOperators::requiresNoValue($sqlOp)) {
                 switch ($sqlOp) {
                     case DbComparisonOperators::IS_NULL:
                         return [$field => null];
                     case DbComparisonOperators::IS_NOT_NULL:
                         return [$field => ['$ne' => null]];
                     case DbComparisonOperators::DOES_EXIST:
                         return [$field => ['$exists' => true]];
                     case DbComparisonOperators::DOES_NOT_EXIST:
                         return [$field => ['$exists' => false]];
                 }
             } else {
                 $value = static::determineValue($value, $field, $params);
                 if ('$eq' === static::localizeOperator($sqlOp)) {
                     // prior to 3.0
                     if ($negate) {
                         return [$field => ['$ne' => $value]];
                     }
                     return [$field => $value];
                 } elseif (DbComparisonOperators::LIKE === $sqlOp) {
                     //			WHERE name LIKE "%Joe%"	(array("name" => new MongoRegex("/Joe/")));
                     //			WHERE name LIKE "Joe%"	(array("name" => new MongoRegex("/^Joe/")));
                     //			WHERE name LIKE "%Joe"	(array("name" => new MongoRegex("/Joe$/")));
                     if ('%' == $value[strlen($value) - 1]) {
                         if ('%' == $value[0]) {
                             $value = '/' . trim($value, '%') . '/ ';
                         } else {
                             $value = '/^' . rtrim($value, '%') . '/ ';
                         }
                     } else {
                         if ('%' == $value[0]) {
                             $value = '/' . trim($value, '%') . '$/ ';
                         } else {
                             $value = '/' . $value . '/ ';
                         }
                     }
                     return [$field => new \MongoRegex($value)];
                 }
             }
             if ($negate) {
                 $value = ['$not' => $value];
             }
             return [$field => [static::localizeOperator($sqlOp) => $value]];
         }
     }
     return $filter;
 }
Ejemplo n.º 2
0
 public static function padOperator($operator)
 {
     if (ctype_alpha($operator)) {
         if (DbComparisonOperators::requiresNoValue($operator)) {
             return ' ' . $operator;
         }
         return ' ' . $operator . ' ';
     }
     return $operator;
 }