Add default file
This commit is contained in:
parent
9d8ae685f6
commit
47c734dfd4
|
@ -34,6 +34,11 @@ class CollectionExtension
|
||||||
return fn ($callback) => $this->registerCustomCallback('withPropertyValidation', $callback);
|
return fn ($callback) => $this->registerCustomCallback('withPropertyValidation', $callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function withFallback()
|
||||||
|
{
|
||||||
|
return fn ($callback) => $this->registerCustomCallback('withFallback', $callback);
|
||||||
|
}
|
||||||
|
|
||||||
public function runCallback()
|
public function runCallback()
|
||||||
{
|
{
|
||||||
return function (string $callback, ...$parameters) {
|
return function (string $callback, ...$parameters) {
|
||||||
|
@ -65,6 +70,7 @@ class CollectionExtension
|
||||||
'storing' => fn ($adder, $name) => $adder,
|
'storing' => fn ($adder, $name) => $adder,
|
||||||
'withDefaultProperties' => fn ($path) => [],
|
'withDefaultProperties' => fn ($path) => [],
|
||||||
'withPropertyValidation' => fn ($path) => [],
|
'withPropertyValidation' => fn ($path) => [],
|
||||||
|
'withFallback' => fn ($parent) => null,
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,18 +74,23 @@ class MediaController
|
||||||
return MediaData::from($media);
|
return MediaData::from($media);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index(Request $request, $parentModel, int $parentId, string $collection): MediaData|DataCollection
|
public function index(Request $request, $parentModel, int $parentId, string $collectionName): MediaData|DataCollection
|
||||||
{
|
{
|
||||||
$model = app('media-library-helpers')->get($parentModel);
|
$model = app('media-library-helpers')->get($parentModel);
|
||||||
$model = $model::find($parentId);
|
$model = $model::find($parentId);
|
||||||
$this->authorize('listMedia', $model);
|
$this->authorize('listMedia', $model);
|
||||||
$isSingle = 1 === $model->getMediaCollection($collection)->collectionSizeLimit;
|
$collection = $model->getMediaCollection($collectionName);
|
||||||
|
$isSingle = 1 === $collection->collectionSizeLimit;
|
||||||
|
|
||||||
abort_if($isSingle && !$model->getFirstMedia($collection), 404);
|
abort_if($isSingle && !$model->getFirstMedia($collectionName) && !MediaData::defaultFromCollection($model, $collection), 404);
|
||||||
|
|
||||||
|
if ($isSingle && !$model->getFirstMedia($collectionName)) {
|
||||||
|
return MediaData::defaultFromCollection($model, $collection);
|
||||||
|
}
|
||||||
|
|
||||||
return $isSingle
|
return $isSingle
|
||||||
? MediaData::from($model->getFirstMedia($collection))
|
? MediaData::from($model->getFirstMedia($collectionName))
|
||||||
: MediaData::collection($model->getMedia($collection));
|
: MediaData::collection($model->getMedia($collectionName));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function destroy(Media $media, Request $request): JsonResponse
|
public function destroy(Media $media, Request $request): JsonResponse
|
||||||
|
|
|
@ -2,17 +2,20 @@
|
||||||
|
|
||||||
namespace Zoomyboy\MedialibraryHelper;
|
namespace Zoomyboy\MedialibraryHelper;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Spatie\LaravelData\Attributes\MapInputName;
|
use Spatie\LaravelData\Attributes\MapInputName;
|
||||||
use Spatie\LaravelData\Attributes\MapOutputName;
|
use Spatie\LaravelData\Attributes\MapOutputName;
|
||||||
use Spatie\LaravelData\Data;
|
use Spatie\LaravelData\Data;
|
||||||
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
use Spatie\LaravelData\Mappers\SnakeCaseMapper;
|
||||||
|
use Spatie\MediaLibrary\HasMedia;
|
||||||
|
use Spatie\MediaLibrary\MediaCollections\MediaCollection;
|
||||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||||
|
|
||||||
#[MapInputName(SnakeCaseMapper::class)]
|
#[MapInputName(SnakeCaseMapper::class)]
|
||||||
#[MapOutputName(SnakeCaseMapper::class)]
|
#[MapOutputName(SnakeCaseMapper::class)]
|
||||||
class MediaData extends Data
|
class MediaData extends Data
|
||||||
{
|
{
|
||||||
public int $id;
|
public ?int $id;
|
||||||
|
|
||||||
public string $originalUrl;
|
public string $originalUrl;
|
||||||
|
|
||||||
|
@ -27,8 +30,36 @@ class MediaData extends Data
|
||||||
#[MapInputName('custom_properties')]
|
#[MapInputName('custom_properties')]
|
||||||
public array $properties;
|
public array $properties;
|
||||||
|
|
||||||
|
public array $conversions = [];
|
||||||
|
|
||||||
public static function fromMedia(Media $media): self
|
public static function fromMedia(Media $media): self
|
||||||
{
|
{
|
||||||
return self::withoutMagicalCreationFrom($media);
|
$conversions = collect($media->getMediaConversionNames())->flip()->map(fn ($integer, $conversion) => [
|
||||||
|
'original_url' => $media->getFullUrl($conversion),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return self::withoutMagicalCreationFrom([
|
||||||
|
...$media->toArray(),
|
||||||
|
'conversions' => $conversions->toArray(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function defaultFromCollection(HasMedia $parent, MediaCollection $collection): ?self
|
||||||
|
{
|
||||||
|
$default = $collection->runCallback('withFallback', $parent);
|
||||||
|
|
||||||
|
if (is_null($default)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return static::from([
|
||||||
|
'id' => null,
|
||||||
|
'originalUrl' => Storage::disk($default[1])->url($default[0]),
|
||||||
|
'size' => -1,
|
||||||
|
'collection_name' => $collection->name,
|
||||||
|
'name' => pathinfo($default[0], PATHINFO_FILENAME),
|
||||||
|
'file_name' => pathinfo($default[0], PATHINFO_BASENAME),
|
||||||
|
'properties' => [],
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ServiceProvider extends BaseServiceProvider
|
||||||
app(Router::class)->group($this->routeGroup(), function ($router) {
|
app(Router::class)->group($this->routeGroup(), function ($router) {
|
||||||
$router->post('mediaupload', [MediaController::class, 'store'])->name('media.store');
|
$router->post('mediaupload', [MediaController::class, 'store'])->name('media.store');
|
||||||
$router->delete('mediaupload/{media}', [MediaController::class, 'destroy'])->name('media.destroy');
|
$router->delete('mediaupload/{media}', [MediaController::class, 'destroy'])->name('media.destroy');
|
||||||
$router->get('mediaupload/{parent_model}/{parent_id}/{collection}', [MediaController::class, 'index'])->name('media.index');
|
$router->get('mediaupload/{parent_model}/{parent_id}/{collection_name}', [MediaController::class, 'index'])->name('media.index');
|
||||||
$router->patch('mediaupload/{media}', [MediaController::class, 'update'])->name('media.update');
|
$router->patch('mediaupload/{media}', [MediaController::class, 'update'])->name('media.update');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
namespace Zoomyboy\MedialibraryHelper\Tests\Feature;
|
namespace Zoomyboy\MedialibraryHelper\Tests\Feature;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\Storage;
|
||||||
|
|
||||||
test('it gets all medias', function () {
|
test('it gets all medias', function () {
|
||||||
$this->auth()->registerModel();
|
$this->auth()->registerModel();
|
||||||
$post = $this->newPost();
|
$post = $this->newPost();
|
||||||
|
@ -46,3 +48,27 @@ test('it returns 404 when media not found', function () {
|
||||||
|
|
||||||
$response->assertStatus(404);
|
$response->assertStatus(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('test it gets conversions for single media', function () {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
$media = $post->addMedia($this->jpgFile()->getPathname())->preservingOriginal()->toMediaCollection('conversionsWithDefault');
|
||||||
|
|
||||||
|
$response = $this->getJson("/mediaupload/post/{$post->id}/conversionsWithDefault");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('conversions.tiny.original_url', $media->getFullUrl('tiny'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('test it gets default single media', function () {
|
||||||
|
$this->auth()->registerModel();
|
||||||
|
$post = $this->newPost();
|
||||||
|
|
||||||
|
$response = $this->getJson("/mediaupload/post/{$post->id}/conversionsWithDefault");
|
||||||
|
|
||||||
|
$response->assertStatus(200);
|
||||||
|
$response->assertJsonPath('id', null);
|
||||||
|
$response->assertJsonPath('original_url', Storage::disk('public')->url('default.jpg'));
|
||||||
|
$response->assertJsonPath('name', 'default');
|
||||||
|
$response->assertJsonPath('file_name', 'default.jpg');
|
||||||
|
});
|
||||||
|
|
|
@ -20,6 +20,13 @@ class Post extends Model implements HasMedia
|
||||||
{
|
{
|
||||||
$this->addMediaCollection('defaultSingleFile')->singleFile();
|
$this->addMediaCollection('defaultSingleFile')->singleFile();
|
||||||
|
|
||||||
|
$this->addMediaCollection('conversionsWithDefault')
|
||||||
|
->singleFile()
|
||||||
|
->withFallback(fn ($parent) => ['default.jpg', 'public'])
|
||||||
|
->registerMediaConversions(function () {
|
||||||
|
$this->addMediaConversion('tiny')->width(200)->height(200);
|
||||||
|
});
|
||||||
|
|
||||||
$this->addMediaCollection('images');
|
$this->addMediaCollection('images');
|
||||||
|
|
||||||
$this->addMediaCollection('singleForced')->singleFile()->forceFileName(function ($name) {
|
$this->addMediaCollection('singleForced')->singleFile()->forceFileName(function ($name) {
|
||||||
|
|
|
@ -37,6 +37,11 @@ class TestCase extends BaseTestCase
|
||||||
return $this->getFile('pdf.pdf', $filename ?: 'pdf.pdf');
|
return $this->getFile('pdf.pdf', $filename ?: 'pdf.pdf');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function jpgFile(?string $filename = null): File
|
||||||
|
{
|
||||||
|
return $this->getFile('jpg.jpg', $filename ?: 'jpg.jpg');
|
||||||
|
}
|
||||||
|
|
||||||
protected function getFile(string $location, string $as): File
|
protected function getFile(string $location, string $as): File
|
||||||
{
|
{
|
||||||
$path = __DIR__.'/stubs/'.$location;
|
$path = __DIR__.'/stubs/'.$location;
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 177 KiB |
Loading…
Reference in New Issue