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

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

报告相同问题?

悬赏问题

  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 对于相关问题的求解与代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料