Symfony 3.4:保存Object ArrayCollection OneToMany的问题

时间:2018-04-28 02:48:32

标签: symfony arraycollection

我需要你的帮助才能将我的数据保存在表格中 我使用fosUserBundle并具有不同的用户类型(Admin,Pro,Client),这些用户类型是扩展基本用户实体的类。 我还有一个与用户链接的语言实体,其中包含一对多关联 要订阅,userClient需要通过复选框查看他说的语言。

表单页面没问题,它显示UserClient表单(+父用户表单),并带有语言列表作为复选框。

问题是表中保存的数据。 我在language列中有相同的值:

O:43:"Doctrine\Common\Collections\ArrayCollection":1:{s:53:"Doctrine\Common\Collections\ArrayCollectionelements";a:2:{i:0;O:32:"LanguagesBundle\Entity\Languages":10:{s:36:"LanguagesBundle\Entity\Languagesid";i:2;s:38:"LanguagesBundle\Entity\Languagesname";s:7:"English";s:44:"LanguagesBundle\Entity\Languagesshort_slug";s:2:"en";s:43:"LanguagesBundle\Entity\Languageslong_slug";s:5:"en_EN";s:43:"LanguagesBundle\Entity\LanguagesisDefault";b:0;s:43:"LanguagesBundle\Entity\LanguagesupdatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-04-20 22:46:48.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";}s:43:"LanguagesBundle\Entity\LanguagesimageFile";N;s:39:"LanguagesBundle\Entity\Languagesimage";s:39:"Flag_of_United_Kingdom_-_Circle-512.png";s:43:"LanguagesBundle\Entity\LanguagesimageSize";i:37621;s:44:"LanguagesBundle\Entity\LanguagesuserClient";N;}i:1;O:32:"LanguagesBundle\Entity\Languages":10:{s:36:"LanguagesBundle\Entity\Languagesid";i:1;s:38:"LanguagesBundle\Entity\Languagesname";s:9:"Français";s:44:"LanguagesBundle\Entity\Languagesshort_slug";s:2:"fr";s:43:"LanguagesBundle\Entity\Languageslong_slug";s:5:"fr_FR";s:43:"LanguagesBundle\Entity\LanguagesisDefault";b:1;s:43:"LanguagesBundle\Entity\LanguagesupdatedAt";O:8:"DateTime":3:{s:4:"date";s:26:"2018-04-20 22:45:50.000000";s:13:"timezone_type";i:3;s:8:"timezone";s:12:"Europe/Paris";}s:43:"LanguagesBundle\Entity\LanguagesimageFile";N;s:39:"LanguagesBundle\Entity\Languagesimage";s:31:"Flag_of_France_-_Circle-512.png";s:43:"LanguagesBundle\Entity\LanguagesimageSize";i:23352;s:44:"LanguagesBundle\Entity\LanguagesuserClient";N;}}}

这是我的代码:

user.php的

    use Doctrine\Common\Collections\ArrayCollection;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    use UserBundle\Entity\UserAdmin;
    use UserBundle\Entity\UserProfessional;
    use UserBundle\Entity\UserClient;
    use UserBundle\Entity\Adress;

    /**
     * @ORM\Entity
     * @ORM\InheritanceType("JOINED")
     * @ORM\DiscriminatorColumn(name="discr", type="string")
     * @ORM\DiscriminatorMap({"client" = "UserClient", "professional"="UserProfessional", "admin"="UserAdmin"})
     */
    abstract class User extends BaseUser {

        /**
         * @ORM\Id
         * @ORM\Column(type="integer")
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;

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

//[...] getters and setters

实体:UserClient.php

<?php

// src/UserBundle/Entity/UserGuest.php

namespace UserBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
 * @ORM\Entity
 */
class UserClient extends User {

    /**
     * @ORM\Column(type="array")
     * @ORM\OneToMany(targetEntity="LanguagesBundle\Entity\Languages", mappedBy="userClient")
     */
    private $languages;

    public function __construct() {
        parent::__construct();
        $this->languages = new ArrayCollection();
    }

    /**
     * Set languages
     *
     * @param array $languages
     *
     * @return UserClient
     */
    public function setLanguages($languages)
    {
        $this->languages = $languages;

    }

    /**
     * Get languages
     *
     * @return array
     */
    public function getLanguages()
    {
        return $this->languages;
    }

    /**
     * Add language
     *
     * @param \LanguagesBundle\Entity\Languages $language
     *
     * @return UserClient
     */
    public function addLanguage(LanguagesBundle\Entity\Languages $language)
    {
        $this->languages[] = $language;
        return $this;
    }

    /**
     * Remove language
     *
     * @param \LanguagesBundle\Entity\Languages $language
     */
    public function removeLanguage(\LanguagesBundle\Entity\Languages $language)
    {
        $this->languages->removeElement($language);
    }
}

Entity Languages.php

<?php

namespace LanguagesBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
 * @ORM\Entity
 *
 * @Vich\Uploadable
 */

class Languages
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;
    /**
     * @var string
     *
     * @ORM\Column(type="string")
     * @Assert\NotBlank()
     */
    private $name;
    /**
     * @ORM\Column(type="string", length=2, unique=true)
     */
    private $short_slug;
    /**
     * @var string
     *
     * @ORM\Column(type="string", length=5, unique=true)
     * @Assert\NotBlank()
     */
    private $long_slug;
    /**
     * @var string
     *
     * @ORM\Column(type="boolean", nullable=true)
     */
    private $isDefault;

    /**
     * @ORM\Column(type="datetime")
     * @var \DateTime
     */

    private $updatedAt;

    /**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     * 
     * @Assert\File(
     *     maxSize="1M",
     *     mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
     * )
     * @Vich\UploadableField(mapping="language_images", fileNameProperty="image", size="imageSize")
     * @var File
     */
    private $imageFile;
    /**
     * @ORM\Column(type="string", length=255, nullable = true)
     * @var string
     */
    private $image;
/**
     * @ORM\Column(type="integer")
     *
     * @var integer
     */
    private $imageSize;


    /**
     * @ORM\ManyToOne(targetEntity="UserBundle\Entity\UserClient", inversedBy="languages")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private $userClient;
    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
     */
    public function setImageFile(?File $image = null): void
    {
        $this->imageFile = $image;

        if (null !== $image) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTimeImmutable();
        }
    }
    public function getImageFile()
    {
        return $this->imageFile;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->updatedAt = new \DateTime();
    }

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

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Languages
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Set shortSlug
     *
     * @param string $shortSlug
     *
     * @return Languages
     */
    public function setShortSlug($shortSlug)
    {
        $this->short_slug = $shortSlug;

        return $this;
    }

    /**
     * Get shortSlug
     *
     * @return string
     */
    public function getShortSlug()
    {
        return $this->short_slug;
    }

    /**
     * Set longSlug
     *
     * @param string $longSlug
     *
     * @return Languages
     */
    public function setLongSlug($longSlug)
    {
        $this->long_slug = $longSlug;

        return $this;
    }

    /**
     * Get longSlug
     *
     * @return string
     */
    public function getLongSlug()
    {
        return $this->long_slug;
    }

    /**
     * Set isDefault
     *
     * @param boolean $isDefault
     *
     * @return Languages
     */
    public function setIsDefault($isDefault)
    {
        $this->isDefault = $isDefault;

        return $this;
    }

    /**
     * Get isDefault
     *
     * @return boolean
     */
    public function getIsDefault()
    {
        return $this->isDefault;
    }

    /**
     * Set updatedAt
     *
     * @param \DateTime $updatedAt
     *
     * @return Languages
     */
    public function setUpdatedAt($updatedAt)
    {
        $this->updatedAt = $updatedAt;

        return $this;
    }

    /**
     * Get updatedAt
     *
     * @return \DateTime
     */
    public function getUpdatedAt()
    {
        return $this->updatedAt;
    }

    /**
     * Set image
     *
     * @param string $image
     *
     * @return Languages
     */
    public function setImage($image)
    {
        $this->image = $image;

        return $this;
    }

    /**
     * Get image
     *
     * @return string
     */
    public function getImage()
    {
        return $this->image;
    }

    /**
     * Set imageSize
     *
     * @param integer $imageSize
     *
     * @return Languages
     */
    public function setImageSize($imageSize)
    {
        $this->imageSize = $imageSize;

        return $this;
    }

    /**
     * Get imageSize
     *
     * @return integer
     */
    public function getImageSize()
    {
        return $this->imageSize;
    }


    /**
     * Set userClient
     *
     * @param \UserBundle\Entity\UserClient $userClient
     *
     * @return Languages
     */
    public function setUserClient(\UserBundle\Entity\UserClient $userClient = null)
    {
        $this->userClient = $userClient;

        return $this;
    }

    /**
     * Get userClient
     *
     * @return \UserBundle\Entity\UserClient
     */
    public function getUserClient()
    {
        return $this->userClient;
    }

    /**
     * {@inheritdoc}
     */
    public function __toString()
    {
        return $this->getName() ?: '-';
    }
}

我的FormType:RegistrationTypeClient.php

<?php

// src/UserBundle/Form/UserContactFormType.php

namespace UserBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use LanguagesBundle\Services\LanguagesService;
use LanguagesBundle\Entity\Languages ;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Doctrine\ORM\EntityRepository;

class RegistrationClientType extends AbstractType {

    protected $service;

    public function buildForm(FormBuilderInterface $builder, array $options) {

        parent::buildForm($builder, $options);

        $builder
                ->add('languages', EntityType::class, [
                'class' => 'LanguagesBundle:Languages',
                'choice_label' => 'name',
                'query_builder' => function (EntityRepository $er) {
        return $er->createQueryBuilder('u')
            ->orderBy('u.name', 'ASC');
    },
                'label'     => 'Langues',
                'expanded'  => true,
                'multiple'  => true,
            ])                 
                ;
    }

    public function getParent() {
        // on inclut le formulaire de base d'inscription utilisateur
        return 'UserBundle\Form\RegistrationType';
    }

    public function getBlockPrefix() {
        return 'app_user_registration_client';
    }

    // For Symfony 2.x
    public function getName() {
        return $this->getBlockPrefix();
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver
                ->setDefaults(array(
            'data_class' => \UserBundle\Entity\UserClient::class,
                ))
                //->setRequired('service_languages');
                ;
    }

}

我的控制器:

public function registerClientAction(Request $request) {
        /** @var $formFactory FactoryInterface */
        //$formFactory = $this->get('fos_user.registration_pro.form.factory');
        /** @var $userManager UserManagerInterface */
        $userManager = $this->get('fos_user.user_manager');
        /** @var $dispatcher EventDispatcherInterface */
        $dispatcher = $this->get('event_dispatcher');

        $user = new UserClient();

        $event = new GetResponseUserEvent($user, $request);
        $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);

        if (null !== $event->getResponse()) {
            return $event->getResponse();
        }

        $form = $this->createForm(RegistrationClientType::class, $user);

        $form->setData($user);
        $form->handleRequest($request);
        if ($form->isSubmitted()) {
            if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

                $userManager->updateUser($user);

                if (null === $response = $event->getResponse()) {
                    $url = $this->generateUrl('fos_user_registration_confirmed');
                    $response = new RedirectResponse($url);
                }

                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }

            $event = new FormEvent($form, $request);
            $dispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);

            if (null !== $response = $event->getResponse()) {
                return $response;
            }
        }

        return $this->render('UserBundle\Registration\register_client.html.twig', array(
                    'form' => $form->createView(),
        ));
    }

Here's a picture showing the data saved in the table

我需要将语言作为userClient的数组存储在数据库中。 你能帮我吗?

1 个答案:

答案 0 :(得分:1)

感谢您重新编辑我的问题Philip-B- 感谢您的阅读。

我通过添加foreach将我的对象转换为数组来解决我的问题: 代码在我的控制器中:

if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);

                foreach ($user->getLanguages() as $value) {
                    $langue[] = $value->getShortSlug();
                }
                $user->setLanguages($langue);
                $userManager->updateUser($user);

                if (null === $response = $event->getResponse()) {
                    $url = $this->generateUrl('fos_user_registration_confirmed');
                    $response = new RedirectResponse($url);
                }

                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));

                return $response;
            }