使用Symfony表单嵌入集合上载,编辑,删除多个文件

时间:2017-07-27 08:53:27

标签: javascript php symfony doctrine

我正在尝试上传多个文件,请参阅以下代码:

文件实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Files
 *
 * @ORM\Table(name="files")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\FilesRepository")
 */
class Files
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="file", type="string", length=255, unique=true)
     * @Assert\NotBlank(message="Please, upload the product brochure as a PDF file.")
     * @Assert\File(mimeTypes={ "application/pdf" })
     */
    private $file;

    /**
     *
     * @return Files
     */
    function getUser() {
        return $this->user();
    }

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

    /**
     * Set file
     *
     * @param string $file
     *
     * @return Files
     */
    public function setFile($file)
    {
        $this->file = $file;

        return $this;
    }

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

用户实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User{

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

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

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

        /**
         * @ORM\ManyToMany(targetEntity="Files", cascade={"persist"})
         */
        private $files;

        function __construct() {
            $this->files = new ArrayCollection();
        }

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

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

            return $this;
        }

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

        /**
         * Set lastName
         *
         * @param string $lastName
         *
         * @return User
         */
        public function setLastName($lastName) {
            $this->lastName = $lastName;

            return $this;
        }

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

        /**
         * Get files
         *
         * @return ArrayCollection
         */
        function getFiles() {
            return $this->files;
        }

        /**
         * Set files
         * @param type $files
         */
        function setFiles($files) {
            $this->files = $files;
        }
    }

的用户类型:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use AppBundle\Form\FilesType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;

class UserType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('lastName')
            ->add('files', CollectionType::class,array(
                'entry_type' => FilesType::class,
                'allow_add' => true,
                'by_reference' => false,
            ))
        ;
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\User'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_user';
    }
}

FilesType:

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class FilesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('file');
    }

    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Files'
        ));
    }

    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_files';
    }
}

文件控制器:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\Files;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Request;

/**
 * File controller.
 *
 * @Route("files")
 */
class FilesController extends Controller
{
    /**
     * Lists all file entities.
     *
     * @Route("/", name="files_index")
     * @Method("GET")
     */
    public function indexAction()
    {
        $em = $this->getDoctrine()->getManager();

        $files = $em->getRepository('AppBundle:Files')->findAll();

        return $this->render('files/index.html.twig', array(
            'files' => $files,
        ));
    }

    /**
     * Creates a new file entity.
     *
     * @Route("/new", name="files_new")
     * @Method({"GET", "POST"})
     */
    public function newAction(Request $request)
    {
        $file = new File();
        $form = $this->createForm('AppBundle\Form\FilesType', $file);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($file);
            $em->flush();

            return $this->redirectToRoute('files_show', array('id' => $file->getId()));
        }

        return $this->render('files/new.html.twig', array(
            'file' => $file,
            'form' => $form->createView(),
        ));
    }

    /**
     * Finds and displays a file entity.
     *
     * @Route("/{id}", name="files_show")
     * @Method("GET")
     */
    public function showAction(Files $file)
    {
        $deleteForm = $this->createDeleteForm($file);

        return $this->render('files/show.html.twig', array(
            'file' => $file,
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing file entity.
     *
     * @Route("/{id}/edit", name="files_edit")
     * @Method({"GET", "POST"})
     */
    public function editAction(Request $request, Files $file)
    {
        $deleteForm = $this->createDeleteForm($file);
        $editForm = $this->createForm('AppBundle\Form\FilesType', $file);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('files_edit', array('id' => $file->getId()));
        }

        return $this->render('files/edit.html.twig', array(
            'file' => $file,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Deletes a file entity.
     *
     * @Route("/{id}", name="files_delete")
     * @Method("DELETE")
     */
    public function deleteAction(Request $request, Files $file)
    {
        $form = $this->createDeleteForm($file);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($file);
            $em->flush();
        }

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

    /**
     * Creates a form to delete a file entity.
     *
     * @param Files $file The file entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(Files $file)
    {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('files_delete', array('id' => $file->getId())))
            ->setMethod('DELETE')
            ->getForm()
            ;
    }
}

UserController中:

<?php

namespace AppBundle\Controller;

use AppBundle\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;

/**
 * User controller.
 *
 * @Route("user")
 */
class UserController extends Controller {

    /**
     * Lists all user entities.
     *
     * @Route("/", name="user_index")
     * @Method("GET")
     */
    public function indexAction() {
        $em = $this->getDoctrine()->getManager();

        $users = $em->getRepository('AppBundle:User')->findAll();

        return $this->render('user/index.html.twig', array(
            'users' => $users,
        ));
    }

    /**
     * Creates a new user entity.
     *
     * @Route("/new", name="user_new")
     * @Method({"GET", "POST"})
     */
    public function newAction(Request $request) {
        $user = new User();
        $form = $this->createForm('AppBundle\Form\UserType', $user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {

            $attachments = $user->getFiles();

            if ($attachments) {
                foreach($attachments as $attachment)
                {
                    $file = $attachment->getFile();

                    var_dump($attachment);
                    $filename = md5(uniqid()) . '.' .$file->guessExtension();

                    $file->move(
                        $this->getParameter('upload_path'), $filename
                    );
                    var_dump($filename);
                    $attachment->setFile($filename);
                }
            }

            $em = $this->getDoctrine()->getManager();
            $em->persist($user);
            $em->flush();

            return $this->redirectToRoute('user_show', array('id' => $user->getId()));
        }

        return $this->render('user/new.html.twig', array(
            'user' => $user,
            'form' => $form->createView(),
        ));
    }

    /**
     * Finds and displays a user entity.
     *
     * @Route("/{id}", name="user_show")
     * @Method("GET")
     */
    public function showAction(User $user) {
        $deleteForm = $this->createDeleteForm($user);

        return $this->render('user/show.html.twig', array(
            'user' => $user,
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Displays a form to edit an existing user entity.
     *
     * @Route("/{id}/edit", name="user_edit")
     * @Method({"GET", "POST"})
     */
    public function editAction(Request $request, User $user) {
        $deleteForm = $this->createDeleteForm($user);
        $editForm = $this->createForm('AppBundle\Form\UserType', $user);
        $editForm->handleRequest($request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->getDoctrine()->getManager()->flush();

            return $this->redirectToRoute('user_edit', array('id' => $user->getId()));
        }

        return $this->render('user/edit.html.twig', array(
            'user' => $user,
            'edit_form' => $editForm->createView(),
            'delete_form' => $deleteForm->createView(),
        ));
    }

    /**
     * Deletes a user entity.
     *
     * @Route("/{id}", name="user_delete")
     * @Method("DELETE")
     */
    public function deleteAction(Request $request, User $user) {
        $form = $this->createDeleteForm($user);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->remove($user);
            $em->flush();
        }

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

    /**
     * Creates a form to delete a user entity.
     *
     * @param User $user The user entity
     *
     * @return \Symfony\Component\Form\Form The form
     */
    private function createDeleteForm(User $user) {
        return $this->createFormBuilder()
            ->setAction($this->generateUrl('user_delete', array('id' => $user->getId())))
            ->setMethod('DELETE')
            ->getForm()
            ;
    }
}

模板:

{% extends 'base.html.twig' %}

{% block body %}
    <h1>File</h1>

    <table>
        <tbody>
        <tr>
            <th>Id</th>
            <td>{{ file.id }}</td>
        </tr>
        <tr>
            <th>File</th>
            <td>{{ file.file }}</td>
        </tr>
        </tbody>
    </table>

    <ul>
        <li>
            <a href="{{ path('files_index') }}">Back to the list</a>
        </li>
        <li>
            <a href="{{ path('files_edit', { 'id': file.id }) }}">Edit</a>
        </li>
        <li>
            {{ form_start(delete_form) }}
            <input type="submit" value="Delete">
            {{ form_end(delete_form) }}
        </li>
    </ul>
{% endblock %}

我有两个问题。我可以上传一个文件和多个文件,但是当我尝试显示文件例如图像时,它不会显示图像。相反,它只显示如下的路径或名称: 576e628f70c22f3264249e60bd0c9700.docx 003a916b73e8f5ab3811fa88183ad951.pdf

第二个问题是在尝试编辑时,它给出了以下错误:

  

表单的视图数据应该是Symfony \ Component \ HttpFoundation \ File \ File类的实例,但是是(n)字符串。您可以通过将“data_class”选项设置为null或通过添加将(n)字符串转换为Symfony \ Component \ HttpFoundation \ File \ File的实例的视图转换器来避免此错误。我试图将data_class optin设置为null,但它给出了另一个错误,它不起作用。

有人可以帮我解决这些问题吗?

1 个答案:

答案 0 :(得分:1)

这是你在做什么,当你上传新文件时,你把它们放在一个特定的位置(使用$ file-&gt; move(...);)然后只在你的用户实体中存储这些文件的名称(使用$ attachment-&gt; setFile($ filename);)

因此,当您尝试编辑ser实体时,FormType需要一个File数组,而是获取一个String数组,因为这是您存储在数据库中的内容以及Symfony从中获取的内容数据库并放入您的实体。

解决方案:在editAction中,使用每个文件的路径创建新的文件对象,并将这些对象放在文件名的位置,这样symfony就可以获得他期望并赢得的文件。 ;给你一个错误。

提交编辑表单时,不要忘记将文件转换回String格式,以便将它们存储在数据库中

编辑:

至于第一个问题,就像我说的那样,你将文件的名称存储在实体中,所以当用{{file.file}}显示它们时,它会显示文件的名称,因为&# 39;它的内容,每种文件类型都有正确的显示方式。示例:如果您的文件是图像,则执行以下操作:&lt; img src =&#34; {{file.file}}&#34; /&gt;当然,您必须从Web文件夹

开始包含该图像的完整路径

对于.pdf,.docx和其他文件类型,您只需要找到一种方法来显示您需要的内容