From 019b1459a57be3561794e9a33d3cd9f3a53e4bf5 Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Mon, 24 Aug 2026 15:29:06 +0200 Subject: [PATCH 1/7] fix(45898): data values not formatted when coming from fields plugin --- inc/commoninjectionlib.class.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index 501fae9e..6ee2bab0 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1098,6 +1098,10 @@ private function reformatThirdPass() //Get search option associated with the field $option = self::findSearchOption($searchOptions, $field); + if ($option && !isset($option['checktype'])) { + $option['checktype'] = $option['datatype']; + } + // Check some types switch ($option['checktype'] ?? 'text') { case "date": From 5de6a4fa22b504c2c2938845ba7ea05ed1cc34be Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Mon, 24 Aug 2026 15:33:52 +0200 Subject: [PATCH 2/7] chore(45898): changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f9c8cd9..a43be598 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Fixed + +- Fix an issue where data are not formatted when coming from a field plugin's custom field. + ## [2.15.10] - 2026-08-07 ### Fixed From bea4c95eb6557b4a55ab6ea7a1d2ee1868de9447 Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Tue, 25 Aug 2026 09:25:12 +0200 Subject: [PATCH 3/7] fix(45898): float format detection by datainjection plugin --- inc/commoninjectionlib.class.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index 6ee2bab0..03081da9 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1099,7 +1099,10 @@ private function reformatThirdPass() $option = self::findSearchOption($searchOptions, $field); if ($option && !isset($option['checktype'])) { - $option['checktype'] = $option['datatype']; + // In some cases, float datatype is wrongly detected as string, decimal or number, so we check that first. + $option['checktype'] = (preg_match('/^\d+(\.|\,)\d+$/', $value) !== 0) + ? "float" + : $option['datatype']; } // Check some types From c7c86a03dde9deb22e45f9d63524017fb5c89815 Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Tue, 25 Aug 2026 12:10:16 +0200 Subject: [PATCH 4/7] fix(45898): incomplete regex that was not properly catching all forms of float numbers --- inc/commoninjectionlib.class.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index 03081da9..e4115bb4 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1100,7 +1100,8 @@ private function reformatThirdPass() if ($option && !isset($option['checktype'])) { // In some cases, float datatype is wrongly detected as string, decimal or number, so we check that first. - $option['checktype'] = (preg_match('/^\d+(\.|\,)\d+$/', $value) !== 0) + //Regex matches all decimal formats accepted by glpi + $option['checktype'] = (preg_match('/^(?:(?:\d{1,3}(?: \d{3})+[.,])|(?:\d{1,3}(?:,\d{3})+\.)|(?:\d+[.,]))\d+$/', $value) !== 0) ? "float" : $option['datatype']; } From 9c05d1760e12b1ee7231f6f443f50610a6fb77f2 Mon Sep 17 00:00:00 2001 From: Julien DURAND Date: Tue, 25 Aug 2026 13:44:04 +0200 Subject: [PATCH 5/7] Update inc/commoninjectionlib.class.php Co-authored-by: Romain B. <8530352+Rom1-B@users.noreply.github.com> --- inc/commoninjectionlib.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index e4115bb4..f9eaed65 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1101,7 +1101,7 @@ private function reformatThirdPass() if ($option && !isset($option['checktype'])) { // In some cases, float datatype is wrongly detected as string, decimal or number, so we check that first. //Regex matches all decimal formats accepted by glpi - $option['checktype'] = (preg_match('/^(?:(?:\d{1,3}(?: \d{3})+[.,])|(?:\d{1,3}(?:,\d{3})+\.)|(?:\d+[.,]))\d+$/', $value) !== 0) + $option['checktype'] = (preg_match('/^(?:(?:\d{1,3}(?: \d{3})+|\d+)[.,]|\d{1,3}(?:,\d{3})+\.)\d+$/', $value) !== 0) ? "float" : $option['datatype']; } From 9891bf42d057f6cbe62f8e884af218ee067ddfa4 Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Tue, 25 Aug 2026 13:53:02 +0200 Subject: [PATCH 6/7] fix(45898): more accurate usage of fieldype in checkType method --- inc/commoninjectionlib.class.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index f9eaed65..4a4b103c 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1405,7 +1405,7 @@ private function checkType($injectionClass, $option, $field_name, $data, $mandat { if (!empty($option)) { - $field_type = ($option['checktype'] ?? 'text'); + $field_type = ($option['checktype'] ?? $option['datatype'] ?? 'text'); //If no data provided AND this mapping is not mandatory if ( From c9a98be0e7e17fae2ecbefdb5c7f56335f403492 Mon Sep 17 00:00:00 2001 From: Julien Durand Date: Tue, 25 Aug 2026 16:30:59 +0200 Subject: [PATCH 7/7] chore(45898): Add unit tests --- inc/commoninjectionlib.class.php | 9 +- .../CommonInjectionLibFloatDetectionTest.php | 95 +++++++++++++++++++ 2 files changed, 103 insertions(+), 1 deletion(-) create mode 100644 tests/unit/CommonInjectionLibFloatDetectionTest.php diff --git a/inc/commoninjectionlib.class.php b/inc/commoninjectionlib.class.php index 4a4b103c..0464274a 100644 --- a/inc/commoninjectionlib.class.php +++ b/inc/commoninjectionlib.class.php @@ -1101,7 +1101,7 @@ private function reformatThirdPass() if ($option && !isset($option['checktype'])) { // In some cases, float datatype is wrongly detected as string, decimal or number, so we check that first. //Regex matches all decimal formats accepted by glpi - $option['checktype'] = (preg_match('/^(?:(?:\d{1,3}(?: \d{3})+|\d+)[.,]|\d{1,3}(?:,\d{3})+\.)\d+$/', $value) !== 0) + $option['checktype'] = (preg_match($this->getFloatDetectionRegex(), $value) !== 0) ? "float" : $option['datatype']; } @@ -1307,6 +1307,13 @@ private static function reformatMacAddress($mac) return $mac; } + //--------------------------------------------------// + //----------- Utility methods -----------------------// + //------------------------------------------------// + public function getFloatDetectionRegex(): string + { + return '/^(?:(?:\d{1,3}(?: \d{3})+|\d+)[.,]|\d{1,3}(?:,\d{3})+\.)\d+$/'; + } //--------------------------------------------------// //----------- Check methods -----------------------// diff --git a/tests/unit/CommonInjectionLibFloatDetectionTest.php b/tests/unit/CommonInjectionLibFloatDetectionTest.php new file mode 100644 index 00000000..cb3a8012 --- /dev/null +++ b/tests/unit/CommonInjectionLibFloatDetectionTest.php @@ -0,0 +1,95 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2007-2023 by DataInjection plugin team. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/datainjection + * ------------------------------------------------------------------------- + */ + +namespace GlpiPlugin\Datainjection\Tests\Unit; + +use Glpi\Tests\DbTestCase; +use PluginDatainjectionCommonInjectionLib; +use PluginDatainjectionComputerInjection; + +require_once dirname(__DIR__, 2) . '/inc/injectioninterface.class.php'; +require_once dirname(__DIR__, 2) . '/inc/commoninjectionlib.class.php'; +require_once dirname(__DIR__, 2) . '/inc/computerinjection.class.php'; + +/** + * Covers the float-detection regex used by reformatThirdPass() to derive + * $option['checktype'] when a search option (e.g. a custom field coming from + * a third-party plugin) only has a 'datatype' and no explicit 'checktype'. + * + * The regex under test is not hardcoded here: it is retrieved from + * PluginDatainjectionCommonInjectionLib::getFloatDetectionRegex(), the same + * shared source reformatThirdPass() itself calls, so this test can never + * drift out of sync with the actual pattern shipped in the code. + */ +final class CommonInjectionLibFloatDetectionTest extends DbTestCase +{ + private static function getFloatDetectionRegex(): string + { + $lib = new PluginDatainjectionCommonInjectionLib(new PluginDatainjectionComputerInjection()); + + return $lib->getFloatDetectionRegex(); + } + + public static function floatDetectionProvider(): array + { + return [ + // Accepted formats + 'plain dot decimal' => ['1234.56', true], + 'plain comma decimal' => ['1234,56', true], + 'leading zero decimal' => ['0.5', true], + 'space-grouped thousands, dot decimal' => ['1 234.56', true], + 'space-grouped thousands, comma decimal' => ['1 234,56', true], + 'multiple space groups, comma decimal' => ['12 345 678,90', true], + 'comma-grouped thousands, dot decimal' => ['1,234.56', true], + 'multiple comma groups, dot decimal' => ['12,345,678.90', true], + 'basic comma decimal, no grouping' => ['12,34', true], + + // Rejected formats (should fall back to $option['datatype']) + 'plain integer, no separator' => ['1234', false], + 'empty string' => ['', false], + 'non numeric text' => ['abc', false], + 'multiple dots (malformed)' => ['1234.56.78', false], + 'comma-grouped integer, no decimal part' => ['1,234,567', false], + 'space-grouped integer, no decimal part' => ['1 234', false], + 'leading dot, no integer part' => ['.56', false], + 'negative float (unsupported by regex)' => ['-1234.56', false], + ]; + } + + /** + * @dataProvider floatDetectionProvider + */ + public function testFloatDetectionRegex(string $value, bool $expected_match): void + { + $regex = self::getFloatDetectionRegex(); + + self::assertSame($expected_match, preg_match($regex, $value) !== 0); + } +}