Symfony 4-LiipImagine-侦听器删除我的所有目录(缓存清除侦听器)

阿扎兹

我有一个Symfony 4项目,该项目的User实体与Avatar实体有关系(通过VichUploaderBundle上传的图像)。

在Avatar.php中:

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 */
private $imageName;

/**
 * NOTE: This is not a mapped field of entity metadata, just a simple property.
 * 
 * @Assert\Image(
 *  mimeTypes="image/jpeg")
 * @Vich\UploadableField(mapping="avatar", fileNameProperty="imageName", size="imageSize")
 * 
 * @var File|null
 */
private $imageFile;

在User.php中:

/**
 * @ORM\OneToOne(targetEntity="App\Entity\Avatar", mappedBy="user", cascade={"persist", "remove"})
 */
private $avatar;

我有一个个人资料页面,可以编辑用户的数据(姓名,姓氏,邮件,头像)。在此页面中,我使用LiipImagineBundle在特定维度上显示当前头像。

当用户编辑个人资料时,我希望听众可以检查头像中是否有更改。在这种情况下,它将删除旧的媒体/缓存。

因此,我为此创建了一个侦听器:

<?php

namespace App\Listener;

use App\Entity\Avatar;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;

class ImageCacheSubscriber implements EventSubscriber
{

    /**
     * CacheManager
     *
     * @var CacheManager
     */
    private $cacheManager;

    /**
     * UploaderHelper
     *
     * @var UploaderHelper
     */
    private $uploaderHelper;

    public function __construct(CacheManager $cacheManager, UploaderHelper $uploaderHelper)
    {
        $this->cacheManager = $cacheManager;
        $this->uploaderHelper = $uploaderHelper;
    }

    public function getSubscribedEvents()
    {
        return [
            'preRemove',
            'preUpdate'
        ];
    }

    public function preRemove(LifecycleEventArgs $args)
    {

        $entity = $args->getEntity();
        if (!$entity instanceof Avatar) {
            return;
        }

        $this->cacheManager->remove($this->uploaderHelper->asset($entity, 'imageFile'));
    }

    public function preUpdate(PreUpdateEventArgs $args)
    {
        dump($args->getEntity());
        dump($args->getObject());

        $entity = $args->getEntity();
        if (!$entity instanceof Avatar) {
            return;
        }

        if ($entity->getImageFile() instanceof UploadedFile) {
            $this->cacheManager->remove($this->uploaderHelper->asset($entity, 'imageFile'));
        }
    }
}

Services.yaml:

  App\Listener\ImageCacheSubscriber:
    tags:
      - { name: doctrine.event_subscriber }

但是,当我更改头像时,侦听器会删除媒体中包含头像的整个文件夹。

他激怒了我这个错误:

无法删除目录“ C:\ Users \ user \ Desktop \ congesTest2 / public / media / cache / avatar_big \ files”:rmdir(C:\ Users \ user \ Desktop \ congesTest2 / public / media / cache / avatar_big \ files) :目录不为空。

我不明白为什么...:'(

编辑:

我将函数preUpdate()更新为postUpdate():

public function getSubscribedEvents()
    {
        return [
            'preRemove',
            'postUpdate'
        ];
    }
public function postUpdate(LifecycleEventArgs $args)
    {
        dump($args->getEntity());

        $entity = $args->getEntity();
        if (!$entity instanceof Avatar) {
            return;
        }

        if ($entity->getImageFile() instanceof UploadedFile) {
            $this->cacheManager->remove($this->uploaderHelper->asset($entity, 'imageFile'));
        }
    }

现在,如果我转储了:

    dd($this->uploaderHelper->asset($entity, 'imageFile'));

我有:

“ /images/avatar/avatar3.jpg”这是好路径!另一方面,图像不会从缓存中删除!remove()函数似乎并没有提供任何令人惊奇的功能

通过转储实体,我看到该文件不再是UploadedFile,而是一个文件。以前好像是一个UploadedFile。所以我换了线

if ($entity->getImageFile() instanceof UploadedFile)

通过

if ($entity->getImageFile() instanceof File)

但是该图像仍未从缓存中删除。

我认为,由于这是一个postUpdate,它将删除新的缓存映像,而不是旧的缓存映像。但是由于用户被重定向到同一页面,因此他在缓存后立即将其交付。(编辑:否,我没有进行测试,图像甚至没有从缓存中删除)

杰芬肖

您可以听事件,而不必听教义vich_uploader.pre_remove事件。这将确保您获得每次都需要删除的旧图像。首先,确保您的VichUploader配置设置为在更新和删除时删除文件。这是默认值。

# config/packages/vich_uploader.yaml

vich_uploader:
    mappings:
        avatar:
            upload_destination: '%kernel.project_dir%/public/uploads/avatar'
            uri_prefix: 'uploads/avatar'

            delete_on_update: true
            delete_on_remove: true

现在,您需要创建侦听器。

// src/EventListener/ImageCacheSubscriber.php

namespace App\EventListener;

use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Vich\UploaderBundle\Event\Event;
use Vich\UploaderBundle\Event\Events;
use Vich\UploaderBundle\Storage\StorageInterface;

class ImageCacheSubscriber implements EventSubscriberInterface
{
    private $storage;
    private $cacheManager;

    public function __construct(StorageInterface $storage, CacheManager $cacheManager)
    {
        $this->storage = $storage;
        $this->cacheManager = $cacheManager;
    }

    public function onRemove(Event $event)
    {
        $path = $this->storage->resolveUri($event->getObject(), $event->getMapping()->getFilePropertyName());
        $this->cacheManager->remove($path);
    }

    public static function getSubscribedEvents()
    {
        return [Events::PRE_REMOVE => 'onRemove'];
    }
}

删除任何VichUploader资产后,此侦听器将尝试从所有过滤器的缓存中删除它。您可以根据需要在CacheManager::remove()方法中指定特定的过滤器您也只能通过检查的实例来删除特定实体的缓存$event->getObject()

这也会对您的LiipImagine配置做出一些假设。如果您使用的是默认的加载器和缓存解析器,则应该可以使用。如果您使用的是自定义加载程序或解析程序,则可能需要根据需要修改此侦听器。

# config/packages/liip_imagine.yaml

liip_imagine:
    resolvers:
        default:
            web_path:
                web_root: '%kernel.project_dir%/public'
                cache_prefix: 'media/cache'

    loaders:
        default:
            filesystem:
                data_root:
                    - '%kernel.project_dir%/public'

    filter_sets:
        cache: ~

        # Your filters...

如果您使用的是Symfony Flex,那么您就完成了。否则,请确保将侦听器注册为服务。

# config/services.yaml

services:
    # ...
    App\EventListener\ImageCacheSubscriber:
        arguments: ['@vich_uploader.storage.file_system', '@liip_imagine.cache.manager']
        tags:
            - { name: kernel.event_subscriber }

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章