Передача переменных в пользовательские типы форм для использования в шаблонах веток - PullRequest
0 голосов
/ 25 сентября 2018

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

ListingController.php

/**
 * @Route("/account/listings/update/{id}", name="listing_update", requirements={"id": "\d+"})
 * @ParamConverter("listing", class="DirectoryPlatform\AppBundle\Entity\Listing")
 */
public function updateAction(Request $request, Listing $listing)
{
    $existingFiles = $this->get('punk_ave.file_uploader')->getFiles(array('folder' => 'tmp/attachments/' . $listing->getId()));
    if ($this->getUser() !== $listing->getUser()) {
        throw $this->createAccessDeniedException('You are not allowed to access this page.');
    }

    $form = $this->createForm(ListingType::class, $listing, [
        'currency' => $this->getParameter('app.currency'),
        'hierarchy_categories' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Category'), 'category', 'categories'),
        'hierarchy_locations' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Location'), 'location', 'locations'),
    ]);
    $form->handleRequest($request);


    if ($form->isSubmitted() && $form->isValid()) {
        /** @var Listing $listing */
        $listing = $form->getData();

        try {
            $em = $this->getDoctrine()->getManager();
            $em->persist($listing);

            /** @var Image $image */
            foreach ($listing->getImages() as $image) {
                if (empty($image->getImageName())) {
                    $em->remove($image);
                }
            }

            $em->flush();
            $this->addFlash('success', $this->get('translator')->trans('Listing has been successfully saved.'));
        } catch (\Exception $e) {
            $this->addFlash('danger', $this->get('translator')->trans('An error occurred when saving listing object.'));
        }

        return $this->redirectToRoute('listing_update', ['id' => $listing->getId()]);
    }

    return $this->render('FrontBundle::Listing/update.html.twig', [
        'listing' => $listing,
        'editId' => $listing->getId(),
        'existingFiles' => $existingFiles,
        'form' => $form->createView(),
    ]);
}

Рассматриваемая переменная $existingFiles, которую я пытаюсь передать в методе render(), чтобы они могли отображатьсяв ветке

dropzone.html.twig

{% block dropzone_widget %}
<div class="{{ class }}">

    {% for file in existingFiles %}
    <img src="/uploads/tmp/attachments/{{ listing.getId }}/large/{{ file }}">
    {% endfor %}
</div>
{% endblock %}

DropzoneType.php

<?php
namespace DirectoryPlatform\FrontBundle\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;

class DropZoneType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
        // default form options
        'class' => 'file-uploader'
        ));
    }

    public function getBlockPrefix()
    {
        return "dropzone";
    }
    /**
     * {@inheritdoc}
     */
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['class'] = $options['class'];
    }
        public function getParent()
    {
        return FormType::class;
    }
}

Но я 'получаю ошибку Variable "existingFiles" does not exist.

Редактировать: Включая мой config.yml

config.yml

# Twig Configuration
twig:
    debug: '%kernel.debug%'
    strict_variables: '%kernel.debug%'
    form_themes:
      - 'AppBundle:Form:bootstrap.html.twig'
      - 'AppBundle:Form:collection.html.twig'
      - 'AppBundle:Form:dropzone.html.twig'
    globals:
        google_maps_api_key: "%google_maps_api_key%"
        google_analytics_code: "%google_analytics_code%"
        enable_registration: "%enable_registration%"

1 Ответ

0 голосов
/ 25 сентября 2018

Поскольку у вас есть тип формы DropZoneType и (я полагаю) вы добавили его в качестве дочернего к типу формы ListingType, вы можете передать его следующим образом:

  1. Передайте существующие файлы как опцию из контроллера в ListingType:

    // ListingController.php
    
    $form = $this->createForm(ListingType::class, $listing, [
        'currency' => $this->getParameter('app.currency'),
        'hierarchy_categories' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Category'), 'category', 'categories'),
        'hierarchy_locations' => new Hierarchy($this->getDoctrine()->getRepository('AppBundle:Location'), 'location', 'locations'),
        'existingFiles' => $existingFiles
    ]);
    
  2. Передайте существующие файлы как опцию из ListingType в DropzoneType:

    // ListingType.php
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $existingFiles = $options['existingFiles'];
    
        $builder
            ...
            ->add('dropzone', DropZoneType::class, [
                // other options          
               'existingFiles' => $existingFiles
            ]);
    }
    
  3. Получите ваши существующие файлы в DropZoneType и установите их как переменную представления формы:

    // DropZoneType.php
    public function buildView(FormView $view, FormInterface $form, array $options)
    {
        $view->vars['class'] = $options['class'];
        $view->vars['existingFiles'] = $options['existingFiles'] ?? []; // in case no existing files are given
    }
    

Затем вы можете отобразить их в своем dropzone.html.twig, как вы в настоящее времяделаем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...