Fixed parent directory link not working when directory path contained URL special characters

This commit is contained in:
Chris Kankiewicz
2020-04-06 15:23:28 -07:00
parent 97187d2c55
commit 4cbc5e833a
6 changed files with 67 additions and 35 deletions

View File

@@ -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,

View File

@@ -1,26 +0,0 @@
<?php
namespace App\ViewFunctions;
use App\Support\Str;
class ParentDir extends ViewFunction
{
/** @var string The function name */
protected $name = 'parent_dir';
/**
* Get the parent directory for a given path.
*
* @param string $path
*
* @return string
*/
public function __invoke(string $path)
{
$parentDir = Str::explode($path, DIRECTORY_SEPARATOR)
->filter()->slice(0, -1)->implode(DIRECTORY_SEPARATOR);
return empty($parentDir) ? '.' : sprintf('?dir=%s', $parentDir);
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace App\ViewFunctions;
use App\Support\Str;
class ParentUrl extends ViewFunction
{
/** @var string The function name */
protected $name = 'parent_url';
/** @var string The directory separator */
protected $directorySeparator;
/**
* Create a new ParentUrl object.
*
* @param string $directorySeparator
*/
public function __construct(string $directorySeparator = DIRECTORY_SEPARATOR)
{
$this->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);
}
}

View File

@@ -1,5 +1,5 @@
<a
href="{{ parentDir ? parent_dir(path) : url(file.getPathname, 'dir') }}"
href="{{ parentDir ? parent_url(path) : url(file.getPathname, 'dir') }}"
class="flex flex-col items-center rounded-lg font-mono group hover:bg-gray-200 hover:shadow"
>
<div class="flex justify-between items-center p-4 w-full">

View File

@@ -53,7 +53,7 @@ class TwigFactoryTest extends TestCase
);
$this->assertInstanceOf(
ViewFunctions\ParentDir::class,
ViewFunctions\ParentUrl::class,
$twig->getEnvironment()->getFunction('parent_dir')->getCallable()
);

View File

@@ -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'));
}
}