new: [localTools] Setting validation
parent
bc7e2baf83
commit
d9bef3dc0c
|
@ -184,7 +184,7 @@ class CRUDComponent extends Component
|
|||
$this->Controller->set('entity', $data);
|
||||
}
|
||||
|
||||
private function prepareValidationMessage($errors)
|
||||
public function prepareValidationMessage($errors)
|
||||
{
|
||||
$validationMessage = '';
|
||||
if (!empty($errors)) {
|
||||
|
@ -280,8 +280,9 @@ class CRUDComponent extends Component
|
|||
$validationErrors = $data->getErrors();
|
||||
$validationMessage = $this->prepareValidationMessage($validationErrors);
|
||||
$message = __(
|
||||
__('{0} could not be modified.'),
|
||||
$this->ObjectAlias
|
||||
'{0} could not be modified.{1}',
|
||||
$this->ObjectAlias,
|
||||
empty($validationMessage) ? '' : PHP_EOL . __('Reason:{0}', $validationMessage)
|
||||
);
|
||||
if ($this->Controller->ParamHandler->isRest()) {
|
||||
} else if ($this->Controller->ParamHandler->isAjax()) {
|
||||
|
|
|
@ -152,9 +152,6 @@ class LocalToolsController extends AppController
|
|||
if (!empty($responsePayload)) {
|
||||
return $responsePayload;
|
||||
}
|
||||
if ($this->ParamHandler->isAjax() && !empty($this->ajaxResponsePayload)) {
|
||||
return $this->ajaxResponsePayload;
|
||||
}
|
||||
$localConnectors = $this->LocalTools->extractMeta($this->LocalTools->getConnectors());
|
||||
$dropdownData = ['connectors' => []];
|
||||
$connector = false;
|
||||
|
|
|
@ -97,26 +97,29 @@ class MispConnector extends CommonConnectorTools
|
|||
]
|
||||
];
|
||||
public $version = '0.1';
|
||||
public $parameters = [
|
||||
public $settings = [
|
||||
'url' => [
|
||||
'required' => true,
|
||||
// 'validation' => 'url',
|
||||
'type' => 'text'
|
||||
],
|
||||
'authkey' => [
|
||||
'required' => true,
|
||||
// 'validation' => 'authkeyLength',
|
||||
'type' => 'text'
|
||||
],
|
||||
'skip_ssl' => [
|
||||
// 'validation' => 'boolean',
|
||||
'type' => 'boolean'
|
||||
],
|
||||
'test_param' => [
|
||||
'options' => [
|
||||
'John',
|
||||
'Doe'
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
public function addSettingValidatorRules($validator)
|
||||
{
|
||||
return $validator
|
||||
->requirePresence('url')
|
||||
->notEmpty('url', __('An URL must be provided'))
|
||||
->requirePresence('authkey')
|
||||
->notEmpty('authkey', __('An Authkey must be provided'))
|
||||
->lengthBetween('authkey', [40, 40], __('The authkey must be 40 character long'))
|
||||
->boolean('skip_ssl');
|
||||
}
|
||||
|
||||
public function addExposedFunction(string $functionName): void
|
||||
{
|
||||
$this->exposedFunctions[] = $functionName;
|
||||
|
|
|
@ -4,6 +4,7 @@ namespace App\Model\Table;
|
|||
|
||||
use App\Model\Table\AppTable;
|
||||
use Cake\ORM\Table;
|
||||
use Cake\ORM\RulesChecker;
|
||||
use Cake\Validation\Validator;
|
||||
use Migrations\Migrations;
|
||||
use Cake\Filesystem\Folder;
|
||||
|
@ -33,7 +34,14 @@ class LocalToolsTable extends AppTable
|
|||
|
||||
public function validationDefault(Validator $validator): Validator
|
||||
{
|
||||
return $validator;
|
||||
return $validator->add('settings', 'validSettings', [
|
||||
'rule' => 'isValidSettings',
|
||||
'provider' => 'table',
|
||||
'message' => __('Invalid settings'),
|
||||
'on' => function ($context) {
|
||||
return !empty($context['data']['settings']);
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
public function loadConnector(string $connectorName): void
|
||||
|
@ -133,7 +141,7 @@ class LocalToolsTable extends AppTable
|
|||
'connector' => $connector_type,
|
||||
'connector_version' => $connector_class->version,
|
||||
'connector_description' => $connector_class->description,
|
||||
'connector_parameters' => $connector_class->parameters ?? []
|
||||
'connector_settings' => $connector_class->settings ?? []
|
||||
];
|
||||
if ($includeConnections) {
|
||||
$connector['connections'] = $this->healthCheck($connector_type, $connector_class);
|
||||
|
@ -298,4 +306,32 @@ class LocalToolsTable extends AppTable
|
|||
}
|
||||
return $connection;
|
||||
}
|
||||
|
||||
public function isValidSettings($settings, array $context)
|
||||
{
|
||||
$settings = json_decode($settings, true);
|
||||
$validationErrors = $this->getLocalToolsSettingValidationErrors($context['data']['id'], $settings);
|
||||
return $this->getValidationMessage($validationErrors);
|
||||
}
|
||||
|
||||
public function getValidationMessage($validationErrors)
|
||||
{
|
||||
$messages = [];
|
||||
foreach ($validationErrors as $key => $errors) {
|
||||
$messages[] = sprintf('%s: %s', $key, implode(', ', $errors));
|
||||
}
|
||||
return empty($messages) ? true : implode('; ', $messages);
|
||||
}
|
||||
|
||||
public function getLocalToolsSettingValidationErrors($connectionId, array $settings): array
|
||||
{
|
||||
$connector = array_values($this->getConnectorByConnectionId($connectionId))[0];
|
||||
$errors = [];
|
||||
if (method_exists($connector, 'addSettingValidatorRules')) {
|
||||
$validator = new Validator();
|
||||
$validator = $connector->addSettingValidatorRules($validator);
|
||||
$errors = $validator->validate($settings);
|
||||
}
|
||||
return $errors;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
'type' => 'codemirror',
|
||||
'codemirror' => [
|
||||
'height' => '10rem',
|
||||
'hints' => $connectors[0]['connector_parameters']
|
||||
'hints' => $connectors[0]['connector_settings']
|
||||
]
|
||||
],
|
||||
[
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
<?php
|
||||
// $randomVal = Cake\Utility\Security::randomString(8);
|
||||
// $params['type'] = 'textarea';
|
||||
// $textareaClass = "area-for-codemirror-{$randomVal}";
|
||||
// $params['class'] = [$textareaClass];
|
||||
// echo $this->FormFieldMassage->prepareFormElement($this->Form, $params, $fieldData);
|
||||
echo $this->element('genericElements/codemirror', [
|
||||
'data' => $fieldData,
|
||||
'params' => $params,
|
||||
|
|
|
@ -68,9 +68,23 @@
|
|||
}
|
||||
cm.save()
|
||||
})
|
||||
registerObserver(cm, $textArea[0])
|
||||
synchronizeClasses(cm, $textArea[0])
|
||||
postInit()
|
||||
}
|
||||
|
||||
// Used to synchronize textarea classes (such as `is-invalid` for content validation)
|
||||
function registerObserver(cm, textarea) {
|
||||
const observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName == 'class') {
|
||||
synchronizeClasses(cm, textarea)
|
||||
}
|
||||
});
|
||||
});
|
||||
observer.observe(textarea, {attributes: true})
|
||||
}
|
||||
|
||||
function postInit() {
|
||||
if ($(cm.getInputField()).closest('.modal').length) { // editor is in modal
|
||||
setTimeout(() => {
|
||||
|
@ -79,6 +93,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
function synchronizeClasses(cm, textarea) {
|
||||
const classes = Array.from(textarea.classList).filter(c => !c.startsWith('area-for-codemirror'))
|
||||
const $wrapper = $(cm.getWrapperElement())
|
||||
classes.forEach(c => {
|
||||
$wrapper.toggleClass(c)
|
||||
});
|
||||
}
|
||||
|
||||
function jsonHints() {
|
||||
const cur = cm.getCursor()
|
||||
const token = cm.getTokenAt(cur)
|
||||
|
@ -130,7 +152,7 @@
|
|||
if (str.length > 0) {
|
||||
let validHints = []
|
||||
let hint
|
||||
for (let i = 0; hints.length < cmOptions.hintOptions.maxHints && i < validHints.length; i++) {
|
||||
for (let i = 0; validHints.length < cmOptions.hintOptions.maxHints && i < hints.length; i++) {
|
||||
if (hints[i].text.startsWith(str)) {
|
||||
validHints.push(hints[i])
|
||||
}
|
||||
|
|
|
@ -6,3 +6,24 @@
|
|||
.CodeMirror-gutters {
|
||||
border-radius: 0.25rem 0 0 0.25rem;
|
||||
}
|
||||
|
||||
.CodeMirror.is-invalid {
|
||||
border-color: #dc3545;
|
||||
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
|
||||
background-repeat: no-repeat;
|
||||
background-position: right calc(0.375em + 0.1875rem) center;
|
||||
background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem);
|
||||
background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem);
|
||||
}
|
||||
|
||||
.CodeMirror.is-invalid .CodeMirror-gutters {
|
||||
/* background-color: #dc3545 !important; */
|
||||
}
|
||||
|
||||
.CodeMirror.is-invalid .CodeMirror-linenumber {
|
||||
/* color: white !important; */
|
||||
}
|
||||
|
||||
.CodeMirror-hints {
|
||||
z-index: 1060 !important; /* Make sure hint is above modal */
|
||||
}
|
Loading…
Reference in New Issue