Skip to content

Commit 5487e31

Browse files
authored
Add support for Backed Enums (#1171)
* Add support for Backed Enums Fixes #1012 Also added docs (and docs for matches operator)
1 parent 12ce28e commit 5487e31

File tree

7 files changed

+823
-571
lines changed

7 files changed

+823
-571
lines changed

docs/designers/language-basic-syntax/language-syntax-operators.md

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,120 @@ separated from surrounding elements by spaces. Note that items listed in
5050
| is \[not\] odd by | | $a is not odd by $b | \[not\] an odd grouping | ($a / $b) % 2 != 0 |
5151
| is in | | $a is in $b | exists in array | in_array($a, $b) |
5252
| is \[not\] in | | $a is not in $b | does not exist in array | !in_array($a, $b) |
53+
| matches | | $a matches $b | regex pattern match | preg_match($b, $a) |
54+
55+
## Regex Matching Operator
56+
57+
The `matches` operator allows you to test if a string matches a regular expression pattern.
58+
59+
### Basic Usage
60+
61+
```smarty
62+
{if "hello" matches "/^[a-z]+$/"}
63+
String matches the pattern!
64+
{/if}
65+
66+
{if $email matches "/^[^@]+@[^@]+\.[^@]+$/"}
67+
Valid email format
68+
{else}
69+
Invalid email format
70+
{/if}
71+
```
72+
73+
### Using Variables
74+
75+
```smarty
76+
{$pattern = '/^[a-zA-Z0-9]{8,}$/'}
77+
{if $password matches $pattern}
78+
Password meets requirements
79+
{else}
80+
Password must be at least 8 alphanumeric characters
81+
{/if}
82+
```
83+
84+
### Pattern Modifiers
85+
86+
The `matches` operator supports all standard PHP regex modifiers:
87+
88+
```smarty
89+
{* Case insensitive matching *}
90+
{if "HELLO" matches "/hello/i"}
91+
Matches (case insensitive)
92+
{/if}
93+
94+
{* Multiline mode *}
95+
{if "line1\nline2" matches "/line2$/m"}
96+
Matches in multiline mode
97+
{/if}
98+
99+
{* Dot matches newlines *}
100+
{if "hello\nworld" matches "/hello.world/s"}
101+
Matches with dotall modifier
102+
{/if}
103+
```
104+
105+
### Complex Conditions
106+
107+
The `matches` operator can be combined with other operators:
108+
109+
```smarty
110+
{if $username matches "/^[a-z]+$/" && $username|length > 3}
111+
Valid username
112+
{else}
113+
Username must be lowercase letters and at least 4 characters
114+
{/if}
115+
116+
{if $input matches "/^[0-9]+$/" || $input matches "/^[a-z]+$/"}
117+
Input is either numeric or lowercase letters
118+
{else}
119+
Invalid input format
120+
{/if}
121+
```
122+
123+
### Practical Examples
124+
125+
**Email Validation:**
126+
```smarty
127+
{if $email matches "/^[^@\s]+@[^@\s]+\.[^@\s]+$/"}
128+
Valid email address
129+
{else}
130+
Please enter a valid email address
131+
{/if}
132+
```
133+
134+
**Password Strength:**
135+
```smarty
136+
{if $password matches "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/"}
137+
Strong password
138+
{else}
139+
Password must contain uppercase, lowercase, numbers and be at least 8 characters
140+
{/if}
141+
```
142+
143+
**URL Validation:**
144+
```smarty
145+
{if $url matches "/^https?:\/\/(www\.)?[a-z0-9\-]+(\.[a-z]{2,})+/i"}
146+
Valid URL format
147+
{else}
148+
Please enter a valid URL
149+
{/if}
150+
```
151+
152+
**Numeric Validation:**
153+
```smarty
154+
{if $input matches "/^[0-9]+$/"}
155+
Valid numeric input
156+
{else}
157+
Please enter numbers only
158+
{/if}
159+
```
160+
161+
### Notes
162+
163+
- The `matches` operator uses PHP's `preg_match()` function internally
164+
- Pattern delimiters must be valid regex delimiters (typically `/`)
165+
- Invalid patterns will cause PHP warnings but won't break template execution
166+
- For complex regex patterns, consider using variables for better readability
53167

54168
## Ternary
55169
You can use the `?:` (or ternary) operator to test one expression and present the value

docs/designers/language-variables/language-assigned-variables.md

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,89 @@ this will output:
123123
```html
124124
name: Zaphod Beeblebrox<br />
125125
email: zaphod@slartibartfast.example.com<br />
126-
```
126+
```
127+
128+
## Backed Enums (PHP 8.1+)
129+
130+
Smarty supports accessing properties of [backed enums](https://www.php.net/manual/en/language.enumerations.backed.php) introduced in PHP 8.1.
131+
132+
### Accessing Enum Properties
133+
134+
You can access the `name` and `value` properties of backed enum cases:
135+
136+
```smarty
137+
{* Access enum case properties *}
138+
<option id="{MyEnum::Foo->name}">{MyEnum::Foo->value}</option>
139+
```
140+
141+
### Complete Example
142+
143+
```php
144+
<?php
145+
use Smarty\Smarty;
146+
147+
// Define a backed enum
148+
enum Status: string {
149+
case Active = 'active';
150+
case Inactive = 'inactive';
151+
case Pending = 'pending';
152+
}
153+
154+
$smarty = new Smarty();
155+
$smarty->assign('currentStatus', Status::Active);
156+
$smarty->display('template.tpl');
157+
```
158+
159+
`template.tpl`:
160+
161+
```smarty
162+
{* Display enum properties *}
163+
Current status: {$currentStatus->name} (value: {$currentStatus->value})
164+
165+
{* Use in HTML attributes *}
166+
<select name="status">
167+
<option value="{Status::Active->value}" {if $currentStatus->name === 'Active'}selected{/if}>Active</option>
168+
<option value="{Status::Inactive->value}" {if $currentStatus->name === 'Inactive'}selected{/if}>Inactive</option>
169+
<option value="{Status::Pending->value}" {if $currentStatus->name === 'Pending'}selected{/if}>Pending</option>
170+
</select>
171+
```
172+
173+
This would output:
174+
175+
```html
176+
Current status: Active (value: active)
177+
178+
<select name="status">
179+
<option value="active" selected>Active</option>
180+
<option value="inactive">Inactive</option>
181+
<option value="pending">Pending</option>
182+
</select>
183+
```
184+
185+
### Integer-backed Enums
186+
187+
Integer-backed enums work the same way:
188+
189+
```php
190+
<?php
191+
enum Priority: int {
192+
case Low = 1;
193+
case Medium = 2;
194+
case High = 3;
195+
}
196+
197+
$smarty->assign('priority', Priority::High);
198+
```
199+
200+
```smarty
201+
{* Access integer enum properties *}
202+
Priority level: {$priority->value} ({$priority->name})
203+
```
204+
205+
Output:
206+
207+
```html
208+
Priority level: 3 (High)
209+
```
210+
211+
> **Note**: Backed enum support requires PHP 8.1 or higher. The enum must be registered or available in the current namespace.

docs/features.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ Some of Smarty's features:
2222
- [Template Inheritance](api/inheritance.md) for
2323
easy management of template content.
2424
- [Plugin](api/extending/introduction.md) architecture
25+
- Regex pattern matching with the [`matches`](designers/language-basic-syntax/language-syntax-operators.md#regex-matching-operator) operator
26+
- Support for PHP 8.1+ [backed enums](designers/language-variables/language-assigned-variables.md#backed-enums-php-81)
2527

2628
## Separation of presentation from application code
2729
- This means templates can certainly contain logic under the condition

docs/index.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,25 @@ It allows you to write **templates**, using **variables**, **modifiers**, **func
88
<p>
99
The number of pixels is: {math equation="x * y" x=$height y=$width}.
1010
</p>
11+
12+
<p>
13+
{if $email matches "/^[^@]+@[^@]+\.[^@]+$/"}
14+
Valid email address
15+
{else}
16+
Please enter a valid email
17+
{/if}
18+
</p>
19+
```
20+
```html
21+
<h1>Hello world</h1>
22+
23+
<p>
24+
The number of pixels is: 307200.
25+
</p>
26+
27+
<p>
28+
Valid email address
29+
</p>
1130
```
1231

1332
When this template is rendered, with the value "Hello world" for the variable $title, 640 for $width,

0 commit comments

Comments
 (0)