From 610c71cb692d1f03bba2954eb6ed0080e4064533 Mon Sep 17 00:00:00 2001 From: Chirag <103994754+chiragnotionforms@users.noreply.github.com> Date: Mon, 3 Oct 2022 00:10:10 +0530 Subject: [PATCH] Fix logic for multi select (#6) * Fix logic for multi select * test case for multi select logic --- app/Rules/FormPropertyLogicRule.php | 66 +++++++++++++------ .../Forms/FormLogicConditionChecker.php | 8 ++- .../form-logic-components/ColumnCondition.vue | 2 +- .../GroupControlSlot.vue | 8 +-- .../js/forms/FormLogicConditionChecker.js | 8 ++- tests/Feature/Forms/FormLogicTest.php | 60 +++++++++++++++++ 6 files changed, 124 insertions(+), 28 deletions(-) diff --git a/app/Rules/FormPropertyLogicRule.php b/app/Rules/FormPropertyLogicRule.php index d7170fa..8e8f84a 100644 --- a/app/Rules/FormPropertyLogicRule.php +++ b/app/Rules/FormPropertyLogicRule.php @@ -6,7 +6,8 @@ use Illuminate\Contracts\Validation\Rule; use Illuminate\Contracts\Validation\DataAwareRule; use Illuminate\Support\Str; -class FormPropertyLogicRule implements Rule, DataAwareRule { +class FormPropertyLogicRule implements Rule, DataAwareRule +{ const ACTIONS_VALUES = [ 'show-block', @@ -242,7 +243,7 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { 'multi_select' => [ 'comparators' => [ 'contains' => [ - 'expected_type' => 'object', + 'expected_type' => ['object', 'string'], 'format' => [ 'type' => 'uuid', ] @@ -384,36 +385,37 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { private $field = []; private $data = []; - private function checkBaseCondition($condtion) { + private function checkBaseCondition($condition) + { - if (!isset($condtion['value'])) { + if (!isset($condition['value'])) { $this->isConditionCorrect = false; return; } - if (!isset($condtion['value']['property_meta'])) { + if (!isset($condition['value']['property_meta'])) { $this->isConditionCorrect = false; return; } - if (!isset($condtion['value']['property_meta']['type'])) { + if (!isset($condition['value']['property_meta']['type'])) { $this->isConditionCorrect = false; return; } - if (!isset($condtion['value']['operator'])) { + if (!isset($condition['value']['operator'])) { $this->isConditionCorrect = false; return; } - if (!isset($condtion['value']['value'])) { + if (!isset($condition['value']['value'])) { $this->isConditionCorrect = false; return; } - $typeField = $condtion['value']['property_meta']['type']; - $operator = $condtion['value']['operator']; - $value = $condtion['value']['value']; + $typeField = $condition['value']['property_meta']['type']; + $operator = $condition['value']['operator']; + $value = $condition['value']['value']; if (!isset(self::CONDITION_MAPPING[$typeField])) { $this->isConditionCorrect = false; @@ -427,18 +429,38 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { $type = self::CONDITION_MAPPING[$typeField]['comparators'][$operator]['expected_type']; - // Type d'objet : string, boolean, number, object + if (is_array($type)) { + $foundCorrectType = false; + foreach ($type as $subtype) { + if ($this->valueHasCorrectType($subtype, $value)) { + $foundCorrectType = true; + } + } + if (!$foundCorrectType) { + $this->isConditionCorrect = false; + } + } else { + if (!$this->valueHasCorrectType($type, $value)) { + $this->isConditionCorrect = false; + } + } + } + + private function valueHasCorrectType($type, $value) + { if ( ($type === 'string' && gettype($value) !== 'string') || ($type === 'boolean' && !is_bool($value)) || ($type === 'number' && !is_numeric($value)) || ($type === 'object' && !is_array($value)) ) { - $this->isConditionCorrect = false; + return false; } + return true; } - private function checkConditions($conditions) { + private function checkConditions($conditions) + { if (isset($conditions['operatorIdentifier'])) { if (($conditions['operatorIdentifier'] !== 'and') && ($conditions['operatorIdentifier'] !== 'or')) { $this->isConditionCorrect = false; @@ -463,19 +485,19 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { } } - private function checkActions($conditions) { + private function checkActions($conditions) + { if (is_array($conditions) && count($conditions) > 0) { foreach($conditions as $val){ if (!in_array($val, static::ACTIONS_VALUES) || (in_array($this->field["type"], ['nf-text', 'nf-page-break', 'nf-divider', 'nf-image']) && !in_array($val, ['hide-block'])) || - (isset($this->field["hidden"]) && $this->field["hidden"] && !in_array($val, ['show-block','require-answer'])) || - (isset($this->field["required"]) && $this->field["required"] && !in_array($val, ['make-it-optional','hide-block'])) + (isset($this->field["hidden"]) && $this->field["hidden"] && !in_array($val, ['show-block', 'require-answer'])) || + (isset($this->field["required"]) && $this->field["required"] && !in_array($val, ['make-it-optional', 'hide-block'])) ) { $this->isActionCorrect = false; break; } } - return; } } @@ -486,7 +508,8 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { * @param mixed $value * @return bool */ - public function passes($attribute, $value) { + public function passes($attribute, $value) + { $this->setProperty($attribute); if(isset($value["conditions"])){ $this->checkConditions($value["conditions"]); @@ -501,7 +524,8 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { * Get the validation error message. * */ - public function message() { + public function message() + { $errorList = []; if(!$this->isConditionCorrect){ $errorList[] = "The logic conditions for ".$this->field['name']." are not complete."; @@ -527,7 +551,7 @@ class FormPropertyLogicRule implements Rule, DataAwareRule { private function setProperty(string $attributeKey) { - $attributeKey = Str::of($attributeKey)->replace('.logic','')->toString(); + $attributeKey = Str::of($attributeKey)->replace('.logic', '')->toString(); $this->field = \Arr::get($this->data, $attributeKey); } } diff --git a/app/Service/Forms/FormLogicConditionChecker.php b/app/Service/Forms/FormLogicConditionChecker.php index b9e9385..14ea0dc 100644 --- a/app/Service/Forms/FormLogicConditionChecker.php +++ b/app/Service/Forms/FormLogicConditionChecker.php @@ -81,7 +81,13 @@ class FormLogicConditionChecker } private function checkListContains ($condition, $fieldValue): bool { - return ($fieldValue) ? (count(array_intersect($condition['value'], $fieldValue)) === count($condition['value'])) : false; + if (is_null($fieldValue)) return false; + + if (is_array($condition['value'])) { + return count(array_intersect($condition['value'], $fieldValue)) === count($condition['value']); + } else { + return in_array($condition['value'], $fieldValue); + } } private function checkStartsWith ($condition, $fieldValue): bool { diff --git a/resources/js/components/open/forms/components/form-logic-components/ColumnCondition.vue b/resources/js/components/open/forms/components/form-logic-components/ColumnCondition.vue index d851ba4..2942ab3 100644 --- a/resources/js/components/open/forms/components/form-logic-components/ColumnCondition.vue +++ b/resources/js/components/open/forms/components/form-logic-components/ColumnCondition.vue @@ -58,7 +58,7 @@ export default { } if (['select', 'multi_select'].includes(this.property.type)) { - componentData.multiple = (this.property.type == 'multi_select') + componentData.multiple = false; componentData.options = this.property[this.property.type].options.map(option => { return { name: option.name, diff --git a/resources/js/components/open/forms/components/form-logic-components/GroupControlSlot.vue b/resources/js/components/open/forms/components/form-logic-components/GroupControlSlot.vue index a645fad..89876e0 100644 --- a/resources/js/components/open/forms/components/form-logic-components/GroupControlSlot.vue +++ b/resources/js/components/open/forms/components/form-logic-components/GroupControlSlot.vue @@ -1,16 +1,16 @@