【问题标题】:Symfony2 File Upload with own EntitySymfony2 使用自己的实体上传文件
【发布时间】:2014-08-29 11:25:33
【问题描述】:

我有一个实体“任务”和另一个“附件”。我想将所有附件存储在与他们的任务和用户关联的自己的表中。所以我创建了这个实体类:

<?php

namespace Seotool\MainBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="attachments")
 */
class Attachments {

/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
protected $id;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\NotBlank
 */
public $name;

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

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="attachments")
 * @ORM\JoinColumn(name="user", referencedColumnName="id")
 */
protected $User;

/**
 * @ORM\ManyToOne(targetEntity="User", inversedBy="attachments")
 * @ORM\JoinColumn(name="editor", referencedColumnName="id")
 */
protected $Editor;

/**
 * @ORM\ManyToOne(targetEntity="Task", inversedBy="attachments")
 * @ORM\JoinColumn(name="task", referencedColumnName="id")
 */
protected $Task;

/**
 * @Assert\File(maxSize="6000000")
 */
private $file;

/**
 * Sets file.
 *
 * @param UploadedFile $file
 */
public function setFile(UploadedFile $file = null)
{
    $this->file = $file;
}

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

public function getAbsolutePath()
{
    return null === $this->path
        ? null
        : $this->getUploadRootDir().'/'.$this->path;
}

public function getWebPath()
{
    return null === $this->path
        ? null
        : $this->getUploadDir().'/'.$this->path;
}

protected function getUploadRootDir()
{
    // the absolute directory path where uploaded
    // documents should be saved
    return __DIR__.'/../../../../web/'.$this->getUploadDir();
}

protected function getUploadDir()
{
    // get rid of the __DIR__ so it doesn't screw up
    // when displaying uploaded doc/image in the view.
    return 'uploads/documents';
}

....

在我的任务表单的表单类型中,我现在要添加文件上传。但是我该怎么做呢? 我无法添加$builder-&gt;add('Attachment', 'file');,因为它不是同一个实体。那我该怎么做,以便我在我的实体任务的FormType中有上传字段,该字段将上传的数据存储在实体类附件的表中??

编辑

这是我的控制器:

/**
@Route(
 *     path = "/taskmanager/user/{user_id}",
 *     name = "taskmanager"
 * )
 * @Template()
 */
public function taskManagerAction($user_id, Request $request)
{

     /* #### NEW TASK #### */

    $task = new Task();
    $attachment = new Attachments();

    $task->getAttachments()->add($attachment);
    $addTaskForm = $this->createForm(new TaskType(), $task);

    $addTaskForm->handleRequest($request);

    if($addTaskForm->isValid()):

        /* User Object of current Users task list */
        $userid = $this->getDoctrine()
            ->getRepository('SeotoolMainBundle:User')
            ->find($user_id);

        $task->setDone(FALSE);
        $task->setUser($userid);
        $task->setDateCreated(new \DateTime());
        $task->setDateDone(NULL);
        $task->setTaskDeleted(FALSE);

        $attachment->setTask($task);
        $attachment->setUser($userid);

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

        $this->log($user_id, $task->getId(), 'addTask');

        return $this->redirect($this->generateUrl('taskmanager', array('user_id' => $user_id)));

    endif;
}

【问题讨论】:

    标签: php symfony file-upload


    【解决方案1】:

    您应该将您的实体从 Attachments 重命名为 Attachment,因为它将只存储一个附件的数据。

    在您的情况下,您需要 Symfony2 表单集合类型以允许在任务表单(TaskType)中添加附件:

    $builder->add('attachments', 'collection', array(
        'type' => new AttachmentType(),
        // 'allow_add' => true,
        // 'allow_delete' => true,
        // 'delete_empty' => true,
    ));
    

    您还需要为单个附件实体创建 AttachmentType 表单类型。

    采集字段类型文档:http://symfony.com/doc/current/reference/forms/types/collection.html 有关嵌入表单集合的更多信息,您可以在以下位置找到:http://symfony.com/doc/current/cookbook/form/form_collections.html

    然后还阅读部分:

    【讨论】:

    • 如果您遇到任何问题,请告诉我。
    • 我做了一个新的答案,会很高兴,你可以看看:)
    【解决方案2】:

    好的,那是因为您必须在控制器中初始化 TaskType 的新实例 - 开头没有分配给此任务的附件。

    public function newAction(Request $request)
    {
        $task = new Task();
    
        $attachment1 = new Attachment();
        $task->getAttachments()->add($attachment1);
        $attachment2 = new Attachment();
        $task->getAttachments()->add($attachment2);
        // create form
        $form = $this->createForm(new TaskType(), $task);
    
        $form->handleRequest($request);
        ...
    }
    

    现在应该有 2 个新附件的文件输入。

    【讨论】:

    • 我得到这个异常:FatalErrorException:错误:调用 /Applications/MAMP/htdocs/Seotool/src/Seotool/MainBundle/Controller/DashboardController 中非对象的成员函数 add()。 php第52行。第52行是:$task->getAttachments()->add($attachment);
    • 你设置了吗:$this->attachments = new ArrayCollection();在您的任务实体类的构造函数中?
    • 我现在做到了。异常消失但没有输出任何内容...没有文件上传。 :-/
    • 这里有解释:symfony.com/doc/current/cookbook/form/form_collections.html - 尝试检查您的代码或给我更多代码:)
    • 例外你的意思是:“Symfony 只有在选择了要上传的文件时才应该添加附件条目?”我是的,您不应该手动执行此操作: $attachment->setTask($task); $attachment->setUser($userid);因为这将始终为您节省一个附件。
    【解决方案3】:

    我添加了一个新的表单类型:AttachmentsType.php

    <?php
    namespace Seotool\MainBundle\Form\Type;
    
    use Doctrine\ORM\EntityRepository;
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
    
    class AttachmentsType extends AbstractType
    {
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', 'text');
        $builder->add('file', 'file');
    }
    
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver
                ->setDefaults(array(
                    'data_class' => 'Seotool\MainBundle\Entity\Attachments'
                ));
    }
    
    public function getName()
    {
        return 'attachments';
    }
    }
    

    并将其用于将其嵌入到我的 TaskType.php 表单构建器中

    $builder->add('attachments', 'collection', array(
        'type' => new AttachmentsType(),
    ));
    

    但我的输出只给了我以下 HTML:

     <div class="form-group"><label class="control-label required">Attachments</label><div id="task_attachments"></div></div><input id="task__token" name="task[_token]" class="form-control" value="brHk4Kk4xyuAhST3TrTHaqwlnA03pbJ5RE4NA0cmY-8" type="hidden"></form>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-25
      • 1970-01-01
      • 2015-10-16
      • 1970-01-01
      • 2015-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多