我的 searchBar 存在问题,该搜索栏包含在带有模板的 base.html.twig 文件中。
当我仅使用 findAll 功能显示产品时它可以工作,但现在我有自己的查询并且搜索不再工作。
清除缓存不起作用。
我使用的是 Symfony 5.5.7 和 PHP 8.2.0
产品存储库
<?php
namespace App\Repository;
use App\Entity\Product;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\Tools\Pagination\Paginator;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<Product>
*
* @method Product|null find($id, $lockMode = null, $lockVersion = null)
* @method Product|null findOneBy(array $criteria, array $orderBy = null)
* @method Product[] findAll()
* @method Product[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class ProductRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Product::class);
}
/**
* Recherche des produits en fonction du formulaire
* @return array
*/
public function search(string $query){
$qb = $this->createQueryBuilder('p');
$qb
->where('MATCH_AGAINST(p.titre, p.description, p.short_titre) AGAINST (:query boolean)>0')
->setParameter('query', $query);
return $qb->getQuery()->getResult();
}
/**
* @return Product[] Returns an array of Product objects
*/
public function newProducts(int $page = 1, int $limit = 10)
{
$query = $this->createQueryBuilder('p')
->where('p.date_publication >= :week_ago')
->setParameter('week_ago', new \DateTime('-7 days'))
->orderBy('p.titre', 'ASC')
->getQuery();
$paginator = new Paginator($query);
$paginator->getQuery()
->setFirstResult($limit * ($page - 1))
->setMaxResults($limit);
return $paginator;
}
public function jvProducts(int $page = 1, int $limit = 10)
{
$query = $this->createQueryBuilder('p')
->where('p.categorie = 29')
->orderBy('p.titre', 'ASC')
->getQuery();
$paginator = new Paginator($query);
$paginator->getQuery()
->setFirstResult($limit * ($page - 1))
->setMaxResults($limit);
return $paginator;
}
public function figurines(int $page = 1, int $limit = 10)
{
$query = $this->createQueryBuilder('p')
->where('p.categorie = 23')
->orderBy('p.titre', 'ASC')
->getQuery();
$paginator = new Paginator($query);
$paginator->getQuery()
->setFirstResult($limit * ($page - 1))
->setMaxResults($limit);
return $paginator;
}
public function produitsMonde(int $page = 1, int $limit = 10)
{
$query = $this->createQueryBuilder('p')
->where('p.categorie = 31')
->orderBy('p.titre', 'ASC')
->getQuery();
$paginator = new Paginator($query);
$paginator->getQuery()
->setFirstResult($limit * ($page - 1))
->setMaxResults($limit);
return $paginator;
}
public function textiles(int $page = 1, int $limit = 10)
{
$query = $this->createQueryBuilder('p')
->where('p.categorie = 32')
->orderBy('p.titre', 'ASC')
->getQuery();
$paginator = new Paginator($query);
$paginator->getQuery()
->setFirstResult($limit * ($page - 1))
->setMaxResults($limit);
return $paginator;
}
// public function findOneBySomeField($value): ?Product
// {
// return $this->createQueryBuilder('p')
// ->andWhere('p.exampleField = :val')
// ->setParameter('val', $value)
// ->getQuery()
// ->getOneOrNullResult()
// ;
// }
}
搜索控制器
<?php
namespace App\Controller;
use App\Repository\ProductRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class SearchController extends AbstractController
{
#[Route('/search', name: 'app_search')]
public function index(): Response
{
return $this->render('search/index.html.twig', [
'controller_name' => 'SearchController',
]);
}
public function searchBar(){
$form = $this->createFormBuilder()
->setAction($this->generateUrl('handleSearch'))
->add('query', TextType::class, [
'label' => false,
'attr' => [
'class' => 'form-control',
'placeholder' => 'Entrez un mot-clé'
]
])
->add('recherche', SubmitType::class, [
'attr' => [
'class' => 'btn btn-primary'
]
])
->getForm();
return $this->render('_partials/_searchBar.html.twig', [
'form' => $form->createView()
]);
}
#[Route('/handleSearch', name: 'handleSearch')]
public function handleSearch(Request $request, ProductRepository $productRepository)
{
$query = $request->request->all('form')['query'];
if($query){
$products = $productRepository->search($query);
}
return $this->render('_partials/_searchIndex.html.twig', [
'products' => $products
]);
}
}
实体 产品.php
<?php
namespace App\Entity;
use App\Repository\ProductRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ProductRepository::class)]
#[ORM\Index(name: 'product', columns: ['titre', 'description', 'short_titre'], flags: ["fulltext"] )]
class Product
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 255)]
private ?string $titre = null;
#[ORM\Column(length: 255)]
private ?string $slug = null;
#[ORM\Column(type: Types::TEXT)]
private ?string $description = null;
#[ORM\Column]
private ?float $prix = null;
#[ORM\Column]
private ?int $quantite = null;
#[ORM\Column(nullable: true)]
private ?float $remise = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $dimensions = null;
#[ORM\Column]
private ?bool $disponibilite = null;
#[ORM\ManyToOne(inversedBy: 'products')]
#[ORM\JoinColumn(nullable: false)]
private ?Categorie $categorie = null;
#[ORM\OneToMany(mappedBy: 'produit', targetEntity: Images::class)]
#[ORM\JoinColumn(onDelete:"CASCADE")]
private Collection $images;
#[ORM\ManyToMany(targetEntity: Couleurs::class, mappedBy: 'product')]
private Collection $couleurs;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?Fabricants $fabricant = null;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?Marques $marque = null;
#[ORM\ManyToMany(targetEntity: Matieres::class, inversedBy: 'products')]
private Collection $matieres;
#[ORM\ManyToMany(targetEntity: Personnages::class, inversedBy: 'products')]
private Collection $personnages;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?SousCategorie1 $sousCategorie1 = null;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?SousCategorie2 $sousCategorie2 = null;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?Univers $univers = null;
#[ORM\ManyToOne(inversedBy: 'products')]
private ?SousUnivers $sousUnivers = null;
#[ORM\Column(type: Types::TEXT, nullable: true)]
private ?string $avis = null;
#[ORM\Column(length: 255, nullable: true)]
private ?string $short_titre = null;
#[ORM\Column(type: Types::DATETIME_MUTABLE)]
private ?\DateTimeInterface $date_publication = null;
public function __toString()
{
return $this->titre;
}
public function __construct()
{
$this->images = new ArrayCollection();
$this->couleurs = new ArrayCollection();
$this->matieres = new ArrayCollection();
$this->personnages = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getTitre(): ?string
{
return $this->titre;
}
public function setTitre(string $titre): static
{
$this->titre = $titre;
return $this;
}
public function getSlug(): ?string
{
return $this->slug;
}
public function setSlug(string $slug): static
{
$this->slug = $slug;
return $this;
}
public function getDescription(): ?string
{
return $this->description;
}
public function setDescription(string $description): static
{
$this->description = $description;
return $this;
}
public function getPrix(): ?float
{
return $this->prix;
}
public function setPrix(float $prix): static
{
$this->prix = $prix;
return $this;
}
public function getQuantite(): ?int
{
return $this->quantite;
}
public function setQuantite(int $quantite): static
{
$this->quantite = $quantite;
return $this;
}
public function getRemise(): ?float
{
return $this->remise;
}
public function setRemise(?float $remise): static
{
$this->remise = $remise;
return $this;
}
public function getDimensions(): ?string
{
return $this->dimensions;
}
public function setDimensions(?string $dimensions): static
{
$this->dimensions = $dimensions;
return $this;
}
public function isDisponibilite(): ?bool
{
return $this->disponibilite;
}
public function setDisponibilite(bool $disponibilite): static
{
$this->disponibilite = $disponibilite;
return $this;
}
public function getCategorie(): ?Categorie
{
return $this->categorie;
}
public function setCategorie(?Categorie $categorie): static
{
$this->categorie = $categorie;
return $this;
}
/**
* @return Collection<int, Images>
*/
public function getImages(): Collection
{
return $this->images;
}
public function addImage(Images $image): static
{
if (!$this->images->contains($image)) {
$this->images->add($image);
$image->setProduit($this);
}
return $this;
}
public function removeImage(Images $image): static
{
if ($this->images->removeElement($image)) {
// set the owning side to null (unless already changed)
if ($image->getProduit() === $this) {
$image->setProduit(null);
}
}
return $this;
}
/**
* @return Collection<int, Couleurs>
*/
public function getCouleurs(): Collection
{
return $this->couleurs;
}
public function addCouleur(Couleurs $couleur): static
{
if (!$this->couleurs->contains($couleur)) {
$this->couleurs->add($couleur);
$couleur->addProduct($this);
}
return $this;
}
public function removeCouleur(Couleurs $couleur): static
{
if ($this->couleurs->removeElement($couleur)) {
$couleur->removeProduct($this);
}
return $this;
}
public function getFabricant(): ?Fabricants
{
return $this->fabricant;
}
public function setFabricant(?Fabricants $fabricant): static
{
$this->fabricant = $fabricant;
return $this;
}
public function getMarque(): ?Marques
{
return $this->marque;
}
public function setMarque(?Marques $marque): static
{
$this->marque = $marque;
return $this;
}
/**
* @return Collection<int, Matieres>
*/
public function getMatieres(): Collection
{
return $this->matieres;
}
public function addMatiere(Matieres $matiere): static
{
if (!$this->matieres->contains($matiere)) {
$this->matieres->add($matiere);
}
return $this;
}
public function removeMatiere(Matieres $matiere): static
{
$this->matieres->removeElement($matiere);
return $this;
}
/**
* @return Collection<int, Personnages>
*/
public function getPersonnages(): Collection
{
return $this->personnages;
}
public function addPersonnage(Personnages $personnage): static
{
if (!$this->personnages->contains($personnage)) {
$this->personnages->add($personnage);
}
return $this;
}
public function removePersonnage(Personnages $personnage): static
{
$this->personnages->removeElement($personnage);
return $this;
}
public function getSousCategorie1(): ?SousCategorie1
{
return $this->sousCategorie1;
}
public function setSousCategorie1(?SousCategorie1 $sousCategorie1): static
{
$this->sousCategorie1 = $sousCategorie1;
return $this;
}
public function getSousCategorie2(): ?SousCategorie2
{
return $this->sousCategorie2;
}
public function setSousCategorie2(?SousCategorie2 $sousCategorie2): static
{
$this->sousCategorie2 = $sousCategorie2;
return $this;
}
public function getUnivers(): ?Univers
{
return $this->univers;
}
public function setUnivers(?Univers $univers): static
{
$this->univers = $univers;
return $this;
}
public function getSousUnivers(): ?SousUnivers
{
return $this->sousUnivers;
}
public function setSousUnivers(?SousUnivers $sousUnivers): static
{
$this->sousUnivers = $sousUnivers;
return $this;
}
public function getAvis(): ?string
{
return $this->avis;
}
public function setAvis(?string $avis): static
{
$this->avis = $avis;
return $this;
}
public function getShortTitre(): ?string
{
return $this->short_titre;
}
public function setShortTitre(?string $short_titre): static
{
$this->short_titre = $short_titre;
return $this;
}
public function getDatePublication(): ?\DateTimeInterface
{
return $this->date_publication;
}
public function setDatePublication(\DateTimeInterface $date_publication): static
{
$this->date_publication = $date_publication;
return $this;
}
}
我正在尝试使用“匹配”功能来搜索标题、描述或短标题中包含单词的产品。搜索应该让我进入一个新页面,其中包含所有结果或一条消息,告诉我未找到任何结果。
您是否尝试过更换:
->where('MATCH_AGAINST(p.titre, p.description, p.short_titre) AGAINST (:query boolean)>0')
与:
->where('MATCH(p.titre, p.description, p.short_titre) AGAINST (:query boolean) > 0')
在
App\Repository\ProductRepository::search()
方法中(在 ProductRepository.php
文件第 113 行)?