Метод setDataMapper класса FormBuilder
Метод setDataMapper класса FormBuilder устанавливает
специальный объект-маппер, который отвечает за преобразование
данных между формой и моделью. Первым параметром передаётся
экземпляр класса, реализующий интерфейс DataMapperInterface.
Маппер используется для нестандартного заполнения объекта данными
формы или для чтения данных из объекта при отображении формы.
Синтаксис
public function setDataMapper(DataMapperInterface $dataMapper): static
Пример
Давайте создадим простой маппер, который вручную переносит данные из формы в объект:
<?php
namespace AppForm;
use AppEntityArticle;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentFormFormInterface;
use SymfonyComponentFormDataMapperDataMapperInterface;
use SymfonyComponentFormExtensionCoreTypeTextType;
use SymfonyComponentFormExtensionCoreTypeSubmitType;
use SymfonyComponentFormAbstractType;
use SymfonyComponentOptionsResolverOptionsResolver;
class ArticleType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title', TextType::class)
->add('content', TextType::class)
->add('save', SubmitType::class);
$builder->setDataMapper(new class() implements DataMapperInterface {
public function mapDataToForms(mixed $viewData, iterable $forms): void
{
$forms = iterator_to_array($forms);
if ($viewData instanceof Article) {
$forms['title']->setData($viewData->getTitle());
$forms['content']->setData($viewData->getContent());
}
}
public function mapFormsToData(iterable $forms, mixed &$viewData): void
{
$forms = iterator_to_array($forms);
if ($viewData instanceof Article) {
$viewData->setTitle($forms['title']->getData());
$viewData->setContent($forms['content']->getData());
}
}
});
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Article::class,
]);
}
}
?>
Пример
Давайте используем кастомный маппер для преобразования данных формы в массив:
<?php
namespace AppController;
use AppFormArticleType;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentFormDataMapperDataMapperInterface;
use SymfonyComponentRoutingAttributeRoute;
class ArticleController extends AbstractController
{
#[Route('/article', name: 'article_form')]
public function form(Request $request, FormBuilderInterface $formBuilder): Response
{
$formBuilder->setDataMapper(new class() implements DataMapperInterface {
public function mapDataToForms(mixed $viewData, iterable $forms): void
{
$forms = iterator_to_array($forms);
if (is_array($viewData)) {
$forms['title']->setData($viewData['title'] ?? '');
$forms['content']->setData($viewData['content'] ?? '');
}
}
public function mapFormsToData(iterable $forms, mixed &$viewData): void
{
$forms = iterator_to_array($forms);
$viewData = [
'title' => $forms['title']->getData(),
'content' => $forms['content']->getData(),
];
}
});
$form = $this->createForm(ArticleType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$res = $form->getData();
return new Response(json_encode($res));
}
return $this->render('article/form.html.twig', [
'form' => $form->createView(),
]);
}
}
?>
Результат выполнения кода после отправки формы:
{"title":"article","content":"hello"}
Смотрите также
-
класс
FormBuilder,
который строит форму -
метод
add,
который добавляет поле в форму -
метод
getForm,
который возвращает готовую форму -
метод
addModelTransformer,
который добавляет трансформер данных