我有一个应用程序,允许用户在申请课程时上传简历。输入表单被返回并显示,没有错误。提交表单时不会引发错误。上传的文件在 POST 数据中 - 作为 UploadedFile 的一个实例,并且设置了 cvUpdatedAt 字段。但是,当记录保存到数据库时,用于存储文件名的列设置为 NULL。
这是我的实体:
<?php
namespace My\CamsBundle\Entity;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\HttpFoundation\File\File;
use Symfony\Component\Validator\Constraints as Assert;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
/**
* @ORM\Entity(repositoryClass="My\CamsBundle\Entity\Repository\ApplicationRepository")
* @ORM\Table(name="application")
* @Vich\Uploadable
* @ORM\HasLifecycleCallbacks()
*/
class Application {
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Assert\File(
* maxSize="2M",
* )
* @Vich\UploadableField(mapping="cv_file", fileNameProperty="cvName")
*
* This is not a mapped field of entity metadata, just a simple property.
*
* @var File $cvFile
*/
protected $cvFile;
/**
* @ORM\Column(type="string", length=255, name="cv_name", nullable=true)
*
* @var string $cvName
*/
protected $cvName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime $cvUpdatedAt
*/
protected $cvUpdatedAt;
public function __construct() { }
/**
* Get id
*
* @return integer
*/
public function getId() {
return $this->id;
}
/**
* If manually uploading a file (i.e. not using Symfony Form) ensure an instance
* of 'UploadedFile' is injected into this setter to trigger the update. If this
* bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
* must be able to accept an instance of 'File' as the bundle will inject one here
* during Doctrine hydration.
*
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $cv
*/
public function setCvFile(File $cv = null) {
$this->cvFile = $cv;
if ($cv) {
// It is required that at least one field changes if you are using doctrine
// otherwise the event listeners won't be called and the file is lost
$this->cvUpdatedAt = new \DateTime('now');
}
}
/**
* @return File
*/
public function getCvFile() {
return $this->cvFile;
}
/**
* @param string $cvName
*/
public function setCvName($cvName) {
$this->cvName = $cvName;
}
/**
* @return string
*/
public function getCvName() {
return $this->cvName;
}
/**
* Set cvUpdatedAt
*
* @param \DateTime $cvUpdatedAt
* @return Application
*/
public function setCvUpdatedAt($cvUpdatedAt) {
$this->cvUpdatedAt = $updatcvUpdatedAt;
return $this;
}
/**
* Get cvUpdatedAt
*
* @return \DateTime
*/
public function getCvUpdatedAt() {
return $this->cvUpdatedAt;
}
}
这是表格:
<?php
namespace My\CamsBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ApplicationType extends AbstractType {
public function buildForm(FormBuilderInterface $builder, array $options) {
if (array_key_exists('action', $options)) {
$builder->setAction($options['action']);
}
// See http://lrotherfield.com/blog/symfony2-forms-hidden-entity-type-part-2/
$builder->add('cvFile', 'vich_file', array(
'required' => false,
'allow_delete' => true, // not mandatory, default is true
'download_link' => true, // not mandatory, default is true
'label' => 'Upload CV',
));
$builder->add('save', 'submit', array(
'label' => 'Save',
'attr' => array(
'class' => 'btn btn-action'
)
));
// Basic query builder solution. Not much better than the documentation.
// http://inchoo.net/dev-talk/symfony2-entity-field-type/
}
public function getName() {
return 'application';
}
public function setDefaultOptions(OptionsResolverInterface $resolver) {
$resolver->setDefaults(array(
'data_class' => 'My\CamsBundle\Entity\Application',
));
}
}
这是配置:
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: @MyCamsBundle/Resources/config/config.yml }
framework:
#esi: ~
#translator: { fallback: "%locale%" }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
templating:
engines: ['twig']
#assets_version: SomeVersionScheme
default_locale: "%locale%"
trusted_proxies: ~
session: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
form:
resources:
- 'VichUploaderBundle:Form:fields.html.twig'
# Doctrine Configuration
doctrine:
dbal:
default_connection: default
connections:
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
customer:
driver: "%database_driver2%"
host: "%database_host2%"
port: "%database_port2%"
dbname: "%database_name2%"
user: "%database_user2%"
password: "%database_password2%"
charset: UTF8
orm:
auto_generate_proxy_classes: "%kernel.debug%"
entity_managers:
default:
auto_mapping: true
mappings:
MyCamsBundle: ~
vich_uploader:
db_driver: orm
mappings:
cv_file:
uri_prefix: /uploads/documents
upload_destination: %kernel.root_dir%/../web/uploads/documents
#namer: vich_uploader.namer_uniqid
inject_on_load: false
delete_on_update: true
delete_on_remove: true
表格模板:
{% extends 'MyCamsBundle::layout.html.twig' %}
{% form_theme form 'MyCamsBundle:Form:fields.html.twig' %}
{% block body %}
<div class="main">
{{ form_errors(form) }}
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="heading">Application</div>
</div>
</div>
<section id="application-form">
{{ form_start(form) }}
<div class="row well demonstrator-experience">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 cv-details">
<span class="btn btn-action btn-file">
{{ form_label(form.cvFile) }} {{ form_widget(form.cvFile) }}
</span>
</div>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 text-right">
</div>
{{ form_widget(form.save) }}
</div>
{{ form_end(form) }}
</section>
</div>
{% endblock %}
控制器:
<?php
namespace My\CamsBundle\Controller;
use DateTime;
use Doctrine\ORM\EntityManager;
use Exception;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Response;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
use My\CamsBundle\Entity\Application;
use My\CamsBundle\Form\ApplicationType;
/**
* Apply for a casual position.
*
* Class ApplicationController
* @package My\CamsBundle\Controller
*/
class ApplicationController extends Controller
{
/**
* Application form.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*
* @Route("/application/create")
*/
public function createAction()
{
$application = new Application();
$em = $this->getDoctrine()->getManager();
$form = $this->createFormModel($application);
return $this->render('MyCamsBundle:Application:create.html.twig', array(
'form' => $form->createView(),
));
}
/**
* Application save form.
*
* @param \Symfony\Component\HttpFoundation\Request $request
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*
* @Route("/application/save")
*/
public function saveAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$raw_application = $request->get('application');
$request->request->set('application', $raw_application);
$application = new Application();
$form = $this->createFormModel($application);
$form->handleRequest($request);
$application_id = 0;
try {
if ($form->isValid()) {
$application = $form->getData();
$em->merge($application);
$em->flush();
$application_id = $application->getId();
} else {
return $this->render('MyCamsBundle:Application:create.html.twig', array(
'form' => $form->createView(),
));
}
} catch (Exception $e) {
$request->getSession()->getFlashBag()->add(
'notice', 'Failed to save changes'
);
$logger = $this->get('logger');
$logger->error($e->getMessage());
return $this->render('MyCamsBundle:Application:create.html.twig', array(
'form' => $form->createView(),
));
}
return $this->redirect($this->generateUrl('my_cams_application_update'));
}
/**
* Application edit form. This is the applicant's dashboard.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|\Symfony\Component\HttpFoundation\Response
*
* @Route("/application/update")
*/
public function updateAction()
{
$em = $this->getDoctrine()->getManager();
// etc.
}
/**
* @param $application
* @return \Symfony\Component\Form\Form
*/
private function createFormModel($application)
{
$form = $this->createForm(new ApplicationType(), $application, array(
'action' => $this->generateUrl('my_cams_application_save')
)
);
return $form;
}
}
和存储库:
<?php
namespace My\CamsBundle\Entity\Repository;
use Doctrine\ORM\EntityRepository;
/**
* ApplicationRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class ApplicationRepository extends EntityRepository
{
}
我不确定 的映射是否vich_uploader
正确加载。我看不到实体和表单定义中缺少任何内容。