Compare commits

..

24 Commits

Author SHA1 Message Date
philipp lang 9f787646c4 Add rcc command
continuous-integration/drone/push Build is passing Details
2024-09-28 01:31:05 +02:00
philipp lang eee6b86e15 Delete temp when updating
continuous-integration/drone/push Build is passing Details
2022-09-13 00:13:59 +02:00
philipp lang 24c53106bd Dont update png files
continuous-integration/drone/push Build is passing Details
2022-09-10 19:59:08 +02:00
philipp lang fe3a0625a1 Lint 2022-09-10 19:58:54 +02:00
philipp lang 72597436a7 Lint 2022-09-10 19:58:24 +02:00
Philipp Lang 347f056df0 Fixed string
continuous-integration/drone/push Build is passing Details
2022-04-04 10:01:30 +02:00
Philipp Lang d94f21c852 Fixed: Dont create tag if image is 1px high
continuous-integration/drone/push Build is failing Details
2022-04-04 09:58:30 +02:00
philipp lang d2253a3417 Fixed: Sluggify created folder
continuous-integration/drone/push Build encountered an error Details
2022-03-22 22:54:57 +01:00
philipp lang 6c9d9b908b Fixed: Slug a filename when uploading 2022-03-22 22:14:39 +01:00
philipp lang fe794ab094 Move ResizeJob to Jobs dir
continuous-integration/drone/push Build encountered an error Details
2022-02-16 03:15:07 +01:00
philipp lang 54fd872452 Fixed: Move event has only target directory as second argument
continuous-integration/drone/push Build encountered an error Details
2022-02-16 03:03:55 +01:00
philipp lang 30bd3dc25f Fixed: Delete images 2022-02-16 02:49:19 +01:00
philipp lang 72ef92b78c Fixed: Get file in resizerTest 2022-02-16 01:48:07 +01:00
philipp lang 74d2dccadc Lint
continuous-integration/drone/push Build encountered an error Details
2022-02-15 18:38:44 +01:00
philipp lang e6d9d0d941 Performance fixes 2022-02-15 18:34:31 +01:00
philipp lang 38ac146340 Lint 2022-02-15 18:15:58 +01:00
philipp lang 55928e7da0 Add phpstan 2022-02-15 18:07:14 +01:00
philipp lang 395c7ec62a Lint 2022-02-15 18:06:51 +01:00
philipp lang e3399a65c8 Add composer paths 2022-02-15 18:06:09 +01:00
philipp lang dcbcae32e7 Fetch compressor only once during resize 2022-02-15 18:05:53 +01:00
philipp lang f419888ec6 Fetch dimensions only once 2022-02-15 17:46:29 +01:00
philipp lang 0382ff970d Add parser for class attribute
continuous-integration/drone/push Build is passing Details
2022-01-20 02:07:36 +01:00
philipp lang a1d12b7df3 Add test for deleting cache of old file
continuous-integration/drone/push Build is passing Details
2021-12-27 02:21:32 +01:00
philipp lang 425a6aa3be Fixed: Clear cache after resizing image 2021-12-27 02:18:56 +01:00
27 changed files with 1625 additions and 1129 deletions

1
.ackrc Normal file
View File

@ -0,0 +1 @@
--ignore-dir=/vendor

View File

@ -2,23 +2,25 @@
namespace Aweos\Resizer;
use Log;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\FileObserver;
use Aweos\Resizer\Classes\ImageResizer;
use Aweos\Resizer\Classes\ResizeJob;
use Aweos\Resizer\Console\ResizeCacheClear;
use Aweos\Resizer\Console\ResizeMake;
use Aweos\Resizer\Console\ResizePurge;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Jobs\DeleteJob;
use Aweos\Resizer\Jobs\MoveJob;
use Aweos\Resizer\Jobs\ResizeJob;
use Aweos\Resizer\Lib\StorageMediaPath;
use Aweos\Resizer\Models\Setting;
use Event;
use MediaLibrary;
use Queue;
use System\Classes\PluginBase;
use System\Models\File;
use ValidationException;
/**
* resizer Plugin Information File
* resizer Plugin Information File.
*/
class Plugin extends PluginBase
{
@ -30,10 +32,10 @@ class Plugin extends PluginBase
public function pluginDetails()
{
return [
'name' => 'aweos.resizer',
'name' => 'aweos.resizer',
'description' => 'No description provided yet...',
'author' => 'aweos',
'icon' => 'icon-leaf'
'author' => 'aweos',
'icon' => 'icon-leaf',
];
}
@ -46,6 +48,7 @@ class Plugin extends PluginBase
{
$this->registerConsoleCommand('resizer.resizemake', ResizeMake::class);
$this->registerConsoleCommand('resizer.resizepurge', ResizePurge::class);
$this->registerConsoleCommand('resizer.resize-cache-clear', ResizeCacheClear::class);
}
/**
@ -65,23 +68,51 @@ class Plugin extends PluginBase
app()->bind('resize', fn () => app(CacheManager::class));
Event::listen('media.folder.create', function ($widget, string $folder) {
$folder = '/' . trim($folder, '/');
$pathinfo = pathinfo($folder);
if ('/' === $pathinfo['dirname']) {
$sluggedFolder = '/' . StorageMediaPath::sluggifyString(trim($folder, '/'));
if ($sluggedFolder !== $folder) {
if (MediaLibrary::instance()->folderExists($sluggedFolder)) {
MediaLibrary::instance()->deleteFolder($folder);
throw new ValidationException(['error' => 'Ordner existiert bereits.']);
}
MediaLibrary::instance()->moveFolder($folder, $sluggedFolder);
}
} else {
$sluggedFolder = $pathinfo['dirname'] . '/' . StorageMediaPath::sluggifyString($pathinfo['filename']);
if ($sluggedFolder !== $folder) {
if (MediaLibrary::instance()->folderExists($sluggedFolder)) {
MediaLibrary::instance()->deleteFolder($folder);
throw new ValidationException(['error' => 'Ordner existiert bereits.']);
}
MediaLibrary::instance()->moveFolder($folder, $sluggedFolder);
}
}
});
Event::listen('media.file.upload', function ($widget, $filePath, $uploadedFile) {
if ((new MediaPath($filePath))->shouldProcess()) {
Queue::push(ResizeJob::class, [$filePath], Setting::get('queue'));
$sluggedPath = (new StorageMediaPath($filePath))->sluggifyPath();
if ($filePath !== $sluggedPath) {
MediaLibrary::instance()->moveFile($filePath, $sluggedPath);
}
if ((new StorageMediaPath($sluggedPath))->shouldProcess()) {
Queue::push(ResizeJob::class, [$sluggedPath], Setting::get('queue'));
}
});
Event::listen('media.file.delete', function ($widget, $filePath) {
app(FileObserver::class)->delete(new MediaPath($filePath));
app(CacheManager::class)->delete(new MediaPath($filePath));
Queue::push(DeleteJob::class, [$filePath], Setting::get('queue'));
});
Event::listen('media.file.move', function ($widget, $old, $new) {
app(FileObserver::class)->rename(new MediaPath($old), new MediaPath($new));
app(CacheManager::class)->delete(new MediaPath($old));
if ((new StorageMediaPath($new))->shouldProcess() || (new StorageMediaPath($old))->shouldProcess()) {
Queue::push(MoveJob::class, [$old, $new . '/' . pathinfo($old, PATHINFO_FILENAME)], Setting::get('queue'));
}
});
Event::listen('media.file.rename', function ($widget, $old, $new) {
app(FileObserver::class)->rename(new MediaPath($old), new MediaPath($new));
app(CacheManager::class)->delete(new MediaPath($old));
if ((new StorageMediaPath($new))->shouldProcess() || (new StorageMediaPath($old))->shouldProcess()) {
Queue::push(MoveJob::class, [$old, $new], Setting::get('queue'));
}
});
}
@ -89,15 +120,15 @@ class Plugin extends PluginBase
{
return [
'resizer' => [
'label' => 'Resizer Settings',
'label' => 'Resizer Settings',
'description' => 'Change how images are resized and compressed',
'category' => 'Base',
'icon' => 'icon-cog',
'class' => '\Aweos\Resizer\Models\Setting',
'order' => 500,
'keywords' => 'setting',
'permissions' => ['aweos.resizer.*']
]
'category' => 'Base',
'icon' => 'icon-cog',
'class' => '\Aweos\Resizer\Models\Setting',
'order' => 500,
'keywords' => 'setting',
'permissions' => ['aweos.resizer.*'],
],
];
}
@ -105,18 +136,13 @@ class Plugin extends PluginBase
{
return [
'filters' => [
'resize' => function ($media, $size = 'original', $sizes = null, $options = []) {
if (is_null($media)) {
Log::warning('Media not found in path ' . url()->current());
}
return app(CacheManager::class)->get(
new MediaPath($media),
$size,
$sizes,
$options,
);
}
]
'resize' => fn ($media, $size = 'original', $sizes = null, $options = []) => app(CacheManager::class)->get(
new StorageMediaPath($media),
$size,
$sizes,
$options,
),
],
];
}
}

View File

@ -3,6 +3,7 @@
namespace Aweos\Resizer\Classes;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Lib\StorageMediaPath;
use Cache;
class CacheManager
@ -11,14 +12,14 @@ class CacheManager
public TagGenerator $tagGenerator;
private string $tagAll = 'resizer';
public function __construct(TagGenerator $tagGenerator)
public function __construct(TagGenerator $tagGenerator)
{
$this->tagGenerator = $tagGenerator;
}
public function get(MediaPath $path, string $size, ?string $sizes, array $options = []): string
{
return Cache::tags($this->pathTag($path, $size))->rememberForever(
return Cache::tags($this->pathTag($path))->rememberForever(
$this->cacheKey($path, $size),
fn () => $this->tagGenerator->generate($path, $size, $sizes, $options)
);
@ -26,7 +27,7 @@ class CacheManager
public function delete(MediaPath $path): void
{
Cache::tags([$this->singlePathTag($path)])->flush();
Cache::tags($this->pathTag($path))->flush();
}
public function flush(): void
@ -39,7 +40,7 @@ class CacheManager
return "resizer.{$size}.{$path->normal()}";
}
private function pathTag(MediaPath $path, string $size): array
private function pathTag(MediaPath $path): array
{
return [$this->tagAll, $this->singlePathTag($path)];
}
@ -51,9 +52,8 @@ class CacheManager
public function biggestVersion(string $path, string $size): string
{
$path = new MediaPath($path);
$path = new StorageMediaPath($path);
return $this->tagGenerator->singleFile($path, $size);
}
}

View File

@ -2,21 +2,20 @@
namespace Aweos\Resizer\Classes;
use Aweos\Resizer\Compressors\Compressor;
use Aweos\Resizer\Exceptions\ResizerException;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Models\Setting;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Support\Collection;
use October\Rain\Resize\Resizer;
use Storage;
class ImageResizer
{
private FilesystemAdapter $disk;
private string $uploadDir;
private MediaPath $file;
private bool $update;
private Compressor $compressor;
public function __construct(FilesystemAdapter $disk, string $uploadDir)
{
@ -27,22 +26,23 @@ class ImageResizer
public function generate(MediaPath $file, bool $update): void
{
$this->file = $file;
$this->compressor = $this->file->compressor();
$this->update = $update;
if (!$file->exists()) {
throw new ResizerException('File versions cannot be generated. Root file "'.$file->root().'" doesnt exist.');
}
if ($this->file->compressor()->shouldGenerateVersions()) {
$this->file->compressor()->start();
if ($this->compressor->shouldGenerateVersions()) {
$this->compressor->start();
$this->generateVersions();
$this->file->compressor()->end();
$this->compressor->end();
}
}
private function dimensions(): Collection
{
[$width, $height] = $this->file->compressor()->originalSize();
[$width, $height] = $this->compressor->originalSize();
return collect(compact('width', 'height'));
}
@ -60,20 +60,21 @@ class ImageResizer
{
$return = collect([]);
$ratios = collect();
$ratios->push($this->dimensions());
$dimensions = $this->dimensions();
$ratios->push($dimensions);
$ratios = $ratios->merge($this->sizes());
foreach (collect(Setting::get('breakpoints'))->push($this->dimensions()->get('width'))->unique() as $size) {
foreach (collect(Setting::get('breakpoints'))->push($dimensions->get('width'))->unique() as $size) {
foreach ($ratios as $ratio) {
$width = $size;
$height = $size * $ratio->get('height') / $ratio->get('width');
if ($height > $this->dimensions()->get('height')) {
$width = $width * $this->dimensions()->get('height') / $height;
$height = $this->dimensions()->get('height');
if ($height > $dimensions->get('height')) {
$width = $width * $dimensions->get('height') / $height;
$height = $dimensions->get('height');
}
if (ceil($width) > $this->dimensions()->get('width') || ceil($height) > $this->dimensions()->get('height')) {
if (ceil($width) > $dimensions->get('width') || ceil($height) > $dimensions->get('height')) {
continue;
}
@ -90,15 +91,14 @@ class ImageResizer
private function generateVersions(): void
{
foreach ($this->possibleSizes() as $size) {
$this->file->compressor()->resize($size, $this->update, function($media, $file) {
$this->compressor->resize($size, $this->update, function ($media, $file) {
if (!file_exists($file)) {
throw new ResizerException('File versions cannot be generated. Version file "'.$file.'" of "'.$this->file->root().'" doesnt exist.');
}
if (file_exists($file) || !$this->update) {
$this->file->compressor()->make($file);
$this->compressor->make($file);
}
});
}
}
}

View File

@ -2,57 +2,92 @@
namespace Aweos\Resizer\Classes;
use Aweos\Resizer\Compressors\Compressor;
use Aweos\Resizer\Compressors\CompressorNotFoundException;
use Aweos\Resizer\Compressors\Factory as CompressorFactory;
use Aweos\Resizer\Exceptions\ResizerException;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Models\Setting;
use Cache;
use Exception;
use Illuminate\Support\Collection;
use Storage;
class TagGenerator {
public array $breakpoints;
public $path;
private CompressorFactory $compressorFactory;
private $defaultOptions = [
class TagGenerator
{
private Compressor $compressor;
public MediaPath $path;
private array $defaultOptions = [
'lazy' => false,
];
public function __construct(CompressorFactory $compressorFactory)
public function generate(MediaPath $path, ?string $ratio = 'original', $sizes = null, array $options = []): string
{
$this->compressorFactory = $compressorFactory;
$this->breakpoints = Setting::get('breakpoints');
ksort($this->breakpoints);
}
$options = array_merge($this->defaultOptions, $options);
$this->path = $path;
$this->compressor = $this->path->compressor();
$this->compressor->start();
public function size(string $name): array
{
$size = collect(Setting::get('sizes'))->filter(fn ($size) => $size['name'] === $name)
->first();
if (is_null($size)) {
throw new ResizerException("Size with name {$name} not found.");
try {
if (!$this->compressor->shouldGenerateVersions()) {
return $this->fallback();
}
} catch (CompressorNotFoundException $e) {
return $this->fallback();
}
return explode('x', $size['aspect_ratio']);
$files = $this->possibleFiles($ratio);
if (null === $files) {
return $this->fallback();
}
$sizes = $this->parseSizes($files, $sizes);
$srcset = $files->map(function ($file) {
return "{$file->get('url')} {$file->get('width')}w";
});
$html = $this->htmlAttributes(collect([
'width' => $files->last()->get('width'),
'height' => $files->last()->get('height'),
'sizes' => $sizes->implode(', '),
$options['lazy'] ? 'data-srcset' : 'srcset' => $srcset->implode(', '),
$options['lazy'] ? 'data-src' : 'src' => $files->last()->get('url'),
'class' => data_get($options, 'class'),
])->filter(fn ($value) => (bool) $value));
$this->compressor->end();
return $html;
}
public function possibleFiles(string $ratio): ?Collection
public function singleFile(MediaPath $path, ?string $ratio = 'original'): string
{
$this->path = $path;
$this->compressor = $this->path->compressor();
$this->compressor->start();
$versions = $this->possibleFiles($ratio);
throw_unless($versions && count($versions), Exception::class, "No files for {$path->root()} found");
$possibleFiles = url($this->possibleFiles($ratio)->last()->get('url'));
$this->compressor->end();
return $possibleFiles;
}
private function possibleFiles(string $ratio): ?Collection
{
$filename = $this->path->filename();
$basePath = $this->path->versionsDirPath();
[$originalWidth, $originalHeight] = $this->path->compressor()->originalSize();
$aspectRatio = $ratio === 'original'
[$originalWidth, $originalHeight] = $this->compressor->originalSize();
$aspectRatio = 'original' === $ratio
? $originalWidth / $originalHeight
: $this->size($ratio)[0] / $this->size($ratio)[1];
$result = collect([]);
foreach ($this->path->versions() as $version) {
if ($version->get('width') / ($version->get('height')+1) > $aspectRatio || $version->get('width') / ($version->get('height')-1) < $aspectRatio) {
if ('1' === $version->get('height')) {
continue;
}
if ($version->get('width') / ($version->get('height') + 1) > $aspectRatio || $version->get('width') / ($version->get('height') - 1) < $aspectRatio) {
continue;
}
@ -69,53 +104,9 @@ class TagGenerator {
: null;
}
public function generate(MediaPath $path, ?string $ratio = 'original', $sizes = null, array $options = []): string
private function htmlAttributes($attr): string
{
$options = array_merge($this->defaultOptions, $options);
$this->path = $path;
try {
if (!$path->compressor()->shouldGenerateVersions()) {
return $this->fallback();
}
} catch (CompressorNotFoundException $e) {
return $this->fallback();
}
$files = $this->possibleFiles($ratio);
if ($files === null) {
return $this->fallback();
}
$sizes = $this->parseSizes($files, $sizes);
$srcset = $files->map(function($file) {
return "{$file->get('url')} {$file->get('width')}w";
});
return $this->htmlAttributes(collect([
'width' => $files->last()->get('width'),
'height' => $files->last()->get('height'),
'sizes' => $sizes->implode(', '),
$options['lazy'] ? 'data-srcset' : 'srcset' => $srcset->implode(', '),
$options['lazy'] ? 'data-src' : 'src' => $files->last()->get('url'),
]));
}
public function singleFile(MediaPath $path, ?string $ratio = 'original'): string
{
$this->path = $path;
$versions = $this->possibleFiles($ratio);
throw_unless($versions && count($versions), Exception::class, "No files for {$path->root()} found");
return url($this->possibleFiles($ratio)->last()->get('url'));
}
private function htmlAttributes($attr) {
return $attr->map(function($value, $key) {
return $attr->map(function ($value, $key) {
return "{$key}=\"{$value}\"";
})->implode(' ');
}
@ -123,18 +114,18 @@ class TagGenerator {
private function parseSizes(Collection $files, ?string $sizes = null): Collection
{
if (is_null($sizes)) {
return $files->map(function($file) {
return $files->map(function ($file) {
return "(max-width: {$file->get('width')}px) {$file->get('width')}px";
});
}
$sizes = collect(explode('|', $sizes));
$minSize = $sizes->shift();
$sizes = $sizes->sortByDesc(function($size) {
$sizes = $sizes->sortByDesc(function ($size) {
return explode(':', $size)[0];
});
return $sizes->map(function($size) {
return $sizes->map(function ($size) {
$components = explode(':', $size);
return "(min-width: {$components[0]}px) {$components[1]}";
@ -145,4 +136,16 @@ class TagGenerator {
{
return 'src="'.$this->path->publicUrl().'"';
}
private function size(string $name): array
{
$size = collect(Setting::get('sizes'))->filter(fn ($size) => $size['name'] === $name)
->first();
if (is_null($size)) {
throw new ResizerException("Size with name {$name} not found.");
}
return explode('x', $size['aspect_ratio']);
}
}

View File

@ -2,7 +2,7 @@
"name": "aweos/oc-resizer-plugin",
"type": "october-plugin",
"require": {
"guzzlehttp/guzzle": "^7.5",
"guzzlehttp/guzzle": "^6.3",
"intervention/image": "^2.6"
},
"require-dev": {
@ -18,7 +18,11 @@
"autoload": {
"psr-4": {
"Aweos\\Resizer\\Compilers\\": "./compilers",
"Aweos\\Resizer\\Exceptions\\": "./exceptions"
"Aweos\\Resizer\\Exceptions\\": "./exceptions",
"Aweos\\Resizer\\Compressors\\": "./compressors",
"Aweos\\Resizer\\Lib\\": "./lib",
"Aweos\\Resizer\\Jobs\\": "./jobs",
"Aweos\\Resizer\\Classes\\": "./classes"
}
}
}

1913
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,7 @@
namespace Aweos\Resizer\Compressors;
use Aweos\Resizer\Lib\MediaPath;
use Illuminate\Support\Collection;
use Storage;
abstract class Compressor
@ -11,10 +12,12 @@ abstract class Compressor
protected MediaPath $media;
abstract function make(string $path): array;
abstract protected function getExtension();
abstract protected function getExtension(): string;
abstract public function getExtensionRegex(): string;
abstract public function shouldGenerateVersions(): bool;
abstract public function start(): void;
abstract public function end(): void;
abstract public function resize(Collection $size, bool $update, callable $callback): void;
public function __construct(MediaPath $media)
{

View File

@ -2,6 +2,8 @@
namespace Aweos\Resizer\Compressors;
use Illuminate\Support\Collection;
class DefaultCompressor extends Compressor {
public function getExtension(): string
@ -24,4 +26,18 @@ class DefaultCompressor extends Compressor {
return false;
}
public function start(): void
{
//
}
public function end(): void
{
//
}
public function resize(Collection $size, bool $update, callable $callback): void {
//
}
}

View File

@ -2,13 +2,12 @@
namespace Aweos\Resizer\Compressors;
use Aweos\Resizer\Exceptions\ResizerException;
use Illuminate\Support\Collection;
use Intervention\Image\ImageManager;
use Storage;
class JpgCompressor extends Compressor {
class JpgCompressor extends Compressor
{
public function getExtensionRegex(): string
{
return 'jpg';
@ -24,7 +23,7 @@ class JpgCompressor extends Compressor {
$output = $this->tmpPath();
system('imagemin '.escapeshellarg($path).' --plugin=jpegtran --plugin=mozjpeg --plugin.mozjpeg.quality=70 > '.escapeshellarg($output));
system("mv ".escapeshellarg($output)." ".escapeshellarg($path));
system('mv '.escapeshellarg($output).' '.escapeshellarg($path));
return [
$path => [$path],
@ -55,6 +54,8 @@ class JpgCompressor extends Compressor {
$versionFilename = $this->media->versionsDirPath().'/'.$this->versionFilename($destWidth, $destHeight);
if ($update && Storage::exists($versionFilename)) {
Storage::delete($temp);
return;
}
@ -64,12 +65,9 @@ class JpgCompressor extends Compressor {
public function start(): void
{
//
}
public function end(): void
{
//
}
}

View File

@ -9,6 +9,7 @@ use Storage;
class PdfCompressor extends Compressor
{
private string $originalImage;
public function getExtensionRegex(): string
{
@ -26,7 +27,7 @@ class PdfCompressor extends Compressor
$mimetype = mime_content_type($path);
system('imagemin '.escapeshellarg($path).' --plugin=jpegtran --plugin=mozjpeg --plugin.mozjpeg.quality=70 > '.escapeshellarg($output));
system("mv ".escapeshellarg($output)." ".escapeshellarg($path));
system('mv '.escapeshellarg($output).' '.escapeshellarg($path));
return [
$path => [$path],
@ -41,6 +42,7 @@ class PdfCompressor extends Compressor
public function start(): void
{
@unlink($this->imagePath());
$this->originalImage = $this->extractImage();
}
public function end(): void
@ -65,10 +67,7 @@ class PdfCompressor extends Compressor
public function originalSize(): array
{
$filename = $this->extractImage($this->media->root());
$size = getimagesize($filename);
return $size;
return getimagesize($this->originalImage);
}
public function shouldGenerateVersions(): bool
@ -78,10 +77,9 @@ class PdfCompressor extends Compressor
public function resize(Collection $size, bool $update, callable $callback): void
{
$temp = $this->extractImage();
$tempBefore = PATHINFO($temp, PATHINFO_FILENAME).'compiled.'.pathinfo($temp, PATHINFO_EXTENSION);
$tempBefore = pathinfo($this->originalImage, PATHINFO_FILENAME).'compiled.'.pathinfo($this->originalImage, PATHINFO_EXTENSION);
$r = app(ImageManager::class)->make($temp)
$r = app(ImageManager::class)->make($this->originalImage)
->fit($size->get('width'), $size->get('height'))
->save($tempBefore);
@ -92,5 +90,4 @@ class PdfCompressor extends Compressor
unlink($tempBefore);
call_user_func($callback, $this->media, Storage::path($versionFilename));
}
}

View File

@ -6,8 +6,8 @@ use Illuminate\Support\Collection;
use Intervention\Image\ImageManager;
use Storage;
class PngCompressor extends Compressor {
class PngCompressor extends Compressor
{
protected function getExtension(): string
{
return 'png';
@ -24,7 +24,7 @@ class PngCompressor extends Compressor {
$mimetype = mime_content_type($path);
system('imagemin '.escapeshellarg($path).' --plugin=pngquant > '.escapeshellarg($output));
system("mv ".escapeshellarg($output)." ".escapeshellarg($path));
system('mv '.escapeshellarg($output).' '.escapeshellarg($path));
return [
$path => [$path],
@ -43,12 +43,10 @@ class PngCompressor extends Compressor {
public function start(): void
{
//
}
public function end(): void
{
//
}
public function resize(Collection $size, bool $update, callable $callback): void
@ -65,8 +63,13 @@ class PngCompressor extends Compressor {
$versionFilename = $this->media->versionsDirPath().'/'.$this->versionFilename($destWidth, $destHeight);
if ($update && Storage::exists($versionFilename)) {
Storage::delete($temp);
return;
}
$this->moveTo($temp, $versionFilename);
call_user_func($callback, $this->media, Storage::path($versionFilename));
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace Aweos\Resizer\Console;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Lib\StorageMediaPath;
use Illuminate\Console\Command;
use Storage;
use Symfony\Component\Console\Input\InputArgument;
class ResizeCacheClear extends Command
{
/**
* @var string The console command name.
*/
protected $name = 'rcc';
/**
* @var string The console command description.
*/
protected $description = 'Clears cache for a specific file';
/**
* Execute the console command.
* @return void
*/
public function handle()
{
$path = new StorageMediaPath($this->argument('path'));
app(CacheManager::class)->delete($path);
}
/**
* Get the console command arguments.
* @return array
*/
protected function getArguments()
{
return [
['path', InputArgument::REQUIRED, 'The path on the storage'],
];
}
/**
* Get the console command options.
* @return array
*/
protected function getOptions()
{
return [];
}
}

View File

@ -1,7 +1,7 @@
<?php namespace Aweos\Resizer\Console;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\ResizeJob;
use Aweos\Resizer\Jobs\ResizeJob;
use Aweos\Resizer\Models\Setting;
use Exception;
use GuzzleHttp\Client;
@ -17,7 +17,7 @@ use Symfony\Component\Console\Input\InputOption;
class ResizeMake extends Command
{
public $media = null;
public MediaLibrary $media;
/**
* @var string The console command name.

36
jobs/DeleteJob.php Normal file
View File

@ -0,0 +1,36 @@
<?php
namespace Aweos\Resizer\Jobs;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\FileObserver;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Lib\StorageMediaPath;
use Log;
use Throwable;
class DeleteJob
{
public function fire($job, $params)
{
list($file) = $params;
$media = new StorageMediaPath($file);
app(FileObserver::class)->delete($media);
app(CacheManager::class)->delete($media);
unset ($media);
$job->delete();
}
public function failed($data, Throwable $e)
{
Log::error("Deleting of image failed", [
'message' => $e->getMessage(),
'exception' => $e,
'data' => $data,
]);
throw $e;
}
}

38
jobs/MoveJob.php Normal file
View File

@ -0,0 +1,38 @@
<?php
namespace Aweos\Resizer\Jobs;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\FileObserver;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Lib\StorageMediaPath;
use Log;
use Throwable;
class MoveJob
{
public function fire($job, $params)
{
list($old, $new) = $params;
$old = new StorageMediaPath($old);
$new = new StorageMediaPath($new);
app(FileObserver::class)->rename($old, $new);
app(CacheManager::class)->delete($old);
unset ($old);
unset ($new);
$job->delete();
}
public function failed($data, Throwable $e)
{
Log::error("Deleting of image failed", [
'message' => $e->getMessage(),
'exception' => $e,
'data' => $data,
]);
throw $e;
}
}

View File

@ -1,8 +1,11 @@
<?php
namespace Aweos\Resizer\Classes;
namespace Aweos\Resizer\Jobs;
use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\ImageResizer;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Lib\TempMediaPath;
use Log;
use Throwable;
@ -12,7 +15,11 @@ class ResizeJob
public function fire($job, $params)
{
list($file) = $params;
app(ImageResizer::class)->generate(new MediaPath($file), $params['update'] ?? false);
$media = new TempMediaPath($file);
app(ImageResizer::class)->generate($media, $params['update'] ?? false);
app(CacheManager::class)->delete($media);
unset ($media);
$job->delete();
}

View File

@ -6,29 +6,23 @@ use Aweos\Resizer\Compressors\Compressor;
use Aweos\Resizer\Compressors\Factory as CompressorFactory;
use Aweos\Resizer\Models\Setting;
use Illuminate\Support\Collection;
use MediaLibrary;
use Storage;
use Illuminate\Support\Facades\Storage;
class MediaPath
abstract class MediaPath
{
protected string $path;
private string $path;
abstract public function get(): string;
abstract public function root(): string;
abstract public function publicUrl(): string;
public function __construct(string $path)
{
$this->path = $path;
}
public function root(): string
{
return Storage::path($this->storagePath());
}
public function storagePath(): string
{
return "media/{$this->normal()}";
}
public function normal(): string
{
return preg_replace('|^/*|', '', $this->path);
@ -41,7 +35,7 @@ class MediaPath
public function filename(): string
{
return pathinfo($this->path, PATHINFO_FILENAME);
return pathinfo($this->root(), PATHINFO_FILENAME);
}
public function exists(): bool
@ -60,7 +54,7 @@ class MediaPath
public function extension(): string
{
return pathinfo($this->path, PATHINFO_EXTENSION);
return pathinfo($this->root(), PATHINFO_EXTENSION);
}
public function versionsPath(): string
@ -70,24 +64,14 @@ class MediaPath
public function versionsDirPath(): string
{
return pathinfo("uploads/public/c/{$this->normal()}", PATHINFO_DIRNAME);
}
public function publicUrl(): string
{
return MediaLibrary::instance()->findFiles($this->path)[0]->publicUrl;
}
public function get(): string
{
return MediaLibrary::instance()->get($this->path);
return pathinfo($this->versionsPath(), PATHINFO_DIRNAME);
}
public function shouldProcess(): bool
{
return collect(Setting::get('folders'))->pluck('folder')->first(
return null !== collect(Setting::get('folders'))->pluck('folder')->first(
fn ($folder) => starts_with('/'.$this->normal(), $folder.'/')
) !== null;
);
}
public function versions(): Collection
@ -122,4 +106,29 @@ class MediaPath
return $return;
}
public function sluggifyPath(): string
{
$fileinfo = pathinfo($this->path);
$filename = $fileinfo['dirname'].'/';
return $filename
.static::sluggifyString($fileinfo['filename'])
.'.'
.$fileinfo['extension'];
}
protected function storagePath(): string
{
return "media/{$this->normal()}";
}
public static function sluggifyString(string $input): string
{
return str_slug(strtr($input, [
'ö' => 'oe',
'ä' => 'ae',
'ü' => 'ue',
'ß' => 'ss',
]));
}
}

36
lib/StorageMediaPath.php Normal file
View File

@ -0,0 +1,36 @@
<?php
namespace Aweos\Resizer\Lib;
use Aweos\Resizer\Compressors\Compressor;
use Aweos\Resizer\Compressors\Factory as CompressorFactory;
use Aweos\Resizer\Models\Setting;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use MediaLibrary;
class StorageMediaPath extends MediaPath
{
public function __construct(string $path)
{
parent::__construct($path);
$this->path = $path;
}
public function root(): string
{
return Storage::path($this->storagePath());
}
public function publicUrl(): string
{
return MediaLibrary::instance()->findFiles($this->path)[0]->publicUrl;
}
public function get(): string
{
return MediaLibrary::instance()->get($this->path);
}
}

59
lib/TempMediaPath.php Normal file
View File

@ -0,0 +1,59 @@
<?php
namespace Aweos\Resizer\Lib;
use Aweos\Resizer\Compressors\Compressor;
use Aweos\Resizer\Compressors\Factory as CompressorFactory;
use Aweos\Resizer\Models\Setting;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use MediaLibrary;
class TempMediaPath extends MediaPath
{
private string $tempPath;
public function __construct(string $path)
{
parent::__construct($path);
$this->createTemp();
}
public function __destruct()
{
$this->destroyTemp();
}
public function root(): string
{
return $this->tempPath;
}
public function publicUrl(): string
{
return '';
}
public function get(): string
{
return file_get_contents($this->tempPath);
}
private function createTemp(): void
{
$this->tempPath = '/tmp/'.pathinfo($this->path, PATHINFO_FILENAME);
if (Storage::exists($this->storagePath())) {
$stream = Storage::readStream($this->storagePath());
$contents = stream_get_contents($stream);
file_put_contents($this->tempPath, $contents);
}
}
private function destroyTemp(): void
{
@unlink($this->tempPath);
}
}

13
phpstan.neon Normal file
View File

@ -0,0 +1,13 @@
parameters:
paths:
- classes
- compressors
- console
- exceptions
- lib
# The level 8 is the highest level
level: 6
checkMissingIterableValueType: false

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="../../../tests/bootstrap.php"
bootstrap="../../../modules/system/tests/bootstrap.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"

View File

@ -6,6 +6,7 @@ use Aweos\Resizer\Classes\CacheManager;
use Aweos\Resizer\Classes\TagGenerator;
use Aweos\Resizer\Exceptions\ResizerException;
use Aweos\Resizer\Lib\MediaPath;
use Aweos\Resizer\Lib\StorageMediaPath;
use Aweos\Resizer\Models\Setting;
use Aweos\Resizer\Tests\TestCase;
use Cache;
@ -21,11 +22,11 @@ class ImageTagTest extends TestCase
{
parent::setUp();
Storage::fake('local');
Setting::set('folders', [['folder' => '/pages']]);
}
public function testItGeneratesAnImageTagWithOriginalSize()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100,200]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
@ -35,25 +36,23 @@ class ImageTagTest extends TestCase
$this->assertEquals(
'width="500" height="500" sizes="(max-width: 100px) 100px, (max-width: 200px) 200px, (max-width: 500px) 500px" srcset="/storage/uploads/public/c/pages/test-100x100.jpg 100w, /storage/uploads/public/c/pages/test-200x200.jpg 200w, /storage/uploads/public/c/pages/test-500x500.jpg 500w" src="/storage/uploads/public/c/pages/test-500x500.jpg"',
app(CacheManager::class)->get(new MediaPath('pages/test.jpg'), 'original', null),
app(CacheManager::class)->get(new StorageMediaPath('pages/test.jpg'), 'original', null),
);
}
public function testItThrowsExceptionWhenSizeNotFound()
{
$this->expectException(ResizerException::class);
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
UploadedFile::fake()->image('test.jpg', 500, 500)->storeAs('uploads/public/c/pages', 'test-500x500.jpg', 'local');
dd(app(CacheManager::class)->get(new MediaPath('pages/test.jpg'), 'notfound', null));
dd(app(CacheManager::class)->get(new StorageMediaPath('pages/test.jpg'), 'notfound', null));
}
public function testFetchPdfImage()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100,200]);
$this->media->put('/pages/test.pdf', file_get_contents(__DIR__.'/stub/dummy.pdf'));
@ -68,7 +67,6 @@ class ImageTagTest extends TestCase
public function testItGeneratesLazyLoadingTags()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
@ -76,13 +74,12 @@ class ImageTagTest extends TestCase
$this->assertEquals(
'width="100" height="100" sizes="(max-width: 100px) 100px" data-srcset="/storage/uploads/public/c/pages/test-100x100.jpg 100w" data-src="/storage/uploads/public/c/pages/test-100x100.jpg"',
app(CacheManager::class)->get(new MediaPath('pages/test.jpg'), 'original', null, ['lazy' => true]),
app(CacheManager::class)->get(new StorageMediaPath('pages/test.jpg'), 'original', null, ['lazy' => true]),
);
}
public function testItGeneratesPngImages()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100,200]);
$this->media->put('/pages/test.png', UploadedFile::fake()->image('test.png', 500, 500)->get());
@ -90,13 +87,12 @@ class ImageTagTest extends TestCase
$this->assertEquals(
'width="100" height="100" sizes="(max-width: 100px) 100px" srcset="/storage/uploads/public/c/pages/test-100x100.png 100w" src="/storage/uploads/public/c/pages/test-100x100.png"',
app(CacheManager::class)->get(new MediaPath('pages/test.png'), 'original', null),
app(CacheManager::class)->get(new StorageMediaPath('pages/test.png'), 'original', null),
);
}
public function testItSkipsImagesWithWrongAspectRatio()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100,200]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
@ -111,7 +107,6 @@ class ImageTagTest extends TestCase
public function testItCanGenerateAAspectRatio()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', [['name' => 'size', 'aspect_ratio' => '1x2']]);
Setting::set('breakpoints', [100,200]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
@ -133,7 +128,6 @@ class ImageTagTest extends TestCase
public function testItServesAspectRatiosThatCanBeOnePixelLarger()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', [['name' => 'size', 'aspect_ratio' => '1200x280']]);
Setting::set('breakpoints', [640]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 1920, 899)->get());
@ -147,7 +141,6 @@ class ImageTagTest extends TestCase
public function testGenerateCache()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', [['name' => 'size', 'aspect_ratio' => '1200x280']]);
Setting::set('breakpoints', [640]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 1920, 899)->get());
@ -159,7 +152,6 @@ class ImageTagTest extends TestCase
public function testPickOriginalImageWhenSvgIsGiven()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', [['name' => 'size', 'aspect_ratio' => '1200x280']]);
Setting::set('breakpoints', [640]);
$this->media->put('/pages/test.svg', file_get_contents(__DIR__.'/stub/close.svg'));
@ -174,7 +166,6 @@ class ImageTagTest extends TestCase
public function testNormalizeFilePathForCache()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', [['name' => 'size', 'aspect_ratio' => '1200x280']]);
Setting::set('breakpoints', [640]);
$this->media->put('/pages/test.svg', file_get_contents(__DIR__.'/stub/close.svg'));
@ -185,7 +176,6 @@ class ImageTagTest extends TestCase
public function testGenerateSizesAttribute()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100, 200]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());
@ -199,7 +189,6 @@ class ImageTagTest extends TestCase
public function testItGeneratesOnlySingleImage()
{
Setting::set('folders', ['pages']);
Setting::set('sizes', []);
Setting::set('breakpoints', [100]);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 500, 500)->get());

View File

@ -21,13 +21,13 @@ class MoveTest extends TestCase
public function testItMovesAllVersionsOfAFile()
{
Cache::tags(['resizer', 'resizer.pages/alt/test.jpg'])->set('resizer.original.pages/alt/test.jpg', 'aa');
Setting::set('folders', ['pages']);
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/alt/test.jpg', UploadedFile::fake()->image('test.jpg', 100, 100)->get());
UploadedFile::fake()->image('test.jpg', 100, 100)->storeAs('uploads/public/c/pages/alt', 'test-200x300.jpg', 'local');
Event::fire('media.file.move', [null, '/pages/alt/test.jpg', '/pages/neu/test.jpg']);
Event::fire('media.file.move', [null, '/pages/alt/test.jpg', '/pages/neu']);
$this->assertFileCount(0, 'pages/alt');
$this->assertHasFile('pages/neu/test-200x300.jpg');
@ -36,7 +36,7 @@ class MoveTest extends TestCase
public function testItMovesFilesOnRename()
{
Setting::set('folders', ['pages']);
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 100, 100)->get());
@ -48,9 +48,27 @@ class MoveTest extends TestCase
$this->assertHasFile('pages/testneu-200x300.jpg');
}
public function testitDeletesOldAndNewCacheWhenMoving()
{
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 100, 100)->get());
UploadedFile::fake()->image(100, 100)->storeAs('uploads/public/c/pages', 'test-200x300.jpg', 'local');
Cache::tags(['resizer', 'resizer.pages/test.jpg'])->put('resizer.original.pages/test.jpg', 'AAA');
Cache::tags(['resizer', 'resizer.pages/testneu.jpg'])->put('resizer.original.pages/testneu.jpg', 'AAA');
Event::fire('media.file.rename', [null, '/pages/test.jpg', '/pages/testneu.jpg']);
$this->assertFileCount(1, 'pages');
$this->assertHasFile('pages/testneu-200x300.jpg');
$this->assertFalse(Cache::tags(['resizer', 'resizer.pages/test.jpg'])->has('resizer.original.pages/test.jpg'));
$this->assertFalse(Cache::tags(['resizer', 'resizer.pages/testneu.jpg'])->has('resizer.original.pages/test.jpg'));
}
public function testRenamePdfHeaderFile()
{
Setting::set('folders', ['pages']);
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/test.pdf', file_get_contents(__DIR__.'/stub/dummy.pdf'));
@ -65,7 +83,7 @@ class MoveTest extends TestCase
public function testItDoesntMoveOtherFilesInTheSameDirectory()
{
Cache::tags(['resizer', 'resizer.pages/test.jpg'])->set('resizer.original.pages/test.jpg', 'aa');
Setting::set('folders', ['pages']);
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$this->media->put('/pages/test.jpg', UploadedFile::fake()->image('test.jpg', 100, 100)->get());

View File

@ -4,15 +4,14 @@ namespace Aweos\Resizer\Tests;
use Aweos\Resizer\Exceptions\ResizerException;
use Aweos\Resizer\Models\Setting;
use Aweos\Resizer\Tests\TestCase;
use Event;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Cache;
use MediaLibrary;
use Storage;
class ResizerTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
@ -26,13 +25,28 @@ class ResizerTest extends TestCase
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->put('/pages/test.jpg', $file);
$this->media->put('/pages/test.jpg', $file->get());
Event::fire('media.file.upload', [null, '/pages/test.jpg', null]);
$this->assertFileCount(0, '');
}
public function testDeleteOldCacheWhenUploadingFile(): void
{
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->put('/pages/test.jpg', $file->get());
Cache::tags(['resizer', 'resizer.pages/test.jpg'])->put('resizer.original.pages/test.jpg', 'AAA');
Event::fire('media.file.upload', [null, '/pages/test.jpg', null]);
$this->assertFileCount(0, '');
$this->assertFalse(Cache::tags(['resizer', 'resizer.pages/test.jpg'])->has('resizer.original.pages/test.jpg'));
}
public function testThrowExceptionWhenOriginalFileNotFound(): void
{
$this->expectException(ResizerException::class);
@ -74,6 +88,21 @@ class ResizerTest extends TestCase
$this->assertHasFile('pages/test-500x600.jpg');
}
public function testSluggifyFilename(): void
{
Setting::set('folders', [['folder' => '/pages']]);
Setting::set('sizes', []);
Setting::set('breakpoints', []);
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->put('/pages/test ö space.jpg', $file->get());
Event::fire('media.file.upload', [null, 'pages/test ö space.jpg', null]);
Storage::assertExists('media/pages/test-oe-space.jpg');
$this->assertFileCount(1, 'pages');
$this->assertHasFile('pages/test-oe-space-500x600.jpg');
}
public function testCopyTwoDirectoriesDeepButNotAnotherDirectory(): void
{
Setting::set('folders', [['folder' => '/pages']]);
@ -240,5 +269,4 @@ class ResizerTest extends TestCase
$this->assertHasFile('pages/test-1275x1650.pdf.jpg');
$this->assertFileCount(4, 'pages');
}
}

59
tests/SlugTest.php Normal file
View File

@ -0,0 +1,59 @@
<?php
namespace Aweos\Resizer\Tests;
use Event;
use Illuminate\Http\UploadedFile;
use MediaLibrary;
use Storage;
class SlugTest extends TestCase
{
public function setUp(): void
{
parent::setUp();
Storage::fake('local');
$this->media = MediaLibrary::instance();
}
public function testDontRenameFolderIfSluggingIsNotNeeded(): void
{
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->makeFolder('testbb');
Event::fire('media.folder.create', [null, '//testbb', null]);
Storage::disk('local')->assertExists('media/testbb');
}
public function testRenameFolder(): void
{
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->makeFolder('test bb');
Event::fire('media.folder.create', [null, '//test bb', null]);
Storage::disk('local')->assertExists('media/test-bb');
Storage::disk('local')->assertMissing('media/test bb');
}
public function testRenameSubfolder(): void
{
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->makeFolder('test/aa bb');
Event::fire('media.folder.create', [null, '/test/aa bb', null]);
Storage::disk('local')->assertExists('media/test/aa-bb');
}
public function testRenameSubfolderWithDoubleSlash(): void
{
$file = UploadedFile::fake()->image('test.jpg', 500, 600);
$this->media->makeFolder('test/aa bb');
Event::fire('media.folder.create', [null, '//test/aa bb', null]);
Storage::disk('local')->assertExists('media/test/aa-bb');
}
}

View File

@ -19,10 +19,6 @@ class TestCase extends PluginTestCase
Setting::set('queue', 'default');
$this->media = MediaLibrary::instance();
$pluginManager = PluginManager::instance();
$pluginManager->registerAll(true);
$pluginManager->bootAll(true);
}
public function assertHasFile($file): void