Skip to content
Snippets Groups Projects
Verified Commit 83f14fba authored by Damien's avatar Damien
Browse files

FEAT #13195 TIME 9:00 Custom fields sql

parent bad794e4
No related branches found
No related tags found
No related merge requests found
[
"users",
"entities"
]
......@@ -26,6 +26,7 @@ use Resource\models\ResModel;
use Respect\Validation\Validator;
use Slim\Http\Request;
use Slim\Http\Response;
use SrcCore\models\CoreConfigModel;
class CustomFieldController
{
......@@ -35,6 +36,15 @@ class CustomFieldController
foreach ($customFields as $key => $customField) {
$customFields[$key]['values'] = json_decode($customField['values'], true);
if (!empty($customFields[$key]['values']['table'])) {
$customFields[$key]['values'] = CustomFieldModel::getValuesSQL($customFields[$key]['values']);
} elseif (!empty($customFields[$key]['values'])) {
$values = $customFields[$key]['values'];
$customFields[$key]['values'] = [];
foreach ($values as $value) {
$customFields[$key]['values'][$value] = $value;
}
}
}
return $response->withJson(['customFields' => $customFields]);
......@@ -61,6 +71,13 @@ class CustomFieldController
return $response->withStatus(400)->withJson(['errors' => 'Custom field with this label already exists']);
}
if (!empty($body['values']['table'])) {
$control = CustomFieldController::controlSQLMode(['body' => $body]);
if (!empty($control['errors'])) {
return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
}
}
$id = CustomFieldModel::create([
'label' => $body['label'],
'type' => $body['type'],
......@@ -111,31 +128,39 @@ class CustomFieldController
return $response->withStatus(400)->withJson(['errors' => 'Custom field with this label already exists']);
}
if (in_array($field['type'], ['checkbox'])) {
$values = json_decode($field['values'], true);
foreach ($values as $key => $value) {
if (!empty($body['values'][$key]) && $body['values'][$key] != $value) {
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_insert(custom_fields, '{{$args['id']}, 0}', '\"{$body['values'][$key]}\"')"],
'where' => ["custom_fields->'{$args['id']}' @> ?"],
'data' => ["\"{$value}\""]
]);
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_set(custom_fields, '{{$args['id']}}', (custom_fields->'{$args['id']}') - '{$value}')"],
'where' => ['1 = ?'],
'data' => [1]
]);
}
if (!empty($body['values']['table'])) {
$control = CustomFieldController::controlSQLMode(['body' => $body]);
if (!empty($control['errors'])) {
return $response->withStatus(400)->withJson(['errors' => $control['errors']]);
}
} elseif (in_array($field['type'], ['select', 'radio'])) {
$values = json_decode($field['values'], true);
foreach ($values as $key => $value) {
if (!empty($body['values'][$key]) && $body['values'][$key] != $value) {
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_set(custom_fields, '{{$args['id']}}', '\"{$body['values'][$key]}\"')"],
'where' => ['1 = ?'],
'data' => [1]
]);
}
$values = json_decode($field['values'], true);
if (empty($body['values']['table']) && empty($values['table'])) {
if (in_array($field['type'], ['checkbox'])) {
foreach ($values as $key => $value) {
if (!empty($body['values'][$key]) && $body['values'][$key] != $value) {
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_insert(custom_fields, '{{$args['id']}, 0}', '\"{$body['values'][$key]}\"')"],
'where' => ["custom_fields->'{$args['id']}' @> ?"],
'data' => ["\"{$value}\""]
]);
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_set(custom_fields, '{{$args['id']}}', (custom_fields->'{$args['id']}') - '{$value}')"],
'where' => ['1 = ?'],
'data' => [1]
]);
}
}
} elseif (in_array($field['type'], ['select', 'radio'])) {
foreach ($values as $key => $value) {
if (!empty($body['values'][$key]) && $body['values'][$key] != $value) {
ResModel::update([
'postSet' => ['custom_fields' => "jsonb_set(custom_fields, '{{$args['id']}}', '\"{$body['values'][$key]}\"')"],
'where' => ['1 = ?'],
'data' => [1]
]);
}
}
}
}
......@@ -198,4 +223,46 @@ class CustomFieldController
return $response->withStatus(204);
}
public static function controlSQLMode(array $args)
{
$body = $args['body'];
if ($body['type'] == 'banAutocomplete') {
return ['errors' => 'SQL is not allowed for type BAN'];
}
if (!Validator::stringType()->notEmpty()->validate($body['values']['key'])) {
return ['errors' => 'Body values[key] is empty or not a string'];
} elseif (!Validator::stringType()->notEmpty()->validate($body['values']['label'])) {
return ['errors' => 'Body values[label] is empty or not a string'];
} elseif (!Validator::stringType()->notEmpty()->validate($body['values']['table'])) {
return ['errors' => 'Body values[table] is empty or not a string'];
} elseif (!Validator::stringType()->notEmpty()->validate($body['values']['clause'])) {
return ['errors' => 'Body values[clause] is empty or not a string'];
}
if (strpos($body['values']['key'], 'password') !== false || strpos($body['values']['key'], 'token') !== false) {
return ['errors' => 'Body values[key] is not allowed'];
} elseif (strpos($body['values']['label'], 'password') !== false || strpos($body['values']['label'], 'token') !== false) {
return ['errors' => 'Body values[key] is not allowed'];
}
$allowedTables = CoreConfigModel::getJsonLoaded(['path' => 'apps/maarch_entreprise/xml/customFieldsWhiteList.json']);
if (!in_array($body['values']['table'], $allowedTables)) {
return ['errors' => 'Body values[table] is not allowed'];
}
if (in_array($body['values']['type'], ['string', 'date', 'int'])) {
$limitPos = stripos($body['values']['clause'], 'limit');
if (!empty($limitPos)) {
$body['values']['clause'] = substr_replace($body['values']['clause'], 'LIMIT 1', $limitPos);
} else {
$body['values']['clause'] .= ' LIMIT 1';
}
}
try {
CustomFieldModel::getValuesSQL($body['values']);
} catch (\Exception $e) {
return ['errors' => 'Clause is not valid'];
}
return true;
}
}
......@@ -104,4 +104,19 @@ class CustomFieldModel
return true;
}
public static function getValuesSQL(array $args)
{
ValidatorModel::notEmpty($args, ['key', 'label', 'table', 'clause']);
ValidatorModel::stringType($args, ['key', 'label', 'table', 'clause']);
$values = DatabaseModel::select([
'select' => [$args['key'], $args['label']],
'table' => [$args['table']],
'where' => [$args['clause']],
]);
$values = array_column($values, $args['label'], $args['key']);
return $values;
}
}
......@@ -370,7 +370,11 @@ class ResourceControlController
}
if (!empty($body['customFields'][$customFieldId])) {
$customField = CustomFieldModel::getById(['id' => $customFieldId, 'select' => ['type', 'values']]);
$possibleValues = empty($customField['values']) ? [] : json_decode($customField['values']);
$possibleValues = empty($customField['values']) ? [] : json_decode($customField['values'], true);
if (!empty($possibleValues['table'])) {
$possibleValues = CustomFieldModel::getValuesSQL($possibleValues);
$possibleValues = array_keys($possibleValues);
}
if (($customField['type'] == 'select' || $customField['type'] == 'radio') && !in_array($body['customFields'][$customFieldId], $possibleValues)) {
return ['errors' => "Body customFields[{$customFieldId}] has wrong value"];
} elseif ($customField['type'] == 'checkbox') {
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment