尝试设置附加到Doctrine实体的文件上传表单,根据这个菜谱配方:
http://symfony.com/doc/2.0/cookbook/doctrine/file_uploads.html
这是我的实体/模型类:
<?php
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
/**
* Invoice
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="TechPeople\InvoiceBundle\Entity\InvoiceRepository")
* @ORM\HasLifecycleCallbacks
*/
class Invoice
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var integer
*
* @ORM\ManyToOne(targetEntity="User", inversedBy="user_invoices")
* @ORM\JoinColumn(name="vendor_id", referencedColumnName="id")
*/
private $vendor;
/**
* @var string
*
* @ORM\Column(name="month", type="string", length=255)
*/
private $month;
/**
* @var integer
*
* @ORM\Column(name="year", type="smallint")
*/
private $year;
/**
* @var boolean
*
* @ORM\Column(name="expenses", type="boolean")
*/
private $expenses;
/**
* @var \DateTime
*
* @ORM\Column(name="due", type="date")
*/
private $due;
/**
* @var \DateTime
*
* @ORM\Column(name="paid", type="date")
*/
private $paid;
/**
* @var \DateTime
*
* @ORM\Column(name="created", type="datetime")
*/
private $created;
/**
* @var float
*
* @ORM\Column(name="expense_amount", type="decimal")
*/
private $expense_amount;
/**
* @var float
*
* @ORM\Column(name="total_amount", type="decimal")
*/
private $total_amount;
/**
* @var UploadedFile
*
* @Assert\File(maxSize="6000000")
*/
public $attachment;
/**
* @var string
*
* @ORM\Column(name="attachment_path", type="string", length=255)
*/
private $attachment_path;
/**
* @ORM\OneToMany(targetEntity="InvoiceItem", mappedBy="invoice")
*/
protected $invoice_items;
/**
* Constructor for Invoice Entity class
*/
public function __construct()
{
$this->products = new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set month
*
* @param string $month
* @return Invoice
*/
public function setMonth($month)
{
$this->month = $month;
return $this;
}
/**
* Get month
*
* @return string
*/
public function getMonth()
{
return $this->month;
}
/**
* Set year
*
* @param integer $year
* @return Invoice
*/
public function setYear($year)
{
$this->year = $year;
return $this;
}
/**
* Get year
*
* @return integer
*/
public function getYear()
{
return $this->year;
}
/**
* Set expenses
*
* @param boolean $expenses
* @return Invoice
*/
public function setExpenses($expenses)
{
$this->expenses = $expenses;
return $this;
}
/**
* Get expenses
*
* @return boolean
*/
public function getExpenses()
{
return $this->expenses;
}
/**
* Set due
*
* @param \DateTime $due
* @return Invoice
*/
public function setDue($due)
{
$this->due = $due;
return $this;
}
/**
* Get due
*
* @return \DateTime
*/
public function getDue()
{
return $this->due;
}
/**
* Set paid
*
* @param \DateTime $paid
* @return Invoice
*/
public function setPaid($paid)
{
$this->paid = $paid;
return $this;
}
/**
* Get paid
*
* @return \DateTime
*/
public function getPaid()
{
return $this->paid;
}
/**
* Set created
*
* @param \DateTime $created
* @return Invoice
*/
public function setCreated($created)
{
$this->created = $created;
return $this;
}
/**
* Get created
*
* @return \DateTime
*/
public function getCreated()
{
return $this->created;
}
/**
* Set expense_amount
*
* @param float $expenseAmount
* @return Invoice
*/
public function setExpenseAmount($expenseAmount)
{
$this->expense_amount = $expenseAmount;
return $this;
}
/**
* Get expense_amount
*
* @return float
*/
public function getExpenseAmount()
{
return $this->expense_amount;
}
/**
* Set total_amount
*
* @param float $totalAmount
* @return Invoice
*/
public function setTotalAmount($totalAmount)
{
$this->total_amount = $totalAmount;
return $this;
}
/**
* Get total_amount
*
* @return float
*/
public function getTotalAmount()
{
return $this->total_amount;
}
/**
* Set attachment
*
* @param string $attachment
* @return Invoice
*/
public function setAttachment($attachment)
{
$this->attachment = $attachment;
return $this;
}
/**
* Get attachment
*
* @return string
*/
public function getAttachment()
{
return $this->attachment;
}
/**
* Set vendor
*
* @param \TechPeople\InvoiceBundle\Entity\User $vendor
* @return Invoice
*/
public function setVendor(\TechPeople\InvoiceBundle\Entity\User $vendor = null)
{
$this->vendor = $vendor;
return $this;
}
/**
* Get vendor
*
* @return \TechPeople\InvoiceBundle\Entity\User
*/
public function getVendor()
{
return $this->vendor;
}
/**
* Add invoice_items
*
* @param \TechPeople\InvoiceBundle\Entity\InvoiceItem $invoiceItems
* @return Invoice
*/
public function addInvoiceItem(\TechPeople\InvoiceBundle\Entity\InvoiceItem $invoiceItems)
{
$this->invoice_items[] = $invoiceItems;
return $this;
}
/**
* Remove invoice_items
*
* @param \TechPeople\InvoiceBundle\Entity\InvoiceItem $invoiceItems
*/
public function removeInvoiceItem(\TechPeople\InvoiceBundle\Entity\InvoiceItem $invoiceItems)
{
$this->invoice_items->removeElement($invoiceItems);
}
/**
* Get invoice_items
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getInvoiceItems()
{
return $this->invoice_items;
}
/**
* Get path for attachment
*
* @param string $type Can return web path, or absolute path, web is default
* @return null|string
*/
public function getAttachmentPath($type='web')
{
if($type == 'absolute') {
return null === $this->attachment_path
? null
: $this->getUploadRootDir().'/'.$this->attachment_path;
} else {
return null === $this->attachment_path
? null
: $this->getUploadDir().'/'.$this->attachment_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/invoice/attachments';
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
if (null !== $this->attachment) {
// do whatever you want to generate a unique name
$filename = sha1(uniqid(mt_rand(), true));
$this->attachment = $filename.'.'.$this->attachment->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null === $this->attachment) {
return;
}
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->attachment->move($this->getUploadRootDir(), $this->path);
unset($this->attachment);
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
if ($file = $this->getAttachmentPath('absolute')) {
unlink($file);
}
}
}
当我尝试提交编辑表单时,我收到以下错误(编辑表单由doctrine生成:generate:crud):
Fatal error: Call to a member function move() on a non-object
可能与以下相同:
但这个问题没有得到解答。我希望发布第二个问题并不违反礼节。
我是Symfony2的新手,只是想学习我的方式,这让我很难过。我可以发布您需要的任何其他信息,让我知道是什么。
这是表单类:
<?php
namespace TechPeople\InvoiceBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class InvoiceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('month')
->add('year')
->add('expenses')
->add('due')
->add('paid')
->add('created')
->add('expense_amount')
->add('total_amount')
->add('attachment')
->add('vendor')
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'TechPeople\InvoiceBundle\Entity\Invoice'
));
}
public function getName()
{
return 'techpeople_invoicebundle_invoicetype';
}
}
这是控制器:
<?php
namespace TechPeople\InvoiceBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use TechPeople\InvoiceBundle\Entity\Invoice;
use TechPeople\InvoiceBundle\Form\InvoiceType;
/**
* Invoice controller.
*
*/
class InvoiceController extends Controller
{
/**
* Lists all Invoice entities.
*
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository('TechPeopleInvoiceBundle:Invoice')->findAll();
return $this->render('TechPeopleInvoiceBundle:Invoice:index.html.twig', array(
'entities' => $entities,
));
}
/**
* Finds and displays a Invoice entity.
*
*/
public function showAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TechPeopleInvoiceBundle:Invoice')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Invoice entity.');
}
$deleteForm = $this->createDeleteForm($id);
return $this->render('TechPeopleInvoiceBundle:Invoice:show.html.twig', array(
'entity' => $entity,
'delete_form' => $deleteForm->createView(), ));
}
/**
* Displays a form to create a new Invoice entity.
*
*/
public function newAction()
{
$entity = new Invoice();
$form = $this->createForm(new InvoiceType(), $entity);
return $this->render('TechPeopleInvoiceBundle:Invoice:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Creates a new Invoice entity.
*
*/
public function createAction(Request $request)
{
$entity = new Invoice();
$form = $this->createForm(new InvoiceType(), $entity);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('invoice_show', array('id' => $entity->getId())));
}
return $this->render('TechPeopleInvoiceBundle:Invoice:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
/**
* Displays a form to edit an existing Invoice entity.
*
*/
public function editAction($id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TechPeopleInvoiceBundle:Invoice')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Invoice entity.');
}
$editForm = $this->createForm(new InvoiceType(), $entity);
$deleteForm = $this->createDeleteForm($id);
return $this->render('TechPeopleInvoiceBundle:Invoice:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Edits an existing Invoice entity.
*
*/
public function updateAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TechPeopleInvoiceBundle:Invoice')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Invoice entity.');
}
$deleteForm = $this->createDeleteForm($id);
$editForm = $this->createForm(new InvoiceType(), $entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('invoice_edit', array('id' => $id)));
}
return $this->render('TechPeopleInvoiceBundle:Invoice:edit.html.twig', array(
'entity' => $entity,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Invoice entity.
*
*/
public function deleteAction(Request $request, $id)
{
$form = $this->createDeleteForm($id);
$form->bind($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('TechPeopleInvoiceBundle:Invoice')->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Invoice entity.');
}
$em->remove($entity);
$em->flush();
}
return $this->redirect($this->generateUrl('invoice'));
}
private function createDeleteForm($id)
{
return $this->createFormBuilder(array('id' => $id))
->add('id', 'hidden')
->getForm()
;
}
}
这些都是非常基本的东西,直接来自文档,因为,正如我所说,我只是在学习Symfony。任何帮助非常感谢。
答案 0 :(得分:2)
$ this-&gt;附件必须是UploadedFile对象。
但是在你的方法preUpload()中你犯了一个错误,并为字符串覆盖它:
$this->attachment = $filename.'.'.$this->attachment->guessExtension();
然后调用upload()方法并检查$ this-&gt;附件是否为null,这是真的,因为它是一个字符串:
if (null === $this->attachment) {
return;
}
在字符串上执行 - &gt; move()会显示错误;)
所以回答一下,在preUpload()方法中替换这一行:
$this->attachment= $filename.'.'.$this->attachment->guessExtension();
有关:
$this->path = $filename.'.'.$this->attachment->guessExtension();