Skip to content

Commit 1bdf24f

Browse files
Added Validator::allowedRegexValues (#371)
Co-authored-by: Chaim Paperman <[email protected]>
1 parent 8e53d9a commit 1bdf24f

File tree

6 files changed

+90
-7
lines changed

6 files changed

+90
-7
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,11 @@ One or more environment variables failed assertions: SESSION_STORE is not an
257257
allowed value
258258
```
259259

260+
It is also possible to define a regex that your environment variable should be.
261+
```php
262+
$dotenv->required('FOO')->allowedRegexValues('([[:lower:]]{3})');
263+
```
264+
260265
### Comments
261266

262267
You can comment your `.env` file using the `#` character. E.g.

src/Regex/Regex.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,21 @@
66

77
class Regex
88
{
9+
/**
10+
* Perform a preg match, wrapping up the result.
11+
*
12+
* @param string $pattern
13+
* @param string $subject
14+
*
15+
* @return \Dotenv\Regex\Result
16+
*/
17+
public static function match($pattern, $subject)
18+
{
19+
return self::pregAndWrap(function ($subject) use ($pattern) {
20+
return (int) @preg_match($pattern, $subject);
21+
}, $subject);
22+
}
23+
924
/**
1025
* Perform a preg replace, wrapping up the result.
1126
*
@@ -18,7 +33,7 @@ class Regex
1833
public static function replace($pattern, $replacement, $subject)
1934
{
2035
return self::pregAndWrap(function ($subject) use ($pattern, $replacement) {
21-
return preg_replace($pattern, $replacement, $subject);
36+
return (string) @preg_replace($pattern, $replacement, $subject);
2237
}, $subject);
2338
}
2439

@@ -34,7 +49,7 @@ public static function replace($pattern, $replacement, $subject)
3449
public static function replaceCallback($pattern, callable $callback, $subject)
3550
{
3651
return self::pregAndWrap(function ($subject) use ($pattern, $callback) {
37-
return preg_replace_callback($pattern, $callback, $subject);
52+
return (string) @preg_replace_callback($pattern, $callback, $subject);
3853
}, $subject);
3954
}
4055

@@ -48,7 +63,7 @@ public static function replaceCallback($pattern, callable $callback, $subject)
4863
*/
4964
private static function pregAndWrap(callable $operation, $subject)
5065
{
51-
$result = (string) @$operation($subject);
66+
$result = $operation($subject);
5267

5368
if (($e = preg_last_error()) !== PREG_NO_ERROR) {
5469
return Error::create(self::lookupError($e));

src/Regex/Result.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ abstract public function success();
1414
/**
1515
* Get the error value, if possible.
1616
*
17-
* @return string
17+
* @return string|int
1818
*/
1919
public function getSuccess()
2020
{

src/Regex/Success.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
class Success extends Result
99
{
1010
/**
11-
* @var string
11+
* @var string|int
1212
*/
1313
private $value;
1414

1515
/**
1616
* Internal constructor for a success value.
1717
*
18-
* @param string $value
18+
* @param string|int $value
1919
*
2020
* @return void
2121
*/
@@ -27,7 +27,7 @@ private function __construct($value)
2727
/**
2828
* Create a new success value.
2929
*
30-
* @param string $value
30+
* @param string|int $value
3131
*
3232
* @return \Dotenv\Regex\Result
3333
*/

src/Validator.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Dotenv;
44

55
use Dotenv\Exception\ValidationException;
6+
use Dotenv\Regex\Regex;
67

78
/**
89
* This is the validator class.
@@ -138,6 +139,30 @@ function ($value) use ($choices) {
138139
);
139140
}
140141

142+
/**
143+
* Assert that each variable matches the given regular expression.
144+
*
145+
* @param string $regex
146+
*
147+
* @throws \Dotenv\Exception\ValidationException
148+
*
149+
* @return \Dotenv\Validator
150+
*/
151+
public function allowedRegexValues($regex)
152+
{
153+
return $this->assertCallback(
154+
function ($value) use ($regex)
155+
{
156+
if ($value === null) {
157+
return true;
158+
}
159+
160+
return Regex::match($regex, $value)->success()->getOrElse(0) === 1;
161+
},
162+
sprintf('does not match "%s"' , $regex)
163+
);
164+
}
165+
141166
/**
142167
* Assert that the callback returns true for each variable.
143168
*

tests/Dotenv/ValidatorTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,42 @@ public function testIfPresentIntegerNonExist()
408408
$dotenv->ifPresent(['VAR_DOES_NOT_EXIST_234782462764'])->isInteger();
409409
$this->assertTrue(true);
410410
}
411+
412+
public function testDotenvRegexMatchPass()
413+
{
414+
$dotenv = Dotenv::create($this->fixturesFolder);
415+
$dotenv->load();
416+
$dotenv->required('FOO')->allowedRegexValues('([[:lower:]]{3})');
417+
$this->assertTrue(true);
418+
}
419+
420+
/**
421+
* @expectedException \Dotenv\Exception\ValidationException
422+
* @expectedExceptionMessage One or more environment variables failed assertions: FOO does not match "/^([[:lower:]]{1})$/".
423+
*/
424+
public function testDotenvRegexMatchFail()
425+
{
426+
$dotenv = Dotenv::create($this->fixturesFolder);
427+
$dotenv->load();
428+
$dotenv->required('FOO')->allowedRegexValues('/^([[:lower:]]{1})$/');
429+
}
430+
431+
/**
432+
* @expectedException \Dotenv\Exception\ValidationException
433+
* @expectedExceptionMessage One or more environment variables failed assertions: FOO does not match "/([[:lower:]{1{".
434+
*/
435+
public function testDotenvRegexMatchError()
436+
{
437+
$dotenv = Dotenv::create($this->fixturesFolder);
438+
$dotenv->load();
439+
$dotenv->required('FOO')->allowedRegexValues('/([[:lower:]{1{');
440+
}
441+
442+
public function testDotenvRegexMatchNotPresent()
443+
{
444+
$dotenv = Dotenv::create($this->fixturesFolder);
445+
$dotenv->load();
446+
$dotenv->ifPresent('FOOOOOOOOOOO')->allowedRegexValues('([[:lower:]]{3})');
447+
$this->assertTrue(true);
448+
}
411449
}

0 commit comments

Comments
 (0)