Skip to content

Commit fb07e44

Browse files
committed
Introduce Trimmed validator
This commit introduces the `Trimmed` validator that ensures a string cannot start or end with a list of specific values. The default values used are a selected list of Unicode invisible characters. To support this change, the StartsWith and EndsWith validators were modified so they can also support multiple values to check for. While StartsWith and EndsWith are more generic, and also perform start-of-array and end-of-array kinds of checks, Trimmed is more focused on string inputs, which tailors to a more specific use case.
1 parent e1ff5aa commit fb07e44

28 files changed

+457
-53
lines changed

docs/validators.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ In this page you will find a list of validators by their category.
4949

5050
**Objects**: [Attributes][] - [Instance][] - [ObjectType][] - [Property][] - [PropertyExists][] - [PropertyOptional][]
5151

52-
**Strings**: [Alnum][] - [Alpha][] - [Base64][] - [Charset][] - [Consonant][] - [Contains][] - [ContainsAny][] - [ContainsCount][] - [Control][] - [Digit][] - [Emoji][] - [EndsWith][] - [Format][] - [Graph][] - [HexRgbColor][] - [In][] - [Json][] - [Lowercase][] - [Phone][] - [PostalCode][] - [Printable][] - [Punct][] - [Regex][] - [Slug][] - [Sorted][] - [Space][] - [Spaced][] - [StartsWith][] - [StringType][] - [StringVal][] - [Uppercase][] - [Uuid][] - [Version][] - [Vowel][] - [Xdigit][]
52+
**Strings**: [Alnum][] - [Alpha][] - [Base64][] - [Charset][] - [Consonant][] - [Contains][] - [ContainsAny][] - [ContainsCount][] - [Control][] - [Digit][] - [Emoji][] - [EndsWith][] - [Format][] - [Graph][] - [HexRgbColor][] - [In][] - [Json][] - [Lowercase][] - [Phone][] - [PostalCode][] - [Printable][] - [Punct][] - [Regex][] - [Slug][] - [Sorted][] - [Space][] - [Spaced][] - [StartsWith][] - [StringType][] - [StringVal][] - [Trimmed][] - [Uppercase][] - [Uuid][] - [Version][] - [Vowel][] - [Xdigit][]
5353

5454
**Structures**: [Attributes][] - [Key][] - [KeyExists][] - [KeyOptional][] - [KeySet][] - [Property][] - [PropertyExists][] - [PropertyOptional][]
5555

@@ -203,6 +203,7 @@ In this page you will find a list of validators by their category.
203203
- [Templated][] - `v::templated('You must provide a valid email', v::email())->assert('foo@bar.com');`
204204
- [Time][] - `v::time()->assert('00:00:00');`
205205
- [Tld][] - `v::tld()->assert('com');`
206+
- [Trimmed][] - `v::trimmed()->assert('lorem ipsum');`
206207
- [TrueVal][] - `v::trueVal()->assert(true);`
207208
- [Undef][] - `v::undef()->assert('');`
208209
- [UndefOr][] - `v::undefOr(v::alpha())->assert('');`
@@ -351,7 +352,7 @@ In this page you will find a list of validators by their category.
351352
[Sorted]: validators/Sorted.md "Validates whether the input is sorted in a certain order or not."
352353
[Space]: validators/Space.md "Validates whether the input contains only whitespaces characters."
353354
[Spaced]: validators/Spaced.md "Validates if a string contains at least one whitespace (spaces, tabs, or line breaks);"
354-
[StartsWith]: validators/StartsWith.md "Validates whether the input starts with a given value."
355+
[StartsWith]: validators/StartsWith.md "Validates whether the input starts with one of the given values."
355356
[StringType]: validators/StringType.md "Validates whether the type of an input is string or not."
356357
[StringVal]: validators/StringVal.md "Validates whether the input can be used as a string."
357358
[SubdivisionCode]: validators/SubdivisionCode.md "Validates subdivision country codes according to ISO 3166-2."
@@ -360,6 +361,7 @@ In this page you will find a list of validators by their category.
360361
[Templated]: validators/Templated.md "Defines a validator with a custom message template."
361362
[Time]: validators/Time.md "Validates whether an input is a time or not. The `$format` argument should be in"
362363
[Tld]: validators/Tld.md "Validates whether the input is a top-level domain."
364+
[Trimmed]: validators/Trimmed.md "Validates whether the input string does not start or end with the given values."
363365
[TrueVal]: validators/TrueVal.md "Validates if a value is considered as `true`."
364366
[Undef]: validators/Undef.md "Validates if the given input is undefined. By _undefined_ we consider `null` or an empty string (`''`)."
365367
[UndefOr]: validators/UndefOr.md "Validates the input using a defined validator when the input is not `null` or an empty string (`''`)."

docs/validators/EndsWith.md

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,32 @@ SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com>
88
# EndsWith
99

1010
- `EndsWith(mixed $endValue)`
11+
- `EndsWith(mixed $endValue, mixed ...$endValues)`
1112

1213
This validator is similar to `Contains()`, but validates
13-
only if the value is at the end of the input.
14+
only if one of the values is at the end of the input.
1415

1516
For strings:
1617

1718
```php
1819
v::endsWith('ipsum')->assert('lorem ipsum');
1920
// Validation passes successfully
21+
22+
v::endsWith('ipsum', 'dolor')->assert('lorem dolor');
23+
// Validation passes successfully
2024
```
2125

2226
For arrays:
2327

2428
```php
2529
v::endsWith('ipsum')->assert(['lorem', 'ipsum']);
2630
// Validation passes successfully
31+
32+
v::endsWith('ipsum', 'dolor')->assert(['lorem', 'dolor']);
33+
// Validation passes successfully
2734
```
2835

29-
Message template for this validator includes `{{endValue}}`.
36+
Message template for this validator includes `{{endValue}}` and `{{endValues}}`.
3037

3138
## Templates
3239

@@ -37,12 +44,20 @@ Message template for this validator includes `{{endValue}}`.
3744
| `default` | {{subject}} must end with {{endValue}} |
3845
| `inverted` | {{subject}} must not end with {{endValue}} |
3946

47+
### `EndsWith::TEMPLATE_MULTIPLE_VALUES`
48+
49+
| Mode | Template |
50+
| ---------: | :------------------------------------------------------- |
51+
| `default` | {{subject}} must end with {{endValues&#124;list:or}} |
52+
| `inverted` | {{subject}} must not end with {{endValues&#124;list:or}} |
53+
4054
## Template placeholders
4155

4256
| Placeholder | Description |
4357
| ----------- | ---------------------------------------------------------------- |
44-
| `endValue` | |
4558
| `subject` | The validated input or the custom validator name (if specified). |
59+
| `endValue` | The value that will be checked to be at the end of the input. |
60+
| `endValues` | Additional values to check. |
4661

4762
## Categorization
4863

@@ -53,6 +68,7 @@ Message template for this validator includes `{{endValue}}`.
5368

5469
| Version | Description |
5570
| ------: | :---------------------------------- |
71+
| 3.1.0 | Added support for multiple values |
5672
| 3.0.0 | Case-insensitive comparison removed |
5773
| 0.3.9 | Created |
5874

@@ -62,3 +78,4 @@ Message template for this validator includes `{{endValue}}`.
6278
- [In](In.md)
6379
- [Regex](Regex.md)
6480
- [StartsWith](StartsWith.md)
81+
- [Trimmed](Trimmed.md)

docs/validators/StartsWith.md

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ SPDX-FileContributor: Henrique Moody <henriquemoody@gmail.com>
99
# StartsWith
1010

1111
- `StartsWith(mixed $startValue)`
12+
- `StartsWith(mixed $startValue, mixed ...$startValues)`
1213

13-
Validates whether the input starts with a given value.
14+
Validates whether the input starts with one of the given values.
1415

1516
This validator is similar to [Contains](Contains.md), but validates only
1617
if the value is at the beginning of the input.
@@ -20,16 +21,22 @@ For strings:
2021
```php
2122
v::startsWith('lorem')->assert('lorem ipsum');
2223
// Validation passes successfully
24+
25+
v::startsWith('lorem', 'ipsum')->assert('ipsum dolor');
26+
// Validation passes successfully
2327
```
2428

2529
For arrays:
2630

2731
```php
2832
v::startsWith('lorem')->assert(['lorem', 'ipsum']);
2933
// Validation passes successfully
34+
35+
v::startsWith('lorem', 'ipsum')->assert(['ipsum', 'dolor']);
36+
// Validation passes successfully
3037
```
3138

32-
Message template for this validator includes `{{startValue}}`.
39+
Message template for this validator includes `{{startValue}}` and `{{startValues}}`.
3340

3441
## Templates
3542

@@ -40,12 +47,20 @@ Message template for this validator includes `{{startValue}}`.
4047
| `default` | {{subject}} must start with {{startValue}} |
4148
| `inverted` | {{subject}} must not start with {{startValue}} |
4249

50+
### `StartsWith::TEMPLATE_MULTIPLE_VALUES`
51+
52+
| Mode | Template |
53+
| ---------: | :----------------------------------------------------------- |
54+
| `default` | {{subject}} must start with {{startValues&#124;list:or}} |
55+
| `inverted` | {{subject}} must not start with {{startValues&#124;list:or}} |
56+
4357
## Template placeholders
4458

45-
| Placeholder | Description |
46-
| ------------ | ---------------------------------------------------------------- |
47-
| `subject` | The validated input or the custom validator name (if specified). |
48-
| `startValue` | |
59+
| Placeholder | Description |
60+
| ------------- | ---------------------------------------------------------------- |
61+
| `subject` | The validated input or the custom validator name (if specified). |
62+
| `startValue` | The value that will be checked to be at the start of the input. |
63+
| `startValues` | Additional values to check. |
4964

5065
## Categorization
5166

@@ -56,6 +71,7 @@ Message template for this validator includes `{{startValue}}`.
5671

5772
| Version | Description |
5873
| ------: | :---------------------------------- |
74+
| 3.1.0 | Added support for multiple values |
5975
| 3.0.0 | Case-insensitive comparison removed |
6076
| 0.3.9 | Created |
6177

@@ -65,3 +81,4 @@ Message template for this validator includes `{{startValue}}`.
6581
- [EndsWith](EndsWith.md)
6682
- [In](In.md)
6783
- [Regex](Regex.md)
84+
- [Trimmed](Trimmed.md)

docs/validators/Trimmed.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<!--
2+
SPDX-License-Identifier: MIT
3+
SPDX-FileCopyrightText: (c) Respect Project Contributors
4+
-->
5+
6+
# Trimmed
7+
8+
- `Trimmed()`
9+
- `Trimmed(string ...$trimValues)`
10+
11+
Validates whether the input string does not start or end with the given values.
12+
13+
When no values are provided, this validator uses a default list of Unicode invisible characters (including regular whitespace, non-breaking spaces, and zero-width characters).
14+
15+
With the default values:
16+
17+
```php
18+
v::trimmed()->assert('lorem ipsum');
19+
// Validation passes successfully
20+
21+
v::trimmed()->assert("\u{200B}lorem");
22+
// → "​lorem" must be trimmed
23+
```
24+
25+
With custom values:
26+
27+
```php
28+
v::trimmed('foo', 'bar')->assert('bazqux');
29+
// Validation passes successfully
30+
31+
v::trimmed('foo', 'bar')->assert('foobaz');
32+
// → "foobaz" must be trimmed of "foo" or "bar"
33+
```
34+
35+
This validator composes [StartsWith](StartsWith.md) and [EndsWith](EndsWith.md).
36+
37+
## Templates
38+
39+
### `Trimmed::TEMPLATE_STANDARD`
40+
41+
| Mode | Template |
42+
| ---------: | :------------------------------ |
43+
| `default` | {{subject}} must be trimmed |
44+
| `inverted` | {{subject}} must not be trimmed |
45+
46+
### `Trimmed::TEMPLATE_CUSTOM`
47+
48+
| Mode | Template |
49+
| ---------: | :------------------------------------------------------------- |
50+
| `default` | {{subject}} must be trimmed of {{trimValues&#124;list:or}} |
51+
| `inverted` | {{subject}} must not be trimmed of {{trimValues&#124;list:or}} |
52+
53+
## Template placeholders
54+
55+
| Placeholder | Description |
56+
| ------------ | ---------------------------------------------------------------- |
57+
| `subject` | The validated input or the custom validator name (if specified). |
58+
| `trimValues` | |
59+
60+
## Categorization
61+
62+
- Strings
63+
64+
## Changelog
65+
66+
| Version | Description |
67+
| ------: | :---------- |
68+
| 3.1.0 | Created |
69+
70+
## See Also
71+
72+
- [EndsWith](EndsWith.md)
73+
- [Space](Space.md)
74+
- [Spaced](Spaced.md)
75+
- [StartsWith](StartsWith.md)

src/Mixins/AllBuilder.php

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Mixins/AllChain.php

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Mixins/Builder.php

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Mixins/Chain.php

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Mixins/KeyBuilder.php

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)