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



我是Symfony 3的新手,当我尝试激活我的帐户时遇到了问题。我从 FOSUserBundle 扩展了我的用户实体。我已经激活了FOS_User的确认系统。此外,当用户注册到我的应用程序时,他必须上传文件。为此,我创建了一个FileUploader服务和ImageUploadListener侦听器。问题是当我从gmail的电子邮件中单击激活链接时,出现以下错误:

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

你能帮我吗?提前感谢一位非常头疼的法国开发人员!

PS:我按照本教程实现了我的文件上传功能。

用户.php

namespace UserBundleEntity;
use FOSUserBundleModelUser as BaseUser;
use DoctrineORMMapping as ORM;
use SymfonyComponentValidatorConstraints as Assert;
/**
 * @ORMEntity
 * @ORMTable(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORMId
     * @ORMColumn(type="integer")
     * @ORMGeneratedValue(strategy="AUTO")
     */
    protected $id;
    /**
     * @ORMColumn(type="string", length=255)
     *
     * @AssertNotBlank(message="Please enter your phone.", groups={"Registration", "Profile"})
     * @AssertLength(
     *     min=3,
     *     max=255,
     *     minMessage="The phone is too short.",
     *     maxMessage="The phone is too long.",
     *     groups={"Registration", "Profile"}
     * )
     */
    protected $phone;
    /**
     * @ORMColumn(type="string")
     *
     * @AssertNotBlank(message="Please, upload a file.")
     * @AssertFile(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;
    }
}

注册类型.php

namespace UserBundleForm;
use UserBundleEntityUser;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use SymfonyComponentFormExtensionCoreTypeFileType;
class RegistrationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('phone')
            ->add('image', FileType::class);
    }
    public function getParent()
    {
        return 'FOSUserBundleFormTypeRegistrationFormType';
        // 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,
        ));
    }
}

文件上传器.php

namespace UserBundleService;
use SymfonyComponentHttpFoundationFileUploadedFile;
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;
    }
}

图像上传侦听器

namespace UserBundleEventListener;
use SymfonyComponentHttpFoundationFileUploadedFile;
use DoctrineORMEventLifecycleEventArgs;
use DoctrineORMEventPreUpdateEventArgs;
use UserBundleEntityUser;
use UserBundleServiceFileUploader;
use SymfonyComponentHttpFoundationFileFile;
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);
    }
}

服务.yml

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

配置.yml

fos_user:
    db_driver: orm
    firewall_name: main
    user_class: UserBundleEntityUser
    service:
        mailer: fos_user.mailer.twig_swift
    from_email:
        address: "%mailer_user%"
        sender_name: "%mailer_user%"
    registration:
        form:
            type: UserBundleFormRegistrationType
        confirmation:
            enabled: true
            template:   '@FOSUser/Registration/email.txt.twig'
            from_email:
                address: "%mailer_user%"
                sender_name: "%mailer_user%"
    profile:
        form:
            type: UserBundleFormEditType

每次保存用户时都会启动您的事件。激活用户帐户时,使用数据库中的原则更新用户,以便调用 preUpdate 事件。

为避免通知,您应该这样做:

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

为了避免每次上传者都调用,您必须检查文件是否已上传或覆盖注册操作以上传它,而不是使用教义事件来执行此操作

最新更新