Skip to content

Commit

Permalink
Merge pull request #7 from Setono/options
Browse files Browse the repository at this point in the history
Options
  • Loading branch information
loevgaard authored Jul 4, 2024
2 parents 3790050 + 3a1e246 commit 1b46a12
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 12 deletions.
45 changes: 45 additions & 0 deletions src/DataMapper/Product/OptionsDataMapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\DataMapper\Product;

use Setono\SyliusMeilisearchPlugin\DataMapper\DataMapperInterface;
use Setono\SyliusMeilisearchPlugin\Document\Document;
use Setono\SyliusMeilisearchPlugin\Document\Product as ProductDocument;
use Setono\SyliusMeilisearchPlugin\Model\IndexableInterface;
use Setono\SyliusMeilisearchPlugin\Provider\IndexScope\IndexScope;
use Sylius\Component\Core\Model\ProductInterface;
use Webmozart\Assert\Assert;

final class OptionsDataMapper implements DataMapperInterface
{
public function map(IndexableInterface $source, Document $target, IndexScope $indexScope, array $context = []): void
{
Assert::true($this->supports($source, $target, $indexScope, $context));

foreach ($source->getEnabledVariants() as $variant) {
foreach ($variant->getOptionValues() as $optionValue) {
$option = $optionValue->getOption()?->getCode();
if ($option === null) {
continue;
}

$target->options[$option][] = (string) $optionValue->getValue();
}
}

foreach ($target->options as $option => $values) {
$target->options[$option] = array_values(array_unique($values));
}
}

/**
* @psalm-assert-if-true ProductInterface $source
* @psalm-assert-if-true ProductDocument $target
*/
public function supports(IndexableInterface $source, Document $target, IndexScope $indexScope, array $context = []): bool
{
return $source instanceof ProductInterface && $target instanceof ProductDocument;
}
}
13 changes: 1 addition & 12 deletions src/Document/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,10 @@ abstract class Document
public ?string $entityClass = null;

/**
* todo do we need this?
*
* This is the FQCN for the document being sent to Meilisearch. This makes it a lot easier to deserialize the JSON
* when it comes back from Meilisearch since we know which class to deserialize to
*
* @var class-string<Document>
*/
public string $documentClass;

/**
* Making the constructor final allows us to always be able toinstantiate an extending class without worrying about constructor arguments
* Making the constructor final allows us to always be able to instantiate an extending class without worrying about constructor arguments
*/
final public function __construct()
{
$this->documentClass = static::class;
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/Document/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Product extends Document implements UrlAwareInterface, ImageUrlsAwareInter

public ?float $originalPrice = null;

/** @var array<string, list<string>> */
public array $options = [];

/**
* This attribute will allow you to create a filter like 'Only show products on sale'
*/
Expand Down
1 change: 1 addition & 0 deletions src/Indexer/DefaultIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ protected function indexEntityClass(string $entity): void
// todo move this to a service
protected function normalize(Document $document): array
{
// todo skip null values
$data = $this->normalizer->normalize($document);
Assert::isArray($data);

Expand Down
59 changes: 59 additions & 0 deletions src/Normalizer/ProductNormalizer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusMeilisearchPlugin\Normalizer;

use Setono\SyliusMeilisearchPlugin\Document\Product;
use Symfony\Component\Serializer\Exception\LogicException;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

final class ProductNormalizer implements NormalizerInterface
{
public function __construct(private readonly NormalizerInterface $normalizer)
{
}

public function normalize(mixed $object, ?string $format = null, array $context = []): array
{
if (!$this->supportsNormalization($object)) {
throw new LogicException(sprintf('The object must be an instance of %s', Product::class));
}

$data = $this->normalizer->normalize($object, $format, $context);
if ($data instanceof \ArrayObject) {
$data = $data->getArrayCopy();
}

if (!is_array($data)) {
throw new LogicException('The normalized product data must be an array or an ArrayObject');
}

/**
* @var string $option
* @var list<string> $values
*/
foreach ($data['options'] as $option => $values) {
$data[$option . '_option'] = $values;
}

unset($data['options']);

return $data;
}

/**
* @psalm-assert-if-true Product $data
*/
public function supportsNormalization(mixed $data, ?string $format = null): bool
{
return $data instanceof Product;
}

public function getSupportedTypes(?string $format): array
{
return [
Product::class => true,
];
}
}
1 change: 1 addition & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<import resource="services/filter.xml"/>
<import resource="services/javascript.xml"/>
<import resource="services/message.xml"/>
<import resource="services/normalizer.xml"/>
<import resource="services/provider.xml"/>
<import resource="services/resolver.xml"/>
<import resource="services/url_generator.xml"/>
Expand Down
4 changes: 4 additions & 0 deletions src/Resources/config/services/data_mapper.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@
<tag name="setono_sylius_meilisearch.data_mapper" priority="100"/>
</service>

<service id="Setono\SyliusMeilisearchPlugin\DataMapper\Product\OptionsDataMapper">
<tag name="setono_sylius_meilisearch.data_mapper" priority="100"/>
</service>

<!-- Taxon data mappers -->
<service id="Setono\SyliusMeilisearchPlugin\DataMapper\Taxon\TaxonDataMapper">
<tag name="setono_sylius_meilisearch.data_mapper" priority="100"/>
Expand Down
11 changes: 11 additions & 0 deletions src/Resources/config/services/normalizer.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="Setono\SyliusMeilisearchPlugin\Normalizer\ProductNormalizer">
<argument type="service" id="serializer.normalizer.object"/>

<tag name="serializer.normalizer"/>
</service>
</services>
</container>

0 comments on commit 1b46a12

Please sign in to comment.