diff --git a/core/trigger.class.inc.php b/core/trigger.class.inc.php index 01242bc2e..ba193b773 100644 --- a/core/trigger.class.inc.php +++ b/core/trigger.class.inc.php @@ -53,7 +53,7 @@ abstract class Trigger extends cmdbAbstractObject MetaModel::Init_AddAttribute(new AttributeEnumSet("context", array("allowed_values" => null, "possible_values" => new ValueSetEnumPadded($aTags, true), "sql" => "context", "depends_on" => array(), "is_null_allowed" => true, "max_items" => 12))); // "complement" is a computed field, fed by Trigger sub-classes, in general in ComputeValues method, for eg. the TriggerOnObject fed it with target_class info MetaModel::Init_AddAttribute(new AttributeString("complement", array("allowed_values" => null, "sql" => "complement", "default_value" => null, "is_null_allowed" => true, "depends_on" => array()))); - MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(implode(",", array_map(fn($case) => $case->value, Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()))), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array()))); + MetaModel::Init_AddAttribute(new AttributeEnum("subscription_policy", array("allowed_values" => new ValueSetEnum(Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::cases()), "sql" => "subscription_policy", "default_value" => \Combodo\iTop\Core\Trigger\Enum\SubscriptionPolicy::AllowNoChannel->value, "is_null_allowed" => false, "depends_on" => array()))); // Display lists MetaModel::Init_SetZListItems('details', array('finalclass', 'description', 'context', 'subscription_policy', 'action_list', 'complement')); // Attributes to be displayed for the complete details diff --git a/core/valuesetdef.class.inc.php b/core/valuesetdef.class.inc.php index 21a7fb654..44733976d 100644 --- a/core/valuesetdef.class.inc.php +++ b/core/valuesetdef.class.inc.php @@ -471,34 +471,12 @@ class ValueSetEnum extends ValueSetDefinition */ protected bool $bSortByValues; - /** - * @param string $sBackedEnumFQCN FQCN of the backed enum to use - * @param bool $bSortValues {@see static::$bSortValues} - * - * @return \ValueSetEnum ValueSetEnum based on the values of the $sBackedEnumFQCN backed enum - * @throws \CoreException - * @since 3.2.0 - */ - public static function FromBackedEnum(string $sBackedEnumFQCN, bool $bSortValues = false): ValueSetEnum - { - // First, check that we pass an enum as there is no generic type hint for that yet - if (false === enum_exists($sBackedEnumFQCN)) { - throw new CoreException("Can't instantiate " . __CLASS__ . "::" . __METHOD__ . " from a non-enum argument", [ - "argument" => $sBackedEnumFQCN - ]); - } - - // Implode cases - $sJoinedValues = implode(",", array_map(fn($case) => $case->value, $sBackedEnumFQCN::cases())); - - return new ValueSetEnum($sJoinedValues, $bSortValues); - } - /** * @param array|string $Values * @param bool $bLocalizedSort * * @since 3.1.0 N°1646 Add $bLocalizedSort parameter + * @since 3.2.0 N°7157 $Values can be an array of backed-enum cases */ public function __construct($Values, bool $bSortByValues = false) { @@ -546,13 +524,21 @@ class ValueSetEnum extends ValueSetDefinition */ protected function LoadValues($aArgs) { + $aValues = []; if (is_array($this->m_values)) { - $aValues = $this->m_values; + foreach ($this->m_values as $value) { + // Handle backed-enum case + if (is_object($value) && enum_exists(get_class($value))) { + $aValues[] = $value->value; + continue; + } + + $aValues[] = $value; + } } elseif (is_string($this->m_values) && strlen($this->m_values) > 0) { - $aValues = array(); foreach (explode(",", $this->m_values) as $sVal) { $sVal = trim($sVal); @@ -562,7 +548,7 @@ class ValueSetEnum extends ValueSetDefinition } else { - $aValues = array(); + $aValues = []; } $this->m_aValues = $aValues; return true; diff --git a/tests/php-unit-tests/unitary-tests/core/ValueSetEnum/ABCEnum.php b/tests/php-unit-tests/unitary-tests/core/ValueSetEnum/ABCEnum.php new file mode 100644 index 000000000..4e8be881b --- /dev/null +++ b/tests/php-unit-tests/unitary-tests/core/ValueSetEnum/ABCEnum.php @@ -0,0 +1,13 @@ + + * @package Combodo\iTop\Test\UnitTest\Core + * @coves \ValueSetEnum + */ +class ValueSetEnumTest extends ItopTestCase +{ + public static function setupBeforeClass(): void + { + require_once __DIR__ . "/ValueSetEnum/ABCEnum.php"; + } + + /** + * @dataProvider LoadValuesProvider + * + * @param mixed $input + * @param array $aExpectedValues + * @param bool $bIsInputBackedEnum + * + * @return void + */ + public function testLoadValues(mixed $input, array $aExpectedValues, bool $bIsInputBackedEnum = false): void + { + if ($bIsInputBackedEnum) { + $input = $input::cases(); + } + $oValueSetEnum = new ValueSetEnum($input); + $aTestedValues = $oValueSetEnum->GetValues([]); + + $this->assertEquals($aExpectedValues, $aTestedValues, "Values should be the same and ordered the same way"); + } + + public function LoadValuesProvider(): array + { + return [ + "CSV list, trimmed values, already ordered" => [ + "a,b,c", + [ + "a" => "a", + "b" => "b", + "c" => "c", + ], + ], + "CSV list, values to trim, already ordered" => [ + "a, b ,c ", + [ + "a" => "a", + "b" => "b", + "c" => "c", + ], + ], + "Array, already ordered" => [ + ["a", "b", "c"], + [ + 0 => "a", + 1 => "b", + 2 => "c", + ], + ], + "Backed-Enum" => [ + ABCEnum::class, + [ + 0 => "a", + 1 => "b", + 2 => "c", + ], + true, // Is the input value a backed enum? + ], + "Invalid int value" => [ + 123, + [], + ] + ]; + } +} \ No newline at end of file