diff --git a/app/src/Factories/TwigFactory.php b/app/src/Factories/TwigFactory.php index a5a9881..1ca5c66 100644 --- a/app/src/Factories/TwigFactory.php +++ b/app/src/Factories/TwigFactory.php @@ -19,7 +19,7 @@ class TwigFactory ViewFunctions\Config::class, ViewFunctions\Icon::class, ViewFunctions\Markdown::class, - ViewFunctions\ParentDir::class, + ViewFunctions\ParentUrl::class, ViewFunctions\SizeForHumans::class, ViewFunctions\Translate::class, ViewFunctions\Url::class, diff --git a/app/src/ViewFunctions/ParentDir.php b/app/src/ViewFunctions/ParentDir.php deleted file mode 100644 index 4d5524d..0000000 --- a/app/src/ViewFunctions/ParentDir.php +++ /dev/null @@ -1,26 +0,0 @@ -filter()->slice(0, -1)->implode(DIRECTORY_SEPARATOR); - - return empty($parentDir) ? '.' : sprintf('?dir=%s', $parentDir); - } -} diff --git a/app/src/ViewFunctions/ParentUrl.php b/app/src/ViewFunctions/ParentUrl.php new file mode 100644 index 0000000..48ce4cc --- /dev/null +++ b/app/src/ViewFunctions/ParentUrl.php @@ -0,0 +1,42 @@ +directorySeparator = $directorySeparator; + } + + /** + * Get the parent directory for a given path. + * + * @param string $path + * + * @return string + */ + public function __invoke(string $path) + { + $parentDir = Str::explode($path, $this->directorySeparator)->map( + function (string $segment): string { + return urlencode($segment); + } + )->filter()->slice(0, -1)->implode($this->directorySeparator); + + return empty($parentDir) ? '.' : sprintf('?dir=%s', $parentDir); + } +} diff --git a/app/views/components/file.twig b/app/views/components/file.twig index d8e8578..9ce450c 100644 --- a/app/views/components/file.twig +++ b/app/views/components/file.twig @@ -1,5 +1,5 @@
diff --git a/tests/Factories/TwigFactoryTest.php b/tests/Factories/TwigFactoryTest.php index 34b65b6..7eea3db 100644 --- a/tests/Factories/TwigFactoryTest.php +++ b/tests/Factories/TwigFactoryTest.php @@ -53,7 +53,7 @@ class TwigFactoryTest extends TestCase ); $this->assertInstanceOf( - ViewFunctions\ParentDir::class, + ViewFunctions\ParentUrl::class, $twig->getEnvironment()->getFunction('parent_dir')->getCallable() ); diff --git a/tests/ViewFunctions/ParentDirTest.php b/tests/ViewFunctions/ParentUrlTest.php similarity index 50% rename from tests/ViewFunctions/ParentDirTest.php rename to tests/ViewFunctions/ParentUrlTest.php index 3c7c7f5..2671866 100644 --- a/tests/ViewFunctions/ParentDirTest.php +++ b/tests/ViewFunctions/ParentUrlTest.php @@ -2,28 +2,28 @@ namespace Tests\ViewFunctions; -use App\ViewFunctions\ParentDir; +use App\ViewFunctions\ParentUrl; use Tests\TestCase; -class ParentDirTest extends TestCase +class ParentUrlTest extends TestCase { public function test_it_can_get_the_parent_directory_when_one_level_deep(): void { - $parentDir = new ParentDir; + $parentDir = new ParentUrl; $this->assertEquals('.', $parentDir('foo')); } public function test_it_can_get_the_parent_directory_when_two_levels_deep(): void { - $parentDir = new ParentDir; + $parentDir = new ParentUrl; $this->assertEquals('?dir=foo', $parentDir('foo/bar')); } public function test_it_can_get_the_parent_directory_when_three_levels_deep(): void { - $parentDir = new ParentDir; + $parentDir = new ParentUrl; $this->assertEquals('?dir=foo/bar', $parentDir('foo/bar/baz')); } @@ -32,8 +32,24 @@ class ParentDirTest extends TestCase { $_SERVER['SCRIPT_NAME'] = '/some/dir/index.php'; - $parentDir = new ParentDir; + $parentDir = new ParentUrl; $this->assertEquals('?dir=foo/bar', $parentDir('foo/bar/baz')); } + + public function test_it_can_get_the_parent_directory_with_back_slashes(): void + { + $parentDir = new ParentUrl('\\'); + + $this->assertEquals('?dir=foo\bar', $parentDir('foo\bar\baz')); + } + + public function test_parent_url_segments_are_url_encoded(): void + { + $parentDir = new ParentUrl; + + $this->assertEquals('?dir=foo/bar%2Bbaz', $parentDir('foo/bar+baz/qux')); + $this->assertEquals('?dir=foo/bar%23baz', $parentDir('foo/bar#baz/qux')); + $this->assertEquals('?dir=foo/bar%26baz', $parentDir('foo/bar&baz/qux')); + } }