Skip to content

Commit

Permalink
IComponentMapper::ITEMS_FILTER - callback
Browse files Browse the repository at this point in the history
  • Loading branch information
janatjak committed Apr 28, 2021
1 parent a0ef733 commit 2cc5bfd
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 7 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,11 @@ Documentation
// order items
->setOption(IComponentMapper::ITEMS_ORDER, ['age' => 'ASC'])
// filter items
->setOption(IComponentMapper::ITEMS_FILTER, ['age !=' => 0])
->setOption(IComponentMapper::ITEMS_FILTER, ['age' => 0])
// filter items by callback
->setOption(IComponentMapper::ITEMS_FILTER, function(QueryBuilder $qb) {
$qb->andWhere('entity.age != 0')
})
// custom select label renderer
->setOption(IComponentMapper::ITEMS_TITLE, function (Author $author) {
return $author->getName() . ' - ' . $author->getAge();
Expand Down Expand Up @@ -106,4 +110,4 @@ Documentation
return $form;
}
}
```
```
22 changes: 17 additions & 5 deletions src/Utils/RelationsHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,22 +83,34 @@ protected function relatedMetadata($entity, string $relationName): ClassMetadata
/**
* @param ClassMetadata $meta
* @param callable|string $associationKeyOrCallback
* @param string[] $criteria
* @param array<string, mixed>|callable $criteria
* @param string[] $orderBy
* @return mixed[]
*/
protected function findPairs(ClassMetadata $meta, $associationKeyOrCallback, array $criteria, array $orderBy): array
protected function findPairs(ClassMetadata $meta, $associationKeyOrCallback, $criteria, array $orderBy): array
{
$classname = $meta->getName();
if (!class_exists($classname)) {
throw new LogicException();
}

$repository = $this->em->getRepository($classname);

$items = [];
$idKey = $meta->getSingleIdentifierFieldName();
foreach ($repository->findBy($criteria, $orderBy) as $entity) {

if (is_callable($criteria)) {
$qb = $this->em->createQueryBuilder()
->select('entity')
->from($classname, 'entity');

// call user func
$criteria($qb);

$entities = $qb->getQuery()->getResult();
} else {
$entities = $this->em->getRepository($classname)->findBy($criteria, $orderBy);
}

foreach ($entities as $entity) {
$identifier = $this->accessor->getValue($entity, $idKey);
if (is_object($identifier) && method_exists($identifier, 'toString')) {
// support for UuidInterface
Expand Down
18 changes: 18 additions & 0 deletions tests/Integration/Mappers/ManyToManyTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace FreezyBee\DoctrineFormMapper\Tests\Integration\Mappers;

require __DIR__ . '/../../bootstrap.php';

use Doctrine\ORM\QueryBuilder;
use FreezyBee\DoctrineFormMapper\DoctrineFormMapper;
use FreezyBee\DoctrineFormMapper\IComponentMapper;
use FreezyBee\DoctrineFormMapper\Mappers\ManyToMany;
Expand Down Expand Up @@ -63,6 +64,23 @@ class ManyToManyTest extends TestCase
Assert::same([1001, 1002], $component->getValue());
}

public function testLoadItemsWithCriteriaCallback()
{
$em = $this->getEntityManager();
$meta = $em->getClassMetadata(Article::class);

$component = new MultiSelectBox;
$component->setOption(IComponentMapper::ITEMS_TITLE, 'name');
$component->setOption(IComponentMapper::ITEMS_FILTER, function (QueryBuilder $qb) {
$qb->andWhere('entity.id = 1001');
});
$component->setParent(new Container, 'tags');

$result = $this->mapper->load($meta, $component, new Article(new Author('', new Address())));
Assert::true($result);
Assert::same([1001 => 'tag name1'], $component->getItems());
}

/**
*
*/
Expand Down
18 changes: 18 additions & 0 deletions tests/Integration/Mappers/ManyToOneTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ namespace FreezyBee\DoctrineFormMapper\Tests\Integration\Mappers;

require __DIR__ . '/../../bootstrap.php';

use Doctrine\ORM\QueryBuilder;
use FreezyBee\DoctrineFormMapper\DoctrineFormMapper;
use FreezyBee\DoctrineFormMapper\Exceptions\InvalidStateException;
use FreezyBee\DoctrineFormMapper\IComponentMapper;
Expand Down Expand Up @@ -66,6 +67,23 @@ class ManyToOneTest extends TestCase
Assert::same([11 => 'author name1', 12 => 'author name2', 13 => 'author name3'], $component->getItems());
}

public function testLoadItemsWithCriteriaCallback()
{
$em = $this->getEntityManager();
$meta = $em->getClassMetadata(Article::class);

$component = new SelectBox;
$component->setOption(IComponentMapper::ITEMS_TITLE, 'name');
$component->setOption(IComponentMapper::ITEMS_FILTER, function (QueryBuilder $qb) {
$qb->andWhere('entity.id = 11');
});
$component->setParent(new Container, 'author');

$result = $this->mapper->load($meta, $component, new Article(new Author('', new Address())));
Assert::true($result);
Assert::same([11 => 'author name1'], $component->getItems());
}

/**
*
*/
Expand Down

0 comments on commit 2cc5bfd

Please sign in to comment.