n_oct/plugins/rainlab/builder/behaviors/IndexModelFormOperations.php

281 lines
8.9 KiB
PHP
Raw Normal View History

2023-06-17 20:52:33 +00:00
<?php namespace RainLab\Builder\Behaviors;
use RainLab\Builder\Classes\IndexOperationsBehaviorBase;
2023-06-18 12:28:15 +00:00
use RainLab\Builder\Classes\ModelFormModel;
use RainLab\Builder\Classes\PluginCode;
2023-06-17 20:52:33 +00:00
use RainLab\Builder\FormWidgets\FormBuilder;
2023-06-18 12:28:15 +00:00
use RainLab\Builder\Classes\ModelModel;
2023-06-17 20:52:33 +00:00
use RainLab\Builder\Classes\ControlLibrary;
use Backend\Classes\FormField;
use Backend\FormWidgets\DataTable;
2023-06-18 12:28:15 +00:00
use ApplicationException;
use Exception;
2023-06-17 20:52:33 +00:00
use Request;
use Flash;
use Input;
use Lang;
/**
* Model form management functionality for the Builder index controller
*
* @package rainlab\builder
* @author Alexey Bobkov, Samuel Georges
*/
class IndexModelFormOperations extends IndexOperationsBehaviorBase
{
2023-06-18 12:28:15 +00:00
protected $baseFormConfigFile = '~/plugins/rainlab/builder/classes/modelformmodel/fields.yaml';
2023-06-17 20:52:33 +00:00
public function __construct($controller)
{
parent::__construct($controller);
// Create the form builder instance to handle AJAX
// requests.
$defaultBuilderField = new FormField('default', 'default');
2023-06-18 12:28:15 +00:00
$formBulder = new FormBuilder($controller, $defaultBuilderField);
$formBulder->alias = 'defaultFormBuilder';
$formBulder->bindToController();
2023-06-17 20:52:33 +00:00
}
public function onModelFormCreateOrOpen()
{
$fileName = Input::get('file_name');
$modelClass = Input::get('model_class');
$pluginCodeObj = $this->getPluginCode();
$options = [
'pluginCode' => $pluginCodeObj->toCode(),
'modelClass' => $modelClass
];
$widget = $this->makeBaseFormWidget($fileName, $options);
$this->vars['fileName'] = $fileName;
$result = [
'tabTitle' => $widget->model->getDisplayName(Lang::get('rainlab.builder::lang.form.tab_new_form')),
'tabIcon' => 'icon-check-square',
'tabId' => $this->getTabId($modelClass, $fileName),
'tab' => $this->makePartial('tab', [
'form' => $widget,
'pluginCode' => $pluginCodeObj->toCode(),
'fileName' => $fileName,
'modelClass' => $modelClass
])
];
return $result;
}
public function onModelFormSave()
{
$model = $this->loadOrCreateFormFromPost();
$model->fill(post());
$model->save();
$result = $this->controller->widget->modelList->updateList();
Flash::success(Lang::get('rainlab.builder::lang.form.saved'));
$modelClass = Input::get('model_class');
$result['builderResponseData'] = [
'builderObjectName' => $model->fileName,
'tabId' => $this->getTabId($modelClass, $model->fileName),
'tabTitle' => $model->getDisplayName(Lang::get('rainlab.builder::lang.form.tab_new_form'))
];
$this->mergeRegistryDataIntoResult($result, $model, $modelClass);
return $result;
}
public function onModelFormDelete()
{
$model = $this->loadOrCreateFormFromPost();
$model->deleteModel();
$result = $this->controller->widget->modelList->updateList();
$modelClass = Input::get('model_class');
$this->mergeRegistryDataIntoResult($result, $model, $modelClass);
return $result;
}
public function onModelFormGetModelFields()
{
$columnNames = ModelModel::getModelFields($this->getPluginCode(), Input::get('model_class'));
$asPlainList = Input::get('as_plain_list');
$result = [];
foreach ($columnNames as $columnName) {
if (!$asPlainList) {
$result[] = [
'title' => $columnName,
'value' => $columnName
];
}
else {
$result[$columnName] = $columnName;
}
}
return [
'responseData' => [
'options' => $result
]
];
}
public function onModelShowAddDatabaseFieldsPopup()
{
$columns = ModelModel::getModelColumnsAndTypes($this->getPluginCode(), Input::get('model_class'));
$config = $this->makeConfig($this->getAddDatabaseFieldsDataTableConfig());
$field = new FormField('add_database_fields_datatable', 'add_database_fields_datatable');
$field->value = $this->getAddDatabaseFieldsDataTableValue($columns);
$datatable = new DataTable($this->controller, $field, $config);
$datatable->alias = 'add_database_fields_datatable';
$datatable->bindToController();
return $this->makePartial('add-database-fields-popup-form', [
'datatable' => $datatable,
'pluginCode' => $this->getPluginCode()->toCode(),
]);
}
protected function loadOrCreateFormFromPost()
{
$pluginCode = Request::input('plugin_code');
$modelClass = Input::get('model_class');
$fileName = Input::get('file_name');
$options = [
'pluginCode' => $pluginCode,
'modelClass' => $modelClass
];
return $this->loadOrCreateBaseModel($fileName, $options);
}
protected function getTabId($modelClass, $fileName)
{
if (!strlen($fileName)) {
return 'modelForm-'.uniqid(time());
}
return 'modelForm-'.$modelClass.'-'.$fileName;
}
protected function loadOrCreateBaseModel($fileName, $options = [])
{
$model = new ModelFormModel();
if (isset($options['pluginCode']) && isset($options['modelClass'])) {
$model->setPluginCode($options['pluginCode']);
$model->setModelClassName($options['modelClass']);
}
if (!$fileName) {
$model->initDefaults();
return $model;
}
$model->loadForm($fileName);
return $model;
}
protected function mergeRegistryDataIntoResult(&$result, $model, $modelClass)
{
if (!array_key_exists('builderResponseData', $result)) {
$result['builderResponseData'] = [];
}
$fullClassName = $model->getPluginCodeObj()->toPluginNamespace().'\\Models\\'.$modelClass;
$pluginCode = $model->getPluginCodeObj()->toCode();
$result['builderResponseData']['registryData'] = [
'forms' => ModelFormModel::getPluginRegistryData($pluginCode, $modelClass),
'pluginCode' => $pluginCode,
'modelClass' => $fullClassName
];
}
/**
2023-06-18 12:28:15 +00:00
* Returns the configuration for the DataTable widget that
* is used in the "add database fields" popup.
2023-06-17 20:52:33 +00:00
*
* @return array
*/
protected function getAddDatabaseFieldsDataTableConfig()
{
// Get all registered controls and build an array that uses the control types as key and value for each entry.
2023-06-18 12:28:15 +00:00
$controls = ControlLibrary::instance()->listControls();
2023-06-17 20:52:33 +00:00
$fieldTypes = array_merge(array_keys($controls['Standard']), array_keys($controls['Widgets']));
2023-06-18 12:28:15 +00:00
$options = array_combine($fieldTypes, $fieldTypes);
2023-06-17 20:52:33 +00:00
return [
'toolbar' => false,
'columns' => [
2023-06-18 12:28:15 +00:00
'add' => [
2023-06-17 20:52:33 +00:00
'title' => 'rainlab.builder::lang.common.add',
2023-06-18 12:28:15 +00:00
'type' => 'checkbox',
2023-06-17 20:52:33 +00:00
'width' => '50px',
],
'column' => [
2023-06-18 12:28:15 +00:00
'title' => 'rainlab.builder::lang.database.column_name_name',
2023-06-17 20:52:33 +00:00
'readOnly' => true,
],
'label' => [
'title' => 'rainlab.builder::lang.list.column_name_label',
],
'type' => [
2023-06-18 12:28:15 +00:00
'title' => 'rainlab.builder::lang.form.control_widget_type',
'type' => 'dropdown',
2023-06-17 20:52:33 +00:00
'options' => $options,
],
],
];
}
/**
2023-06-18 12:28:15 +00:00
* Returns the initial value for the DataTable widget that
2023-06-17 20:52:33 +00:00
* is used in the "add database columns" popup.
*
* @param array $columns
2023-06-18 12:28:15 +00:00
*
2023-06-17 20:52:33 +00:00
* @return array
*/
protected function getAddDatabaseFieldsDataTableValue(array $columns)
{
// Map database column types to widget types.
$typeMap = [
2023-06-18 12:28:15 +00:00
'string' => 'text',
'integer' => 'number',
'text' => 'textarea',
'timestamp' => 'datepicker',
2023-06-17 20:52:33 +00:00
'smallInteger' => 'number',
2023-06-18 12:28:15 +00:00
'bigInteger' => 'number',
'date' => 'datepicker',
'time' => 'datepicker',
'dateTime' => 'datepicker',
'binary' => 'checkbox',
'boolean' => 'checkbox',
'decimal' => 'number',
'double' => 'number',
2023-06-17 20:52:33 +00:00
];
2023-06-18 12:28:15 +00:00
return array_map(function ($column) use ($typeMap) {
2023-06-17 20:52:33 +00:00
return [
'column' => $column['name'],
2023-06-18 12:28:15 +00:00
'label' => str_replace('_', ' ', ucfirst($column['name'])),
'type' => $typeMap[$column['type']] ?? $column['type'],
'add' => false,
2023-06-17 20:52:33 +00:00
];
}, $columns);
}
}