mirror of
https://github.com/flarum/framework.git
synced 2024-11-25 08:43:21 +08:00
feat: upgrade intervention/image
to 3.2 (#3947)
* chore: create standalone imageprovider * chore: upgrade intervention to v3 * Apply fixes from StyleCI * use new static instatiation * Revert "Apply fixes from StyleCI" This reverts commit 096b4d9a79fa41c948a7572cf65316ebc6b07d36. * get avatar from remote * Apply fixes from StyleCI * fix: incorrect gid exception namespace * fix test * remove debug code --------- Co-authored-by: StyleCI Bot <bot@styleci.io>
This commit is contained in:
parent
d400dcbc2f
commit
e3350543af
|
@ -130,7 +130,7 @@
|
|||
"illuminate/support": "^10.0",
|
||||
"illuminate/validation": "^10.0",
|
||||
"illuminate/view": "^10.0",
|
||||
"intervention/image": "^2.7.2",
|
||||
"intervention/image": "^3.2",
|
||||
"jenssegers/agent": "^2.6",
|
||||
"laminas/laminas-diactoros": "^3.0",
|
||||
"laminas/laminas-httphandlerrunner": "^2.6",
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
"illuminate/support": "^10.0",
|
||||
"illuminate/validation": "^10.0",
|
||||
"illuminate/view": "^10.0",
|
||||
"intervention/image": "^2.7.2",
|
||||
"intervention/image": "^3.2",
|
||||
"jenssegers/agent": "^2.6.4",
|
||||
"laminas/laminas-diactoros": "^3.0",
|
||||
"laminas/laminas-httphandlerrunner": "^2.6.1",
|
||||
|
|
|
@ -13,8 +13,8 @@ use Flarum\Foundation\ValidationException;
|
|||
use Flarum\Locale\TranslatorInterface;
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Interfaces\EncodedImageInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
class UploadFaviconController extends UploadImageController
|
||||
|
@ -31,7 +31,7 @@ class UploadFaviconController extends UploadImageController
|
|||
parent::__construct($settings, $filesystemFactory);
|
||||
}
|
||||
|
||||
protected function makeImage(UploadedFileInterface $file): Image
|
||||
protected function makeImage(UploadedFileInterface $file): EncodedImageInterface
|
||||
{
|
||||
$this->fileExtension = pathinfo($file->getClientFilename(), PATHINFO_EXTENSION);
|
||||
|
||||
|
@ -45,10 +45,9 @@ class UploadFaviconController extends UploadImageController
|
|||
]);
|
||||
}
|
||||
|
||||
$encodedImage = $this->imageManager->make($file->getStream()->getMetadata('uri'))->resize(64, 64, function ($constraint) {
|
||||
$constraint->aspectRatio();
|
||||
$constraint->upsize();
|
||||
})->encode('png');
|
||||
$encodedImage = $this->imageManager->read($file->getStream()->getMetadata('uri'))
|
||||
->scale(64, 64)
|
||||
->toPng();
|
||||
|
||||
$this->fileExtension = 'png';
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use Illuminate\Contracts\Filesystem\Factory;
|
|||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\EncodedImageInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Tobscure\JsonApi\Document;
|
||||
|
@ -55,5 +55,5 @@ abstract class UploadImageController extends ShowForumController
|
|||
return parent::data($request, $document);
|
||||
}
|
||||
|
||||
abstract protected function makeImage(UploadedFileInterface $file): Image;
|
||||
abstract protected function makeImage(UploadedFileInterface $file): EncodedImageInterface;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,8 @@ namespace Flarum\Api\Controller;
|
|||
|
||||
use Flarum\Settings\SettingsRepositoryInterface;
|
||||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Intervention\Image\Interfaces\EncodedImageInterface;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
|
||||
class UploadLogoController extends UploadImageController
|
||||
|
@ -28,11 +28,11 @@ class UploadLogoController extends UploadImageController
|
|||
parent::__construct($settings, $filesystemFactory);
|
||||
}
|
||||
|
||||
protected function makeImage(UploadedFileInterface $file): Image
|
||||
protected function makeImage(UploadedFileInterface $file): EncodedImageInterface
|
||||
{
|
||||
$encodedImage = $this->imageManager->make($file->getStream()->getMetadata('uri'))->heighten(60, function ($constraint) {
|
||||
$constraint->upsize();
|
||||
})->encode('png');
|
||||
$encodedImage = $this->imageManager->read($file->getStream()->getMetadata('uri'))
|
||||
->scale(height: 60)
|
||||
->toPng();
|
||||
|
||||
return $encodedImage;
|
||||
}
|
||||
|
|
|
@ -10,20 +10,14 @@
|
|||
namespace Flarum\Filesystem;
|
||||
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Foundation\Config;
|
||||
use Flarum\Foundation\Paths;
|
||||
use Flarum\Http\UrlGenerator;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Arr;
|
||||
use Intervention\Image\ImageManager;
|
||||
use League\Flysystem\Visibility;
|
||||
use RuntimeException;
|
||||
|
||||
class FilesystemServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
protected const INTERVENTION_DRIVERS = ['gd' => 'gd', 'imagick' => 'imagick'];
|
||||
|
||||
public function register(): void
|
||||
{
|
||||
$this->container->singleton('files', function () {
|
||||
|
@ -65,26 +59,5 @@ class FilesystemServiceProvider extends AbstractServiceProvider
|
|||
$container->make('flarum.filesystem.resolved_drivers')
|
||||
);
|
||||
});
|
||||
|
||||
$this->container->singleton(ImageManager::class, function (Container $container) {
|
||||
/** @var Config $config */
|
||||
$config = $this->container->make(Config::class);
|
||||
|
||||
$intervention = $config->offsetGet('intervention');
|
||||
$driver = Arr::get($intervention, 'driver', self::INTERVENTION_DRIVERS['gd']);
|
||||
|
||||
// Check that the imagick library is actually available, else default back to gd.
|
||||
if ($driver === self::INTERVENTION_DRIVERS['imagick'] && ! extension_loaded(self::INTERVENTION_DRIVERS['imagick'])) {
|
||||
$driver = self::INTERVENTION_DRIVERS['gd'];
|
||||
}
|
||||
|
||||
if (! Arr::has(self::INTERVENTION_DRIVERS, $driver)) {
|
||||
throw new RuntimeException("intervention/image: $driver is not valid");
|
||||
}
|
||||
|
||||
return new ImageManager([
|
||||
'driver' => $driver
|
||||
]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ use Flarum\Forum\ForumServiceProvider;
|
|||
use Flarum\Frontend\FrontendServiceProvider;
|
||||
use Flarum\Group\GroupServiceProvider;
|
||||
use Flarum\Http\HttpServiceProvider;
|
||||
use Flarum\Image\ImageServiceProvider;
|
||||
use Flarum\Locale\LocaleServiceProvider;
|
||||
use Flarum\Mail\MailServiceProvider;
|
||||
use Flarum\Notification\NotificationServiceProvider;
|
||||
|
@ -115,6 +116,7 @@ class InstalledSite implements SiteInterface
|
|||
$app->register(GroupServiceProvider::class);
|
||||
$app->register(HashServiceProvider::class);
|
||||
$app->register(HttpServiceProvider::class);
|
||||
$app->register(ImageServiceProvider::class);
|
||||
$app->register(LocaleServiceProvider::class);
|
||||
$app->register(MailServiceProvider::class);
|
||||
$app->register(NotificationServiceProvider::class);
|
||||
|
|
53
framework/core/src/Image/ImageServiceProvider.php
Normal file
53
framework/core/src/Image/ImageServiceProvider.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Flarum.
|
||||
*
|
||||
* For detailed copyright and license information, please view the
|
||||
* LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Flarum\Image;
|
||||
|
||||
use Flarum\Foundation\AbstractServiceProvider;
|
||||
use Flarum\Foundation\Config;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
use Illuminate\Support\Arr;
|
||||
use Intervention\Image\Drivers;
|
||||
use Intervention\Image\ImageManager;
|
||||
use RuntimeException;
|
||||
|
||||
class ImageServiceProvider extends AbstractServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->container->bind('image.drivers', function (): array {
|
||||
return [
|
||||
'gd' => Drivers\Gd\Driver::class,
|
||||
'imagick' => Drivers\Imagick\Driver::class
|
||||
];
|
||||
});
|
||||
|
||||
$this->container->singleton('image', function (Container $container): ImageManager {
|
||||
$interventionDrivers = $container->make('image.drivers');
|
||||
|
||||
$configDriver = $container->make(Config::class)->offsetGet('intervention.driver');
|
||||
|
||||
// Default to 'gd' if not present in the config
|
||||
$driver = $configDriver ?? 'gd';
|
||||
|
||||
// Check that the imagick library is actually available, else default back to gd.
|
||||
if ($driver === 'imagick' && ! extension_loaded('imagick')) {
|
||||
$driver = 'gd';
|
||||
}
|
||||
|
||||
if (! Arr::has($interventionDrivers, $driver)) {
|
||||
throw new RuntimeException("intervention/image: $driver is not valid");
|
||||
}
|
||||
|
||||
return new ImageManager($interventionDrivers[$driver]);
|
||||
});
|
||||
|
||||
$this->container->alias('image', ImageManager::class);
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ namespace Flarum\User;
|
|||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Support\Str;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class AvatarUploader
|
||||
{
|
||||
|
@ -23,16 +23,19 @@ class AvatarUploader
|
|||
$this->uploadDir = $filesystemFactory->disk('flarum-avatars');
|
||||
}
|
||||
|
||||
public function upload(User $user, Image $image): void
|
||||
public function upload(User $user, ImageInterface $image): void
|
||||
{
|
||||
if (extension_loaded('exif')) {
|
||||
$image->orientate();
|
||||
$image = $image->cover(100, 100);
|
||||
$avatarPath = Str::random();
|
||||
|
||||
if ($image->isAnimated()) {
|
||||
$encodedImage = $image->toGif();
|
||||
$avatarPath .= '.gif';
|
||||
} else {
|
||||
$encodedImage = $image->toPng();
|
||||
$avatarPath .= '.png';
|
||||
}
|
||||
|
||||
$encodedImage = $image->fit(100, 100)->encode('png');
|
||||
|
||||
$avatarPath = Str::random().'.png';
|
||||
|
||||
$this->removeFileAfterSave($user);
|
||||
$user->changeAvatarPath($avatarPath);
|
||||
|
||||
|
|
|
@ -14,7 +14,8 @@ use Flarum\Foundation\ValidationException;
|
|||
use Flarum\Locale\TranslatorInterface;
|
||||
use Illuminate\Validation\Factory;
|
||||
use Illuminate\Validation\Validator;
|
||||
use Intervention\Image\Exception\NotReadableException;
|
||||
use Intervention\Gif\Exceptions\DecoderException as GifDecoderException;
|
||||
use Intervention\Image\Exceptions\DecoderException;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Psr\Http\Message\UploadedFileInterface;
|
||||
use Symfony\Component\Mime\MimeTypes;
|
||||
|
@ -76,8 +77,8 @@ class AvatarValidator extends AbstractValidator
|
|||
}
|
||||
|
||||
try {
|
||||
$this->imageManager->make($file->getStream()->getMetadata('uri'));
|
||||
} catch (NotReadableException) {
|
||||
$this->imageManager->read($file->getStream()->getMetadata('uri'));
|
||||
} catch (DecoderException|GifDecoderException) {
|
||||
$this->raise('image');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use Flarum\User\Exception\PermissionDeniedException;
|
|||
use Flarum\User\RegistrationToken;
|
||||
use Flarum\User\User;
|
||||
use Flarum\User\UserValidator;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Str;
|
||||
|
@ -135,9 +136,30 @@ class RegisterUserHandler
|
|||
throw new InvalidArgumentException("Provided avatar URL must have scheme http or https. Scheme provided was $scheme.", 503);
|
||||
}
|
||||
|
||||
$image = $this->imageManager->make($url);
|
||||
$urlContents = $this->retrieveAvatarFromUrl($url);
|
||||
|
||||
$this->avatarUploader->upload($user, $image);
|
||||
if ($urlContents !== null) {
|
||||
$image = $this->imageManager->read($urlContents);
|
||||
|
||||
$this->avatarUploader->upload($user, $image);
|
||||
}
|
||||
}
|
||||
|
||||
private function retrieveAvatarFromUrl(string $url): ?string
|
||||
{
|
||||
$client = new Client();
|
||||
|
||||
try {
|
||||
$response = $client->get($url);
|
||||
} catch (\Exception $e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($response->getStatusCode() !== 200) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $response->getBody()->getContents();
|
||||
}
|
||||
|
||||
private function fulfillToken(User $user, RegistrationToken $token): void
|
||||
|
|
|
@ -43,7 +43,7 @@ class UploadAvatarHandler
|
|||
|
||||
$this->validator->assertValid(['avatar' => $command->file]);
|
||||
|
||||
$image = $this->imageManager->make($command->file->getStream()->getMetadata('uri'));
|
||||
$image = $this->imageManager->read($command->file->getStream()->getMetadata('uri'));
|
||||
|
||||
$this->events->dispatch(
|
||||
new AvatarSaving($user, $actor, $image)
|
||||
|
|
|
@ -10,14 +10,14 @@
|
|||
namespace Flarum\User\Event;
|
||||
|
||||
use Flarum\User\User;
|
||||
use Intervention\Image\Image;
|
||||
use Intervention\Image\Interfaces\ImageInterface;
|
||||
|
||||
class AvatarSaving
|
||||
{
|
||||
public function __construct(
|
||||
public User $user,
|
||||
public User $actor,
|
||||
public Image $image
|
||||
public ImageInterface $image
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use Illuminate\Contracts\Events\Dispatcher;
|
|||
use Illuminate\Contracts\Filesystem\Factory;
|
||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Intervention\Image\ImageManagerStatic;
|
||||
use Intervention\Image\ImageManager;
|
||||
use Mockery as m;
|
||||
|
||||
class AvatarUploaderTest extends TestCase
|
||||
|
@ -93,7 +93,7 @@ class AvatarUploaderTest extends TestCase
|
|||
$user->changeAvatarPath('ABCDEFGHabcdefgh.png');
|
||||
$user->syncOriginal();
|
||||
|
||||
$this->uploader->upload($user, ImageManagerStatic::canvas(50, 50));
|
||||
$this->uploader->upload($user, ImageManager::gd()->create(50, 50));
|
||||
|
||||
// Simulate saving
|
||||
foreach ($user->releaseAfterSaveCallbacks() as $callback) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user