Skip to content

Instantly share code, notes, and snippets.

@dmz9
Created April 8, 2018 21:50
Show Gist options
  • Save dmz9/4603ec301dd052b05a078c1a47adaf68 to your computer and use it in GitHub Desktop.
Save dmz9/4603ec301dd052b05a078c1a47adaf68 to your computer and use it in GitHub Desktop.
url to criteria
<?php
/**
* Date: 02.03.2018
* Time: 0:16
*/
use Doctrine\Common\Collections\Criteria;
use Doctrine\Common\Collections\Expr\CompositeExpression;
use Doctrine\Common\Collections\Expr\Expression;
use Doctrine\Common\Collections\ExpressionBuilder;
use Symfony\Component\HttpFoundation\Request;
class Filtering {
/**
* @var Request
*/
private $request;
private $result;
/**
* @var array
*/
private $allowedFields;
/**
* Filtering constructor.
*
* @param Request $request
* @param array $allowedFields
*/
public function __construct( Request $request, array $allowedFields ) {
$this->request = $request;
$this->allowedFields = $allowedFields;
}
public function __toString() {
if ( empty( $this->result ) ) {
$this->parse();
}
return empty( $this->result ) ? "" : http_build_query( $this->result );
}
/**
* @return Expression
*/
public function toExpression() {
$this->parse();
$builder = Criteria::expr();
$expressions = [];
foreach ( $this->result as $name => $value ) {
$parsed = self::parseFilterValue( $builder, $name, $value );
if ( null != $parsed ) {
$expressions[] = $parsed;
}
}
return empty( $expressions ) ? null : new CompositeExpression( CompositeExpression::TYPE_AND, $expressions );
}
/**
* @param ExpressionBuilder $builder
* @param string $field
* @param string $value
*
* @return Expression
*/
private function parseFilterValue( ExpressionBuilder $builder, $field = "", $value = "" ) {
$valueIsSingle = strpos( $value, "," ) === false;
$hasOperand = strpos( $value, ":" ) !== false;
if ( ! $hasOperand ) {
return $valueIsSingle ? $builder->eq( $field, $value ) : $builder->in( $field, explode( ",", $value ) );
}
$exploded = \explode( ":", $value, 2 );
$operand = strtolower( trim( (string) $exploded[ 0 ] ) );
$value = trim( $exploded[ 1 ] );
if ( empty( $operand ) || $operand == "in" || $operand == "eq" ) {
return $valueIsSingle ? $builder->eq( $field, $value ) : $builder->in( $field, explode( ",", $value ) );
}
switch ( $operand ) {
case "like":
return $builder->contains( $field, $value );
break;
case "lt":
return $builder->lt( $field, $value );
break;
case "gt":
return $builder->gt( $field, $value );
break;
case "lte":
return $builder->lte( $field, $value );
break;
case "gte":
return $builder->gte( $field, $value );
break;
default :
return null;
}
}
private function parse() {
$filter = [];
foreach ( $this->request->query->all() as $name => $value ) {
if ( ! in_array( $name, $this->allowedFields ) || empty( $name ) || empty( $value ) ) {
continue;
}
$filter[ $name ] = $value;
}
$this->result = $filter;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment