В форме, как разрешить только часть выбора сущности?

Я сделал форму для создания событий. Во-первых, пользователь должен создать профиль и подключиться. У него есть список собственных адресов. В настоящее время в форме он может выбирать любые адреса, даже созданные другими пользователями. Я хотел бы разрешить ему видеть только те адреса, которые он создал при выборе перетаскивания.

  • В файле EventType я использовал EntityType::class для объекта Location, зная, что благодаря ему создаются адреса.

  • В файле сущностей для местоположения создается столбец «Организатор», чтобы узнать, кто создал адрес. Он связан с классом ManyToOne to User.

Где я должен указать, что пользователь должен выбрать только свой адрес в форме?

EventType.php

<?php

namespace App\Form;

use App\Entity\Event;
use App\Entity\Language;
use App\Entity\Location;
use App\Entity\Category;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;

class EventType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('title')
            ->add('description', TextareaType::class)
            ->add('spokenlanguage', EntityType::class, [
                'class' => Language::class,
                'choice_label' => 'name',
                'placeholder' => 'Je sélectionne une langue étrangère',
            ])
            ->add('category', EntityType::class, [
                'class' => Category::class,
                'choice_label' => 'title',
                'placeholder' => 'Je sélectionne un type de sortie ou d\'activité',
            ])
            ->add('start', DateTimeType::class, [
                'widget' => 'choice'
            ])
            ->add('end', TimeType::class, [
                'input'  => 'datetime',
                'widget' => 'choice',
            ])
            ->add('address', EntityType::class, [
                'class' => Location::class,
                'choice_label' => 'address',
                'placeholder' => 'Je sélectionne une adresse',
            ])
            ->add('save', SubmitType::class, [
                'attr' => ['class' => 'save'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Event::class,
            'translation_domain' => 'forms'
        ]);
    }
}

Location.php

<?php

namespace App\Entity;

use App\Repository\LocationRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: LocationRepository::class)]
class Location
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

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

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

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

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

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

    #[ORM\ManyToOne(inversedBy: 'locations')]
    private ?BigCity $bigcity = null;

    #[ORM\OneToMany(mappedBy: 'address', targetEntity: Event::class)]
    private Collection $events;

    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
    private ?string $lat = null;

    #[ORM\Column(type: Types::DECIMAL, precision: 10, scale: 7, nullable: true)]
    private ?string $lon = null;

    #[ORM\ManyToOne(inversedBy: 'locations')]
    private ?User $organizer = null;

    public function __construct()
    {
        $this->events = new ArrayCollection();
    }

    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 getNameAndId(): ?string
    {
        $nameandid =$this->getName() . ' (Id : ' . $this->getId() . ')';
        return $nameandid;
    }

    public function getNumber(): ?string
    {
        return $this->number;
    }

    public function setNumber(string $number): self
    {
        $this->number = $number;

        return $this;
    }

    public function getStreet(): ?string
    {
        return $this->street;
    }

    public function setStreet(string $street): self
    {
        $this->street = $street;

        return $this;
    }

    public function getZipcode(): ?string
    {
        return $this->zipcode;
    }

    public function setZipcode(string $zipcode): self
    {
        $this->zipcode = $zipcode;

        return $this;
    }

    public function getCity(): ?string
    {
        return $this->city;
    }

    public function setCity(string $city): self
    {
        $this->city = $city;

        return $this;
    }

    public function getAddress(): ?string
    {
        $address =$this->getName() . ', ' . $this->getNumber() . ' ' . $this->getStreet() . ', ' . $this->getCity();
        return $address;
    }

    public function getBigcity(): ?BigCity
    {
        return $this->bigcity;
    }

    public function setBigcity(?BigCity $bigcity): self
    {
        $this->bigcity = $bigcity;

        return $this;
    }

    /**
     * @return Collection<int, Event>
     */
    public function getEvents(): Collection
    {
        return $this->events;
    }

    public function addEvent(Event $event): self
    {
        if (!$this->events->contains($event)) {
            $this->events->add($event);
            $event->setAddress($this);
        }

        return $this;
    }

    public function removeEvent(Event $event): self
    {
        if ($this->events->removeElement($event)) {
            // set the owning side to null (unless already changed)
            if ($event->getAddress() === $this) {
                $event->setAddress(null);
            }
        }

        return $this;
    }

    public function getLat(): ?string
    {
        return $this->lat;
    }

    public function setLat(?string $lat): self
    {
        $this->lat = $lat;

        return $this;
    }

    public function getLon(): ?string
    {
        return $this->lon;
    }

    public function setLon(?string $lon): self
    {
        $this->lon = $lon;

        return $this;
    }

    public function getOrganizer(): ?User
    {
        return $this->organizer;
    }

    public function setOrganizer(?User $organizer): self
    {
        $this->organizer = $organizer;

        return $this;
    }
}

Привет, Вы можете передать текущего пользователя из контроллера в formType в опциях или выбрать его непосредственно в formType, тогда вы используете опцию query_buildder symfony.com/doc/current/reference/forms/types/…

hous 23.10.2022 07:33

Большое спасибо Хаус. Если вы ищете атрибуцию ответа, вы можете скопировать и вставить мой ответ, и я отмечу ваш ответ как правильный.

Emilie Tossan 24.10.2022 00:35

Нет, авторство не ищу, спасибо. Главное, что вы нашли, как это сделать, и это хорошо.

hous 24.10.2022 13:07

Это очень мило с твоей стороны. У меня может быть последний билет, который я опубликую в течение дня...

Emilie Tossan 24.10.2022 13:50
JS - События опций формы
JS - События опций формы
В продолжение предыдущей статьи CSS - стили, связанные с вводом формы , в этой статье мы будем использовать JS для взаимодействия с формами, на этот...
CSS - Стили, связанные с вводом формы
CSS - Стили, связанные с вводом формы
Общими стилями ввода для форм являются Input (включая Text, Radio, checkbox), Select и Textarea, из которых Input относительно прост, поэтому в этой...
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Создание многостраничной формы заявления о приеме на работу с помощью Angular
Наличие на корпоративном сайте форм заявлений о приеме на работу, или "трудовых анкет", экономит время и деньги как для соискателей, так и для...
1
4
90
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

это возможно по разному

Опция 1 список отфильтрованных опций из EventController.php

$form = $this->createForm(EventType::class, $event, [
    'addresses' => $locationRepository->findBy(['organizer' => $user])
]);

Дополнительная информация https://symfony.com/doc/current/forms.html#passing-options-to-forms

и в EventType.php список выбора в EntityType

->add('address', EntityType::class, [
    'class' => Location::class,
    'choice_label' => 'address',
    'choices' => $options['addresses'],
])

Дополнительная информация https://symfony.com/doc/current/reference/forms/types/entity.html#choices

Вариант 2 перенос пользователя, как уже описано выше под себя

EventController.php

$form = $this->createForm(EventType::class, $event, ['user' => $user]);

и создайте запрос с опцией query_builder

EventType.php

$user = $options['user'];    
    
$builder
    ...
    ->add('address', EntityType::class, [
        ...
        'query_builder' => function (EntityRepository $er) use ($user) {
            $qb = $er->createQueryBuilder('l');
        
            return $er
                ->andWhere(
                    $qb->expr()->eq('l.user', ':user')
                )
                ->setParameter('user', $user)
            ;
        },
    ])
    ...
;

Спасибо, фатальная ошибка. Мне понравилось ваше первое решение, но что-то не сработало. addresses не был распознан.

Emilie Tossan 24.10.2022 13:57

Вы установили addresses в качестве опции в распознавателе?

Fatal Error 24.10.2022 14:44

Вот решение:

Файл Type.php

$user = $options['user'];

$builder
    ->add('address', EntityType::class, [
        'class' => Location::class,
        'query_builder' => function (EntityRepository $er) use ($user) {
            return $er
                ->createQueryBuilder('l')
                ->andWhere('l.organizer = :user')
                ->setParameter('user', $user);
        },
        'choice_label' => 'address',
        'placeholder' => 'Je sélectionne une adresse',
    ])

public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => Event::class,
            'user' => User::class
        ]);
    }

Указать пользователя в Controller.php

$form = $this->createForm(EventType::class, $event, ['user' => $user]);

Другие вопросы по теме