diff --git a/lib/questionlib.php b/lib/questionlib.php index 8b95027026d..8f2c8344469 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -2407,13 +2407,16 @@ function core_question_find_next_unused_idnumber(?string $oldidnumber, int $cate [$categoryid], '', 'idnumber, 1'); // Find the next unused idnumber. - $newidnumber = $oldidnumber; + $numberbit = 'X' . $matches[0]; // Need a string here so PHP does not do '0001' + 1 = 2. + $stem = substr($oldidnumber, 0, -strlen($matches[0])); do { + // If we have got to something9999, insert an extra digit before incrementing. - if (preg_match('~^(.*[^0-9])(9+)$~', $newidnumber, $matches)) { - $newidnumber = $matches[1] . '0' . $matches[2]; + if (preg_match('~^(.*[^0-9])(9+)$~', $numberbit, $matches)) { + $numberbit = $matches[1] . '0' . $matches[2]; } - $newidnumber++; + $numberbit++; + $newidnumber = $stem . substr($numberbit, 1); } while (isset($usedidnumbers[$newidnumber])); return (string) $newidnumber; diff --git a/lib/tests/questionlib_test.php b/lib/tests/questionlib_test.php index 3142b266bc1..2347fb646db 100644 --- a/lib/tests/questionlib_test.php +++ b/lib/tests/questionlib_test.php @@ -2155,6 +2155,10 @@ class core_questionlib_testcase extends advanced_testcase { ['id9', 'id10'], ['id009', 'id010'], ['id999', 'id1000'], + ['0', '1'], + ['-1', '-2'], + ['1.0E+29', '1.0E+30'], // Idnumbers are strings, not floats. + ['1.0E-29', '1.0E-30'], // By the way, this is not a sensible idnumber! ]; }