Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(bridge): APIP bridge #7

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"psr-4": {
"MeiliSearchBundle\\": "src/",
"MeiliSearchBundle\\Bridge\\": "src/Bridge/",
"MeiliSearchBundle\\Bridge\\ApiPlatform\\": "src/Bridge/ApiPlatform/",
"MeiliSearchBundle\\Bridge\\ApiPlatform\\Api\\": "src/Bridge/ApiPlatform/Api/",
"MeiliSearchBundle\\Bridge\\ApiPlatform\\DataProvider\\": "src/Bridge/ApiPlatform/DataProvider/",
"MeiliSearchBundle\\Bridge\\ApiPlatform\\Filter\\": "src/Bridge/ApiPlatform/Filter/",
"MeiliSearchBundle\\Bridge\\Doctrine\\": "src/Bridge/Doctrine/",
"MeiliSearchBundle\\Bridge\\Doctrine\\Annotation\\": "src/Bridge/Doctrine/Annotation/",
"MeiliSearchBundle\\Bridge\\Doctrine\\Annotation\\Reader\\": "src/Bridge/Doctrine/Annotation/Reader/",
Expand Down Expand Up @@ -55,6 +59,10 @@
"psr-4": {
"Tests\\MeiliSearchBundle\\": "tests/",
"Tests\\MeiliSearchBundle\\Bridge\\": "tests/Bridge/",
"Tests\\MeiliSearchBundle\\Bridge\\ApiPlatform\\": "tests/Bridge/ApiPlatform/",
"Tests\\MeiliSearchBundle\\Bridge\\ApiPlatform\\Api\\": "tests/Bridge/ApiPlatform/Api/",
"Tests\\MeiliSearchBundle\\Bridge\\ApiPlatform\\DataProvider\\": "tests/Bridge/ApiPlatform/DataProvider/",
"Tests\\MeiliSearchBundle\\Bridge\\ApiPlatform\\Filter\\": "tests/Bridge/ApiPlatform/Filter/",
"Tests\\MeiliSearchBundle\\Bridge\\Doctrine\\": "tests/Bridge/Doctrine/",
"Tests\\MeiliSearchBundle\\Bridge\\Doctrine\\Annotation\\": "tests/Bridge/Doctrine/Annotation/",
"Tests\\MeiliSearchBundle\\Bridge\\Doctrine\\Annotation\\Reader\\": "tests/Bridge/Doctrine/Annotation/Reader/",
Expand Down
16 changes: 16 additions & 0 deletions doc/api_platform.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Api-Platform

This bundle provides **reading** API-Platform support.

## Installation

Make sure APIP is installed then enable the APIP support via the configuration:

```yaml
# meili_search.yaml
meili_search:
api_platform:
enabled: true

# ...
```
30 changes: 30 additions & 0 deletions src/Bridge/ApiPlatform/Api/IdentifierExtractor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace MeiliSearchBundle\Bridge\ApiPlatform\Api;

use ApiPlatform\Core\Api\IdentifiersExtractorInterface;
use ApiPlatform\Core\Bridge\Elasticsearch\Api\IdentifierExtractorInterface;
use ApiPlatform\Core\Bridge\Elasticsearch\Exception\NonUniqueIdentifierException;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class IdentifierExtractor implements IdentifierExtractorInterface
{
private $identifiersExtractor;

public function __construct(IdentifiersExtractorInterface $identifiersExtractor)
{
$this->identifiersExtractor = $identifiersExtractor;
}

/**
* {@inheritdoc}
*/
public function getIdentifierFromResourceClass(string $resourceClass): string
{
// TODO: Implement getIdentifierFromResourceClass() method.
}
}
72 changes: 72 additions & 0 deletions src/Bridge/ApiPlatform/DataProvider/ItemDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

namespace MeiliSearchBundle\Bridge\ApiPlatform\DataProvider;

use ApiPlatform\Core\Bridge\Elasticsearch\Exception\IndexNotFoundException;
use ApiPlatform\Core\Bridge\Elasticsearch\Exception\NonUniqueIdentifierException;
use ApiPlatform\Core\DataProvider\ItemDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\Exception\ResourceClassNotFoundException;
use ApiPlatform\Core\Exception\ResourceClassNotSupportedException;
use ApiPlatform\Core\Metadata\Resource\Factory\ResourceMetadataFactoryInterface;
use MeiliSearchBundle\Bridge\ApiPlatform\Api\IdentifierExtractor;
use MeiliSearchBundle\Document\DocumentEntryPointInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class ItemDataProvider implements ItemDataProviderInterface, RestrictedDataProviderInterface
{
private $denormalizer;
private $documentEntryPoint;
private $identifierExtractor;
private $resourceMetadataFactory;

public function __construct(
DenormalizerInterface $denormalizer,
DocumentEntryPointInterface $documentEntryPoint,
IdentifierExtractor $identifierExtractor,
ResourceMetadataFactoryInterface $resourceMetadataFactory
) {
$this->denormalizer = $denormalizer;
$this->documentEntryPoint = $documentEntryPoint;
$this->identifierExtractor = $identifierExtractor;
$this->resourceMetadataFactory = $resourceMetadataFactory;
}

/**
* {@inheritdoc}
*/
public function getItem(string $resourceClass, $id, string $operationName = null, array $context = [])
{
}

public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
try {
$resourceMetadata = $this->resourceMetadataFactory->create($resourceClass);
if (false === $resourceMetadata->getItemOperationAttribute($operationName, 'meilisearch', true, true)) {
return false;
}
} catch (ResourceClassNotFoundException $e) {
return false;
}

try {
$this->documentMetadataFactory->create($resourceClass);
} catch (IndexNotFoundException $e) {
return false;
}

try {
$this->identifierExtractor->getIdentifierFromResourceClass($resourceClass);
} catch (NonUniqueIdentifierException $e) {
return false;
}

return true;
}
}
12 changes: 12 additions & 0 deletions src/Bridge/ApiPlatform/Filter/OffsetFilter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace MeiliSearchBundle\Bridge\ApiPlatform\Filter;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class OffsetFilter
{
}
9 changes: 9 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ public function getConfigTreeBuilder(): TreeBuilder
->info('Define the directory filters are stored the metadata')
->defaultValue('%kernel.project_dir%/var/_ms')
->end()
->arrayNode('api_platform')
->info('Configure the API-Platform support')
->children()
->scalarNode('enabled')
->info('Enable the Api-Platform support')
->defaultValue(false)
->end()
->end()
->end()
->arrayNode('cache')
->validate()
->always()
Expand Down
39 changes: 39 additions & 0 deletions src/Document/DocumentMetadata.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace MeiliSearchBundle\Document;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class DocumentMetadata
{
private const DEFAULT_TYPE = 'array';

/**
* @var string
*/
private $index;

/**
* @var string
*/
private $type;

public function __construct(string $index, ?string $type = self::DEFAULT_TYPE)
{
$this->index = $index;
$this->type = $type;
}

public function getIndex(): string
{
return $this->index;
}

public function getType(): string
{
return $this->type;
}
}
2 changes: 1 addition & 1 deletion src/Update/UpdateOrchestratorInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function getUpdate(string $index, int $updateId): UpdateInterface;
/**
* @param string $uid
*
* @return array<int, UpdateInterface>
* @return UpdateInterface[]
*
* @throws Throwable
*/
Expand Down
14 changes: 14 additions & 0 deletions tests/Bridge/ApiPlatform/Api/IdentifierExtractorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Bridge\ApiPlatform\Api;

use PHPUnit\Framework\TestCase;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class IdentifierExtractorTest extends TestCase
{
}
14 changes: 14 additions & 0 deletions tests/Bridge/ApiPlatform/DataProvider/ItemDataProviderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace Bridge\ApiPlatform\DataProvider;

use PHPUnit\Framework\TestCase;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class ItemDataProviderTest extends TestCase
{
}
15 changes: 15 additions & 0 deletions tests/Bridge/ApiPlatform/Filter/OffsetFilterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

declare(strict_types=1);

namespace Bridge\ApiPlatform\Filter;

use PHPUnit\Framework\TestCase;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class OffsetFilterTest extends TestCase
{
}

18 changes: 17 additions & 1 deletion tests/DependencyInjection/ConfigurationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,22 @@ public function testConfigurationCanDefinePrefix(): void
static::assertSame('bar', $configuration['prefix']);
}

public function testConfigurationCanEnableApiPlatform()
{
$configuration = (new Processor())->processConfiguration(new Configuration(), [
'meili_search' => [
'apiKey' => 'test',
'api_platform' => [
'enabled' => true,
],
],
]);

static::assertArrayHasKey('api_platform', $configuration);
static::assertArrayHasKey('enabled', $configuration['api_platform']);
static::assertTrue($configuration['api_platform']['enabled']);
}

public function testConfigurationDoesNotEnableCacheByDefault(): void
{
$configuration = (new Processor())->processConfiguration(new Configuration(), [
Expand All @@ -90,7 +106,7 @@ public function testConfigurationDoesNotEnableCacheByDefault(): void

static::assertArrayHasKey('cache', $configuration);
static::assertArrayHasKey('enabled', $configuration['cache']);
static::assertSame(false, $configuration['cache']['enabled']);
static::assertFalse($configuration['cache']['enabled']);
static::assertArrayHasKey('pool', $configuration['cache']);
static::assertSame('app', $configuration['cache']['pool']);
}
Expand Down
27 changes: 27 additions & 0 deletions tests/Document/DocumentMetadataTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace Tests\MeiliSearchBundle\Document;

use MeiliSearchBundle\Document\DocumentMetadata;
use PHPUnit\Framework\TestCase;

/**
* @author Guillaume Loulier <[email protected]>
*/
final class DocumentMetadataTest extends TestCase
{
public function testMetadataCanBeCreated(): void
{
$metadata = new DocumentMetadata('foo', 'object');

static::assertSame('foo', $metadata->getIndex());
static::assertSame('object', $metadata->getType());

$metadata = new DocumentMetadata('foo');

static::assertSame('foo', $metadata->getIndex());
static::assertSame('array', $metadata->getType());
}
}