-
Notifications
You must be signed in to change notification settings - Fork 297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use getKeyName to determine key to support UUID based Media models #307
base: master
Are you sure you want to change the base?
Use getKeyName to determine key to support UUID based Media models #307
Conversation
Also on download action it uses the id column not the uuid column. SingleFile uses this.image.id should be able to pass the this.image.uuid or perhaps can improve the DownloadMediaController return $model::find($mediaId); To return $model::where('id', $mediaId)->first(); I was able to extend the models and controller and use an alias for the controller. AppServiceProvider.php in the register function $loader = AliasLoader::getInstance();
$loader->alias('Ebess\AdvancedNovaMediaLibrary\Http\Controllers\DownloadMediaController', \App\Nova\Controllers\DownloadMediaController::class); App\Nova\Controllers\DownloadMediaController.php <?php
namespace App\Nova\Controllers;
use App\Http\Controllers\Controller;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
}
```class DownloadMediaController extends Controller
{
public function show($mediaId)
{
$model = config('media-library.media_model') ?: Media;
return $model::where('id', $mediaId)->first();
}
} The guts of the models looks like this for each had to copy the private methods... <?php
namespace App\Nova\Fields;
use Ebess\AdvancedNovaMediaLibrary\Fields\HandlesExistingMediaTrait;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Http\Requests\NovaRequest;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\FileAdder;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class Media extends \Ebess\AdvancedNovaMediaLibrary\Fields\Media
{
use HandlesExistingMediaTrait;
// TODO: Make this a trait.
protected function handleMedia(NovaRequest $request, $model, $attribute, $data)
{
$remainingIds = $this->removeDeletedMedia($data, $model->getMedia($attribute));
$newIds = $this->addNewMedia($request, $data, $model, $attribute);
$existingIds = $this->addExistingMedia($request, $data, $model, $attribute, $model->getMedia($attribute));
$this->setOrder($remainingIds->union($newIds)->union($existingIds)->sortKeys()->all());
}
// Round about way of applying a fix for uuid mentioned here: https://github.com/ebess/advanced-nova-media-library/pull/307/commits/eb413b16c8af1991353087c0cc09f0212f6c044b
private function removeDeletedMedia($data, Collection $medias): Collection
{
$remainingIds = collect($data)->filter(function ($value) {
// New files will come in as UploadedFile objects,
// whereas Vapor-uploaded files will come in as arrays.
return ! $value instanceof UploadedFile
&& ! is_array($value);
});
$mediaClass = config('media-library.media_model');
$key = app($mediaClass)->getKeyName();
$medias->pluck($key)->diff($remainingIds)->each(function ($id) use ($medias, $key) {
/** @var \Ebess\AdvancedNovaMediaLibrary\Fields\Media $media */
if ($media = $medias->where($key, $id)->first()) {
$media->delete();
}
});
return $remainingIds->intersect($medias->pluck($key));
}
private function addNewMedia(NovaRequest $request, $data, HasMedia $model, string $collection): Collection
{
return collect($data)
->filter(function ($value) {
// New files will come in as UploadedFile objects,
// whereas Vapor-uploaded files will come in as arrays.
return $value instanceof UploadedFile || is_array($value);
})->map(function ($file, int $index) use ($request, $model, $collection) {
if ($file instanceof UploadedFile) {
$media = $model->addMedia($file)->withCustomProperties($this->customProperties);
$fileName = $file->getClientOriginalName();
$fileExtension = $file->getClientOriginalExtension();
} else {
$media = $this->makeMediaFromVaporUpload($file, $model);
$fileName = $file['file_name'];
$fileExtension = pathinfo($file['file_name'], PATHINFO_EXTENSION);
}
if ($this->responsive) {
$media->withResponsiveImages();
}
if (! empty($this->customHeaders)) {
$media->addCustomHeaders($this->customHeaders);
}
if (is_callable($this->setFileNameCallback)) {
$media->setFileName(
call_user_func($this->setFileNameCallback, $fileName, $fileExtension, $model)
);
}
if (is_callable($this->setNameCallback)) {
$media->setName(
call_user_func($this->setNameCallback, $fileName, $model)
);
}
$media = $media->toMediaCollection($collection);
// fill custom properties for recently created media
$this->fillMediaCustomPropertiesFromRequest($request, $media, $index, $collection);
return $media->getKey();
});
}
/**
* This creates a Media object from a previously, client-side, uploaded file.
* The file is uploaded using a pre-signed S3 URL, via Vapor.store.
* This method will use addMediaFromUrl(), passing it the
* temporary location of the file.
*/
private function makeMediaFromVaporUpload(array $file, HasMedia $model): FileAdder
{
$diskName = config('filesystems.default');
$disk = config('filesystems.disks.' . $diskName . 'driver') === 's3' ? $diskName : 's3';
$url = Storage::disk($disk)->temporaryUrl($file['key'], Carbon::now()->addHour());
return $model->addMediaFromUrl($url)
->usingFilename($file['file_name']);
}
/**
* @param \Spatie\MediaLibrary\Models\Media $media
*/
private function fillMediaCustomPropertiesFromRequest(NovaRequest $request, $media, int $index, string $collection)
{
// prevent overriding the custom properties set by other processes like generating convesions
$media->refresh();
/** @var Field $field */
foreach ($this->customPropertiesFields as $field) {
$targetAttribute = "custom_properties->{$field->attribute}";
$requestAttribute = "__media-custom-properties__.{$collection}.{$index}.{$field->attribute}";
$field->fillInto($request, $media, $targetAttribute, $requestAttribute);
}
$media->save();
}
private function setOrder($ids)
{
$mediaClass = config('media-library.media_model');
$mediaClass::setNewOrder($ids);
}
} |
When overriding the default media-library Media model with a custom class that overrides
$primaryKey
, saving an entity in Nova without changing the image can trigger aCall to a member function determineOrderColumnName() on null
in./vendor/spatie/laravel-medialibrary/src/MediaCollections/Models/Concerns/IsSorted.php
. This is because in./src/Fields/Media.php
the name of the primary key is assumed to beid
. This pull request fixes that.