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_filestable:Plugin.php
updates/add_color_column_to_system_files.php