给出了str2 Doctrine \ ORM \ PersistentCollection的实例

时间:2017-03-30 07:41:16

标签: symfony file-upload collections persistent

我是php和symfony的新手 我在symfony 2.8中使用文件服务进行上传 我有两张桌子一个沙龙到很多档案

我可以在newaction中上传多个文件。 问题出现在我的SalonController的editAction上。

我想删除旧文件,以便在editfiles.html.twig中添加新文件。我尝试了一个foreach以获得这个数组...

你能帮帮我吗?

这是错误

  

类型错误:传递给DefaultBundle \ Service \ FileService :: upload()的参数1必须是DefaultBundle \ Entity \ File的实例,Doctrine \ ORM \ PersistentCollection的实例,在/ var / www / html / salon中调用第131行的-beaute / src / SalonBundle / Controller / SalonController.php

堆栈跟踪集中在fileservice.php的第18行

  

公共函数上传(文件$文件= NULL,$型){

这是我的SalonController的新动作和编辑动作

class SalonController extends Controller

{     / **      *创建一个新的沙龙实体。      *      * @Route(“/ new”,name =“salon_new”)      * @Method({“GET”,“POST”})      * /     public function newAction(Request $ request)     {         $这 - > denyAccessUnlessGranted( 'ROLE_SALON');         $ em = $ this-> getDoctrine() - > getManager();         $ salon = new Salon();

    $options = array('role' => $this->getUser()->getRoles(), 'page' => 'add');

    $form = $this->createForm( 'SalonBundle\Form\SalonType',$salon, $options);
    $user = $this->getUser();
    $form->handleRequest($request);

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

        $uploadService = $this->get('app.file');

        $myFiles = $form->get('file')->getData();

        foreach($myFiles['path'] as $new_file) {

            $file = new File();
            $file->setPath($new_file);
            $file->setSalon($salon);
            $salon->addFile($file);
            $uploadService->upload($file, 'salon');
            $em->persist($file);
        }

        $user->setSalon($salon);
        $salon->setEnable(false);
        $em->persist($user);
        $em->persist($salon);
        $em->flush();

        $this->get('email')->salon($salon);
        return $this->redirectToRoute('salon_show', array('id' => $salon->getId()));
    }
/**
 * Displays a form to edit an existing salon entity.
 *
 * @Route("/edit", name="salon_edit")
 * @Method({"GET", "POST"})
 * @Security("has_role('ROLE_SALON')")
 */
public function editAction(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $user = $this->getUser();
    $salon = $user->getSalon();
    $deleteForm = $this->createDeleteForm($salon);
    $options = array('role' => $this->getUser()->getRoles(), 'page' => 'edit');

    $editForm = $this->createForm('SalonBundle\Form\SalonType', $salon, $options);

    $editForm->handleRequest($request);

    if ($editForm->isSubmitted() && $editForm->isValid()) {
        // If new file
        $edit_file = $editForm->get('edit_file')->getData();
        if (!is_null($edit_file)) {
            $file_current = $salon->getFiles();
            $salon->getFiles($edit_file);
            if (!$this->get('app.file')->upload($salon->getFiles(), 'salon'))
                $salon->getFiles($file_current);
        }

        foreach($edit_file['path'] as $new_edit_file) {
            $file = new File();
            $file->setPath($new_edit_file);
            $file->setSalon($salon);
            $salon->addFile($file);
            $this->get('app.file')->upload($file);
            $em->persist($file);
        }

        $this->getDoctrine()->getManager()->flush();
        $this->addFlash('success', 'Le partenaire a bien été modifié');
        return $this->redirectToRoute('salon_show');
    }

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

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

我SalonType的一部分

    class SalonType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $page = $options['page'];

        $builder
            ->add('name', TextType::class, array(
                'label' => 'Nom du salon'
            ))
            ->add('content', TextareaType::class, array(
                'label' => 'Descriptif'
            ))
            ->add('address_salon', AddressType::class, array(
                'label' => ' '
            ))
        ;

        if($page == 'add') {
            $builder
                ->add('file', FileType::class, array(
                    'label' => 'Vous pouvez téléchargez jusqu\'à 3 images',
                    'required' => false,
                    'mapped' =>false,
                ));
        }

        if($page == 'edit') {
            $builder
                ->add('edit_file', FileType::class, array(
                    'label' => 'Nouveau fichier',
                    'required' => false,
                    'mapped' => false
                ));
        };

    }



    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'SalonBundle\Entity\Salon',
            'role' => null
        ));
        $resolver
            ->setRequired(['page']);
    }


My fileType

    class FileType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('path', \Symfony\Component\Form\Extension\Core\Type\FileType::class, array(
                'label' => 'Image',
                'multiple' => true,
            ))
        ;
    }

    public function configureOptions(OptionsResolver $resolver) {
        $resolver->setDefaults(array(
            'data_class' => null,
        ));
    }
}

My fileService

    <?php
namespace DefaultBundle\Service;

use DefaultBundle\Entity\File;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class FileService {
    private $directory_root;
    private $directory_default;


    public function __construct($directory_root, $directory_default) {
        $this->directory_root = $directory_root;
        $this->directory_default = $directory_default;
    }

    public function upload(File $file = null, $type) {
        $path = $this->getDirectory($type);

        if (is_null($file))
            return false;

        // Get file (Class UploadFile)
        $file_uploaded = $file->getPath();

        if ($file_uploaded->getError())
            return false;

        // Move file
        $file_name = md5(uniqid()) . '.' . $file_uploaded->guessExtension();
        $file_uploaded->move($this->directory_root . $path, $file_name);

        // Update object file
        $path .= '/' . $file_name;
        $file->update($file_uploaded, $path);

        return true;
    }

    public function delete(File $file){
        $path = $this->directory_root.$file->getPath();
        if(file_exists($path))
            unlink($path);
    }

    private function getDirectory($type) {
        switch ($type) {
            default:
                return $this->directory_default;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

你的代码有点混乱,我的意思是你的控制器中有很多逻辑: - )

只知道控制器中哪一行是131?

这里有错误(不知道是否为131行)

if (!$this->get('app.file')->upload($salon->getFiles(), 'salon'))

在这里你发送一个集合到upload(),你自己说了

  

一个沙龙到多个文件

但在尝试修补此修改之前,请参阅教程here,了解如何处理多个文件上传。

此教程还提供full demo source code。代码很清楚,您应该能够轻松理解它。

修改

如果您不想重写代码,可能需要修改代码

if (!is_null($edit_file)) {
    $file_current = $salon->getFiles();
    //$salon->getFiles($edit_file); What is the goal of this?
    foreach ($salon->getFiles() as $file) {
        // Note that now we send a single File object not a collection
        if (!$this->get('app.file')->upload($file, 'salon')) {
            $salon->setFiles($file_current); // You want to set the files no?
            break;
        }
    }
}

这是200%的丑陋,我甚至不确定它是否会起作用。你应该考虑重构你的代码。

修改2

您现在遇到的问题是您正在混合File对象和symfony中的UploadedFile对象。

你做$file_uploaded = $file->getPath();然后你有错误

  

在字符串

上调用成员函数getError()

这是正常的,因为getPath()会返回一个字符串。

我假设您已经查看了symfony doc的Uploader Service。您可以看到它们传递了UploadedFile对象,该对象是symfony包的一部分,而不是自定义实体。

如果我想快速修复,这绝对不是我推荐的,我会做这样的事情

// Your controller (newAction)
foreach($myFiles['path'] as $new_file) {
    // $new_file is an uploadedFile object, this is the file you want to upload
    $file = new File();
    $file->setPath($new_file);
    $file->setSalon($salon);
    $salon->addFile($file);
    $uploadService->upload($file, $new_file, 'salon');
    $em->persist($file);
}

// Your FileService
public function upload(File $file = null, UploadedFile $file_uploaded = null, $type) {
    $path = $this->getDirectory($type);

    if (is_null($file_uploaded) || is_null($file))
        return false;

    // Get file (Class UploadFile), No here you get the file path => a string
    //$file_uploaded = $file->getPath();

    if ($file_uploaded->getError())
        return false;

    //... end of your method
}