-
Notifications
You must be signed in to change notification settings - Fork 317
/
Copy pathHandlesCustomPropertiesTrait.php
93 lines (76 loc) · 3.62 KB
/
HandlesCustomPropertiesTrait.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?php
namespace Ebess\AdvancedNovaMediaLibrary\Fields;
use Laravel\Nova\Fields\Field;
use Laravel\Nova\Http\Requests\NovaRequest;
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\FileBag;
/**
* @mixin Media
*/
trait HandlesCustomPropertiesTrait
{
protected $customPropertiesFields = [];
protected $customProperties = [];
public function customPropertiesFields(array $customPropertiesFields): self
{
$this->customPropertiesFields = collect($customPropertiesFields);
return $this->withMeta(compact('customPropertiesFields'));
}
public function customProperties(array $customProperties): self
{
$this->customProperties = $customProperties;
return $this;
}
/**
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param string $requestAttribute The form attribute of the media field.
* @param \Spatie\MediaLibrary\HasMedia $model The model which has associated media.
* @param string $collection The selected media collection.
*/
private function fillCustomPropertiesFromRequest(NovaRequest $request, string $requestAttribute, HasMedia $model, string $collection): void
{
// If we are dealing with nested resources or multiple panels, media fields are prefixed.
$key = str_replace($collection, '__media__.'.$collection, $requestAttribute);
$mediaItems = $model->getMedia($collection);
$items = $request->input($key, []);
// do not handle files as custom properties on files are not supported yet
if ($items instanceof FileBag) {
return;
}
collect($items)
->reject(function ($value) {
return $value instanceof UploadedFile || $value instanceof FileBag;
})
->each(function ($id, int $index) use ($request, $mediaItems, $collection, $requestAttribute) {
if (! $media = $mediaItems->where('id', $id)->first()) {
return;
}
$this->fillMediaCustomPropertiesFromRequest($request, $media, $index, $collection, $requestAttribute);
});
}
/**
* Fills custom properties for a given Media model from the request.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media The Media model with custom properties.
* @param int $index The file's index in the corresponding Media collection, to retrieve its custom properties from the request.
* @param string $collection The selected media collection.
* @param string $requestAttribute The form attribute of the media field.
*/
private function fillMediaCustomPropertiesFromRequest(NovaRequest $request, Media $media, int $index, string $collection, string $requestAttribute): void
{
// prevent overriding the custom properties set by other processes like generating conversions
$media->refresh();
/** @var Field $field */
foreach ($this->customPropertiesFields as $field) {
// If we are dealing with nested resources or multiple panels, custom property fields are prefixed.
$key = '__media-custom-properties__.' . $collection;
$targetAttribute = "custom_properties->{$field->attribute}";
$requestAttribute = "{$key}.{$index}.{$field->attribute}";
$field->fillInto($request, $media, $targetAttribute, $requestAttribute);
}
$media->save();
}
}