image_name 在数据库中始终为空 vichuploaderbundle symfony2

image_name in database is always null vichuploaderbundle symfony2

我正在尝试使用图像文件添加新用户。我正在使用 VichUpladerBundle and FOSUserBundle。因此创建了新用户,但 image_name 始终为空。

这是我的图像实体:

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';
  }
}

注册表单:

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 处有一个空值。我该如何解决?

您应该将一个映射字段(例如,updatedAt)添加到您的图像实体中。当您使用方法 setImageFile 设置图像时,您还应该更新映射字段以触发原则事件侦听器并处理上传的文件。

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;
    }
}