Skip to content

Commit

Permalink
fix(filters): GET request support in ApiRequestHanler
Browse files Browse the repository at this point in the history
After a some fixes and refactoring the filter system were not working anymore. This commit fixes the problem.

Please notice that it's not possible to send content in GET. This is
invalid on REST POV but could be required in some extremely rare
situation. I suggest to redefine the RequestApiHandler in those cases.
  • Loading branch information
Nek- committed Aug 19, 2020
1 parent 747c895 commit fcf4296
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 0 deletions.
31 changes: 31 additions & 0 deletions features/crud.feature
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,34 @@ Feature:
"content": "hello"
}
"""

Scenario: filter todo
Given there are some todos
When I make a GET request on "/todos?q=ba"
Then the last response contains:
"""
{
"meta": {
"totalPages": 1,
"totalResults": 2,
"currentPage": 1,
"maxPerPage": 30
},
"links": {
"prev": null,
"next": null,
"last": "http://localhost/todos?q=ba",
"first": "http://localhost/todos?q=ba"
},
"data": [
{
"id": 2,
"content": "bar"
},
{
"id": 3,
"content": "baz"
}
]
}
"""
6 changes: 6 additions & 0 deletions src/Form/ApiRequestHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ public function handleRequest(FormInterface $form, $request = null)
throw new UnexpectedTypeException($request, 'Symfony\Component\HttpFoundation\Request');
}

if ('GET' === $request->getMethod()) {
$form->submit($request->query->all());

return;
}

$clearMissing = $form->getConfig()->getOption(ApiType::CLEAR_MISSING_OPTION);
if (null === $clearMissing) {
$clearMissing = !in_array($request->getMethod(), ['POST', 'PUT']);
Expand Down
11 changes: 11 additions & 0 deletions tests/Melodiia/Form/ApiRequestHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\Request;

class ApiRequestHandlerTest extends TestCase
Expand Down Expand Up @@ -81,4 +82,14 @@ public function testICanChangeClearMissingOption()

$this->subject->handleRequest($this->form->reveal(), $this->request->reveal());
}

public function testItSupportsGetRequests()
{
$query = new ParameterBag(['hello' => 'foo']);
$this->form->submit(['hello' => 'foo'])->shouldBeCalled();
$this->request->getMethod()->willReturn('GET');
$this->request->query = $query;

$this->subject->handleRequest($this->form->reveal(), $this->request->reveal());
}
}
3 changes: 3 additions & 0 deletions tests/TestApplication/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,6 @@ services:

TestApplication\Controller\TodoContainsAction:
tags: ['controller.service_arguments']

TestApplication\Filters\TodoContainFilter:
autoconfigure: true
37 changes: 37 additions & 0 deletions tests/TestApplication/src/Filters/TodoContainFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace TestApplication\Filters;

use Doctrine\ORM\QueryBuilder;
use SwagIndustries\Melodiia\Crud\FilterInterface;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use TestApplication\Entity\Todo;

class TodoContainFilter implements FilterInterface
{
/**
* @param QueryBuilder $queryBuilder
*/
public function filter($queryBuilder, FormInterface $form): void
{
$q = $form->get('q')->getData();
if (!empty($q)) {
$queryBuilder->andWhere($queryBuilder->expr()->like('item.content', ':like'));
$queryBuilder->setParameter('like', '%' . $q . '%');
}
}

public function supports(string $class): bool
{
return Todo::class === $class;
}

public function buildForm(FormBuilderInterface $formBuilder): void
{
$formBuilder->add('q', TextType::class);
}
}

0 comments on commit fcf4296

Please sign in to comment.