Symfony — Преобразователь данных ничего не делает?

Я работаю над этим уже целую неделю и просто не знаю, как это сделать. Надеюсь, вы можете дать мне несколько советов.

На рисунке ниже показано, как я могу загрузить файл и добавить в него столько тегов, сколько захочу. Поле «MainMedia tags» объекта имеет отношение «многие ко многим» с объектом «Tag».введите описание изображения здесь

MainMedia юридическое лицо:

класс MainMedia
{
/ **
* @var int
*
* @ORM \ Column (name = «id», type = «integer»)
* @ORM \ Id
* @ORM \ GeneratedValue (стратегии = «АВТО»)
* /
приватный $ 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;
}

У меня тогда есть 2 формы, TagType и AddMedia. Поле тегов формы AddMedia использует форму TagType. В форме TagType, как показано ниже, я использую преобразователь данных.

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,
));
}

Трансформатор:

Я не могу использовать теги кода, он настолько сломан, он просто не публикует код с отступом. введите описание изображения здесь

    /**
* 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()];
}`

Twig:

`    <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>`

Я знаю, что это много кода, но я просто пытаюсь объяснить все это. Итак, ошибка. Я не очень понимаю, почему мои файлы веток все еще получают массив, когда преобразователь должен превращать его в строку? Спасибо!

Я забыл добавить ошибку:

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

1

Решение

Как описано в документе Вот, Вы должны прикрепить преобразователь к полю формы, например, в своем пользовательском FormType:

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

Другая проблема может заключаться в том, что вам нужно пройти ObjectManager экземпляр конструктора вашего трансформатора, вы также должны найти правильный метод для этого в документации

0

Другие решения

Читайте об этой функции:

prePersist — Событие prePersist наступает для данного объекта перед выполнением соответствующей операции EntityManager для этого объекта.

preUpdate — Событие preUpdate наступает перед операциями обновления базы данных до данных объекта. Он не вызывается для оператора DQL UPDATE.

Например ссылка на сайт

0

По вопросам рекламы [email protected]