我正在尝试添加带有图像文件的新用户。我正在使用VichUpladerBundle和FOSUserBundle。因此创建了新用户,但image_name始终为null。
这是我的图片实体:
namespace SocialNetworkBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Image
*
* @ORM\Table(name="image")
* @ORM\Entity(repositoryClass="SocialNetworkBundle\Repository\ImageRepository")
* @Vich\Uploadable
*/
class Image {
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* @return int
*/
public function getId() {
return $this->id;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="image", fileNameProperty="imageName")
* @Assert\File(
* maxSize = "1024k",
* mimeTypes = {"image/png", "image/jpeg", "image/jpg"},
* mimeTypesMessage = "Please upload a valid PDF or valid IMAGE"
* )
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var string
*/
private $imageName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime
*/
private $updatedAt;
/**
* Set imageName
*
* @param string $imageName
*
* @return Image
*/
public function setImageName($imageName) {
$this->imageName = $imageName;
return $this;
}
/**
* Get imageName
*
* @return string
*/
public function getImageName() {
return $this->imageName;
}
/**
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return Image
*/
public function setImageFile(File $image = null) {
$this->imageFile = $image;
if ($image) {
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return File|null
*/
public function getImageFile() {
return $this->imageFile;
}
}
用户实体:
namespace UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
use SocialNetworkBundle\Entity\Image ;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="UserBundle\Repository\UserRepository")
* @Vich\Uploadable
*/
class User extends BaseUser
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @var string
*
* @ORM\Column(name="name", type="string", length=255, unique=false)
* @Assert\Length(min=2, max=100)
*/
private $name;
/**
* @ORM\OneToOne(targetEntity="SocialNetworkBundle\Entity\Image", cascade={"persist", "merge", "remove"})
* @ORM\JoinColumn(name="image_id", referencedColumnName="id")
* @Assert\Valid()
*/
private $image;
/**
* Set name
*
* @param string $name
*
* @return User
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* Set image
*
* @param \SocialNetworkBundle\Entity\Image $image
*
* @return User
*/
public function setImage(\SocialNetworkBundle\Entity\Image $image = null)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* @return \SocialNetworkBundle\Entity\Image
*/
public function getImage()
{
return $this->image;
}
}
图片类型:
namespace SocialNetworkBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Vich\UploaderBundle\Form\Type\VichFileType;
class ImageType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', VichFileType::class, array(
'required' => false,
'allow_delete' => true, // not mandatory, default is true
'download_link' => true, // not mandatory, default is true
))
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SocialNetworkBundle\Entity\Image',
));
}
public function getName()
{
return 'socialnetworkbundle_image';
}
}
RegistrationForm:
namespace UserBundle\Form\Type;
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use SocialNetworkBundle\Form\ImageType;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder->add('name')
->add('roles', 'collection', array(
'type' => 'choice',
'options' => array(
'choices' => array(
'ROLE_ADMIN' => 'Admin',
),
),
))
->add('image', new ImageType())
;
}
public function getName()
{
return 'user_registration';
}
}
和register.html.twig
{% extends "UserBundle::layout.html.twig" %}
{% block body %}
<center> <h1> Inscription </h1> </center>
<aside class="col-sm-3">
<div class="panel panel-default">
<div class="panel-heading">Inscription</div>
<div class="panel-body">
Veuillez remplir les champs
</div>
</div>
</aside>
<!--timeline-->
<section class="timeline col-sm-9">
<!--post Timeline-->
<div class="thumbnail thumbnail-post">
<!--caption-->
<div class="caption">
<form action="{{ path('fos_user_registration_register') }}" {{ form_enctype(form) }} method="POST" class="form-horizontal">
<div class="form-group">
{{ form_errors(form.name) }}
<div class="col-sm-9">
Nom {{ form_widget(form.name, { 'attr': {'class': 'form-control', 'placeholder': 'form.name'|trans } })}}
</div>
</div>
<div class="form-group">
{{ form_errors(form.email) }}
<div class="col-sm-9">
Email {{ form_widget(form.email, { 'attr': {'class': 'form-control', 'placeholder': 'form.email'|trans } }) }}
</div>
</div>
<div class="form-group">
{{ form_errors(form.username) }}
<div class="col-sm-9">
Pseudo {{ form_widget(form.username, { 'attr': {'class': 'form-control', 'placeholder': 'form.username'|trans } }) }}
</div>
</div>
<div class="form-group">
{{ form_errors(form.plainPassword.first) }}
<div class="col-sm-9">
Mot de passe {{ form_widget(form.plainPassword.first, { 'attr': {'class': 'form-control', 'placeholder': 'form.password'|trans } }) }}
</div>
</div>
<div class="form-group">
{{ form_errors(form.plainPassword.second) }}
<div class="col-sm-9">
Confirmer le mot de passe {{ form_widget(form.plainPassword.second, { 'attr': {'class': 'form-control', 'placeholder': 'form.password_confirmation'|trans } }) }}
</div>
</div>
<div class="form-group">
{# Génération du label. #}
{{ form_label(form.image.imageFile, "Image", {'label_attr': {'class': 'col-sm-3 control-label'}}) }}
{# Affichage des erreurs pour ce champ précis. #}
{{ form_errors(form.image.imageFile) }}
<div class="col-sm-4">
{# Génération de l'input. #}
{{ form_widget(form.image.imageFile, {'attr': {'class': 'form-control'}}) }}
</div>
</div>
<br />
<div id="roles">
<div class="form-group">
<div class="col-sm-4"> {{ form_widget(form.roles, { 'attr': {'class': 'form-control', 'placeholder': 'form.role'|trans } }) }}
</div>
{{ form_errors(form.roles) }}
</div>
</div>
{{ form_rest(form) }}
<div class="form-group">
<div class="col-md-4 col-sm-4 col-xs-12 col-md-offset-3">
<input class="btn btn-default submit" type="submit" value="{{ 'registration.submit'|trans }}">
</div>
</div>
</form>
</div> <!--#caption-->
<!--#post timeline-->
</div>
<!--#timeline-->
</section>
{% endblock %}
{% block js %}
<script>
$(document).ready(function () {
$('#roles').hide();
});
</script>
{% endblock %}
config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
- { resource: "@SocialNetworkBundle/Resources/config/services.yml" }
- { resource: "@UserBundle/Resources/config/services.yml" }
# Put parameters here that don't need to change on each machine where the app is deployed
# http://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters:
locale: en
fos_user.template.engine: 'twig'
framework:
#esi: ~
#translator: { fallbacks: ["%locale%"] }
secret: "%secret%"
router:
resource: "%kernel.root_dir%/config/routing.yml"
strict_requirements: ~
form: ~
csrf_protection: ~
validation: { enable_annotations: true }
#serializer: { enable_annotations: true }
templating:
engines: ['twig']
default_locale: "%locale%"
trusted_hosts: ~
trusted_proxies: ~
session:
# handler_id set to null will use default session handler from php.ini
handler_id: ~
fragments: ~
http_method_override: true
# Twig Configuration
twig:
debug: "%kernel.debug%"
strict_variables: "%kernel.debug%"
form_themes:
# other form themes
- 'VichUploaderBundle:Form:fields.html.twig'
# Doctrine Configuration
doctrine:
dbal:
driver: pdo_mysql
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# if using pdo_sqlite as your database driver:
# 1. add the path in parameters.yml
# e.g. database_path: "%kernel.root_dir%/data/data.db3"
# 2. Uncomment database_path in parameters.yml.dist
# 3. Uncomment next line:
# path: "%database_path%"
orm:
auto_generate_proxy_classes: "%kernel.debug%"
naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true
# Swiftmailer Configuration
swiftmailer:
transport: "%mailer_transport%"
host: "%mailer_host%"
username: "%mailer_user%"
password: "%mailer_password%"
spool: { type: memory }
# FOSUser Configuration
fos_user:
db_driver: orm
# Le type de BDD à utiliser, nous utilisons l'ORM Doctrine depuis le début
firewall_name: main
# Le nom du firewall derrière lequel on utilisera ces utilisateurs
user_class: UserBundle\Entity\User
# La classe de l'entité User que nous utilisons
#autoriser l'envoie de mail si reset password
service:
mailer: fos_user.mailer.twig_swift
registration:
form:
type: user_registration
# Assetic
assetic:
debug: '%kernel.debug%'
use_controller: false
bundles:
- "SocialNetworkBundle"
filters:
cssrewrite: ~
jpegoptim:
bin: /usr/local/bin/jpegoptim
max: 20
apply_to: "\.jpg$"
twig:
functions:
jpegoptim: ~
#VichUploader
vich_uploader:
db_driver: orm
mappings:
user_image:
uri_prefix: /SocialNetowrk/web/images/user
upload_destination: '%kernel.root_dir%/../web/images/user'
inject_on_load: false
delete_on_update: true
delete_on_remove: true
namer: vich_uploader.namer_uniqid
在我的数据库中,我在列image_name上有一个空值。我该如何解决?
答案 0 :(得分:2)
您应该将一个映射的字段(例如,updatedAt)添加到Image实体中。使用方法setImageFile设置图像时,还应更新映射字段以触发doctrine事件侦听器并处理上载的文件。
namespace SocialNetworkBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\HttpFoundation\File\File;
/**
* Image
*
* @ORM\Table(name="image")
* @ORM\Entity(repositoryClass="SocialNetworkBundle\Repository\ImageRepository")
* @Vich\Uploadable
*/
class Image
{
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* @Vich\UploadableField(mapping="image", fileNameProperty="imageName")
* @Assert\File(
* maxSize = "1024k",
* mimeTypes = {"image/png", "image/jpeg", "image/jpg"},
* mimeTypesMessage = "Please upload a valid PDF or valid IMAGE"
* )
*
* @var File
*/
private $imageFile;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*
* @var string
*/
private $imageName;
/**
* @ORM\Column(type="datetime")
*
* @var \DateTime
*/
private $updatedAt;
/**
* Set imageName
*
* @param string $imageName
*
* @return Image
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;
return $this;
}
/**
* Get imageName
*
* @return string
*/
public function getImageName()
{
return $this->imageName;
}
/**
* @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*
* @return Image
*/
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
$this->updatedAt = new \DateTime('now');
}
return $this;
}
/**
* @return File|null
*/
public function getImageFile()
{
return $this->imageFile;
}
}