Symfony API搜索本地化产品

Symfony API search for localized products

提问人:bechir 提问时间:11/17/2023 最后编辑:Brian Tompsett - 汤莱恩bechir 更新时间:11/18/2023 访问量:33

问:

对不起,如果标题不清楚,我不知道该怎么说。

我使用可翻译的学说将产品翻译成不同的语言,例如 和 。 我想使用为产品添加基本的搜索功能问题是我不知道如何添加自定义搜索过滤器或查询集合扩展以根据名称字段搜索产品,因为我与可翻译实体没有直接关系。可能不清楚,所以让我展示代码:frenApiPlatform

我有一个基本:Product

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use ApiPlatform\Metadata\GetCollection;
use App\Repository\ProductRepository;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslatableInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslatableTrait;
use Symfony\Component\Serializer\Annotation\Groups;

#[ORM\Entity(repositoryClass: ProductRepository::class)]
#[ApiResource(
    operations: [
        new GetCollection(
            normalizationContext: ['groups' => ['Product:collection', 'read']],
        ),
    ],
)]
class Product implements TranslatableInterface
{
    use TranslatableTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    #[Groups('read')]
    private ?int $id = null;

    #[ORM\Column]
    #[Groups(['Product:collection'])]
    private ?int $price = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getPrice(): ?int
    {
        return $this->price;
    }

    public function setPrice(int $price): self
    {
        $this->price = $price;

        return $this;
    }
}

ProductTranslation

<?php

namespace App\Entity;

use App\Repository\ProductTranslationRepository;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Contract\Entity\TranslationInterface;
use Knp\DoctrineBehaviors\Model\Translatable\TranslationTrait;

#[ORM\Entity(repositoryClass: ProductTranslationRepository::class)]
class ProductTranslation implements TranslationInterface
{
    use TranslationTrait;

    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\Column(length: 255)]
    private ?string $name = null;

    #[ORM\Column(type: Types::TEXT, nullable: true)]
    private ?string $description = null;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(?string $description): self
    {
        $this->description = $description;

        return $this;
    }
}

目标是做一些工作,并根据请求区域设置搜索类内字段的产品。/products?search_terms=foonameProductTranslation

有人尝试过这样做还是更好的选择?

交响乐 学说 api-platform.com

评论


答:

1赞 bechir 11/18/2023 #1

固定!有人遇到了同样的问题,解决方案在这里 https://github.com/KnpLabs/DoctrineBehaviors/issues/674

<?php

namespace App\ApiPlatform;

use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use App\Entity\Product;
use Doctrine\ORM\QueryBuilder;

class QueryCollectionExtension implements QueryCollectionExtensionInterface
{
    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, Operation $operation = null, array $context = []): void
    {
        if ($resourceClass === Product::class) {
            $searchTerms = $context['filters']['search_terms'] ?? null;

            if (null !== $searchTerms && '' != $searchTerms) {
                $alais = $queryBuilder->getRootAliases()[0];

                $queryBuilder->join(sprintf('%s.translations', $alais), 'p_tr')
                    ->andWhere('p_tr.name LIKE :terms')
                    ->setParameter('terms', '%' . $searchTerms . '%')
                ;
            }
        }
    }
}

评论

0赞 Alexandre Tranchant 11/20/2023
感谢您分享您的答案!你能接受你自己的答案吗?
1赞 bechir 11/21/2023
好的,我接受了。