Добавить объект в коллекцию типа Symfony 4

Я пытаюсь добавить пользователей в свою форму назначения в Symfony 4, но при попытке загрузить форму получаю следующее исключение:

Could not load type "App\Entity\User": class does not implement "Symfony\Component\Form\FormTypeInterface".

Я написал следующий код:

AssigmentFormType.php:

class AssignmentFormType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('description', TextareaType::class
            )
            ->add('deadline', DateType::class, array(
                'empty_data' => array(
                    'year' => date('Y'), 'month' => date('M'), 'day' => date('d'),
                )
            ))
            ->add('status')
            ->add('story', TextareaType::class)
            ->add('company', EntityType::class, array(
                'class' => Company::class,
                'choice_label' => 'name',
                'placeholder' => 'Select a value',
                'empty_data' => null,
            ))
            ->add('user', CollectionType::class, array(
                'entry_type' => User::class,
                'entry_options' => array('label' => false),
                'allow_add' => true
            ))
        ;
    }

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

AssignmentController:

class AssignmentController extends Controller
{
    /**
     * @Security("is_authenticated()")
     * @Route("/assignments", name = "assignments")
     */
    public function index(Request $request)
    {

        $assignment_rep = $this->getDoctrine()->getRepository(Assignment::class);

        if ($request->get('search') == null) {
            $companies = $assignment_rep->findAll();
        }
        else{
            $companies = $assignment_rep->search($request->get('search'));
        }

        $page = $request->query->get('page', 1);

        $adapter = new ArrayAdapter($companies);

        $pagerfanta = new Pagerfanta($adapter);
        $pagerfanta->setMaxPerPage(25);
        $pagerfanta->setCurrentPage($page);

        $companies = $pagerfanta->getCurrentPageResults();

        return $this->render('assignment/index.html.twig', array(
            'assignments' => $companies,
            'pager' => $pagerfanta
        ));
    }

    /**
     * @Route("/assignment/new", name = "newAssignment")
     * @IsGranted("ROLE_ADMIN")
     */
    public function add(Request $request)
    {
        $form = $this->createForm(AssignmentFormType::class);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $this->addFlash('success', 'Assignment added');

            $company = $form->getData();

            $em = $this->getDoctrine()->getManager();
            $em->persist($company);
            $em->flush();

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

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

Assignment.php

class Assignment
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type = "integer")
     */
    private $id;

    /**
     * @ORM\Column(type = "string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(type = "datetime", nullable=true)
     */
    private $deadline;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $description;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $status;

    /**
     * @ORM\Column(type = "string", length=255, nullable=true)
     */
    private $story;

    /**
     * @ORM\ManyToOne(targetEntity = "App\Entity\Company", inversedBy = "assignments")
     * @ORM\JoinColumn(nullable=false)
     */
    private $company;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\User", inversedBy = "assignments")
     */
    private $user;

    /**
     * @ORM\OneToMany(targetEntity = "App\Entity\Task", mappedBy = "assignment")
     */
    private $tasks;

    public function __construct()
    {
        $this->user = new ArrayCollection();
        $this->tasks = new ArrayCollection();

    }

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

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

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

        return $this;
    }

    public function getDeadline(): ?\DateTimeInterface
    {
        return $this->deadline;
    }

    public function setDeadline(?\DateTimeInterface $deadline): self
    {
        $this->deadline = $deadline;

        return $this;
    }

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

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

        return $this;
    }

    public function getStatus(): ?string
    {
        return $this->status;
    }

    public function setStatus(?string $status): self
    {
        $this->status = $status;

        return $this;
    }

    public function getStory(): ?string
    {
        return $this->story;
    }

    public function setStory(?string $story): self
    {
        $this->story = $story;

        return $this;
    }

    public function getCompany(): ?Company
    {
        return $this->company;
    }

    public function setCompany(?Company $company): self
    {
        $this->company = $company;

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getUser(): Collection
    {
        return $this->user;
    }

    public function addUser(User $user): self
    {
        if (!$this->user->contains($user)) {
            $this->user[] = $user;
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->user->contains($user)) {
            $this->user->removeElement($user);
        }

        return $this;
    }

    /**
     * @return Collection|Task[]
     */
    public function getTasks(): Collection
    {
        return $this->tasks;
    }

    public function addTask(Task $task): self
    {
        if (!$this->tasks->contains($task)) {
            $this->tasks[] = $task;
            $task->setAssignment($this);
        }

        return $this;
    }

    public function removeTask(Task $task): self
    {
        if ($this->tasks->contains($task)) {
            $this->tasks->removeElement($task);
            // set the owning side to null (unless already changed)
            if ($task->getAssignment() === $this) {
                $task->setAssignment(null);
            }
        }

        return $this;
    }
}

User.php

class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Column(type = "integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy = "AUTO")
     */
    public $id;

    /**
     * @ORM\Column(type = "string", length=25, unique=true)
     */
    public $username;

    /**
     * @ORM\Column(type = "string", length=64)
     */
    public $password;

    /**
     * @ORM\Column(type = "string", length=128, unique=true)
     * @Assert\Email()
     */
    public $email;

    /**
     * @ORM\Column(name = "is_active", type = "boolean")
     */
    public $isActive;

    /**
     * @ORM\Column(name = "roles", type = "array")
     */
    public $roles = [];

    /**
     * @ORM\OneToOne(targetEntity = "App\Entity\UserDetails", mappedBy = "user", cascade = {"persist", "remove"})
     */
    private $userDetails;

    /**
     * @ORM\ManyToMany(targetEntity = "App\Entity\Assignment", mappedBy = "user")
     */
    private $assignments;

    public function __construct()
    {
        $this->isActive = true;
        $this->assignments = new ArrayCollection();
        // may not be needed, see section on salt below
        // $this->salt = md5(uniqid('', true));
    }

    /**
     * @param mixed $isActive
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;
    }


    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }

    public function getUsername()
    {
        return $this->username;
    }

    public function setUsername($username)
    {
        $this->username = $username;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function setPassword($password)
    {
        $this->password = $password;
    }

    public function getSalt()
    {
        // The bcrypt and argon2i algorithms don't require a separate salt.
        // You *may* need a real salt if you choose a different encoder.
        return null;
    }


    public function getRoles()
    {
        $roles = $this->roles;

        if (!in_array('ROLE_USER', $roles)) {
            $roles[] = 'ROLE_USER';
        }
        return $roles;
    }

    /**
     * @return mixed
     */
    public function getId()
    {
        return $this->id;
    }

    public function setRoles(array $roles)
    {
        $this->roles = $roles;
    }

    public function eraseCredentials()
    {
    }

    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive
            // see section on salt below
            // $this->salt,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
            $this->id,
            $this->username,
            $this->password,
            $this->isActive
            // see section on salt below
            // $this->salt
            ) = unserialize($serialized, ['allowed_classes' => false]);
    }

    public function isAccountNonExpired()
    {
        return true;
    }

    public function isAccountNonLocked()
    {
        return true;
    }

    public function isCredentialsNonExpired()
    {
        return true;
    }

    public function isEnabled()
    {
        return $this->isActive;
    }

    public function getUserDetails(): ?UserDetails
    {
        return $this->userDetails;
    }

    public function setUserDetails(UserDetails $userDetails): self
    {
        $this->userDetails = $userDetails;

        // set the owning side of the relation if necessary
        if ($this !== $userDetails->getUser()) {
            $userDetails->setUser($this);
        }

        return $this;
    }

    /**
     * @return Collection|Assignment[]
     */
    public function getAssignments(): Collection
    {
        return $this->assignments;
    }

    public function addAssignment(Assignment $assignment): self
    {
        if (!$this->assignments->contains($assignment)) {
            $this->assignments[] = $assignment;
            $assignment->addUser($this);
        }

        return $this;
    }

    public function removeAssignment(Assignment $assignment): self
    {
        if ($this->assignments->contains($assignment)) {
            $this->assignments->removeElement($assignment);
            $assignment->removeUser($this);
        }

        return $this;
    }
}

Проблема решается удалением атрибута allow_add => true в массиве, но таким образом я не могу добавлять пользователей в свое назначение. Может ли кто-нибудь помочь мне добавить пользователей в ассигмнет в форме?

Ошибка четко указывает, в чем проблема. Вам нужно будет реализовать "Symfony\Component\Form\FormTypeInterface".

user2849211 14.05.2018 21:58

@ mission712 Я не могу найти никакой документации по FormTypeInterface в Symfony4

Sander Bakker 14.05.2018 22:05

entry_type в вашей пользовательской коллекции должен быть фактическим типом формы, а не пользовательской сущностью. По сути, вам нужно сделать себе UserType. Следуйте пример в документации.

Cerad 14.05.2018 22:13

@Cerad Но получу ли я тогда окно выбора с моими существующими пользователями? Я не хочу добавлять новых пользователей, а только добавляю в задание существующих пользователей

Sander Bakker 14.05.2018 22:21

Похоже, вам нужен тип множественного выбора вместо коллекции.

Cerad 15.05.2018 16:00
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
5
5 942
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Как говорится в комментариях, ошибка вызвана тем, что entry_type должен быть одним из типов форм Symfony. Документация здесь

Если вы хотите, чтобы в вашей форме был список существующих пользователей, вам следует вместо этого использовать Тип объекта. Он предоставляет список ваших существующих пользователей. Это также позволяет вам делать множественный выбор, если хотите.

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