Skip to content

Instantly share code, notes, and snippets.

@blaues0cke
Last active October 14, 2015 08:15
Show Gist options
  • Save blaues0cke/6f1a53e1bd5d9dda8974 to your computer and use it in GitHub Desktop.
Save blaues0cke/6f1a53e1bd5d9dda8974 to your computer and use it in GitHub Desktop.
A filter that allows you to sort by related entities using DunglasApiBundle (https://github.com/dunglas/DunglasApiBundle).
<?php
namespace Your\AppBundle\Api\Filter;
use Dunglas\ApiBundle\Doctrine\Orm\Filter\AbstractFilter;
use Doctrine\Common\Persistence\ManagerRegistry;
use Doctrine\ORM\QueryBuilder;
use Dunglas\ApiBundle\Api\IriConverterInterface;
use Dunglas\ApiBundle\Api\ResourceInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
/**
* Description of OrderByRelationFilter
*
* @author thomas.kekeisen
*/
class OrderByRelationFilter extends AbstractFilter
{
/**
* @var array List of properties by witch the collection can or cannot be ordered.
*/
protected $properties;
/**
* @var string Keyword used to retrieve the value.
*/
protected $orderParameter;
/**
* @param ManagerRegistry $managerRegistry
* @param string $orderParameter Keyword used to retrieve the value.
* @param array|null $properties List of property names on which the filter will be enabled.
*/
public function __construct(ManagerRegistry $managerRegistry, $orderParameter)
{
$this->managerRegistry = $managerRegistry;
$this->orderParameter = $orderParameter;
}
/**
* {@inheritdoc}
*/
public function apply(ResourceInterface $resource, QueryBuilder $queryBuilder, Request $request)
{
$this->applyFilter($resource, $queryBuilder, $request->query->get($this->orderParameter));
}
/**
* {@inheritdoc}
*/
protected function applyFilter(ResourceInterface $resource, QueryBuilder $queryBuilder, array $values = null)
{
$metadata = $this->getClassMetadata($resource);
$associations = $metadata->getAssociationNames();
$currentChar = 65;
if (!empty($values) && is_array($values))
{
foreach ($values as $relationName => $order)
{
$splittedName = explode('.', $relationName);
if (count($splittedName) == 2)
{
if (in_array($splittedName[0], $associations))
{
$mapping = $metadata->associationMappings[$splittedName[0]];
if ($mapping['type'] == '1' || $mapping['type'] == '2')
{
$class = $metadata->getAssociationTargetClass($splittedName[0]);
if (property_exists($class, $splittedName[1]))
{
$alias = 'oj'.chr($currentChar);
$queryBuilder
->leftJoin('o.'.$splittedName[0], $alias)
->addOrderBy(sprintf('%s.%s', $alias, $splittedName[1]), $order);
}
++$currentChar;
}
}
}
}
}
}
/**
* {@inheritdoc}
*/
public function getDescription(ResourceInterface $resource)
{
$description = [];
// TODO: Return all possible sorting parameters?
return $description;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment