Skip to content

Commit

Permalink
[API][Products] Add custom Taxon filter
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamKasp committed Apr 14, 2021
1 parent 18b1ed4 commit 410863b
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 1 deletion.
72 changes: 72 additions & 0 deletions src/Sylius/Bundle/ApiBundle/Filter/TaxonFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace Sylius\Bundle\ApiBundle\Filter;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractContextAwareFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Core\Bridge\Symfony\Routing\IriConverter;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

/**
* It should be replaced with generic collection filter after fixed: https://github.com/api-platform/api-platform/issues/1868
*/
final class TaxonFilter extends AbstractContextAwareFilter
{
/** @var IriConverter */
private $iriConverter;

/** @var ManagerRegistry */
protected $managerRegistry;

public function __construct(IriConverter $iriConverter, ManagerRegistry $managerRegistry)
{
parent::__construct($managerRegistry);
$this->iriConverter = $iriConverter;
}

protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
{
if ($property !== 'productTaxons') {
return;
}

$taxon = $this->iriConverter->getItemFromIri($value);
$alias = $queryBuilder->getRootAliases()[0];
$valueParameter = $queryNameGenerator->generateParameterName('taxon');

$queryBuilder
->join(sprintf('%s.productTaxons', $alias), 'p')
->andWhere(sprintf('p.taxon = :%s', $valueParameter))
->setParameter($valueParameter, $taxon)
;
}

public function getDescription(string $resourceClass): array
{
$description = [];
$description["productTaxons"] =
[
'type' => 'string',
'required' => false,
'property' => null,
'swagger' => [
'name' =>'Product taxon filter',
'description' => 'Get a collection of product with chosen taxon'
]
];

return $description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<attribute>sylius.api.product_order_filter</attribute>
<attribute>sylius.api.product_taxon_code_filter</attribute>
<attribute>sylius.api.translation_order_name_and_locale_filter</attribute>
<attribute>sylius.api.product_taxon_filter</attribute>
</attribute>
<attribute name="normalization_context">
<attribute name="groups">shop:product:read</attribute>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,17 @@

<service id="sylius.api.product_taxon_code_filter" parent="api_platform.doctrine.orm.search_filter">
<argument type="collection">
<argument key="productTaxons.taxon.code">exact</argument>
<argument key="productTaxons.taxon">exact</argument>
</argument>
<tag name="api_platform.filter" />
</service>

<service id="sylius.api.product_taxon_filter" class="Sylius\Bundle\ApiBundle\Filter\TaxonFilter">
<argument type="service" id="api_platform.iri_converter" />
<argument type="service" id="Doctrine\Common\Persistence\ManagerRegistry" />
<tag name="api_platform.filter" />
</service>

<service id="sylius.api.product_name_filter" parent="api_platform.doctrine.orm.search_filter">
<argument type="collection">
<argument key="translations.name">partial</argument>
Expand Down
61 changes: 61 additions & 0 deletions src/Sylius/Bundle/ApiBundle/spec/Filter/TaxonFilterSpec.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace spec\Sylius\Bundle\ApiBundle\Filter;

use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Core\Bridge\Symfony\Routing\IriConverter;
use Doctrine\ORM\QueryBuilder;
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
use Sylius\Component\Core\Model\TaxonInterface;
use Symfony\Bridge\Doctrine\ManagerRegistry;

final class TaxonFilterSpec extends ObjectBehavior
{
function let(IriConverter $iriConverter, ManagerRegistry $managerRegistry): void
{
$this->beConstructedWith($iriConverter, $managerRegistry);
}

function it_adds_taxon_filter_if_property_is_product_taxon(
IriConverter $iriConverter,
TaxonInterface $taxon,
QueryBuilder $queryBuilder,
QueryNameGeneratorInterface $queryNameGenerator
): void {
$iriConverter->getItemFromIri('api/taxon')->willReturn($taxon);
$queryBuilder->getRootAliases()->shouldNotBeCalled();
$queryNameGenerator->generateParameterName('taxon')->willReturn('taxon1');

$queryBuilder
->join('o.productTaxons', 'p')
->shouldBeCalled()
->willReturn($queryBuilder)
;

$queryBuilder
->andWhere('p.taxon = taxon1')
->shouldBeCalled()
->willReturn($queryBuilder)
;

$queryBuilder
->setParameter('taxon1', $taxon)
->shouldBeCalled()
->willReturn($queryBuilder)
;

$this->filterProperty('productTaxon', 'api/taxon', $queryBuilder, $queryNameGenerator, Argument::type('string'));
}
}

0 comments on commit 410863b

Please sign in to comment.