Skip to content

Commit 6d62b49

Browse files
committed
feat(intl): support optional inputs
1 parent 051078b commit 6d62b49

File tree

6 files changed

+59
-3
lines changed

6 files changed

+59
-3
lines changed

packages/intl/src/MessageFormat/Formatter/MessageFormatter.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,18 @@ private function formatMessage(MessageNode $message): string
8282
$variableName = $expression->variable->name->name;
8383

8484
if (! array_key_exists($variableName, $this->variables)) {
85-
throw new FormattingException("Required input variable `{$variableName}` not provided.");
85+
if ($declaration->optional) {
86+
$parameters = $this->evaluateOptions($expression->function?->options ?? []);
87+
88+
$this->variables[$variableName] = new LocalVariable(
89+
identifier: $variableName,
90+
value: $parameters['default'],
91+
function: $this->getSelectorFunction((string) $expression->function?->identifier),
92+
parameters: $parameters,
93+
);
94+
} else {
95+
throw new FormattingException("Required input variable `{$variableName}` not provided.");
96+
}
8697
}
8798

8899
if ($expression->function instanceof FunctionCall) {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Tempest\Intl\MessageFormat\Functions;
4+
5+
use Tempest\Intl\MessageFormat\SelectorFunction;
6+
7+
final class BooleanFunction implements SelectorFunction
8+
{
9+
public string $name = 'boolean';
10+
11+
public function match(string $key, mixed $value, array $parameters): bool
12+
{
13+
return match ((bool) $value) {
14+
true => in_array($key, ['true', true], strict: true),
15+
false => in_array($key, ['false', false], strict: true),
16+
};
17+
}
18+
}

packages/intl/src/MessageFormat/Functions/StringFunction.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function match(string $key, mixed $value, array $parameters): bool
1919

2020
public function format(mixed $value, array $parameters): FormattedValue
2121
{
22-
$string = Str\parse($value, default: '');
22+
$string = Str\parse($value, default: Arr\get_by_key($parameters, 'default', default: ''));
2323
$formatted = match (Arr\get_by_key($parameters, 'style')) {
2424
'uppercase', 'upper' => Str\to_upper_case($string),
2525
'lowercase', 'lower' => Str\to_lower_case($string),

packages/intl/src/MessageFormat/Parser/MessageFormatParser.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,14 @@ private function parseInputDeclaration(): InputDeclaration
125125
$this->consumeKeyword('.input');
126126
$this->consumeRequiredWhitespace();
127127

128-
return new InputDeclaration($this->parseVariableExpression());
128+
$expression = $this->parseVariableExpression();
129+
130+
$optional = (bool) array_find(
131+
array: $expression->function?->options ?? [],
132+
callback: fn (Option $option) => $option->identifier->name === 'default' && ! is_null($option->value->value),
133+
);
134+
135+
return new InputDeclaration($expression, $optional);
129136
}
130137

131138
private function parseLocalDeclaration(): LocalDeclaration

packages/intl/src/MessageFormat/Parser/Node/Declaration/InputDeclaration.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@
88
{
99
public function __construct(
1010
public VariableExpression $expression,
11+
public bool $optional,
1112
) {}
1213
}

packages/intl/tests/FormatterTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,25 @@ public function test_match_number(int $count, string $expected): void
9494
$this->assertSame($expected, $value);
9595
}
9696

97+
public function test_default_input(): void
98+
{
99+
$formatter = new MessageFormatter([]);
100+
101+
$value = $formatter->format(<<<'TXT'
102+
.input {$field :string default=unknown}
103+
field is {$field}
104+
TXT);
105+
106+
$this->assertSame('field is unknown', $value);
107+
108+
$value = $formatter->format(<<<'TXT'
109+
.input {$field :string default=unknown}
110+
field is {$field}
111+
TXT, field: 'here');
112+
113+
$this->assertSame('field is here', $value);
114+
}
115+
97116
public function test_unquoted_text(): void
98117
{
99118
$formatter = new MessageFormatter();

0 commit comments

Comments
 (0)