Skip to content

Commit b056244

Browse files
authored
Merge pull request #3005 from michalsn/uri_setSilent
Add setSilent() method to URI class
2 parents 9bbc991 + 71731d2 commit b056244

File tree

3 files changed

+124
-1
lines changed

3 files changed

+124
-1
lines changed

system/HTTP/URI.php

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ class URI
153153
*/
154154
protected $showPassword = false;
155155

156+
/**
157+
* If true, will continue instead of throwing exceptions.
158+
*
159+
* @var boolean
160+
*/
161+
protected $silent = false;
162+
156163
//--------------------------------------------------------------------
157164

158165
/**
@@ -172,6 +179,23 @@ public function __construct(string $uri = null)
172179

173180
//--------------------------------------------------------------------
174181

182+
/**
183+
* If $silent == true, then will not throw exceptions and will
184+
* attempt to continue gracefully.
185+
*
186+
* @param boolean $silent
187+
*
188+
* @return URI
189+
*/
190+
public function setSilent(bool $silent = true)
191+
{
192+
$this->silent = $silent;
193+
194+
return $this;
195+
}
196+
197+
//--------------------------------------------------------------------
198+
175199
/**
176200
* Sets and overwrites any current URI information.
177201
*
@@ -187,6 +211,11 @@ public function setURI(string $uri = null)
187211

188212
if ($parts === false)
189213
{
214+
if ($this->silent)
215+
{
216+
return $this;
217+
}
218+
190219
throw HTTPException::forUnableToParseURI($uri);
191220
}
192221

@@ -480,7 +509,7 @@ public function getSegment(int $number): string
480509
// but we still have to deal with a zero-based array.
481510
$number -= 1;
482511

483-
if ($number > count($this->segments))
512+
if ($number > count($this->segments) && ! $this->silent)
484513
{
485514
throw HTTPException::forURISegmentOutOfRange($number);
486515
}
@@ -505,6 +534,11 @@ public function setSegment(int $number, $value)
505534

506535
if ($number > count($this->segments) + 1)
507536
{
537+
if ($this->silent)
538+
{
539+
return $this;
540+
}
541+
508542
throw HTTPException::forURISegmentOutOfRange($number);
509543
}
510544

@@ -689,6 +723,11 @@ public function setPort(int $port = null)
689723

690724
if ($port <= 0 || $port > 65535)
691725
{
726+
if ($this->silent)
727+
{
728+
return $this;
729+
}
730+
692731
throw HTTPException::forInvalidPort($port);
693732
}
694733

@@ -749,6 +788,11 @@ public function setQuery(string $query)
749788
{
750789
if (strpos($query, '#') !== false)
751790
{
791+
if ($this->silent)
792+
{
793+
return $this;
794+
}
795+
752796
throw HTTPException::forMalformedQueryString();
753797
}
754798

tests/system/HTTP/URITest.php

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ public function testSegmentOutOfRange()
6565

6666
//--------------------------------------------------------------------
6767

68+
public function testSegmentOutOfRangeWithSilent()
69+
{
70+
$url = 'http://abc.com/a123/b/c';
71+
$uri = new URI($url);
72+
$this->assertEquals('', $uri->setSilent()->getSegment(22));
73+
}
74+
75+
//--------------------------------------------------------------------
76+
6877
public function testCanCastAsString()
6978
{
7079
$url = 'http://username:password@hostname:9090/path?arg=value#anchor';
@@ -225,6 +234,18 @@ public function testSetPortInvalidValues()
225234

226235
//--------------------------------------------------------------------
227236

237+
public function testSetPortInvalidValuesSilent()
238+
{
239+
$url = 'http://example.com/path';
240+
$uri = new URI($url);
241+
242+
$uri->setSilent()->setPort(70000);
243+
244+
$this->assertEquals(null, $uri->getPort());
245+
}
246+
247+
//--------------------------------------------------------------------
248+
228249
public function testSetPortTooSmall()
229250
{
230251
$url = 'http://example.com/path';
@@ -372,6 +393,18 @@ public function testSetQueryThrowsErrorWhenFragmentPresent()
372393

373394
//--------------------------------------------------------------------
374395

396+
public function testSetQueryThrowsErrorWhenFragmentPresentSilent()
397+
{
398+
$url = 'http://example.com/path';
399+
$uri = new URI($url);
400+
401+
$uri->setSilent()->setQuery('?key=value#fragment');
402+
403+
$this->assertEquals('', $uri->getQuery());
404+
}
405+
406+
//--------------------------------------------------------------------
407+
375408
public function authorityInfo()
376409
{
377410
return [
@@ -783,6 +816,18 @@ public function testSetBadSegment()
783816
$uri->setSegment(6, 'banana');
784817
}
785818

819+
public function testSetBadSegmentSilent()
820+
{
821+
$base = 'http://example.com/foo/bar/baz';
822+
823+
$uri = new URI($base);
824+
825+
$segments = $uri->getSegments();
826+
$uri->setSilent()->setSegment(6, 'banana');
827+
828+
$this->assertEquals($segments, $uri->getSegments());
829+
}
830+
786831
//--------------------------------------------------------------------
787832
// Exploratory testing, investigating https://github.com/codeigniter4/CodeIgniter4/issues/2016
788833

@@ -856,4 +901,24 @@ public function testEmptyURIPath()
856901
$this->assertEquals(0, $uri->getTotalSegments());
857902
}
858903

904+
public function testSetURI()
905+
{
906+
$url = ':';
907+
$uri = new URI();
908+
909+
$this->expectException(HTTPException::class);
910+
$this->expectExceptionMessage(lang('HTTP.cannotParseURI', [$url]));
911+
912+
$uri->setURI($url);
913+
}
914+
915+
public function testSetURISilent()
916+
{
917+
$url = ':';
918+
$uri = new URI();
919+
$uri->setSilent()->setURI($url);
920+
921+
$this->assertTrue(true);
922+
}
923+
859924
}

user_guide_src/source/libraries/uri.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,17 @@ Finally, you can retrieve an array of all of the segments::
248248
1 => '15',
249249
2 => 'profile'
250250
]
251+
252+
===========================
253+
Disable Throwing Exceptions
254+
===========================
255+
256+
By default, some methods of this class may throw an exception. If you want to disable it, you can set a special flag
257+
that will prevent throwing exceptions.
258+
::
259+
260+
// Disable throwing exceptions
261+
$uri->setSilent();
262+
263+
// Enable throwing exceptions (default)
264+
$uri->setSilent(false);

0 commit comments

Comments
 (0)