Skip to content

Commit

Permalink
Merge pull request #246 from BitBagCommerce/op-303-api-support
Browse files Browse the repository at this point in the history
OP-303: API support
  • Loading branch information
senghe authored Jun 10, 2024
2 parents 6d4b136 + f9f9fd5 commit 36fee9e
Show file tree
Hide file tree
Showing 18 changed files with 989 additions and 1 deletion.
62 changes: 62 additions & 0 deletions src/Api/DataProvider/ProductCollectionDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace BitBag\SyliusElasticsearchPlugin\Api\DataProvider;

use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use BitBag\SyliusElasticsearchPlugin\Api\RequestDataHandler\RequestDataHandlerInterface;
use BitBag\SyliusElasticsearchPlugin\Api\Resolver\FacetsResolverInterface;
use BitBag\SyliusElasticsearchPlugin\Finder\ShopProductsFinderInterface;

final class ProductCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface
{
private const SUPPORTED_OPERATION_TYPE = 'elasticsearch_shop_get';

public function __construct(
private RequestDataHandlerInterface $dataHandler,
private ShopProductsFinderInterface $shopProductsFinder,
private FacetsResolverInterface $facetsResolver
) {
}

public function getCollection(
string $resourceClass,
string $operationName = null,
array $context = []
) {
$data = $this->dataHandler->retrieveData($context);
$facets = $this->facetsResolver->resolve($data);
$products = $this->shopProductsFinder->find($data);

return [
'items' => $products->jsonSerialize(),
'facets' => $facets,
'pagination' => [
'current_page' => $products->getCurrentPage(),
'has_previous_page' => $products->hasPreviousPage(),
'has_next_page' => $products->hasNextPage(),
'per_page' => $products->getMaxPerPage(),
'total_items' => $products->getNbResults(),
'total_pages' => $products->getNbPages(),
],
];
}

public function supports(
string $resourceClass,
string $operationName = null,
array $context = []
): bool {
return self::SUPPORTED_OPERATION_TYPE === $operationName;
}
}
36 changes: 36 additions & 0 deletions src/Api/RequestDataHandler/RequestDataHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace BitBag\SyliusElasticsearchPlugin\Api\RequestDataHandler;

use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\DataHandlerInterface;

final class RequestDataHandler implements RequestDataHandlerInterface
{
public function __construct(
private DataHandlerInterface $sortDataHandler,
private DataHandlerInterface $paginationDataHandler,
) {
}

public function retrieveData(array $context): array
{
$requestData = $context['filters'] ?? [];

return array_merge(
$this->sortDataHandler->retrieveData($requestData),
$this->paginationDataHandler->retrieveData($requestData),
['query' => $requestData['query'] ?? ''],
['facets' => $requestData['facets'] ?? []],
);
}
}
18 changes: 18 additions & 0 deletions src/Api/RequestDataHandler/RequestDataHandlerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace BitBag\SyliusElasticsearchPlugin\Api\RequestDataHandler;

interface RequestDataHandlerInterface
{
public function retrieveData(array $context): array;
}
52 changes: 52 additions & 0 deletions src/Api/Resolver/FacetsResolver.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace BitBag\SyliusElasticsearchPlugin\Api\Resolver;

use BitBag\SyliusElasticsearchPlugin\Facet\AutoDiscoverRegistryInterface;
use BitBag\SyliusElasticsearchPlugin\Facet\RegistryInterface;
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
use Elastica\Query;
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;

final class FacetsResolver implements FacetsResolverInterface
{
public function __construct(
private AutoDiscoverRegistryInterface $autoDiscoverRegistry,
private QueryBuilderInterface $queryBuilder,
private RegistryInterface $facetRegistry,
private PaginatedFinderInterface $finder,
) {
}

public function resolve(array $data): array
{
$this->autoDiscoverRegistry->autoRegister();

$boolQuery = $this->queryBuilder->buildQuery($data);
$query = new Query($boolQuery);
$query->setSize(0);

foreach ($this->facetRegistry->getFacets() as $facetId => $facet) {
$query->addAggregation($facet->getAggregation()->setName($facetId));
}

$facets = $this->finder->findPaginated($query);
$adapter = $facets->getAdapter();
if (!$adapter instanceof FantaPaginatorAdapter) {
return [];
}

return $adapter->getAggregations();
}
}
18 changes: 18 additions & 0 deletions src/Api/Resolver/FacetsResolverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* another great project.
* You can find more information about us on https://bitbag.io and write us
* an email on hello@bitbag.io.
*/

declare(strict_types=1);

namespace BitBag\SyliusElasticsearchPlugin\Api\Resolver;

interface FacetsResolverInterface
{
public function resolve(array $data): array;
}
Loading

0 comments on commit 36fee9e

Please sign in to comment.