Symfony使用原理更新和删除多个文件 [英] Symfony Update and delete multiple files using doctrine

查看:70
本文介绍了Symfony使用原理更新和删除多个文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更新(多个)上传的文件

I am trying to Update (multiple) uploaded files

我遇到两个问题。当我尝试从index.html树枝输入编辑表单时,出现以下错误:

I am having two problems. When I try to enter the edit form from index.html twig it gives me the following error:


该表单的视图数据预计为类Symfony,Component,HttpFoundation,File,File的实例,但为字符串。您可以通过将 data_class选项设置为null或添加一个将a(n)字符串转换为Symfony\Component\HttpFoundation\File\File实例的视图转换器来避免此错误。

The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.

我尝试将data_class选项设置为null,但它又给出了另一个错误,它没有用。

I tried to set data_class option to null but it gave another error it didn't work.

所以不是在我尝试更新时,而是在我尝试进入编辑表单时。我已经尝试了其他有关堆栈溢出的其他问题的多种解决方案,但我一直收到此错误。

So not when I try to update but when I try to go to the edit form. I have tried multiple solution from other questions on stack overflow but I keep getting this error.

第二个问题是当我尝试删除文件时,它仅从以下位置删除数据库而不是文件。我知道删除时没有提到文件的位置。我不知道该怎么做。我已经看到了一些Symfony 2的示例,但是当我尝试过时它没有用。有人可以帮我解决这些问题吗?

Second problem is at the moment when I try to delete file, it only delete from database not the file. I know I haven't Referred to the location of the file when I delete. I don't know how to do that. I have seen some examples of Symfony 2 but it didn't work when I tried. Can someone help me fix these problems?

编辑

我已经设置了FileType $ builder-> add('file',FileType :: class,array('data_class'=> null,'by_reference'=> false,)); 多次清除现金后,我可以最终进入页面,但是它不显示上载的文件,但可以显示名称和姓氏。如果我将此< a href = {{asset('upload /'〜element.file)}}> view< / a> 添加到我的表单中,则它给了我错误

I have set FileType $builder->add('file',FileType::class, array( 'data_class' => null, 'by_reference' => false,)); after clearing cash multiple time I can finaly enter the page but nou it does not show the uploaded file, but it does show name and lastname. If I add this <a href="{{ asset('upload/' ~ element.file) }}">view</a> to my form then it gives me error


在呈现模板期间引发了异常(可捕获的致命错误:Symfony\Component类的对象\Form\FormView无法转换为字符串)。

An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Symfony\Component\Form\FormView could not be converted to string").

因此,如果我尝试通过添加新文件进行更新,它将给我错误文件位置不存在这可能是我的树枝出现的问题如何返回上载的文件,因为我确实使用user.id显示了上载的数据。

So if I try update by adding new file It gives me error file location does not exist That is probably A problem with my twig How Can I return the uploaded file because I do use user.id to show the uploaded data.

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\Tests\StringableObject;
use Symfony\Component\Validator\Constraints as Assert;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * 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( maxSize = "100M")
     *
     */
    private $file;

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


    public function addUser(User $user)
    {
        if (!$this->user->contains($user)) {
            $this->user->add($user);
        }
    }
    /**
     * @param $path
     * @return $this
     */
    public function setPath($path)
    {
        $this->path = $path;

        return $this;
    }

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


//
//    /**
//     * @ORM\ManyToMany(targetEntity="User", cascade={"persist"})
//     */
//    private $user;
//
//    function __construct() {
//        $this->user = new ArrayCollection();
//    }

    /**
     *
     * @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;
    }
    /**
     * @param ExecutionContextInterface $context
     */
    public function validate(ExecutionContextInterface $context)
    {
        if (! in_array($this->file->getMimeType(), array(
            'image/jpeg',
            'image/gif',
            'image/png',
            'video/mp4',
            'video/quicktime',
            'video/avi',
        ))) {
            $context
                ->buildViolation('Wrong file type (jpg,gif,png,mp4,mov,avi)')
                ->atPath('fileName')
                ->addViolation()
            ;
        }
    }
}



用户实体:



User entity:

    <?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\Tests\StringableObject;
use Symfony\Component\Validator\Constraints as Assert;
//use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Doctrine\Common\Collections\ArrayCollection;


/**
 * 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( maxSize = "100M")
     *
     */
    private $file;

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


    public function addUser(User $user)
    {
        if (!$this->user->contains($user)) {
            $this->user->add($user);
        }
    }
    /**
     * @param $path
     * @return $this
     */
    public function setPath($path)
    {
        $this->path = $path;

        return $this;
    }

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


//
//    /**
//     * @ORM\ManyToMany(targetEntity="User", cascade={"persist"})
//     */
//    private $user;
//
//    function __construct() {
//        $this->user = new ArrayCollection();
//    }

    /**
     *
     * @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;
    }
    /**
     * @param ExecutionContextInterface $context
     */
    public function validate(ExecutionContextInterface $context)
    {
        if (! in_array($this->file->getMimeType(), array(
            'image/jpeg',
            'image/gif',
            'image/png',
            'video/mp4',
            'video/quicktime',
            'video/avi',
        ))) {
            $context
                ->buildViolation('Wrong file type (jpg,gif,png,mp4,mov,avi)')
                ->atPath('fileName')
                ->addViolation()
            ;
        }
    }
}



UserType:



UserType:

<?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,
            'allow_delete'=> 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:



FilesType:

    namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;

class FilesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('file',FileType::class, array(
        // ...
        'data_class' => null,
        'by_reference' => false,
    ));
    }

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

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


}



UserController:



UserController:

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

/**
 * @param Request $request
 * @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
 *   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()) {
        $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(
                    new File($this->getParameter('upload_path') . '/' . $attachment->getFile())
                );
            }
        }

        $this->getDoctrine()->getManager()->flush();

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

    return $this->render('user/new.html.twig', array(
        'user' => $user,
        '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();
}

}

**Index.html.twig**
  <tbody>
                    {% for user in users %}
                        <tr>
                            <td><a href="{{ path('user_show', { 'id': user.id }) }}">{{ user.id }}</a></td>
                            <td>{{ user.name }}</td>
                            <td>{{ user.lastName }}</td>
                            <td style="text-align: center; vertical-align: middle;">
                                <ul style="list-style-type: none;">
                                    <li>
                                        <a type="button" class="btn btn-info"
                                           href="{{ path('user_show', { 'id': user.id }) }}">show</a>
                                    </li>
                                    <li>
                                        <a class="btn btn-default btn-xs"
                                           href="{{ path('user_edit', { 'id': user.id }) }}">edit</a>
                                    </li>
                                </ul>
                            </td>
                        </tr>
                    {% endfor %}
                    </tbody>

**Edit.twig.html**

     <div class="row-fluid">
            {{ form_start(form) }}
            <div class="form-group">
                {{ form_row(form.name, {'attr': {'class': 'form-control'}}) }}
            </div>
            <div class="form-group">
                {{ form_row(form.lastName, {'attr': {'class': 'form-control'}}) }}
            </div>
            <ul style="list-style-type: none;" class="files" data-prototype="{{ form_widget(form.files.vars.prototype)|e('html_attr') }}">
                {% for element in form.files %}
                    <li>
                        {{ form_widget(element.file) }}
                    </li>
                {% endfor %}
            </ul>
            <input  class="btn btn-success" type="submit" value="Create"/>
            {{ form_end(form) }}

            <ul style="list-style-type: none;">
                <li>
                    <a type="button" class="btn btn-primary btn-lg btn-block" href="{{ path('user_index') }}">Back to
                        the list</a>
                </li>
            </ul>
        </div>


推荐答案

1 /您必须更改表格FilesType:

1/ You must change your form FilesType:

$ builder-> add('file',FileType :: class); (确保您导入了FileType类)
,并且不要忘记使用AddFile,在您实体下的removeFile方法中,by_reference为false以使其添加/删除文件
来看看文档

$builder->add('file', FileType::class); (make sure you import FileType class) and don't forget to use AddFile, removeFile methodes under your entity with by_reference to false to make it add/delete file take a look at documentation.

2 /请注意您可以使用文件系统组件的删除函数。如果您不想使用文件系统组件,那么可以使用unlink(),在此文档的删除功能中有一个很好的例子:
公共功能removeUpload()

2/Note that you can use the remove function of the filesystem component. If you don't want to use the filesystem component, that's fine, you can use unlink(), there is a great example in this remove function of the doc: public function removeUpload()

{
    if (isset($this->file)) {
        unlink($this->file);
    }
}

这篇关于Symfony使用原理更新和删除多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆