2015-10-14 4 views
1

Моя проблема в том, что когда я загружаю файл с формой редактирования, если поле объекта пустое, файл загружается отлично, но если поле объекта не пусто (ранее я выгрузили файл), поле, которое ссылается на загруженный файл, не обновляется, и файл не загружается.Symfony2 - Загрузить файл (Редактировать форму)

Мои отношения объект является следующим:

  • Класс Документы => Таблица, где имена и пути сохраняются.
  • MyEntity Класс (любой с действием редактирования) => Entitys с полем Int, что ссылка Documents.id

MyEntityController.php

public function editTeamAction($comp, $id) { 
    if(!$id) 
     throw $this->createNotFoundException('ID is needed, '. $id); 
    $em = $this->getDoctrine()->getEntityManager(); 
    $entity = $em->getRepository('MyBundle:MyEntity')->find($id); 
    if(!$entity) 
     throw $this->createNotFoundException('Entity not found with id '. $id); 
    $editForm = $this->createEditForm($entity); 

    return $this->render("MyBundle::edit.html.twig", array("entity"=> $entity, "comp" => $comp, "edit_form"=>$editForm->createView(), "path_form" => "ent_update")); 
} 

private function createEditForm(MyEntity $entity) { 
    $form = $this->createForm(new MyEntityType(), $entity); 
    $form->add('submit', 'submit', array('label' => 'Update')); 

    return $form; 
} 

public function updateTeamAction(Request $request, $comp, $id) { 
    $em = $this->getDoctrine()->getEntityManager(); 
    $entity = $em->getRepository('MyBundle:MyEntity')->find($id); 
    if(!$entity) 
     throw $this->createNotFoundException('Entity not found with id '. $id); 

    $editForm = $this->createEditForm($entity); 
    $editForm->handleRequest($request); 

    if($editForm->isValid()) 
    { 
     $em->persist($entity); 
     $em->flush(); 

     $this->get('session')->getFlashBag()->add(
      'notice', 
      'Edit success.' 
     ); 
     return $this->redirect($this->generateUrl('ent_edit', array('comp' => $comp, 'id' => $id))); 
    } 
    return $this->render("MyBundle::edit.html.twig", array("entity"=> $entity, "comp" => $comp, "edit_form"=>$editForm->createView(), "path_form" => "ent_update")); 
} 

MyEntity.php

namespace My\Bundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use My\Bundle\Entity\Documents; 

/** 
* MyEntity 
* 
* @ORM\Table() 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks 
*/ 
class MyEntity 
{ 
    /** 
    * @var integer 
    * 
    * @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; 

    /** 
    * @ORM\ManyToOne(targetEntity="Comp", inversedBy="myentity") 
    * @ORM\JoinColumn(name="comp_id", referencedColumnName="id") 
    */ 
    protected $Comp; 

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

    /** 
    * @ORM\ManyToOne(targetEntity="Documents", cascade={"persist", "remove"}, inversedBy="myentity") 
    * @ORM\JoinColumn(name="logo", referencedColumnName="id", nullable=true) 
    */ 
    private $logo = null; 

    /** 
    * @ORM\Column(type="datetime") 
    * 
    * @var \DateTime 
    */ 
    private $updatedAt; 

    /** 
    * @ORM\ManyToOne(targetEntity="Documents", inversedBy="myentity") 
    * @ORM\JoinColumn(name="images", referencedColumnName="id", nullable=true) 
    */ 
    protected $images = null; 

    public function __construct() 
    { 
    } 

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

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

     return $this; 
    } 

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

    /** 
    * Set comp 
    * 
    * @param \My\Bundle\Entity\Comp $comp 
    * @return MyEntity 
    */ 
    public function setComp(\My\Bundle\Entity\Comp $comp = null) 
    { 
     $this->comp = $comp; 

     return $this; 
    } 

    /** 
    * Get comp 
    * 
    * @return \My\Bundle\Entity\Comp 
    */ 
    public function getCompeticion() 
    { 
     return $this->competicion; 
    } 

    /** 
    * Set web 
    * 
    * @param string $web 
    * @return MyEntity 
    */ 
    public function setWeb($web) 
    { 
     $this->web = $web; 

     return $this; 
    } 

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

    /** 
    * Set images 
    * 
    * @param \My\Bundle\Entity\Documents $images 
    * @return MyEntity 
    */ 
    public function setImages(\My\Bundle\Entity\Documents $images = null) 
    { 
     $this->images = $images; 

     return $this; 
    } 

    /** 
    * Get images 
    * 
    * @return \My\Bundle\Entity\Documents 
    */ 
    public function getImages() 
    { 
     return $this->images; 
    } 

    /** 
    * Set updatedAt 
    * 
    * @param \DateTime $updatedAt 
    * @return MyEntity 
    */ 
    public function setUpdatedAt($updatedAt) 
    { 
     $this->updatedAt = $updatedAt; 

     return $this; 
    } 

    /** 
    * Get updatedAt 
    * 
    * @return \DateTime 
    */ 
    public function getUpdatedAt() 
    { 
     return $this->updatedAt; 
    } 

    /** 
    * Set logo 
    * 
    * @param \My\Bundle\Entity\Documents $logo 
    * @return MyEntity 
    */ 
    public function setLogo(\My\Bundle\Entity\Documents $logo = null) 
    { 
     $this->logo = $logo; 

     return $this; 
    } 

    /** 
    * Get logo 
    * 
    * @return \My\Bundle\Entity\Documents 
    */ 
    public function getLogo() 
    { 
     return $this->logo; 
    } 
} 

Документы.php

namespace My\Bundle\Entity; 

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

/** 
* Documents 
* 
* @ORM\Table() 
* @ORM\Entity 
* @ORM\HasLifecycleCallbacks 
*/ 
class Documents 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

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

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

    public $file; 

    /** 
    * @ORM\OneToMany(targetEntity="MyEntity", mappedBy="images") 
    */ 
    protected $myentity; 

    public function __construct($path = "") 
    { 
     $this->myentity = new \Doctrine\Common\Collections\ArrayCollection(); 
     $this->setPath($path); 
    } 

    /** 
    * @ORM\PrePersist() 
    * @ORM\PreUpdate() 
    */ 
    public function preUpload() 
    { 
     $this->tempFile = $this->getAbsolutePath(); 
     $this->oldFile = $this->getPath(); 
     if(null !== $this->file) 
     { 
      $filename = sha1(uniqid(mt_rand(), true)); 
      $this->name = $filename.'.'.$this->file->guessExtension(); 
     } 
    } 

    /** 
    * @ORM\PostPersist() 
    * @ORM\PostUpdate() 
    */ 
    public function upload() 
    { 
     if (null === $this->file) 
      return; 
     $this->preUpload($this->file); 
     if(null !== $this->file) 
     { 
      $this->file->move($this->getUploadRootDir().$this->path, $this->name); 
      unset($this->file); 

      //if($this->oldFile != null) 
      //  unlink($this->tempFile);  
     } 
    } 

    /** 
    * @ORM\PostLoad() 
    */ 
    public function postLoad() 
    { 
     $this->updatedAt = new \DateTime('now'); 
    } 

    /** 
    * @ORM\PreRemove() 
    */ 
    public function preRemoveUpload() 
    { 
     $this->tempFile = $this->getAbsolutePath(); 
    } 

    /** 
    * @ORM\PostRemove() 
    */ 
    public function removeUpload() 
    { 
     // if($file = $this->getAbsolutePath()) 
     //  unlink($file); 
     if(file_exists($this->tempFile)) 
      unlink($this->tempFile); 
    } 

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

    public function getAssetPath() 
    { 
     return $this->getUploadDir().$this->path; 
    } 

    /** 
    * Called after entity persistence 
    * 
    * @ORM\PostPersist() 
    * @ORM\PostUpdate() 
    */ 

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

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

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

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

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

     return $this; 
    } 

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

    /** 
    * Set path 
    * 
    * @param string $path 
    * @return Documents 
    */ 
    public function setPath($path) 
    { 
     $this->path = $path; 

     return $this; 
    } 

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

    /** 
    * Add myentity 
    * 
    * @param \My\Bundle\Entity\MyEntity $myentity 
    * @return Documents 
    */ 
    public function addMyentity(\My\Bundle\Entity\MyEntity $myentity) 
    { 
     $this->myentity[] = $myentity; 

     return $this; 
    } 

    /** 
    * Remove myentity 
    * 
    * @param \My\Bundle\Entity\MyEntity $myentity 
    */ 
    public function removeMyentity(\My\Bundle\Entity\MyEntity $myentity) 
    { 
     $this->myentity->removeElement($myentity); 
    } 

    /** 
    * Get myentity 
    * 
    * @return \Doctrine\Common\Collections\Collection 
    */ 
    public function getMyentity() 
    { 
     return $this->myentity; 
    } 

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

MyEntityType.php

namespace My\Bundle\Form; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Doctrine\ORM\EntityRepository; 

class MyEntityType extends AbstractType 
{ 
    public function __construct() 
    { 
    } 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('comp', "entity", array(
       "label"=>"Comp", 
       "class" => "MyBundle:Comp", 
       "property" => "nameEn", 
       "query_builder" => function(EntityRepository $er) { 
        return $er->createQueryBuilder("c") 
         ->orderBy("c.nameEn", "ASC"); 
       })) 
      ->add('name', 'text') 
      ->add('country', "entity", array(
       "label"=>"Country", 
       "class" => "CountryBundle:Country", 
       "property" => "englishName", 
       "query_builder" => function(EntityRepository $er) { 
        return $er->createQueryBuilder("p") 
         ->orderBy("p.englishName", "ASC"); 
       })) 
      ->add('web', 'text', array("required" => false, "render_optional_text" => false)) 
      ->add('logo', new DocumentsType('logo_entity'), array('horizontal' => false, 'label' => 'Logo')) 
     ; 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'My\Bundle\Entity\MyEntity' 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return ''; 
    } 
} 

DocumentsType.php

namespace My\Bundle\Form; 

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

class DocumentsType extends AbstractType 
{ 
    /** 
    * @param FormBuilderInterface $builder 
    * @param array $options 
    */ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      ->add('file', 'file', array('required' => false, 'label' => false)) 
     ; 
    } 

    /** 
    * @param OptionsResolverInterface $resolver 
    */ 
    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'My\Bundle\Entity\Documents' 
     )); 
    } 

    /** 
    * @return string 
    */ 
    public function getName() 
    { 
     return 'documents'; 
    } 
} 

edit.html.twig

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

{% block stylesheets %} 
    {{ parent() }} 
{% endblock %} 
{% block javascripts %} 
    {{parent()}} 
{% endblock %} 
{% block wrapper %} 
    {{parent()}} 
    <h3>Edit</h3> 
    {% for flashMessage in app.session.flashbag.get('notice') %} 
     {{ flashMessage }} 
    {% endfor %} 
    <form action="{{ path(path_form, { 'id': entity.id, 'comp' : comp }) }}" method="POST" {{ form_enctype(edit_form) }}> 
     {{ form(edit_form) }} 
    </form> 
{% endblock %} 

ответ

0

Ну, я нашел (наконец-то!) решение этой проблемы.

UpdateAction от Controller должен проверить, если форма отправлена ​​новым файлом. Если нет, сущность должна установить logLogo (в моем случае) фактический логотип, который имеет в БД. Если новый файл существует и действителен, я создаю новый объект «Документы» и устанавливаю файл с загруженным файлом. Наконец, я удаляю предыдущий логотип с сервера (это необязательно).

Кодекса UpdateAction:

MyEntityController.PHP

public function updateTeamAction(Request $request, $comp, $id) { 
    $em = $this->getDoctrine()->getEntityManager(); 
    $entity = $em->getRepository('MyBundle:MyEntity')->find($id); 
    if(!$entity) 
     throw $this->createNotFoundException('Entity not found with id '. $id); 

    $editForm = $this->createEditForm($entity); 
    //Save original Logo 
    $logoOriginal = $entity->getLogo(); 
    $editForm->handleRequest($request); 
    if($editForm->isValid()) 
    { 
     $files = $request->files; 
     $uploadedFile = $files->get('logo')['file']; 
     if(count($uploadedFile)==0) 
      $entity->setLogo($logoOriginal); 
     else 
     { 
      $documents = new Documents(); 
      $documents->setPath('logo'); 
      $documents->setFile($uploadedFile); 

      $entity->setLogo($documents); 
      if(!empty($logoOriginal)) 
      { 
       $fs = new Filesystem(); 
       $fs->remove($documents->getAbsolutePath().'/'.$logoOriginal->getName()); 
      } 
     } 
     $em->persist($entity); 
     $em->flush(); 
     $this->get('session')->getFlashBag()->add(
      'notice', 
      'Edit success.' 
     ); 
     return $this->redirect($this->generateUrl('ent_edit', array('comp' => $comp, 'id' => $id))); 
    } 
    return $this->render("MyBundle::edit.html.twig", array("entity"=> $entity, "comp" => $comp, "edit_form"=>$editForm->createView(), "path_form" => "ent_update")); 
} 

Если вы хотите, чтобы шаг, чтобы удалить, добавить в контроллер этого:

use Symfony\Component\Filesystem\Filesystem; 

В конце концов, я понял, что проблема с именем нового файла, созданного (не было то же самое, что было сохранено в БД, которая была создана в папке сервера). В объекте Документы я изменил функцию upload(), удалив эту строку

$ this-> preUpload ($ this-> file);

Итак, окончательный код функции загрузки() является следующим:

Documents.php

/** 
* @ORM\PostPersist() 
* @ORM\PostUpdate() 
*/ 
public function upload() 
{ 
    if (null === $this->file) 
     return; 
    if(null !== $this->file) 
    { 
     $this->file->move($this->getUploadRootDir().$this->path, $this->name); 
     unset($this->file); 
     //if($this->oldFile != null) 
     //  unlink($this->tempFile);  
    } 
} 
0

Привет думает, что проблема в контроллере (MyEntityController.php)
После проверки формы, в updateTeamAction вы используете это:

if($editForm->isValid()) 
{ 
    $em->persist($entity); 
    $em->flush(); 

    $this->get('session')->getFlashBag()->add(
     'notice', 
     'Edit success.' 
    ); 
    return $this->redirect($this->generateUrl('ent_edit', array('comp' => $comp, 'id' => $id))); 
} 

Но таким образом вы сохраняющиеся в $ сущности, и не обновляется. вам нужно получить объект из формы таким образом:

if($editForm->isValid()) 
{ 
    $em->persist($editForm->getData()); 
    $em->flush(); 

    $this->get('session')->getFlashBag()->add(
     'notice', 
     'Edit success.' 
    ); 
    return $this->redirect($this->generateUrl('ent_edit', array('comp' => $comp, 'id' => $id))); 
} 

Попробуйте этот путь и дать нам свой отзыв

Смежные вопросы