Refactor form property logic rule to load condition mapping from external JSON file (#698)

* Refactor form property logic rule to load condition mapping from external JSON file

* fix CONDITION_MAPPING

* use config file for load mapping

* Simplify condition mapping retrieval in FormPropertyLogicRule

---------

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag Chhatrala 2025-02-15 04:02:55 +05:30 committed by GitHub
parent 82fae97a3e
commit e7585c32d3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 23 additions and 664 deletions

View File

@ -18,661 +18,12 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule
'disable-block',
];
public const CONDITION_MAPPING = [
'text' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
],
'does_not_equal' => [
'expected_type' => 'string',
],
'contains' => [
'expected_type' => 'string',
],
'does_not_contain' => [
'expected_type' => 'string',
],
'starts_with' => [
'expected_type' => 'string',
],
'ends_with' => [
'expected_type' => 'string',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
'matches_regex' => [
'expected_type' => 'string',
'format' => [
'type' => 'regex'
]
],
'does_not_match_regex' => [
'expected_type' => 'string',
'format' => [
'type' => 'regex'
]
],
],
],
'matrix' => [
'comparators' => [
'equals' => [
'expected_type' => 'object',
'format' => [
'type' => 'object',
],
],
'does_not_equal' => [
'expected_type' => 'object',
'format' => [
'type' => 'object',
],
],
'contains' => [
'expected_type' => 'object',
'format' => [
'type' => 'object',
],
],
'does_not_contain' => [
'expected_type' => 'object',
'format' => [
'type' => 'object',
],
],
],
],
'url' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
],
'does_not_equal' => [
'expected_type' => 'string',
],
'contains' => [
'expected_type' => 'string',
],
'does_not_contain' => [
'expected_type' => 'string',
],
'starts_with' => [
'expected_type' => 'string',
],
'ends_with' => [
'expected_type' => 'string',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'email' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
],
'does_not_equal' => [
'expected_type' => 'string',
],
'contains' => [
'expected_type' => 'string',
],
'does_not_contain' => [
'expected_type' => 'string',
],
'starts_with' => [
'expected_type' => 'string',
],
'ends_with' => [
'expected_type' => 'string',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'phone_number' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
],
'does_not_equal' => [
'expected_type' => 'string',
],
'contains' => [
'expected_type' => 'string',
],
'does_not_contain' => [
'expected_type' => 'string',
],
'starts_with' => [
'expected_type' => 'string',
],
'ends_with' => [
'expected_type' => 'string',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'number' => [
'comparators' => [
'equals' => [
'expected_type' => 'number',
],
'does_not_equal' => [
'expected_type' => 'number',
],
'greater_than' => [
'expected_type' => 'number',
],
'less_than' => [
'expected_type' => 'number',
],
'greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'less_than_or_equal_to' => [
'expected_type' => 'number',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'rating' => [
'comparators' => [
'equals' => [
'expected_type' => 'number',
],
'does_not_equal' => [
'expected_type' => 'number',
],
'greater_than' => [
'expected_type' => 'number',
],
'less_than' => [
'expected_type' => 'number',
],
'greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'less_than_or_equal_to' => [
'expected_type' => 'number',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'scale' => [
'comparators' => [
'equals' => [
'expected_type' => 'number',
],
'does_not_equal' => [
'expected_type' => 'number',
],
'greater_than' => [
'expected_type' => 'number',
],
'less_than' => [
'expected_type' => 'number',
],
'greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'less_than_or_equal_to' => [
'expected_type' => 'number',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'slider' => [
'comparators' => [
'equals' => [
'expected_type' => 'number',
],
'does_not_equal' => [
'expected_type' => 'number',
],
'greater_than' => [
'expected_type' => 'number',
],
'less_than' => [
'expected_type' => 'number',
],
'greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'less_than_or_equal_to' => [
'expected_type' => 'number',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'content_length_equals' => [
'expected_type' => 'number',
],
'content_length_does_not_equal' => [
'expected_type' => 'number',
],
'content_length_greater_than' => [
'expected_type' => 'number',
],
'content_length_greater_than_or_equal_to' => [
'expected_type' => 'number',
],
'content_length_less_than' => [
'expected_type' => 'number',
],
'content_length_less_than_or_equal_to' => [
'expected_type' => 'number',
],
],
],
'checkbox' => [
'comparators' => [
'equals' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'does_not_equal' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
private static $conditionMappingData = null;
],
],
'select' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
],
'does_not_equal' => [
'expected_type' => 'string',
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
],
],
'multi_select' => [
'comparators' => [
'contains' => [
'expected_type' => ['object', 'string'],
'format' => [
'type' => 'uuid',
],
],
'does_not_contain' => [
'expected_type' => ['object', 'string'],
'format' => [
'type' => 'uuid',
],
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
],
],
'date' => [
'comparators' => [
'equals' => [
'expected_type' => 'string',
'format' => [
'type' => 'date',
],
],
'before' => [
'expected_type' => 'string',
'format' => [
'type' => 'date',
],
],
'after' => [
'expected_type' => 'string',
'format' => [
'type' => 'date',
],
],
'on_or_before' => [
'expected_type' => 'string',
'format' => [
'type' => 'date',
],
],
'on_or_after' => [
'expected_type' => 'string',
'format' => [
'type' => 'date',
],
],
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'past_week' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
'past_month' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
'past_year' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
'next_week' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
'next_month' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
'next_year' => [
'expected_type' => 'object',
'format' => [
'type' => 'empty',
'values' => '{}',
],
],
],
],
'files' => [
'comparators' => [
'is_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
'is_not_empty' => [
'expected_type' => 'boolean',
'format' => [
'type' => 'enum',
'values' => [true],
],
],
],
],
];
public static function getConditionMapping()
{
return config('opnform.condition_mapping');
}
private $isConditionCorrect = true;
@ -688,7 +39,6 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule
private function checkBaseCondition($condition)
{
if (!isset($condition['value'])) {
$this->isConditionCorrect = false;
$this->conditionErrors[] = 'missing condition body';
@ -729,21 +79,21 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule
$this->operator = $operator;
$value = $condition['value']['value'];
if (!isset(self::CONDITION_MAPPING[$typeField])) {
if (!isset(self::getConditionMapping()[$typeField])) {
$this->isConditionCorrect = false;
$this->conditionErrors[] = 'configuration not found for condition type';
return;
}
if (!isset(self::CONDITION_MAPPING[$typeField]['comparators'][$operator])) {
if (!isset(self::getConditionMapping()[$typeField]['comparators'][$operator])) {
$this->isConditionCorrect = false;
$this->conditionErrors[] = 'configuration not found for condition operator';
return;
}
$type = self::CONDITION_MAPPING[$typeField]['comparators'][$operator]['expected_type'];
$type = self::getConditionMapping()[$typeField]['comparators'][$operator]['expected_type'] ?? null;
if (is_array($type)) {
$foundCorrectType = false;
@ -765,8 +115,8 @@ class FormPropertyLogicRule implements DataAwareRule, ValidationRule
private function valueHasCorrectType($type, $value)
{
if ($type === 'string' && isset(self::CONDITION_MAPPING[$this->field['type']]['comparators'][$this->operator]['format'])) {
$format = self::CONDITION_MAPPING[$this->field['type']]['comparators'][$this->operator]['format'];
if ($type === 'string' && isset(self::getConditionMapping()[$this->field['type']]['comparators'][$this->operator]['format'])) {
$format = self::getConditionMapping()[$this->field['type']]['comparators'][$this->operator]['format'];
if ($format['type'] === 'regex') {
try {
preg_match('/' . $value . '/', '');

View File

@ -58,21 +58,21 @@ class IntegrationLogicRule implements DataAwareRule, ValidationRule
$operator = $condition['value']['operator'];
$value = $condition['value']['value'];
if (!isset(FormPropertyLogicRule::CONDITION_MAPPING[$typeField])) {
if (!isset(FormPropertyLogicRule::getConditionMapping()[$typeField])) {
$this->isConditionCorrect = false;
$this->conditionErrors[] = 'configuration not found for condition type';
return;
}
if (!isset(FormPropertyLogicRule::CONDITION_MAPPING[$typeField]['comparators'][$operator])) {
if (!isset(FormPropertyLogicRule::getConditionMapping()[$typeField]['comparators'][$operator])) {
$this->isConditionCorrect = false;
$this->conditionErrors[] = 'configuration not found for condition operator';
return;
}
$type = FormPropertyLogicRule::CONDITION_MAPPING[$typeField]['comparators'][$operator]['expected_type'];
$type = FormPropertyLogicRule::getConditionMapping()[$typeField]['comparators'][$operator]['expected_type'];
if (is_array($type)) {
$foundCorrectType = false;

View File

@ -6,4 +6,5 @@ return [
'template_editor_emails' => explode(',', env('TEMPLATE_EDITOR_EMAILS') ?? ''),
'extra_pro_users_emails' => explode(',', env('EXTRA_PRO_USERS_EMAILS') ?? ''),
'show_official_templates' => env('SHOW_OFFICIAL_TEMPLATES', true),
'condition_mapping' => json_decode(file_get_contents(resource_path('data/open_filters.json')), true),
];

View File

@ -25,6 +25,7 @@ environments:
- "php artisan disposable:update"
deploy:
- "php artisan migrate --force"
- "php artisan optimize"
firewall:
rate-limit: 1000
timeout: 60
@ -42,6 +43,7 @@ environments:
- "php artisan disposable:update"
deploy:
- "php artisan migrate --force"
- "php artisan optimize"
firewall:
rate-limit: 1000
timeout: 60

View File

@ -10,7 +10,8 @@ main() {
prep_storage
wait_for_db
apply_db_migrations
run_init_project
run_init_project
optimize_application
run_server "$@"
fi
}
@ -57,6 +58,11 @@ run_init_project() {
./artisan app:init-project
}
optimize_application() {
echo "Optimizing application"
./artisan optimize
}
run_server() {
echo "Starting server $@"
exec "$@"