Skip to content

Instantly share code, notes, and snippets.

@K-Phoen
Last active July 21, 2017 18:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save K-Phoen/04830079aa020b3577b7 to your computer and use it in GitHub Desktop.
Save K-Phoen/04830079aa020b3577b7 to your computer and use it in GitHub Desktop.
On Taming Repository Classes in Doctrine… Among other things.
interface Specification
{
public function getCriteria();
}
class FilterGroup implements Specification
{
private $group;
public function __construct($group)
{
$this->group = $group;
}
public function getCriteria()
{
return new Expr\Comparison('group', Expr\Comparison::EQ, new Expr\Value($this->group));
}
}
$specification = Criteria::create();
$specification->where(
$specification->expr()->andX(
(new Spec\FilterGroup($groupId))->getCriteria(),
(new Spec\FilterPermission($permission))->getCriteria()
)
);
$groups = $app['orm.ems']['api']
->getRepository('\EasyBib\Api\Entity\Group')
->matching($specification);
$rulerz = new RulerZ(/* stuff */);
// 1. Write a rule.
$rule = 'group in :groups and points > :points and length(name) > 2';
// 2. Filter a QueryBuilder
$usersQb = $entityManager
->createQueryBuilder()
->select('u')
->from('Entity\User', 'u');
// or an array of objects
$usersObj = [
new User('Joe', 'guest', 40),
new User('Moe', 'guest', 20),
];
// 3. Enjoy!
$parameters = [
'points' => 30,
'groups' => ['customer', 'guest'],
];
var_dump($rulerz->filter($usersQb, $rule, $parameters));
var_dump($rulerz->filter($usersObj, $rule, $parameters));
interface Specification
{
public function getRule();
public function getParameters();
}
class FilterGroup implements Specification
{
private $group;
public function __construct($group)
{
$this->group = $group;
}
public function getRule()
{
return 'group = :group';
}
public function getParameters()
{
return [
'group' => $this->group,
];
}
}
class AndX implements Specification
{
private $specifications = [];
public function __construct(array $specifications = [])
{
foreach ($specifications as $specification) {
$this->specifications[] = $specification;
}
}
public function getRule()
{
return implode(' AND ', array_map(function ($specification) {
return $specification->getRule();
}, $this->specifications));
}
public function getParameters()
{
return call_user_func_array('array_merge', array_map(function ($specification) {
return $specification->getParameters();
}, $this->specifications));
}
}
$specification = new Spec\AndX(
new Spec\FilterGroup($groupId),
new Spec\FilterPermission($permission)
);
$rulerz->filter($target, $specification->getRule(), $specification->getParameters());
interface Specification
{
public function match(QueryBuilder $qb, $dqlAlias);
public function modifyQuery(Query $query);
}
class FilterGroup implements Specification
{
private $group;
public function __construct($group)
{
$this->group = $group;
}
public function match(QueryBuilder $qb, $dqlAlias)
{
$qb->setParameter('group', $this->group);
return $qb->expr()->eq($dqlAlias . '.group', ':group');
}
public function modifyQuery(Query $query) { /* empty ***/ }
}
$specification = new Spec\AsArray(new Spec\AndX(
new Spec\FilterGroup($groupId),
new Spec\FilterPermission($permission)
));
$groups = $app['orm.ems']['api']
->getRepository('\EasyBib\Api\Entity\Group')
->match($specification);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment