diff --git a/lib/functions.php b/lib/functions.php index 90d4499c529aed56cccf8863c0676ffbccefd721..b68658a25ff6079483f6739a1b3c249768af3501 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -1859,3 +1859,34 @@ function xml_escape($string) $string = preg_replace('/[\x00-\x08\x0b\x0c\x0e-\x1f]/', '', $string); return htmlspecialchars($string, ENT_QUOTES, 'UTF-8'); } + +/** + * This function mimics the functionality of the $gettextInterpolate function in JavaScript. + * This makes it easier to format text in translatable strings. + * + * Note that the behavior of this function is simplified in comparison with $gettextInterpolate: + * - All placeholders that have a value are replaced with the string value of that value. + * Numbers must be pre-formatted before added to the parameters. + * - All placeholders that have no replacements in the parameters array are output. + * + * @param string $gettext_string The translation string to be interpolated. + * + * @param array $parameters The parameters that replace the placeholders in the translation string. + * Array keys are the names of the placeholders while array values are the values that are + * placed inside the string. + * + * @return string The interpolated translation string. + */ +function studip_interpolate(string $gettext_string, array $parameters) : string +{ + return preg_replace_callback( + '/%\{\s*(\w+)\s*\}/', + function ($match) use ($parameters): string { + if (!isset($parameters[$match[1]])) { + throw new Exception('The parameter for the placeholder ' . $match[1] . ' is missing.'); + } + return $parameters[$match[1]]; + }, + $gettext_string + ); +} diff --git a/tests/unit/lib/FunctionsTest.php b/tests/unit/lib/FunctionsTest.php index 9a92f1a2755979dbf8c88f3906b3066950003832..670d00c74b8ea59dedeeee595c048be9e407a000 100644 --- a/tests/unit/lib/FunctionsTest.php +++ b/tests/unit/lib/FunctionsTest.php @@ -80,11 +80,29 @@ class FunctionsTest extends \Codeception\Test\Unit public function testTrailsControllerExtractActionAndArgs() { $controller = new Trails_Controller(null); - list($action, $args, $format) = $controller->extract_action_and_args('foo/bar//42.html'); + [$action, $args, $format] = $controller->extract_action_and_args('foo/bar//42.html'); $this->assertEquals('foo', $action); $this->assertEquals(['bar', '', '42'], $args); $this->assertEquals('html', $format); } + + /** + * @covers ::studip_interpolate + */ + public function testStudipInterpolate() + { + $this->assertEquals( + '12bar34', + studip_interpolate('12%{foo}34', ['foo' => 'bar']) + ); + $this->assertEquals( + 'foo', + studip_interpolate('%{ bar }', ['bar' => 'foo']) + ); + + $this->expectException(Exception::class); + studip_interpolate('%{foo}', []); + } }