Compare commits
7 Commits
Author | SHA1 | Date |
---|---|---|
|
4a87b83b5a | |
|
09919a1c29 | |
|
820a725517 | |
|
2d39816954 | |
|
7e8f762885 | |
|
9c33c8f128 | |
|
cfb38ed792 |
|
@ -0,0 +1,28 @@
|
||||||
|
# Laravel Medialibrary Helper
|
||||||
|
|
||||||
|
This package creates routes for the popular Medialibrary Package from Spatie ().
|
||||||
|
|
||||||
|
## Available methods
|
||||||
|
|
||||||
|
In RegisterMediaCollections, you have the following methods available:
|
||||||
|
|
||||||
|
You can set a filename by default for the file. This accepts the associated Model, as well as the original filename. You should return the new name of the file with the extension (e.g. disc.jpg).
|
||||||
|
|
||||||
|
```
|
||||||
|
forceFileName(fn ($model, $path) => Str::slug($path))
|
||||||
|
```
|
||||||
|
|
||||||
|
You can set a max width (in Pixels) for images. This will resize the image BEFORE any normal Medialibrary conversions take place.
|
||||||
|
|
||||||
|
```
|
||||||
|
maxWidth(fn () => 2500)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can call whatever you want after an image has been added, modified or deleted.
|
||||||
|
|
||||||
|
```
|
||||||
|
->after(function ($model) {
|
||||||
|
....
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
|
"ext-imagick": ">=3.6.0",
|
||||||
"spatie/laravel-medialibrary": "^10.7",
|
"spatie/laravel-medialibrary": "^10.7",
|
||||||
"laravel/framework": "^9.50",
|
"laravel/framework": "^9.50",
|
||||||
"spatie/laravel-data": "^3.1",
|
"spatie/laravel-data": "^3.1",
|
||||||
|
@ -35,5 +36,12 @@
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
"pestphp/pest-plugin": true
|
"pestphp/pest-plugin": true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"laravel": {
|
||||||
|
"providers": [
|
||||||
|
"Zoomyboy\\MedialibraryHelper\\ServiceProvider"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,8 @@ class CollectionExtension
|
||||||
{
|
{
|
||||||
public function boot(): void
|
public function boot(): void
|
||||||
{
|
{
|
||||||
MediaCollection::mixin(new class() {
|
MediaCollection::mixin(new class()
|
||||||
|
{
|
||||||
public function forceFileName()
|
public function forceFileName()
|
||||||
{
|
{
|
||||||
return fn ($callback) => $this->registerCustomCallback('forceFileName', $callback);
|
return fn ($callback) => $this->registerCustomCallback('forceFileName', $callback);
|
||||||
|
@ -86,7 +87,7 @@ class CollectionExtension
|
||||||
'after' => fn ($event) => true,
|
'after' => fn ($event) => true,
|
||||||
'destroyed' => fn ($event) => true,
|
'destroyed' => fn ($event) => true,
|
||||||
'storing' => fn ($adder, $name) => $adder,
|
'storing' => fn ($adder, $name) => $adder,
|
||||||
'withDefaultProperties' => fn ($path) => [],
|
'withDefaultProperties' => fn ($path, $pathinfo) => [],
|
||||||
'withPropertyValidation' => fn ($path) => [],
|
'withPropertyValidation' => fn ($path) => [],
|
||||||
'withFallback' => fn ($parent) => null,
|
'withFallback' => fn ($parent) => null,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
namespace Zoomyboy\MedialibraryHelper;
|
namespace Zoomyboy\MedialibraryHelper;
|
||||||
|
|
||||||
|
use Imagick;
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
use Illuminate\Http\JsonResponse;
|
use Illuminate\Http\JsonResponse;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
@ -48,12 +49,12 @@ class MediaController
|
||||||
$medias = collect($content)->map(function ($c) use ($collection, $model) {
|
$medias = collect($content)->map(function ($c) use ($collection, $model) {
|
||||||
$pathinfo = pathinfo($c['name']);
|
$pathinfo = pathinfo($c['name']);
|
||||||
$basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']);
|
$basename = $collection->runCallback('forceFileName', $model, $pathinfo['filename']);
|
||||||
$path = $basename.'.'.$pathinfo['extension'];
|
$path = $basename . '.' . $pathinfo['extension'];
|
||||||
|
|
||||||
$adder = $this->fileAdderFromData($model, $c['content'], $collection)
|
$adder = $this->fileAdderFromData($model, $c['content'], $collection)
|
||||||
->usingName($basename)
|
->usingName($basename)
|
||||||
->usingFileName($path)
|
->usingFileName($path)
|
||||||
->withCustomProperties($collection->runCallback('withDefaultProperties', $path));
|
->withCustomProperties($collection->runCallback('withDefaultProperties', $path, $pathinfo));
|
||||||
|
|
||||||
return tap(
|
return tap(
|
||||||
$collection->runCallback('storing', $adder, $path)->toMediaCollection($collection->name),
|
$collection->runCallback('storing', $adder, $path)->toMediaCollection($collection->name),
|
||||||
|
@ -160,6 +161,14 @@ class MediaController
|
||||||
$tmpFile = tempnam(sys_get_temp_dir(), 'media-library');
|
$tmpFile = tempnam(sys_get_temp_dir(), 'media-library');
|
||||||
file_put_contents($tmpFile, $binaryData);
|
file_put_contents($tmpFile, $binaryData);
|
||||||
|
|
||||||
|
$i = (new Imagick());
|
||||||
|
$i->readImage($tmpFile);
|
||||||
|
|
||||||
|
if ($i->getImageFormat() === 'HEIC') {
|
||||||
|
$i->setFormat('jpg');
|
||||||
|
$i->writeImage($tmpFile);
|
||||||
|
}
|
||||||
|
|
||||||
if (null !== $maxWidth && 'image/jpeg' === mime_content_type($tmpFile)) {
|
if (null !== $maxWidth && 'image/jpeg' === mime_content_type($tmpFile)) {
|
||||||
Image::load($tmpFile)->width($maxWidth)->save();
|
Image::load($tmpFile)->width($maxWidth)->save();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Zoomyboy\MedialibraryHelper\Tests\Feature;
|
|
||||||
|
|
||||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
||||||
use Zoomyboy\MedialibraryHelper\Tests\TestCase;
|
|
||||||
|
|
||||||
class MiddlewareTest extends TestCase
|
|
||||||
{
|
|
||||||
|
|
||||||
use RefreshDatabase;
|
|
||||||
|
|
||||||
public function testItReturns401WhenNotLoggedIn(): void
|
|
||||||
{
|
|
||||||
$this->registerModel();
|
|
||||||
$post = $this->newPost();
|
|
||||||
|
|
||||||
$response = $this->postJson('/mediaupload', [
|
|
||||||
'model' => 'post',
|
|
||||||
'id' => $post->id,
|
|
||||||
'collection' => 'defaultSingleFile',
|
|
||||||
'content' => base64_encode($this->pdfFile()->getContent()),
|
|
||||||
'name' => 'beispiel bild.jpg',
|
|
||||||
]);
|
|
||||||
|
|
||||||
$response->assertStatus(401);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function testItReturns401WhenDestroying(): void
|
|
||||||
{
|
|
||||||
$this->registerModel();
|
|
||||||
$post = $this->newPost();
|
|
||||||
$media = $post->addMedia($this->pdfFile()->getPathname())->toMediaCollection('defaultSingleFile');
|
|
||||||
|
|
||||||
$response = $this->deleteJson("/mediaupload/{$media->id}");
|
|
||||||
|
|
||||||
$response->assertStatus(401);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function defineEnvironment($app)
|
|
||||||
{
|
|
||||||
$app['config']->set('media-library.middleware', ['web', 'auth:web']);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -35,6 +35,22 @@ test('it uploads a single file to a single file collection', function () {
|
||||||
$response->assertJsonMissingPath('model_id');
|
$response->assertJsonMissingPath('model_id');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('it uploads heig image', function () {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$content = base64_encode($this->getFile('heic.jpg', 'heic.jpg')->getContent());
|
||||||
|
|
||||||
|
$this->postJson('/mediaupload', [
|
||||||
|
'model' => 'post',
|
||||||
|
'id' => $post->id,
|
||||||
|
'collection' => 'conversionsWithDefault',
|
||||||
|
'payload' => [
|
||||||
|
'content' => $content,
|
||||||
|
'name' => 'beispiel bild.jpg',
|
||||||
|
],
|
||||||
|
])->assertStatus(201);
|
||||||
|
});
|
||||||
|
|
||||||
test('it uploads a single image to a single file collection', function () {
|
test('it uploads a single image to a single file collection', function () {
|
||||||
$this->auth()->registerModel();
|
$this->auth()->registerModel();
|
||||||
$post = $this->newPost();
|
$post = $this->newPost();
|
||||||
|
@ -233,14 +249,14 @@ test('it returns 403 when not authorized', function () {
|
||||||
$post = $this->newPost();
|
$post = $this->newPost();
|
||||||
|
|
||||||
$response = $this->postJson('/mediaupload', [
|
$response = $this->postJson('/mediaupload', [
|
||||||
'model' => 'post',
|
'model' => 'post',
|
||||||
'id' => $post->id,
|
'id' => $post->id,
|
||||||
'collection' => 'defaultSingleFile',
|
'collection' => 'defaultSingleFile',
|
||||||
'payload' => [
|
'payload' => [
|
||||||
'content' => base64_encode($this->pdfFile()->getContent()),
|
'content' => base64_encode($this->pdfFile()->getContent()),
|
||||||
'name' => 'beispiel bild.jpg',
|
'name' => 'beispiel bild.jpg',
|
||||||
],
|
],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$response->assertStatus(403);
|
$response->assertStatus(403);
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,20 +23,20 @@ class Post extends Model implements HasMedia
|
||||||
$this->addMediaCollection('defaultSingleFile')->maxWidth(fn () => 250)->singleFile();
|
$this->addMediaCollection('defaultSingleFile')->maxWidth(fn () => 250)->singleFile();
|
||||||
|
|
||||||
$this->addMediaCollection('conversionsWithDefault')
|
$this->addMediaCollection('conversionsWithDefault')
|
||||||
->singleFile()
|
->singleFile()
|
||||||
->withFallback(fn ($parent) => ['default.jpg', 'public'])
|
->withFallback(fn ($parent) => ['default.jpg', 'public'])
|
||||||
->registerMediaConversions(function () {
|
->registerMediaConversions(function () {
|
||||||
$this->addMediaConversion('tiny')->width(200)->height(200);
|
$this->addMediaConversion('tiny')->width(200)->height(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addMediaCollection('images')->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
$this->addMediaCollection('images')->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
||||||
|
|
||||||
$this->addMediaCollection('singleForced')->singleFile()->forceFileName(function ($model, $name) {
|
$this->addMediaCollection('singleForced')->singleFile()->forceFileName(function ($model, $name) {
|
||||||
return $name.' '.now()->format('Y-m-d');
|
return $name . ' ' . now()->format('Y-m-d');
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addMediaCollection('multipleForced')->forceFileName(function ($model, $name) {
|
$this->addMediaCollection('multipleForced')->forceFileName(function ($model, $name) {
|
||||||
return $name.' '.now()->format('Y-m-d');
|
return $name . ' ' . now()->format('Y-m-d');
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addMediaCollection('singleStoringHook')->singleFile()->storing(function ($adder, $fileName) {
|
$this->addMediaCollection('singleStoringHook')->singleFile()->storing(function ($adder, $fileName) {
|
||||||
|
@ -49,18 +49,18 @@ class Post extends Model implements HasMedia
|
||||||
$this->addMediaCollection('singleWithEvent')->singleFile()->stored(function (Media $media) {
|
$this->addMediaCollection('singleWithEvent')->singleFile()->stored(function (Media $media) {
|
||||||
Event::dispatch(new MediaStored($media));
|
Event::dispatch(new MediaStored($media));
|
||||||
})
|
})
|
||||||
->destroyed(fn ($model) => Event::dispatch(new MediaDestroyed($model)))
|
->destroyed(fn ($model) => Event::dispatch(new MediaDestroyed($model)))
|
||||||
->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
||||||
|
|
||||||
$this->addMediaCollection('multipleFilesWithEvent')->stored(function (Media $media) {
|
$this->addMediaCollection('multipleFilesWithEvent')->stored(function (Media $media) {
|
||||||
Event::dispatch(new MediaStored($media));
|
Event::dispatch(new MediaStored($media));
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->addMediaCollection('multipleProperties')->singleFile()->withDefaultProperties(fn ($path) => [
|
$this->addMediaCollection('multipleProperties')->singleFile()->withDefaultProperties(fn ($path, $pathinfo) => [
|
||||||
'test' => Str::camel($path),
|
'test' => Str::camel($path),
|
||||||
])->withPropertyValidation(fn ($path) => [
|
])->withPropertyValidation(fn ($path) => [
|
||||||
'test' => 'string|max:10',
|
'test' => 'string|max:10',
|
||||||
])
|
])
|
||||||
->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
->after(fn ($model) => Event::dispatch(new MediaChange($model)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@ class TestCase extends BaseTestCase
|
||||||
*/
|
*/
|
||||||
protected function defineDatabaseMigrations(): void
|
protected function defineDatabaseMigrations(): void
|
||||||
{
|
{
|
||||||
$this->loadMigrationsFrom(__DIR__.'/migrations');
|
$this->loadMigrationsFrom(__DIR__ . '/migrations');
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getPackageProviders($app): array
|
protected function getPackageProviders($app): array
|
||||||
|
@ -44,8 +44,8 @@ class TestCase extends BaseTestCase
|
||||||
|
|
||||||
protected function getFile(string $location, string $as): File
|
protected function getFile(string $location, string $as): File
|
||||||
{
|
{
|
||||||
$path = __DIR__.'/stubs/'.$location;
|
$path = __DIR__ . '/stubs/' . $location;
|
||||||
$to = sys_get_temp_dir().'/'.$as;
|
$to = sys_get_temp_dir() . '/' . $as;
|
||||||
copy($path, $to);
|
copy($path, $to);
|
||||||
|
|
||||||
return new File($to);
|
return new File($to);
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue