douxiegan6468 2017-10-24 14:19
浏览 128
已采纳

为什么Symfony似乎在使用FOSUserBundle的确认过程中调用了我的eventListener?

I am New to Symfony 3 and I have an Issue when I try to activate my account. I extend my User Entity from FOSUserBundle. I have activated the confirmation system of FOS_User. Furthermore, when a user register into my app, he must upload a file. To do this, I created a FileUploader service and a ImageUploadListener listener. The problem is when I click on my activation link from my gmail's email, I get the following error:

Uncaught PHP Exception Symfony\Component\Debug\Exception\ContextErrorException: "Notice: Undefined variable: fileName" at /home/clement/Rendu/tech-web/src/UserBundle/EventListener/ImageUploadListener.php line 49

Could you help me ? Thank you in advance from a french dev with a big headache !

PS: I followed this tutorial to implement my file upload functionality.

User.php

namespace UserBundle\Entity;

use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=255)
     *
     * @Assert\NotBlank(message="Please enter your phone.", groups={"Registration", "Profile"})
     * @Assert\Length(
     *     min=3,
     *     max=255,
     *     minMessage="The phone is too short.",
     *     maxMessage="The phone is too long.",
     *     groups={"Registration", "Profile"}
     * )
     */
    protected $phone;

    /**
     * @ORM\Column(type="string")
     *
     * @Assert\NotBlank(message="Please, upload a file.")
     * @Assert\File(mimeTypes={ "application/pdf", "image/jpeg" })
     */
    private $image;

    public function __construct()
    {
        parent::__construct();
        // your own logic
        $this->roles = array('ROLE_USER');
    }

    public function getPhone() {
        return $this->phone;
    }

    public function setPhone($phone) {
        $this->phone = $phone;  
    }


    public function setImage($image)
    {
        $this->image = $image;
        return $this;
    }

    public function getImage()
    {
        return $this->image;
    }
}

RegistrationType.php

namespace UserBundle\Form;

use UserBundle\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;

class RegistrationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('phone')
            ->add('image', FileType::class);
    }

    public function getParent()
    {
        return 'FOS\UserBundle\Form\Type\RegistrationFormType';

        // Or for Symfony < 2.8
        // return 'fos_user_registration';
    }

    public function getBlockPrefix()
    {
        return 'app_user_registration';
    }

    // For Symfony 2.x
    public function getName()
    {
        return $this->getBlockPrefix();
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => User::class,
        ));
    }
}

FileUploader.php

namespace UserBundle\Service;

use Symfony\Component\HttpFoundation\File\UploadedFile;

class FileUploader
{
    private $targetDir;
    public function __construct($targetDir)
    {
        $this->targetDir = $targetDir;
    }

    public function upload(UploadedFile $file)
    {

        $fileName = md5(uniqid()).'.'.$file->guessExtension();
        $file->move($this->getTargetDir(), $fileName);
        return $fileName;
    }

    public function getTargetDir()
    {
        return $this->targetDir;
    }
}

ImageUploadListener

namespace UserBundle\EventListener;

use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use UserBundle\Entity\User;
use UserBundle\Service\FileUploader;
use Symfony\Component\HttpFoundation\File\File;

class ImageUploadListener
{
    private $uploader;
    private $fileName;

    public function __construct(FileUploader $uploader)
    {
        $this->uploader = $uploader;
    }

    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $this->uploadFile($entity);
    }

    public function preUpdate(PreUpdateEventArgs $args)
    {
        $entity = $args->getEntity();
        $this->uploadFile($entity);
    }

    private function uploadFile($entity)
    {
        // upload only works for User entities
        if (!$entity instanceof User) {
            return;
        }

        $file = $entity->getImage();

        // only upload new files
        if ($file instanceof UploadedFile) {
            $fileName = $this->uploader->upload($file);
        }

        $entity->setImage($fileName);
    }
}

services.yml

parameters:
    #parameter_name: value
services:
    _defaults:
        autowire: true
        autoconfigure: true
        public: false
    AppBundle\:
        resource: '../../src/AppBundle/*'
        exclude: '../../src/AppBundle/{Entity,Repository,Tests}'
    AppBundle\Controller\:
        resource: '../../src/AppBundle/Controller'
        public: true
        tags: ['controller.service_arguments']
    app.form.registration:
        class: UserBundle\Form\RegistrationType
        tags:
            - { name: form.type, alias: app_user_registration }           
    UserBundle\Service\FileUploader:
        arguments:
            $targetDir: '%images_directory%'             
    UserBundle\EventListener\ImageUploadListener:
        tags:
            - { name: doctrine.event_listener, event: prePersist }
            - { name: doctrine.event_listener, event: preUpdate }

config.yml

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: UserBundle\Entity\User
    service:
        mailer: fos_user.mailer.twig_swift
    from_email:
        address: "%mailer_user%"
        sender_name: "%mailer_user%"
    registration:
        form:
            type: UserBundle\Form\RegistrationType
        confirmation:
            enabled: true
            template:   '@FOSUser/Registration/email.txt.twig'
            from_email:
                address: "%mailer_user%"
                sender_name: "%mailer_user%"
    profile:
        form:
            type: UserBundle\Form\EditType
  • 写回答

1条回答 默认 最新

  • doujie3888 2017-10-24 14:27
    关注

    Your event is launched each time you save an user. When you activate the user account you update the user with doctrine in the database so the preUpdate event is call.

    To avoid the notice you should do this :

    // only upload new files
    if ($file instanceof UploadedFile) {
        $fileName = $this->uploader->upload($file);
        $entity->setImage($fileName); 
    }
    

    And to avoid to call each time your uploader you have to check if the file is already upload or override the register action to upload it instead of use a doctrine event to do this

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 安卓adb backup备份应用数据失败
  • ¥15 eclipse运行项目时遇到的问题
  • ¥15 关于#c##的问题:最近需要用CAT工具Trados进行一些开发
  • ¥15 南大pa1 小游戏没有界面,并且报了如下错误,尝试过换显卡驱动,但是好像不行
  • ¥15 没有证书,nginx怎么反向代理到只能接受https的公网网站
  • ¥50 成都蓉城足球俱乐部小程序抢票
  • ¥15 yolov7训练自己的数据集
  • ¥15 esp8266与51单片机连接问题(标签-单片机|关键词-串口)(相关搜索:51单片机|单片机|测试代码)
  • ¥15 电力市场出清matlab yalmip kkt 双层优化问题
  • ¥30 ros小车路径规划实现不了,如何解决?(操作系统-ubuntu)