我正在尝试使用 doctrine 和 query Builder 在 symfony 中创建一个列表过滤器

I'm trying to make a list filter in symfony using doctrine and query Builder

我正在尝试在 Symfony 中构建列表过滤器。我对 PHP、MySQL 和 twig 还是个新手。官方文档帮助不大。要求我有一个包含所有 class 列表的页面,并且在该页面旁边有一个搜索栏,用户可以在其中输入他们想要的 class,并且它将显示在页面上,而不会显示其他内容。我会 post 我的代码,但我认为它缺少很多代码。我只需要很少的帮助,也许还需要有关如何操作的文档来源官方文档对于零经验的人来说不是很清楚。

我的ClassesRepository.php

<?php

namespace App\Repository;

use App\Entity\Classes;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @method Classes|null find($id, $lockMode = null, $lockVersion = null)
 * @method Classes|null findOneBy(array $criteria, array $orderBy = null)
 * @method Classes[]    findAll()
 * @method Classes[]    findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 */
class ClassesRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Classes::class);
    }


    public function findbyName()
    {
        return $this->createQueryBuilder('c')
        ->getQuery()->getResult();
    }

    public function getSearchClasses($class){

        $qb = $this->createQueryBuilder('c')
                   ->where('c.Title LIKE :Title')
                   ->setParameter('Title', '%' . $class->getTitle() . '%')
                   ->orderBy('c.Title', 'DESC')
                   ->getQuery();
    }
}

classesController:

<?php

namespace App\Controller;

use App\Entity\Classes;
use App\Entity\Students;
use App\Entity\Courses;
use Symfony\Component\Form\FormTypeInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;


class ClassesController extends AbstractController
{
    /**
     * @Route("custom/classes", name="classes_list")
     */
    public function index()
    {
        $classes = $this->getDoctrine()->getRepository(classes::class)->findAll();
        return $this->render('classes/index.html.twig', [
            'classes' => $classes 
        ]);
    }

   

    /**
     * @Route("/classes/new", name="new_class")
     * @Method({"GET","POST"})
     */
    public function new(Request $request)
    {
        $class = new Classes();

        $form = $this->createFormBuilder($class)
            ->add('Title', TextType::class, array('attr' =>
            array('class' => 'form-control')))
            ->add('save', SubmitType::class,array('label' => 'Create',
            'attr' => array('class' => 'btn btn-primary mt-3')))
            ->getForm();

            $form->handleRequest($request);

            if($form->isSubmitted() && $form->isValid()) {
                $class = $form->getData();

                $entityManager = $this->getDoctrine()->getManager();
                $entityManager->persist($class);
                $entityManager->flush();

                return $this->redirectToRoute('classes_list'); 
            }

            return $this->render('classes/new.html.twig', array(
                'form' => $form->createView()
            ));
  
    }

    /**
     * @Route("/classes/edit/{id}", name="edit_class")
     * @Method({"GET","POST"})
     */
    public function edit(Request $request, $id)
    {
        $class = new Classes();

        $class = $this->getDoctrine()->getRepository(classes::class)->find($id);

        $form = $this->createFormBuilder($class)
            ->add('Title', TextType::class, array('attr' =>
            array('class' => 'form-control')))
            ->add('save', SubmitType::class,array('label' => 'Create',
            'attr' => array('class' => 'btn btn-primary mt-3')))
            ->getForm();

            $form->handleRequest($request);

            if($form->isSubmitted() && $form->isValid()) {
               
                $entityManager = $this->getDoctrine()->getManager();
                $entityManager->flush();

                return $this->redirectToRoute('classes_list'); 
            }

            return $this->render('classes/edit.html.twig', array(
                'form' => $form->createView()
            ));
  
    }

     /**
     * @Route("/classes/delete/{id}")
     * @Method({"DELETE"})
     */
    public function delete(Request $request, $id){
        $class = $this->getDoctrine()->getRepository(Classes::class)->find($id);
        
        $entityManager = $this->getDoctrine()->getManager();
        $entityManager->remove($class);
        $entityManager->flush();

        $response = new Response();
        $response->send();
    }
  

    /**
     * @Route("/classes/{id}", name="classes_show")
     * @Method({"GET"})
     */
    public function show($id){
        
        $_class = $this->getDoctrine()->getRepository(Classes::class)->find($id);

        
        return $this->render('classes/show.html.twig', array('classes' => $_class));

    }


    // /**
    //  * @Route("custom/classes/save")
    //  */
    //   public function save() {
    //       $entityManager = $this->getDoctrine()->getManager();

    //       $classes = new Classes();
    //       $classes->setTitle('Grade 2');
          

    //       $entityManager->persist($classes);
    //       $entityManager->flush();

    //       return new Response('Saved an classes with the id of '.$classes->getId());
    // }
}

Index.html.twig 是我需要找到列表过滤器的位置

{% extends 'base.html.twig' %}

{% block title %}Classes{% endblock %}

{% block body %}
<br>
<h1>Classes:</h1>
<a href="/classes/new" class = "btn btn-success" style = "position:absolute; left:840px; top:85px; height:40px; width:100px"> Create </a>
<br>
{% if classes %}
  <div class="alignleft">  
        <table id="classes" class="table table-striped" style="width:70%">
             <thead>  
                <tr>   
                    <th>Class</th>
                    <th>Details </th>
                    <th>Edit</th>
                    <th>Delete</th>
                 </tr>
             </thead>
               <tbody>
                    {% for classes in classes %}
                        <tr>
                            <td> {{ classes.title }}</td>
                            <td>
                                <a href="/classes/{{ classes.id }}" class = "btn btn-info">Show Class Details</a>
                            </td> 
                            <td>
                                <a href="/classes/edit/{{ classes.id }}" class = "btn btn-primary">Edit</a>
                            </td>
                            <td>
                                <a href="#" class = "btn btn-danger delete-class" data-id="{{ classes.id }}">X</a>
                            </td>
                        </tr> 
                    {% endfor %}
             </tbody>
        </table>
    </div>
    <div>
        <form method="GET" action="search" style = "position:absolute; left:1100px; top:150px; height:100px; width:100px">
            <input type="text" name="q" placeholder="Search Query...">
            <select name="column" style = "position:absolute; left:40px; top:30px; width:100px ">
                <option value="classes.Title" >Class</option>
            </select> 
            <input type="submit" class="btn btn-warning" value="Find" style = "position:absolute; left:40px; top:56px; width:100px "> 
        </form>
    </div>
{% else %}
    <p>No Classes Available</p>
{% endif %}
{% endblock %}


{% block javascripts %}
    <script src="/js/classmain.js"></script>
{% endblock %}

我不明白你期望过滤器的行为,但我希望它能帮助你..

  • 在你的ClassesRepository.php
    // if has not $classTitle and $query it will find all
    public function getSearchClasses($classTitle = null , $query=null){

        $qb = $this->createQueryBuilder('c')
                   ->orderBy('c.Title', 'DESC');

           if($classTitle && $classTitle !== '') {

             $qb->andWhere('c.Title LIKE :classTitle')
                   ->setParameter('classTitle', '%' . classTitle . '%');
           }
           
           if($query && $query !== '') {

            // doSomethings with query input
           }
                  
         return $qb->getQuery()->getResult();

    }
  • 在您的 classesController 中:
    /**
     * @Route("custom/classes", name="classes_list")
     */
    public function index(Request $request)
    {
        $classTitle = $request->query->get('classTitle',null);
        $query = $request->query->get('query',null);

        // if has not $classTitle and $query it will find all

        $classes = $this->getDoctrine()->getRepository(classes::class)->getSearchClasses($classTitle,$query);

        return $this->render('classes/index.html.twig', [
            'classes' => $classes 
        ]);
    }


  • 在你的index.html.twig
// redirect to the same route that render this template ..

<form method="GET" action="{{ path('classes_list') }}">
    <input type="text" name="query" placeholder="Search Query...">

    <select name="classTitle">
    {% for class in classes%}
        <option value="{{class.title}" >{{class.title}}</option>
     {% endfor %}
    </select>
    
    <input type="submit" class="btn btn-warning" value="Find">

</form>