From ca7e8d71aa56da8c2d9110863d2fd54378ac97b9 Mon Sep 17 00:00:00 2001 From: Johan Cwiklinski Date: Wed, 11 Sep 2024 09:27:20 +0200 Subject: [PATCH] Capacity to add new itemtypes on schema --- lib/php/Converter.php | 121 ++++++++++-------- .../Glpi/Inventory/tests/units/Converter.php | 21 +++ 2 files changed, 92 insertions(+), 50 deletions(-) diff --git a/lib/php/Converter.php b/lib/php/Converter.php index 519d221..125d443 100644 --- a/lib/php/Converter.php +++ b/lib/php/Converter.php @@ -85,6 +85,8 @@ class Converter private array $extra_properties = []; /** @var array>> */ private array $extra_sub_properties = []; + /** @var array */ + private array $extra_itemtypes = []; /** * @var array> @@ -194,6 +196,16 @@ public function setExtraSubProperties(array $properties): self return $this; } + /** + * @param array $itemtypes + * @return $this + */ + public function setExtraItemtypes(array $itemtypes): self + { + $this->extra_itemtypes = $itemtypes; + return $this; + } + /** * Build (extended) JSON schema * @return mixed @@ -206,63 +218,72 @@ public function buildSchema() } $schema = json_decode($string); + $known_itemtypes = []; + preg_match('/\^\((.+)\)\$/', $schema->properties->itemtype->pattern, $known_itemtypes); + $known_itemtypes = explode('|', $known_itemtypes[1]); + foreach ($this->extra_itemtypes as $extra_itemtype) { + if (!in_array($extra_itemtype, $known_itemtypes)) { + $known_itemtypes[] = addslashes($extra_itemtype); + } + } + $schema->properties->itemtype->pattern = sprintf( + '^(%s)$', + implode('|', $known_itemtypes) + ); + $properties = $schema->properties->content->properties; - if ($this->extra_properties != null) { - foreach ($this->extra_properties as $extra_property => $extra_config) { - if (!property_exists($properties, $extra_property)) { - $properties->$extra_property = json_decode((string)json_encode($extra_config)); - } else { - trigger_error( - sprintf('Property %1$s already exists in schema.', $extra_property), - E_USER_WARNING - ); - } + foreach ($this->extra_properties as $extra_property => $extra_config) { + if (!property_exists($properties, $extra_property)) { + $properties->$extra_property = json_decode((string)json_encode($extra_config)); + } else { + trigger_error( + sprintf('Property %1$s already exists in schema.', $extra_property), + E_USER_WARNING + ); } } - if ($this->extra_sub_properties != null) { - foreach ($this->extra_sub_properties as $extra_sub_property => $extra_sub_config) { - if (property_exists($properties, $extra_sub_property)) { - foreach ($extra_sub_config as $subprop => $subconfig) { - $type = $properties->$extra_sub_property->type; - switch ($type) { - case 'array': - if (!property_exists($properties->$extra_sub_property->items->properties, $subprop)) { - $properties->$extra_sub_property->items->properties->$subprop = - json_decode((string)json_encode($subconfig)); - } else { - trigger_error( - sprintf('Property %1$s already exists in schema.', $subprop), - E_USER_WARNING - ); - } - break; - case 'object': - if (!property_exists($properties->$extra_sub_property->properties, $subprop)) { - $properties->$extra_sub_property->properties->$subprop = - json_decode((string)json_encode($subconfig)); - } else { - trigger_error( - sprintf( - 'Property %1$s/%2$s already exists in schema.', - $extra_sub_property, - $subprop - ), - E_USER_WARNING - ); - } - break; - default: - trigger_error('Unknown type ' . $type, E_USER_WARNING); - } + foreach ($this->extra_sub_properties as $extra_sub_property => $extra_sub_config) { + if (property_exists($properties, $extra_sub_property)) { + foreach ($extra_sub_config as $subprop => $subconfig) { + $type = $properties->$extra_sub_property->type; + switch ($type) { + case 'array': + if (!property_exists($properties->$extra_sub_property->items->properties, $subprop)) { + $properties->$extra_sub_property->items->properties->$subprop = + json_decode((string)json_encode($subconfig)); + } else { + trigger_error( + sprintf('Property %1$s already exists in schema.', $subprop), + E_USER_WARNING + ); + } + break; + case 'object': + if (!property_exists($properties->$extra_sub_property->properties, $subprop)) { + $properties->$extra_sub_property->properties->$subprop = + json_decode((string)json_encode($subconfig)); + } else { + trigger_error( + sprintf( + 'Property %1$s/%2$s already exists in schema.', + $extra_sub_property, + $subprop + ), + E_USER_WARNING + ); + } + break; + default: + trigger_error('Unknown type ' . $type, E_USER_WARNING); } - } else { - trigger_error( - sprintf('Property %1$s does not exists in schema.', $extra_sub_property), - E_USER_WARNING - ); } + } else { + trigger_error( + sprintf('Property %1$s does not exists in schema.', $extra_sub_property), + E_USER_WARNING + ); } } diff --git a/tests/Glpi/Inventory/tests/units/Converter.php b/tests/Glpi/Inventory/tests/units/Converter.php index eaa8f6e..d9fae9e 100644 --- a/tests/Glpi/Inventory/tests/units/Converter.php +++ b/tests/Glpi/Inventory/tests/units/Converter.php @@ -734,6 +734,27 @@ public function testValidateVersionClient() $this->assertFalse($instance->validate($json)); } + public function testValidateUnknownItemtype() + { + //itemtype \Glpi\Custom\Asset\Mine is unknown + $itemtype = '\Glpi\Custom\Asset\Mine'; + $json = json_decode(json_encode(['deviceid' => 'myid', 'itemtype' => $itemtype, 'content' => ['versionclient' => 'GLPI-Agent_v1.0', 'hardware' => ['name' => 'my inventory']]])); + $instance = new \Glpi\Inventory\Converter(); + $this->expectException(\RuntimeException::class); + $this->expectExceptionMessage('\\\\Glpi\\\\Custom\\\\Asset\\\\Mine" does not match to ^(Unmanaged|Computer|Phone|NetworkEquipment|Printer)$'); + $this->assertFalse($instance->validate($json)); + } + + public function testValidateNewItemtype() + { + //itemtype \Glpi\Custom\Asset\Mine is unknown + $itemtype = '\Glpi\Custom\Asset\Mine'; + $json = json_decode(json_encode(['deviceid' => 'myid', 'itemtype' => $itemtype, 'content' => ['versionclient' => 'GLPI-Agent_v1.0', 'hardware' => ['name' => 'my inventory']]])); + $instance = new \Glpi\Inventory\Converter(); + $this->assertInstanceOf(\Glpi\Inventory\Converter::class, $instance->setExtraItemtypes([$itemtype])); + $this->assertTrue($instance->validate($json)); + } + public function testValidateUnknownExtraPlugin_node() { //extra "plugin_node" is unknown