Add custom form fields/options to a File attachment
3
Create a Acme\Plugin\Models\FileOption
model (with a db table) then add a $belongsTo
relation to it:
public $belongsTo = [
'file' => \System\Models\File::class
];
In the plugin boot
method, add a $hasOne
relationship for the File
model:
File::extend(function ($model) {
$model->hasOne['file_option'] = [
\Acme\Plugin\Models\FileOption::class,
'key' => 'system_file_id'
];
// create the relation otherwise the file fields (title, description)
// aren't saved if the extended fields are empty
$model->bindEvent('model.beforeCreate', function() use ($model) {
$model->file_option = new \Acme\Plugin\Models\FileOption;
});
});
Extend the File
backend form with the fields you wish to add (also in the boot()
method):
Event::listen('backend.form.extendFields', function ($widget) {
if (!$widget->model instanceof \System\Models\File) return;
if (!$widget->getController() instanceof \Acme\Plugin\Models\YourModel) return;
$widget->addFields([
'file_option[color]' => [
'label' => 'Color',
'type' => 'colorpicker',
],
// ... other fields
]);
});
One problem I've noticed is that if any of the extended fields were empty the title and description field weren't saved upon change.
The solution for now was to create the relationship at file upload hence the code
$model->bindEvent('model.beforeCreate', function() use ($model){
$model->file_option = new \Acme\Plugin\Models\FileOption;
});
And for existing files I has to run this code once :
Event::listen('backend.form.extendFields', function ($widget) {
foreach (File::get() as $file) {
if ($file->file_option === null) {
$file->file_option = new \Acme\Plugin\Models\FileOption;
$file->save();
}
}
});
This way it works by storing the colorpicker field directly within the
system_files
table:Plugin.php
updates/add_color_column_to_system_files.php