diff --git a/modules/modeller_bpmn/tests/src/Kernel/BpmnBaseModellerTest.php b/modules/modeller_bpmn/tests/src/Kernel/BpmnBaseModellerTest.php index 22ec4de5170366cedce583e7fba8c26784ddc395..ad2207c512a06c505077c506f19f5d2c87f5a372 100644 --- a/modules/modeller_bpmn/tests/src/Kernel/BpmnBaseModellerTest.php +++ b/modules/modeller_bpmn/tests/src/Kernel/BpmnBaseModellerTest.php @@ -161,7 +161,7 @@ class BpmnBaseModellerTest extends Base { else { $name = $property['binding']['name']; $label = $property['label']; - $this->assertEquals(self::getExpectedOptionFields($name, $label, $property['value'], $property['choices'], $property['description'] ?? ''), + $this->assertEquals(self::getExpectedOptionFields($name, $label, $property['value'], $property['choices'], $property['description'] ?? '', $property['constraints'] ?? NULL), $property, "Option list $name for plugin $label should be properly prepared."); } } @@ -182,11 +182,13 @@ class BpmnBaseModellerTest extends Base { * The available options for the field. * @param string $description * The optional description. + * @param array|null $constraints + * The optional constraints. * * @return array * The expected option field definition. */ - private static function getExpectedOptionFields(string $name, string $label, string $value, array $choices, string $description): array { + private static function getExpectedOptionFields(string $name, string $label, string $value, array $choices, string $description, ?array $constraints): array { $options = [ 'label' => $label, 'type' => 'Dropdown', @@ -201,6 +203,9 @@ class BpmnBaseModellerTest extends Base { if (!empty($description)) { $options['description'] = $description; } + if (isset($constraints)) { + $options['constraints'] = $constraints; + } return $options; } diff --git a/src/Plugin/FormFieldPluginTrait.php b/src/Plugin/FormFieldPluginTrait.php index d4fe64a2db1e4d6853cd8145879ca59b7ff3ac20..57cad771b15d9ac0bb774378d61c9b27d92c6f17 100644 --- a/src/Plugin/FormFieldPluginTrait.php +++ b/src/Plugin/FormFieldPluginTrait.php @@ -305,11 +305,14 @@ trait FormFieldPluginTrait { * The current element in scope. * @param mixed $key * The key to lookup. + * @param bool $is_root_call + * (optional) This is a recursive function, and this flag indicates whether + * the invokation is the root one. * * @return array * The found element candidates. */ - protected function lookupFormElements(mixed &$element, mixed $key): array { + protected function lookupFormElements(mixed &$element, mixed $key, bool $is_root_call = TRUE): array { $found = []; $lookup_keys = $this->lookupKeys; foreach ($lookup_keys as $lookup_key) { @@ -323,7 +326,7 @@ trait FormFieldPluginTrait { } else { /* @noinspection SlowArrayOperationsInLoopInspection */ - $found = array_merge($found, $this->lookupFormElements($element[$child_key], $key)); + $found = array_merge($found, $this->lookupFormElements($element[$child_key], $key, FALSE)); } } break; @@ -337,7 +340,7 @@ trait FormFieldPluginTrait { } else { /* @noinspection SlowArrayOperationsInLoopInspection */ - $found = array_merge($found, $this->lookupFormElements($element[$child_key], $key)); + $found = array_merge($found, $this->lookupFormElements($element[$child_key], $key, FALSE)); } } break; @@ -350,6 +353,17 @@ trait FormFieldPluginTrait { } $this->lookupKeys = $lookup_keys; + + if ($is_root_call) { + // Sort the found elements from the smallest number of parents to the + // highest number of parents. When a specified form element key defines + // a subset of parent keys, then this sorting makes sure, that the element + // with the highest probability of exact match will be used. + uasort($found, function ($a, $b) { + return count($a['#parents'] ?? []) - count($b['#parents'] ?? []); + }); + } + return $found; }