Upgrading to Flysystem v2 causes error
Uncaught PHP Exception TypeError: "Argument 2 passed to Liip\ImagineBundle\Binary\Loader\FlysystemLoader::__construct() must be an instance of League\Flysystem\FilesystemInterface, instance of League\Flysystem\Filesystem given, called in /app/var/cache/prod/ContainerMppLxC7/getLiipImagine_Binary_Loader_DefaultService.php on line 20" at /app/vendor/liip/imagine-bundle/Binary/Loader/FlysystemLoader.php line 33
The current workaround I have is a Custom FlysystemLoader.
References:
i was wondering why this can happen, but found that flysystem is an optional dependency in composer.json. we currently only test with flysystem 1.
can you do a pull request that adjusts the flysystem in require-dev to allow version 1 or 2? if there are any tests, we should see if it works.
the error you get is surpising me though. why would the Filesystem class not implement the FilesystemInterface? glad if you can investigate and provide a fix pull request.
The upgrade to Flysystem v2 doesn't have a "FilesystemInterface". There are also some method changes. I'm not 100% sure what the best solution would be right now. Either create a "v2" class or check if the FilesystemInterface exists. Could be another option.
Here's what I did.
<?php
namespace App\ImagineBundle\Binary\Loader;
use League\Flysystem\Filesystem;
use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
use Liip\ImagineBundle\Exception\InvalidArgumentException;
use Liip\ImagineBundle\Model\Binary;
use Liip\ImagineBundle\Binary\Loader\LoaderInterface;
use Liip\ImagineBundle\Binary\BinaryInterface;
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesserInterface as DeprecatedExtensionGuesserInterface;
use Symfony\Component\Mime\MimeTypesInterface;
class FlysystemLoader implements LoaderInterface
{
/**
* @var Filesystem
*/
protected $filesystem;
/**
* @var MimeTypesInterface|DeprecatedExtensionGuesserInterface
*/
protected $extensionGuesser;
/**
*/
public function __construct(MimeTypesInterface $extensionGuesser, Filesystem $filesystem)
{
if (!$extensionGuesser instanceof MimeTypesInterface && !$extensionGuesser instanceof DeprecatedExtensionGuesserInterface) {
throw new InvalidArgumentException('$extensionGuesser must be an instance of Symfony\Component\Mime\MimeTypesInterface or Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesserInterface');
}
if (interface_exists(MimeTypesInterface::class) && $extensionGuesser instanceof DeprecatedExtensionGuesserInterface) {
@trigger_error(sprintf('Passing a %s to "%s()" is deprecated since Symfony 4.3, pass a "%s" instead.', DeprecatedExtensionGuesserInterface::class, __METHOD__, MimeTypesInterface::class), E_USER_DEPRECATED);
}
$this->extensionGuesser = $extensionGuesser;
$this->filesystem = $filesystem;
}
/**
* {@inheritdoc}
*/
public function find($path)
{
if (false === $this->filesystem->fileExists($path)) {
throw new NotLoadableException(sprintf('Source image "%s" not found.', $path));
}
$mimeType = $this->filesystem->mimetype($path);
$extension = $this->getExtension($mimeType);
return new Binary(
$this->filesystem->read($path),
$mimeType,
$extension
);
}
private function getExtension(?string $mimeType): ?string
{
if ($this->extensionGuesser instanceof DeprecatedExtensionGuesserInterface) {
return $this->extensionGuesser->guess($mimeType);
}
if (null === $mimeType) {
return null;
}
return $this->extensionGuesser->getExtensions($mimeType)[0] ?? null;
}
}
# config/services.yaml
# ...
App\ImagineBundle\Binary\Loader\FlysystemLoader:
arguments: ['@mime_types', '@League\Flysystem\Filesystem']
tags:
- { name: 'liip_imagine.binary.loader', loader: flysystemV2 }
It looks like supper for v2 has been merged - we just need a tag :)
Most helpful comment
It looks like supper for v2 has been merged - we just need a tag :)