From b8e21bb4b1512d5cd91e8e8b949553cb2a5d3116 Mon Sep 17 00:00:00 2001 From: David Cox Jr Date: Wed, 10 Oct 2018 08:59:15 -0400 Subject: [PATCH 1/3] Make customProperties work as expected I know you had said that this package will be left as is but I was hoping that wouldn't include PR's.... When using customProperties as it stands now, the expected results would be that the image shown would be the image with the customProperties only. That is not the case and although you can set the image and the customProperties are added, they aren't respected when looking up the image for detail or Form views. This just handles that particular case so that customProperties are expected. --- src/Fields/Image.php | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Fields/Image.php b/src/Fields/Image.php index 6557279..f93cf82 100644 --- a/src/Fields/Image.php +++ b/src/Fields/Image.php @@ -85,7 +85,20 @@ protected function fillAttributeFromRequest(NovaRequest $request, $requestAttrib protected function resolveAttribute($resource, $attribute) { $conversion = $this->meta()['usingConversion'] ?? []; - $media = $resource->getFirstMedia($this->mediaCollection); + $customProperties = $this->meta()['ml_withCustomProperties'] ?? []; + $media = $resource->getMedia($this->mediaCollection); + + if (!empty($customProperties)) { + $customProperties = array_first($customProperties) ?: []; + $media = $media->first(function ($image) use ($customProperties) { + foreach ($customProperties as $property => $value) { + $valid = ($valid ?? true) && ($image->getCustomProperty($property) == $value); + } + return $valid ?? false; + }); + } else { + $media = $media->first(); + } if ($media) { if ($media->hasGeneratedConversion($conversion)) { From 253723345871e4851761be2da1b60ce2368ef040 Mon Sep 17 00:00:00 2001 From: David Cox Date: Thu, 11 Oct 2018 09:26:58 -0400 Subject: [PATCH 2/3] fix bugs; enable File field to use the same customProperty logic --- resources/js/components/File/FormField.vue | 6 - resources/js/components/Image/FormField.vue | 6 - src/Fields/File.php | 102 +-------------- src/Fields/Image.php | 89 ++------------ src/Fields/MediaField.php | 130 ++++++++++++++++++++ 5 files changed, 143 insertions(+), 190 deletions(-) create mode 100644 src/Fields/MediaField.php diff --git a/resources/js/components/File/FormField.vue b/resources/js/components/File/FormField.vue index 18062c4..f3dade0 100644 --- a/resources/js/components/File/FormField.vue +++ b/resources/js/components/File/FormField.vue @@ -93,12 +93,6 @@ mounted() { this.field.fill = formData => { formData.append(this.field.attribute, this.file, this.fileName) - - for (let attribute in this.field) { - if (attribute.substr(0, 3) === 'ml_') { - formData.append(attribute, this.field[attribute]) - } - } } }, diff --git a/resources/js/components/Image/FormField.vue b/resources/js/components/Image/FormField.vue index ca2b70a..7fb835e 100644 --- a/resources/js/components/Image/FormField.vue +++ b/resources/js/components/Image/FormField.vue @@ -114,12 +114,6 @@ mounted() { this.field.fill = formData => { formData.append(this.field.attribute, this.file, this.fileName) - - for (let attribute in this.field) { - if (attribute.substr(0, 3) === 'ml_') { - formData.append(attribute, this.field[attribute]) - } - } } }, diff --git a/src/Fields/File.php b/src/Fields/File.php index d867046..9413616 100644 --- a/src/Fields/File.php +++ b/src/Fields/File.php @@ -2,17 +2,8 @@ namespace Kingsley\NovaMediaLibrary\Fields; -use Illuminate\Support\Str; -use Illuminate\Http\Request; -use Laravel\Nova\Fields\Field; -use Laravel\Nova\Fields\Deletable; -use Laravel\Nova\Http\Requests\NovaRequest; -use Laravel\Nova\Contracts\Deletable as DeletableContract; - -class File extends Field implements DeletableContract +class File extends MediaField { - use Deletable; - /** * The field's component. * @@ -20,94 +11,5 @@ class File extends Field implements DeletableContract */ public $component = 'nova-media-library-file-field'; - /** - * The media collection. - * - * @var string - */ - public $mediaCollection; - - /** - * Create a new field. - * - * @return void - */ - public function __construct(string $name, string $collection = 'default') - { - parent::__construct($name); - - $this->mediaCollection = $collection; - - $this->delete(function () { - // - }); - } - - /** - * Hydrate the given attribute on the model based on the incoming request. - * - * @param \Laravel\Nova\Http\Requests\NovaRequest $request - * @param string $requestAttribute - * @param object $model - * @param string $attribute - * @return void - */ - protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute) - { - if (! $request[$requestAttribute]) { - return; - } - - $request->validate([ - $requestAttribute => 'file' - ]); - - $query = $model->addMedia($request[$requestAttribute]); - - foreach ($request->all() as $key => $value) { - if (starts_with($key, 'ml_')) { - $method = substr($key, 3); - $arguments = is_array($value) ? $value : [$value]; - $query->$method(...$arguments); - } - } - - $query->toMediaCollection($this->mediaCollection); - } - - /** - * Resolve the given attribute from the given resource. - * - * @param mixed $resource - * @param string $attribute - * @return mixed - */ - protected function resolveAttribute($resource, $attribute) - { - $media = $resource->getFirstMedia($this->mediaCollection); - - return $media ?? null; - } - - /** - * Dynamically set a media-library setting on the field. - * - * @return $this - */ - public function __call($method, $arguments) - { - return $this->withMeta(['ml_' . $method => $arguments]); - } - - /** - * Get additional meta information to merge with the element payload. - * - * @return array - */ - public function meta() - { - return array_merge([ - 'deletable' => isset($this->deleteCallback) && $this->deletable - ], $this->meta); - } + protected $validationRules = ['file']; } diff --git a/src/Fields/Image.php b/src/Fields/Image.php index 39beb76..da66a9f 100644 --- a/src/Fields/Image.php +++ b/src/Fields/Image.php @@ -2,17 +2,10 @@ namespace Kingsley\NovaMediaLibrary\Fields; -use Illuminate\Support\Str; -use Illuminate\Http\Request; -use Laravel\Nova\Fields\Field; -use Laravel\Nova\Fields\Deletable; use Laravel\Nova\Http\Requests\NovaRequest; -use Laravel\Nova\Contracts\Deletable as DeletableContract; -class Image extends Field implements DeletableContract +class Image extends MediaField { - use Deletable; - /** * The field's component. * @@ -21,59 +14,11 @@ class Image extends Field implements DeletableContract public $component = 'nova-media-library-image-field'; /** - * The media collection. + * The validation rules. * - * @var string + * @var array */ - public $mediaCollection; - - /** - * Create a new field. - * - * @return void - */ - public function __construct(string $name, string $collection = 'default') - { - parent::__construct($name); - - $this->mediaCollection = $collection; - - $this->delete(function () { - // - }); - } - - /** - * Hydrate the given attribute on the model based on the incoming request. - * - * @param \Laravel\Nova\Http\Requests\NovaRequest $request - * @param string $requestAttribute - * @param object $model - * @param string $attribute - * @return void - */ - protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute) - { - if (! $request[$requestAttribute]) { - return; - } - - $request->validate([ - $requestAttribute => 'image' - ]); - - $query = $model->addMedia($request[$requestAttribute]); - - foreach ($request->all() as $key => $value) { - if (starts_with($key, 'ml_')) { - $method = substr($key, 3); - $arguments = is_array($value) ? $value : [$value]; - $query->$method(...$arguments); - } - } - - $query->toMediaCollection($this->mediaCollection); - } + protected $validationRules = ['image']; /** * Resolve the given attribute from the given resource. @@ -84,21 +29,9 @@ protected function fillAttributeFromRequest(NovaRequest $request, $requestAttrib */ protected function resolveAttribute($resource, $attribute) { - $conversion = $this->meta()['usingConversion'] ?? ''; - $customProperties = $this->meta()['ml_withCustomProperties'] ?? []; - $media = $resource->getMedia($this->mediaCollection); - - if (!empty($customProperties)) { - $customProperties = array_first($customProperties) ?: []; - $media = $media->first(function ($image) use ($customProperties) { - foreach ($customProperties as $property => $value) { - $valid = ($valid ?? true) && ($image->getCustomProperty($property) == $value); - } - return $valid ?? false; - }); - } else { - $media = $media->first(); - } + $media = parent::resolveAttribute($resource, $attribute); + + $conversion = $this->meta()['usingConversion'] ?? []; if ($media) { if ($media->hasGeneratedConversion($conversion)) { @@ -106,11 +39,9 @@ protected function resolveAttribute($resource, $attribute) } else { $media->preview_url = url($media->getUrl()); } - - return $media; } - return null; + return $media; } /** @@ -166,7 +97,9 @@ public function usingConversion(string $name) */ public function __call($method, $arguments) { - return $this->withMeta(['ml_' . $method => $arguments]); + $this->mediaLibraryMethods[$method] = $arguments; + + return $this; } /** diff --git a/src/Fields/MediaField.php b/src/Fields/MediaField.php new file mode 100644 index 0000000..65cf1ab --- /dev/null +++ b/src/Fields/MediaField.php @@ -0,0 +1,130 @@ +mediaCollection = $collection; + + $this->delete(function () { + // + }); + } + + /** + * Hydrate the given attribute on the model based on the incoming request. + * + * @param \Laravel\Nova\Http\Requests\NovaRequest $request + * @param string $requestAttribute + * @param object $model + * @param string $attribute + * @return void + */ + protected function fillAttributeFromRequest(NovaRequest $request, $requestAttribute, $model, $attribute) + { + if (! $request[$requestAttribute]) { + return; + } + + $request->validate([ + $requestAttribute => $this->validationRules + ]); + + $query = $model->addMedia($request[$requestAttribute]); + + foreach ($this->mediaLibraryMethods as $method => $arguments) { + $query->$method(...$arguments); + } + + $query->toMediaCollection($this->mediaCollection); + } + + /** + * Resolve the given attribute from the given resource. + * + * @param mixed $resource + * @param string $attribute + * @return mixed + */ + protected function resolveAttribute($resource, $attribute) + { + $customProperties = $this->mediaLibraryMethods['withCustomProperties'] ?? []; + $media = $resource->getMedia($this->mediaCollection); + + if (!empty($customProperties)) { + $customProperties = array_first($customProperties) ?: []; + $media = $media->first(function ($item) use ($customProperties) { + foreach ($customProperties as $property => $value) { + $valid = ($valid ?? true) && $item->getCustomProperty($property) == $value; + } + return $valid ?? false; + }); + } else { + $media = $media->first(); + } + + return $media ?? null; + } + + /** + * Dynamically set a media-library setting on the field. + * + * @return $this + */ + public function __call($method, $arguments) + { + $this->mediaLibraryMethods[$method] = $arguments; + + return $this; + } + + /** + * Get additional meta information to merge with the element payload. + * + * @return array + */ + public function meta() + { + return array_merge([ + 'deletable' => isset($this->deleteCallback) && $this->deletable + ], $this->meta); + } +} From 1f2f9c2873e7621d5c060cabcf94f88dd2125aa6 Mon Sep 17 00:00:00 2001 From: David Cox Date: Thu, 11 Oct 2018 09:40:14 -0400 Subject: [PATCH 3/3] keep the most recent fix from master --- src/Fields/MediaField.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fields/MediaField.php b/src/Fields/MediaField.php index 65cf1ab..6cc1c3f 100644 --- a/src/Fields/MediaField.php +++ b/src/Fields/MediaField.php @@ -86,7 +86,7 @@ protected function fillAttributeFromRequest(NovaRequest $request, $requestAttrib */ protected function resolveAttribute($resource, $attribute) { - $customProperties = $this->mediaLibraryMethods['withCustomProperties'] ?? []; + $customProperties = $this->mediaLibraryMethods['withCustomProperties'] ?? ''; $media = $resource->getMedia($this->mediaCollection); if (!empty($customProperties)) {