WordPress Version: 6.4
/**
* WordPress' implementation of PHP sprintf() with filters.
*
* @since 2.5.0
* @since 5.3.0 Formalized the existing and already documented `...$args` parameter
* by adding it to the function signature.
*
* @link https://www.php.net/sprintf
*
* @param string $pattern The string which formatted args are inserted.
* @param mixed ...$args Arguments to be formatted into the $pattern string.
* @return string The formatted string.
*/
function wp_sprintf($pattern, ...$args)
{
$len = strlen($pattern);
$start = 0;
$result = '';
$arg_index = 0;
while ($len > $start) {
// Last character: append and break.
if (strlen($pattern) - 1 === $start) {
$result .= substr($pattern, -1);
break;
}
// Literal %: append and continue.
if ('%%' === substr($pattern, $start, 2)) {
$start += 2;
$result .= '%';
continue;
}
// Get fragment before next %.
$end = strpos($pattern, '%', $start + 1);
if (false === $end) {
$end = $len;
}
$fragment = substr($pattern, $start, $end - $start);
// Fragment has a specifier.
if ('%' === $pattern[$start]) {
// Find numbered arguments or take the next one in order.
if (preg_match('/^%(\d+)\$/', $fragment, $matches)) {
$index = $matches[1] - 1;
// 0-based array vs 1-based sprintf() arguments.
$arg = isset($args[$index]) ? $args[$index] : '';
$fragment = str_replace("%{$matches[1]}\$", '%', $fragment);
} else {
$arg = isset($args[$arg_index]) ? $args[$arg_index] : '';
++$arg_index;
}
/**
* Filters a fragment from the pattern passed to wp_sprintf().
*
* If the fragment is unchanged, then sprintf() will be run on the fragment.
*
* @since 2.5.0
*
* @param string $fragment A fragment from the pattern.
* @param string $arg The argument.
*/
$_fragment = apply_filters('wp_sprintf', $fragment, $arg);
if ($_fragment !== $fragment) {
$fragment = $_fragment;
} else {
$fragment = sprintf($fragment, (string) $arg);
}
}
// Append to result and move to next fragment.
$result .= $fragment;
$start = $end;
}
return $result;
}