Skip to content

Commit

Permalink
🐛 Fix for issue #209 (#210)
Browse files Browse the repository at this point in the history
* ✅ (TDD) amending test case for #209

* 🐛 fixed uri parsing

* Apply fixes from StyleCI

* 🐛 #! uri now supported

* 📝 adding changelog for #209

* Apply fixes from StyleCI
  • Loading branch information
carbontwelve authored Jun 9, 2017
1 parent 876dd10 commit 864679a
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 1.0.9
## Bugfixes
- #209 Fix Url helper parsing of Uri with parameters

# 1.0.8
## Bugfixes
- #186 Removed dead code in File class
Expand Down
110 changes: 95 additions & 15 deletions src/Entities/Url.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,7 @@ public function parse($uri = '')
$this->loadSiteUrl();
$uri = $this->cleanUri($uri);

$parts = explode('/', $uri);
foreach ($parts as &$part) {
if (strpos($part, 'index') !== false) {
$part = null;
continue;
}
$part = rawurlencode($part);
}
unset($part);

$parts = array_filter($parts, function ($value) {
return ! is_null($value);
});

return $this->siteUrl.'/'.implode('/', $parts);
return $this->siteUrl.'/'.$this->encode($uri);
}

private function loadSiteUrl()
Expand All @@ -70,4 +56,98 @@ private function cleanUri($text)

return ($text === false) ? '' : $text;
}

/**
* @param string $uri
* @return array
*/
private function encode($uri = '')
{
$parts = explode('/', $uri);
foreach ($parts as &$part) {
if (strpos($part, 'index') !== false) {
$part = null;
continue;
}
$part = $this->encodePart($part);
}
unset($part);

$parts = array_filter($parts, function ($value) {
return ! is_null($value);
});

// If the last uri part doesn't contain a file name e.g. index.html or readme.txt

$e = end($parts);
if (
strlen($e) > 0 &&
strpos($e, '?') === false &&
strpos($e, '=') === false &&
strpos($e, '&') === false &&
strpos($e, '#') === false &&
strpos($e, '.') === false
) {
array_push($parts, '');
}

return trim(implode('/', $parts));
}

/**
* Ensures that uri parts containing ? or # get encoded correctly.
*
* @param string $part
* @return string
*/
private function encodePart($part)
{
if (strpos($part, '?') !== false) {
if (strpos($part, '?') === 0) {
$output = '?';
$part = substr($part, 1);
} else {
$pe = explode('?', $part);
$output = $pe[0].'/?';
$part = $pe[1];
unset($pe);
}

if (strpos($part, '&')) {
$parts = explode('&', $part);
} else {
$parts = [$part];
}
foreach ($parts as &$p) {
if (strpos($p, '=') !== false) {
$pe = explode('=', $p);
$p = $pe[0].'='.urlencode($pe[1]);
}
}
unset($p, $pe);

$output .= implode('&', $parts);

return $output;
}

if (strpos($part, '#') !== false) {
if (strpos($part, '#') === 0) {
if (substr($part, 1, 1) === '!') {
return '#!'.rawurlencode(substr($part, 2));
}

return '#'.rawurlencode(substr($part, 1));
}

$pe = explode('#', $part);
if (substr($pe[1], 0, 1) === '!') {
return $pe[0].'/#!'.rawurlencode(substr($pe[1], 1));
}

return $pe[0].'/#'.rawurlencode($pe[1]);
}

return rawurlencode($part);
}
}
53 changes: 39 additions & 14 deletions tests/EntitiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,33 +21,58 @@ public function testUrlEntity()
$this->assertSame('http://www.example.com/', $url->parse(''));
$this->assertSame('http://www.example.com/', $url->parse('/'));

$this->assertSame('http://www.example.com/?abc=123&def=456', $url->parse('?abc=123&def=456'));
$this->assertSame('http://www.example.com/?abc=123&def=456', $url->parse('/?abc=123&def=456'));

$this->assertSame('http://www.example.com/abc', $url->parse('abc'));
$this->assertSame('http://www.example.com/abc', $url->parse('/abc'));
$this->assertSame('http://www.example.com/#abc-123', $url->parse('#abc-123'));
$this->assertSame('http://www.example.com/#abc-123', $url->parse('/#abc-123'));

$this->assertSame('http://www.example.com/abc/', $url->parse('abc'));
$this->assertSame('http://www.example.com/abc/', $url->parse('/abc'));
$this->assertSame('http://www.example.com/abc/', $url->parse('/abc/'));

$this->assertSame('http://www.example.com/abc/123', $url->parse('abc/123'));
$this->assertSame('http://www.example.com/abc/123', $url->parse('/abc/123'));
$this->assertSame('http://www.example.com/abc/#!abc', $url->parse('abc#!abc'));
$this->assertSame('http://www.example.com/abc/#!abc', $url->parse('/abc#!abc'));
$this->assertSame('http://www.example.com/abc/#!abc', $url->parse('/abc/#!abc'));

$this->assertSame('http://www.example.com/abc/123/', $url->parse('abc/123'));
$this->assertSame('http://www.example.com/abc/123/', $url->parse('/abc/123'));
$this->assertSame('http://www.example.com/abc/123/', $url->parse('/abc/123/'));

$this->assertEquals('http://www.example.com/abc', $url->parse('abc/index.html'));
$this->assertEquals('http://www.example.com/abc/123', $url->parse('abc/123/index.html'));
$this->assertSame('http://www.example.com/abc/123/?abc=123&def=456', $url->parse('abc/123?abc=123&def=456'));
$this->assertSame('http://www.example.com/abc/123/?abc=123&def=456', $url->parse('/abc/123?abc=123&def=456'));
$this->assertSame('http://www.example.com/abc/123/?abc=123&def=456', $url->parse('/abc/123/?abc=123&def=456'));

$this->assertSame('http://www.example.com/abc/123/?abc=123+xyz&def=456+abc', $url->parse('abc/123?abc=123 xyz&def=456 abc'));
$this->assertSame('http://www.example.com/abc/123/?abc=123+xyz&def=456+abc', $url->parse('/abc/123?abc=123 xyz&def=456 abc'));
$this->assertSame('http://www.example.com/abc/123/?abc=123+xyz&def=456+abc', $url->parse('/abc/123/?abc=123 xyz&def=456 abc'));

$this->assertSame('http://www.example.com/abc/123/#abc-123', $url->parse('abc/123#abc-123'));
$this->assertSame('http://www.example.com/abc/123/#abc-123', $url->parse('/abc/123#abc-123'));
$this->assertSame('http://www.example.com/abc/123/#abc-123', $url->parse('/abc/123/#abc-123'));

$this->assertSame('http://www.example.com/abc/123/#abc%20123', $url->parse('abc/123#abc 123'));
$this->assertSame('http://www.example.com/abc/123/#abc%20123', $url->parse('/abc/123#abc 123'));
$this->assertSame('http://www.example.com/abc/123/#abc%20123', $url->parse('/abc/123/#abc 123'));

$this->assertEquals('http://www.example.com/abc/', $url->parse('abc/index.html'));
$this->assertEquals('http://www.example.com/abc/123/', $url->parse('abc/123/index.html'));
$this->assertEquals('http://www.example.com/abc/123.html', $url->parse('abc/123.html'));

$this->assertEquals('http://www.example.com/0', $url->parse(0));
$this->assertEquals('http://www.example.com/0/', $url->parse(0));
$this->assertEquals('http://www.example.com/', $url->parse(null));
$this->assertEquals('http://www.example.com/-1', $url->parse(-1));
$this->assertEquals('http://www.example.com/3.33', $url->parse(3.33));
$this->assertEquals('http://www.example.com/-1/', $url->parse(-1));
$this->assertEquals('http://www.example.com/3.33', $url->parse(3.33)); // 3.33 is a file named 3 with the ext 33

$this->assertSame('http://www.example.com/hello%20world', $url->parse('hello world'));
$this->assertSame('http://www.example.com/hello%20world', $url->parse('/hello world'));
$this->assertSame('http://www.example.com/hello%20world/', $url->parse('hello world'));
$this->assertSame('http://www.example.com/hello%20world/', $url->parse('/hello world'));
$this->assertSame('http://www.example.com/hello%20world/', $url->parse('/hello world/'));

$this->assertSame('http://www.example.com/hello%20world/this%20is%20a%20test', $url->parse('hello world/this is a test'));
$this->assertSame('http://www.example.com/hello%20world/this%20is%20a%20test', $url->parse('/hello world/this is a test'));
$this->assertSame('http://www.example.com/hello%20world/this%20is%20a%20test/', $url->parse('hello world/this is a test'));
$this->assertSame('http://www.example.com/hello%20world/this%20is%20a%20test/', $url->parse('/hello world/this is a test'));
$this->assertSame('http://www.example.com/hello%20world/this%20is%20a%20test/', $url->parse('/hello world/this is a test/'));

$this->assertSame('http://www.example.com/hello/world', $url->parse('hello/world/index.html'));
$this->assertSame('http://www.example.com/hello/world/', $url->parse('hello/world/index.html'));
}

public function testUrlEntityThrowsException()
Expand Down
2 changes: 1 addition & 1 deletion tests/ViewFileTraitTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public function testGetUrlHelper()
__DIR__ . '/mocks/TestExcerptFile.md', ['site' => ['url' => 'http://www.example.com']]
);

$this->assertEquals('http://www.example.com/testexcerptfile', $viewFile->getUrl());
$this->assertEquals('http://www.example.com/testexcerptfile/', $viewFile->getUrl());

$viewFile->getFile()->setData(['permalink' => '/folder1/folder2/folder3/test.html']);
$this->assertEquals('http://www.example.com/folder1/folder2/folder3/test.html', $viewFile->getUrl());
Expand Down

0 comments on commit 864679a

Please sign in to comment.