Symfony - 数据转换器什么都不做?

时间:2017-05-15 09:50:55

标签: php forms symfony tags transformer

我一直在努力工作一周,我真的不知道怎么做。所以希望你能给我一些指示。

下图显示了我如何上传文件并添加任意数量的标签。实体MainMedia标记字段与标记实体具有多对多的关系。enter image description here

MainMedia实体:

类MainMedia    {     / **      * @var int      *      * @ORM \ Column(name =“id”,type =“integer”)      * @ORM \ Id      * @ORM \ GeneratedValue(strategy =“AUTO”)      * /     私人$ id;

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

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

/**
 * @var Tag[]|ArrayCollection
 *
 * @ORM\ManyToMany(targetEntity="Tag", cascade={"persist"})
 * @ORM\JoinTable(name="tags")
 * @ORM\Column(name="tags")
 *
 */
private $tags;

/**
 * @var bool
 *
 * @ORM\Column(name="public", type="boolean")
 */
private $public;

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

/**
 * @var string
 *
 * @ORM\Column(name="publicationNumber", type="decimal", scale=1, nullable=true)
 */
private $publicationNumber;

/**
 * @var int
 *
 * @ORM\Column(name="leafletCode", type="integer", nullable=true)
 */
private $leafletCode;

/**
 * @var \MyThorluxBundle\Entity\MediaType
 *
 * @ORM\ManyToOne(targetEntity="MyThorluxBundle\Entity\MediaType")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="type", referencedColumnName="id")
 * })
 */
private $type;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateCreated", type="datetime")
 */
private $dateCreated;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateModified", type="datetime")
 */
private $dateModified;

// ...

/**
 * @ORM\Column(type="string")
 *
 * @Assert\NotBlank(message="Please, upload the file")
 * @Assert\File(mimeTypes = {"application/pdf", "image/png", "jpeg", "image/bmp", "application/msword", "video/mp4", "text/csv"})
 *  maxSize = "1024k",
 *
 */
private $file;

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

/**
 * Set title
 *
 * @param string $title
 *
 * @return MainMedia
 */
public function setTitle($title)
{
    $this->title = $title;

    return $this;
}


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

/**
 * Set fileName
 *
 * @param string $fileName
 *
 * @return MainMedia
 */
public function setFileName($fileName)
{
    $this->fileName = $fileName;

    return $this;
}

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

/**
 * Set public
 *
 * @param boolean $public
 *
 * @return MainMedia
 */
public function setPublic($public)
{
    $this->public = $public;

    return $this;
}

/**
 * Get public
 *
 * @return bool
 */
public function getPublic()
{
    return $this->public;
}

/**
 * Set country
 *
 * @param string $country
 *
 * @return MainMedia
 */
public function setCountry($country)
{
    $this->country = $country;

    return $this;
}

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

/**
 * Set publicationNumber
 *
 * @param string $publicationNumber
 *
 * @return MainMedia
 */
public function setPublicationNumber($publicationNumber)
{
    $this->publicationNumber = $publicationNumber;

    return $this;
}

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

/**
 * Set leafletCode
 *
 * @param integer $leafletCode
 *
 * @return MainMedia
 */
public function setLeafletCode($leafletCode)
{
    $this->leafletCode = $leafletCode;

    return $this;
}

/**
 * Get leafletCode
 *
 * @return int
 */
public function getLeafletCode()
{
    return $this->leafletCode;
}

/**
 * Set type
 *
 * @param string $type
 *
 * @return MainMedia
 */
public function setType($type)
{
    $this->type = $type;

    return $this;
}

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

/**
 * Set dateCreated
 *
 * @param \DateTime $dateCreated
 * @ORM\PrePersist
 * @return MainMedia
 */
public function setCreatedAt()
{

    if(!$this->dateCreated){
        $this->dateCreated = new \DateTime();
    }

    return $this;
}

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

/**
 * Set dateModified
 *
 * @param \DateTime $dateModified
 * @ORM\PrePersist
 * @return MainMedia
 */
public function setUpdatedAt()
{
    $this->dateModified = new \DateTime();

    return $this;
}

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

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

public function addType(MediaType $mediaType)
{
    $mediaType->setMediaType($this);
    $this->types->add($mediaType);

    return $this;
}

public function getFile()
{
    return $this->file;
}

public function setFile($file)
{
    $this->file = $file;

    return $this;
}

public function addTags(Tag $tags)
{
    $this->tags->add($tags);
}

public function removeTag(Tag $tags)
{
    $this->tags->removeElement($tags);
}

public function getTags()
{
    return $this->tags;
}
}

标记实体:

class Tag
{
/**
 * @var int
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

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

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateCreated", type="datetime")
 */
private $dateCreated;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateModified", type="datetime")
 */
private $dateModified;

/**
 * Get name
 *
 * @return string
 */

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

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

然后我有两个表单,TagType和AddMedia。 AddMedia表单标记字段使用TagType表单。在TagType表单中,如下所示,我使用datatransformer。

class AddMedia extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{

    $builder
        ->add('file', FileType::class, array('label' => 'File Upload: ', 
'data_class' => null))
        ->add('title')
        ->add('fileName')
        ->add('public')
        ->add('country')
        ->add('type', EntityType::class, array(
            'class' => 'MyThorluxBundle\Entity\MediaType',
            'choice_label' => function (MediaType $mediaType) {
                return $mediaType->getMediaType();
            }))
        ->add('publicationNumber')
        ->add('leafletCode')
        ->add('tags', CollectionType::class, array(
            'entry_type' => TagType::class,
            'allow_add' => true,
            'by_reference' => false,
            'allow_delete' => true,
            'label' => false,
        ))
        ->add('Submit', SubmitType::class);

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


   class TagType extends AbstractType
   {

private $manager;

public function __construct(ObjectManager $manager)
{
    $this->manager = $manager;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('name', TextType::class, [
        'label' => 'Tag: ',
    ]);

    $builder->get('name')
        ->addModelTransformer(new CollectionToArrayTransformer(), true)
        ->addModelTransformer(new TagArrayToStringTransformer($this->manager), true);
}

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

变压器:

我不能使用代码标签它是如此破碎,它只是不会发布代码缩进。 enter image description here

    /**
 * Load media database add page
 *
 * @Route("/media-database-add", name="media_add_route")
 * @Template()
 * @return array
 */
public function mediaAddAction(Request $request)
{
    $mediaType = new MediaType();
    $media = new MainMedia();
    $media->addType($mediaType);

    $manager = $this->getDoctrine()->getManager();
    $mediaForm = $this->createForm(AddMedia::class, $media);

    $mediaForm->handleRequest($request);
    if ($mediaForm->isSubmitted() && $mediaForm->isValid()) {

        $file = $media->getFile();
        $fileName = $this->get('file_uploader')->upload($file);

        $media->setFile($fileName);
        $em = $this->getDoctrine()->getManager();
        $em->persist($media);
        $em->flush();

        $this->addFlash(
            'success-upload',
            'Successfully uploaded ' . $media->getTitle() . ' to the intranet'
        );

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

    return [
        'mediaForm' => $mediaForm->createView()
    ];
}

上述控制器允许我将文件上传到数据库中。这不是我得到错误的地方。

我得到的错误是在我尝试编辑上传文件的页面上,因此我应该可以编辑其标签。

控制器:

`    /**
 * edit media database page
 *
 * @Route("/media-database-update/edit/{id}", name="media_update_route")
 * @Template("MyThorluxBundle:Database:mediaUpdate.html.twig")
 * @param Request $request
 * @param MainMedia $media
 * @return array
 */
public function updateAction(MainMedia $media,Request $request)
{
    $editForm = $this->createForm(AddMedia::class, $media);

    $editForm->handleRequest($request);

    if ($editForm->isSubmitted() && $editForm->isValid()) {
        $em = $this->getDoctrine()->getManager();
        $media->setUpdatedAt();
        $em->persist($media);
        $em->flush();

        $this->addFlash(
            'media-updated',
            'Successfully updated ' . $media->getTitle()
        );
        return $this->redirectToRoute('media_database_route');
    }

    return ['editForm' => $editForm->createView()];
}`

嫩枝:

`    <div class="content-padding">
    <h1>Update Media</h1>

    {% form_theme editForm 'MyThorluxBundle:Forms:fields.html.twig' %}
    {{ form_start(editForm) }}

    {{ form_start(editForm) }}
    {{ form_row(editForm.file) }}
    {{ form_row(editForm.title) }}
    {{ form_row(editForm.fileName) }}
    {{ form_row(editForm.public) }}
    {{ form_row(editForm.country) }}
    {{ form_row(editForm.type) }}
    {{ form_row(editForm.publicationNumber) }}
    {{ form_row(editForm.leafletCode) }}
    {{ form_row(editForm.tags.name) }}

    {{ form_end(editForm) }}

</div>`

我知道这是很多代码,但我很难解释这一切。所以错误。我真的不明白为什么当变换器应该将它变成一个字符串时,我的twig文件仍在接收一个数组?谢谢!

我忘了添加错误:

Expected argument of type "array or (\Traversable and \ArrayAccess)", "string" given

2 个答案:

答案 0 :(得分:0)

如文档here中所述,您应该将转换器附加到表单的字段中,例如,在自定义FormType中:

class AddMedia extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
 ....
         $builder->get('tag')
            ->addModelTransformer(new TagAttayToStringTransformer($this->manager));
}

另一个问题可能是您需要将ObjectManager实例传递给变换器的构造函数,您应该在文档中找到正确的方法来执行此操作

答案 1 :(得分:0)

了解这个功能:

prePersist - 在执行该实体的相应EntityManager持久操作之前,对于给定实体发生prePersist事件。

preUpdate - preUpdate事件发生在对实体数据的数据库更新操作之前。它不是为DQL UPDATE语句调用的。

例如link