Skip to content

Commit 16c40a4

Browse files
authored
Merge pull request #5268 from kenjis/add-valid_url_strict
feat: add valid_url_strict rule
2 parents 01c55b0 + 2ad981a commit 16c40a4

File tree

3 files changed

+98
-8
lines changed

3 files changed

+98
-8
lines changed

system/Validation/FormatRules.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,10 @@ public function valid_ip(?string $ip = null, ?string $which = null): bool
268268
}
269269

270270
/**
271-
* Checks a URL to ensure it's formed correctly.
271+
* Checks a string to ensure it is (loosely) a URL.
272+
*
273+
* Warning: this rule will pass basic strings like
274+
* "banana"; use valid_url_strict for a stricter rule.
272275
*
273276
* @param string $str
274277
*/
@@ -291,6 +294,27 @@ public function valid_url(?string $str = null): bool
291294
return filter_var($str, FILTER_VALIDATE_URL) !== false;
292295
}
293296

297+
/**
298+
* Checks a URL to ensure it's formed correctly.
299+
*
300+
* @param string|null $validSchemes comma separated list of allowed schemes
301+
*/
302+
public function valid_url_strict(?string $str = null, ?string $validSchemes = null): bool
303+
{
304+
if (empty($str)) {
305+
return false;
306+
}
307+
308+
$scheme = strtolower(parse_url($str, PHP_URL_SCHEME));
309+
$validSchemes = explode(
310+
',',
311+
strtolower($validSchemes ?? 'http,https')
312+
);
313+
314+
return in_array($scheme, $validSchemes, true)
315+
&& filter_var($str, FILTER_VALIDATE_URL) !== false;
316+
}
317+
294318
/**
295319
* Checks for a valid date and matches a given date format
296320
*

tests/system/Validation/FormatRulesTest.php

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public function testRegexMatchFalse()
8888
/**
8989
* @dataProvider urlProvider
9090
*/
91-
public function testValidURL(?string $url, bool $expected)
91+
public function testValidURL(?string $url, bool $isLoose, bool $isStrict)
9292
{
9393
$data = [
9494
'foo' => $url,
@@ -98,7 +98,36 @@ public function testValidURL(?string $url, bool $expected)
9898
'foo' => 'valid_url',
9999
]);
100100

101-
$this->assertSame($expected, $this->validation->run($data));
101+
$this->assertSame($isLoose, $this->validation->run($data));
102+
}
103+
104+
/**
105+
* @dataProvider urlProvider
106+
*/
107+
public function testValidURLStrict(?string $url, bool $isLoose, bool $isStrict)
108+
{
109+
$data = [
110+
'foo' => $url,
111+
];
112+
113+
$this->validation->setRules([
114+
'foo' => 'valid_url_strict',
115+
]);
116+
117+
$this->assertSame($isStrict, $this->validation->run($data));
118+
}
119+
120+
public function testValidURLStrictWithSchema()
121+
{
122+
$data = [
123+
'foo' => 'http://www.codeigniter.com',
124+
];
125+
126+
$this->validation->setRules([
127+
'foo' => 'valid_url_strict[https]',
128+
]);
129+
130+
$this->assertFalse($this->validation->run($data));
102131
}
103132

104133
public function urlProvider()
@@ -107,60 +136,90 @@ public function urlProvider()
107136
[
108137
'www.codeigniter.com',
109138
true,
139+
false,
110140
],
111141
[
112142
'http://codeigniter.com',
113143
true,
144+
true,
114145
],
115-
//https://bugs.php.net/bug.php?id=51192
146+
// https://bugs.php.net/bug.php?id=51192
116147
[
117148
'http://accept-dashes.tld',
118149
true,
150+
true,
119151
],
120152
[
121153
'http://reject_underscores',
122154
false,
155+
false,
123156
],
124-
// https://github.com/codeigniter4/CodeIgniter/issues/4415
157+
// https://github.com/bcit-ci/CodeIgniter/issues/4415
125158
[
126159
'http://[::1]/ipv6',
127160
true,
161+
true,
128162
],
129163
[
130164
'htt://www.codeigniter.com',
131165
false,
166+
false,
132167
],
133168
[
134169
'',
135170
false,
171+
false,
172+
],
173+
// https://github.com/codeigniter4/CodeIgniter4/issues/3156
174+
[
175+
'codeigniter',
176+
true, // What?
177+
false,
136178
],
137179
[
138180
'code igniter',
139181
false,
182+
false,
140183
],
141184
[
142185
null,
143186
false,
187+
false,
144188
],
145189
[
146190
'http://',
147-
true,
148-
], // this is apparently valid!
191+
true, // Why?
192+
false,
193+
],
149194
[
150195
'http:///oops.com',
151196
false,
197+
false,
152198
],
153199
[
154200
'123.com',
155201
true,
202+
false,
156203
],
157204
[
158205
'abc.123',
159206
true,
207+
false,
160208
],
161209
[
162210
'http:8080//abc.com',
211+
true, // Insane?
212+
false,
213+
],
214+
[
215+
163216
true,
217+
false,
218+
],
219+
[
220+
'//example.com',
221+
false,
222+
false,
164223
],
165224
];
166225
}

user_guide_src/source/libraries/validation.rst

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,14 @@ valid_emails No Fails if any value provided in a comma
860860
valid_ip No Fails if the supplied IP is not valid. valid_ip[ipv6]
861861
Accepts an optional parameter of ‘ipv4’ or
862862
‘ipv6’ to specify an IP format.
863-
valid_url No Fails if field does not contain a valid URL.
863+
valid_url No Fails if field does not contain (loosely) a
864+
URL. Includes simple strings that could be
865+
hostnames, like "codeigniter".
866+
valid_url_strict Yes Fails if field does not contain a valid URL. valid_url_strict[https]
867+
You can optionally specify a list of valid
868+
schemas. If not specified, ``http,https``
869+
are valid. This rule uses
870+
PHP's ``FILTER_VALIDATE_URL``.
864871
valid_date No Fails if field does not contain a valid date. valid_date[d/m/Y]
865872
Accepts an optional parameter to matches
866873
a date format.

0 commit comments

Comments
 (0)