Created
May 15, 2015 06:24
-
-
Save temp/26148b1fc700cc969e07 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* phlexible | |
* | |
* @copyright 2007 brainbits GmbH (http://www.brainbits.net) | |
* @license http://www.makeweb.de/LICENCE Dummy Licence | |
*/ | |
namespace Phlexible\Component\Expression; | |
use Doctrine\ORM\QueryBuilder; | |
use Webmozart\Expression\Comparison\Contains; | |
use Webmozart\Expression\Comparison\EndsWith; | |
use Webmozart\Expression\Comparison\Equals; | |
use Webmozart\Expression\Comparison\GreaterThan; | |
use Webmozart\Expression\Comparison\GreaterThanEqual; | |
use Webmozart\Expression\Comparison\In; | |
use Webmozart\Expression\Comparison\IsEmpty; | |
use Webmozart\Expression\Comparison\KeyExists; | |
use Webmozart\Expression\Comparison\KeyNotExists; | |
use Webmozart\Expression\Comparison\LessThan; | |
use Webmozart\Expression\Comparison\LessThanEqual; | |
use Webmozart\Expression\Comparison\Matches; | |
use Webmozart\Expression\Comparison\NotEmpty; | |
use Webmozart\Expression\Comparison\NotEquals; | |
use Webmozart\Expression\Comparison\NotSame; | |
use Webmozart\Expression\Comparison\Same; | |
use Webmozart\Expression\Comparison\StartsWith; | |
use Webmozart\Expression\Expression; | |
use Webmozart\Expression\Logic\AlwaysFalse; | |
use Webmozart\Expression\Logic\AlwaysTrue; | |
use Webmozart\Expression\Logic\Conjunction; | |
use Webmozart\Expression\Logic\Disjunction; | |
use Webmozart\Expression\Logic\Literal; | |
use Webmozart\Expression\Logic\Not; | |
use Webmozart\Expression\Selector\All; | |
use Webmozart\Expression\Selector\AtLeast; | |
use Webmozart\Expression\Selector\AtMost; | |
use Webmozart\Expression\Selector\Exactly; | |
use Webmozart\Expression\Selector\Key; | |
/** | |
* Expression visitor | |
* | |
* @author Stephan Wentz <sw@brainbits.net> | |
*/ | |
class QueryBuilderExpressionVisitor | |
{ | |
/** | |
* @var QueryBuilder | |
*/ | |
private $qb; | |
/** | |
* @var string | |
*/ | |
private $currentField; | |
/** | |
* @param QueryBuilder $qb | |
*/ | |
public function __construct(QueryBuilder $qb) | |
{ | |
$this->qb = $qb; | |
} | |
/** | |
* Dispatches walking an expression to the appropriate handler. | |
* | |
* @param Expression $expr | |
* | |
* @return mixed | |
* | |
* @throws \RuntimeException | |
*/ | |
public function dispatch(Expression $expr) | |
{ | |
switch (true) { | |
case ($expr instanceof Conjunction): | |
$and = $this->qb->expr()->andX(); | |
foreach ($expr->getConjuncts() as $conjunct) { | |
$and->add($this->dispatch($conjunct)); | |
} | |
return $and; | |
case ($expr instanceof Disjunction): | |
$or = $this->qb->expr()->orX(); | |
foreach ($expr->getDisjuncts() as $disjunct) { | |
$or->add($this->dispatch($disjunct)); | |
} | |
return $or; | |
case ($expr instanceof Key): | |
$this->currentField = $expr->getKey(); | |
$result = $this->dispatch($expr->getExpression()); | |
$this->currentField = null; | |
return $result; | |
case ($expr instanceof AlwaysTrue): | |
return $this->qb->expr()->eq(1, 1); | |
case ($expr instanceof AlwaysFalse): | |
return $this->qb->expr()->eq(1, 0); | |
case ($expr instanceof Not): | |
return $this->qb->expr()->not($this->dispatch($expr->getNegatedExpression())); | |
case ($expr instanceof All): | |
case ($expr instanceof AtLeast): | |
case ($expr instanceof AtMost): | |
case ($expr instanceof Exactly): | |
throw new \RuntimeException("Unsupported selector " . get_class($expr)); | |
case ($expr instanceof Literal): | |
return $this->walkComparison($expr); | |
default: | |
throw new \RuntimeException("Unknown Expression " . get_class($expr)); | |
} | |
} | |
/** | |
* {@inheritDoc} | |
*/ | |
public function walkComparison(Literal $comparison) | |
{ | |
if (!$this->currentField) { | |
throw new \RuntimeException("Comparison without field"); | |
} | |
$field = 'm.' . $this->currentField; | |
if ($comparison instanceof Contains) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->like($field, $this->literal("%$value%")); | |
} elseif ($comparison instanceof EndsWith) { | |
$value = $comparison->getAcceptedSuffix(); | |
return $this->qb->expr()->eq($field, $this->literal("%$value")); | |
} elseif ($comparison instanceof Equals) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->eq($field, $this->literal($value)); | |
} elseif ($comparison instanceof GreaterThan) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->gt($field, $this->literal($value)); | |
} elseif ($comparison instanceof GreaterThanEqual) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->gte($field, $this->literal($value)); | |
} elseif ($comparison instanceof In) { | |
$values = $comparison->getAcceptedValues(); | |
return $this->qb->expr()->in($field, $this->literal($values)); | |
} elseif ($comparison instanceof IsEmpty) { | |
throw new \RuntimeException("Unsupported comparison " . get_class($comparison)); | |
} elseif ($comparison instanceof KeyExists) { | |
throw new \RuntimeException("Unsupported comparison " . get_class($comparison)); | |
} elseif ($comparison instanceof KeyNotExists) { | |
throw new \RuntimeException("Unsupported comparison " . get_class($comparison)); | |
} elseif ($comparison instanceof LessThan) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->lt($field, $this->literal($value)); | |
} elseif ($comparison instanceof LessThanEqual) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->lte($field, $this->literal($value)); | |
} elseif ($comparison instanceof Matches) { | |
throw new \RuntimeException("Unsupported comparison " . get_class($comparison)); | |
} elseif ($comparison instanceof NotEmpty) { | |
throw new \RuntimeException("Unsupported comparison " . get_class($comparison)); | |
} elseif ($comparison instanceof NotEquals) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->neq($field, $this->literal($value)); | |
} elseif ($comparison instanceof NotSame) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->neq($field, $this->literal($value)); | |
} elseif ($comparison instanceof Same) { | |
$value = $comparison->getComparedValue(); | |
return $this->qb->expr()->eq($field, $this->literal($value)); | |
} elseif ($comparison instanceof StartsWith) { | |
$value = $comparison->getAcceptedPrefix(); | |
return $this->qb->expr()->like($field, $this->literal("$value%")); | |
} else { | |
throw new \RuntimeException("Unknown comparison " . get_class($comparison)); | |
} | |
} | |
private function literal($value) | |
{ | |
if (is_array($value)) { | |
foreach ($value as $index => $v) { | |
$value[$index] = $this->qb->expr()->literal($v); | |
} | |
} else { | |
$value = $this->qb->expr()->literal($value); | |
} | |
return $value; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment