mirror of
https://github.com/DirectoryLister/DirectoryLister.git
synced 2025-08-11 00:24:02 +02:00
Added alternate base path configuration
This commit is contained in:
@@ -40,7 +40,7 @@ Features
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- Directory Lister requires [PHP](https://www.php.net/) >= 8.0
|
||||
- Directory Lister requires [PHP](https://www.php.net/) >= 8.1
|
||||
- The [Zip](https://www.php.net/manual/en/book.zip.php) extension is required for zip downloads
|
||||
- The [DOM](https://www.php.net/en/dom) and [Fileinfo](https://www.php.net/manual/en/book.fileinfo.php) extensions are required for README rendering
|
||||
|
||||
|
@@ -1,15 +1,19 @@
|
||||
<?php
|
||||
|
||||
use App\Config;
|
||||
use App\Factories;
|
||||
use App\Middlewares;
|
||||
use App\SortMethods;
|
||||
use App\ViewFunctions;
|
||||
use function DI\create;
|
||||
use function DI\env;
|
||||
use function DI\factory;
|
||||
use function DI\get;
|
||||
use function DI\string;
|
||||
use function DI\value;
|
||||
|
||||
return [
|
||||
/** Path definitions */
|
||||
/** Path definitions and helpers */
|
||||
'base_path' => dirname(__DIR__, 2),
|
||||
'app_path' => dirname(__DIR__),
|
||||
'asset_path' => string('{app_path}/assets'),
|
||||
@@ -18,6 +22,8 @@ return [
|
||||
'source_path' => string('{app_path}/src'),
|
||||
'translations_path' => string('{app_path}/translations'),
|
||||
'views_path' => string('{app_path}/views'),
|
||||
'files_path' => env('FILES_PATH', get('base_path')),
|
||||
'full_path' => value(fn (string $path, Config $config): string => $config->get('files_path') . '/' . $path),
|
||||
|
||||
/** Array of application files (to be hidden) */
|
||||
'app_files' => ['app', 'index.php', '.analytics', '.env', '.env.example', '.hidden'],
|
||||
|
@@ -3,6 +3,7 @@
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Config;
|
||||
use DI\Container;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
@@ -16,6 +17,7 @@ class DirectoryController
|
||||
{
|
||||
/** Create a new IndexController object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
private Finder $finder,
|
||||
private Twig $view,
|
||||
@@ -25,10 +27,11 @@ class DirectoryController
|
||||
/** Invoke the IndexController. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $request->getQueryParams()['dir'] ?? '.';
|
||||
$relativePath = $request->getQueryParams()['dir'] ?? '.';
|
||||
$fullPath = $this->container->call('full_path', ['path' => $relativePath]);
|
||||
|
||||
try {
|
||||
$files = $this->finder->in($path)->depth(0);
|
||||
$files = $this->finder->in($fullPath)->depth(0);
|
||||
} catch (Exception $exception) {
|
||||
return $this->view->render($response->withStatus(404), 'error.twig', [
|
||||
'message' => $this->translator->trans('error.directory_not_found'),
|
||||
@@ -37,9 +40,9 @@ class DirectoryController
|
||||
|
||||
return $this->view->render($response, 'index.twig', [
|
||||
'files' => $files,
|
||||
'path' => $path,
|
||||
'path' => $relativePath,
|
||||
'readme' => $this->readme($files),
|
||||
'title' => $path == '.' ? 'Home' : $path,
|
||||
'title' => $relativePath == '.' ? 'Home' : $relativePath,
|
||||
]);
|
||||
}
|
||||
|
||||
|
41
app/src/Controllers/FileController.php
Normal file
41
app/src/Controllers/FileController.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Config;
|
||||
use DI\Container;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Factory\StreamFactory;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
use SplFileInfo;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class FileController
|
||||
{
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $this->container->call('full_path', ['path' => $request->getQueryParams()['file']]);
|
||||
|
||||
$file = new SplFileInfo((string) realpath($path));
|
||||
|
||||
if (! $file->isFile()) {
|
||||
return $response->withStatus(404, $this->translator->trans('error.file_not_found'));
|
||||
}
|
||||
|
||||
$response = $response->withHeader('Content-Description', 'File Transfer');
|
||||
$response = $response->withHeader('Content-Disposition', sprintf('attachment; filename="%s"', $file->getFilename()));
|
||||
$response = $response->withHeader('Content-Length', $file->getSize());
|
||||
$response = $response->withHeader('Content-Type', $file->getType());
|
||||
|
||||
return $response->withBody(
|
||||
(new StreamFactory)->createStreamFromFile($file->getRealPath())
|
||||
);
|
||||
}
|
||||
}
|
@@ -3,6 +3,7 @@
|
||||
namespace App\Controllers;
|
||||
|
||||
use App\Config;
|
||||
use DI\Container;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
@@ -14,6 +15,7 @@ class FileInfoController
|
||||
{
|
||||
/** Create a new FileInfoHandler object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
private CacheInterface $cache,
|
||||
private TranslatorInterface $translator
|
||||
@@ -22,11 +24,9 @@ class FileInfoController
|
||||
/** Invoke the FileInfoHandler. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $request->getQueryParams()['info'];
|
||||
$path = $this->container->call('full_path', ['path' => $request->getQueryParams()['info']]);
|
||||
|
||||
$file = new SplFileInfo(
|
||||
(string) realpath($this->config->get('base_path') . '/' . $path)
|
||||
);
|
||||
$file = new SplFileInfo((string) realpath($path));
|
||||
|
||||
if (! $file->isFile()) {
|
||||
return $response->withStatus(404, $this->translator->trans('error.file_not_found'));
|
||||
|
@@ -17,18 +17,16 @@ class IndexController
|
||||
/** Invoke the IndexController. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
switch (true) {
|
||||
case array_key_exists('info', $request->getQueryParams()):
|
||||
return $this->container->call(FileInfoController::class, [$request, $response]);
|
||||
$firstQueryParam = array_key_first($request->getQueryParams());
|
||||
|
||||
case array_key_exists('search', $request->getQueryParams()):
|
||||
return $this->container->call(SearchController::class, [$request, $response]);
|
||||
$controller = match ($firstQueryParam) {
|
||||
'file' => FileController::class,
|
||||
'info' => FileInfoController::class,
|
||||
'search' => SearchController::class,
|
||||
'zip' => ZipController::class,
|
||||
default => DirectoryController::class,
|
||||
};
|
||||
|
||||
case array_key_exists('zip', $request->getQueryParams()):
|
||||
return $this->container->call(ZipController::class, [$request, $response]);
|
||||
|
||||
default:
|
||||
return $this->container->call(DirectoryController::class, [$request, $response]);
|
||||
}
|
||||
return $this->container->call($controller, [$request, $response]);
|
||||
}
|
||||
}
|
||||
|
@@ -6,6 +6,7 @@ use App\CallbackStream;
|
||||
use App\Config;
|
||||
use App\Support\Str;
|
||||
use DateTime;
|
||||
use DI\Container;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use RuntimeException;
|
||||
@@ -22,6 +23,7 @@ class ZipController
|
||||
{
|
||||
/** Create a new ZipHandler object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
private Finder $finder,
|
||||
private TranslatorInterface $translator
|
||||
@@ -34,7 +36,7 @@ class ZipController
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $request->getQueryParams()['zip'];
|
||||
$path = $this->container->call('full_path', ['path' => $request->getQueryParams()['zip']]);
|
||||
|
||||
if (! $this->config->get('zip_downloads') || ! is_dir($path)) {
|
||||
return $response->withStatus(404, $this->translator->trans('error.file_not_found'));
|
||||
@@ -100,9 +102,7 @@ class ZipController
|
||||
|
||||
protected function augmentHeadersWithEstimatedSize(Response $response, int $size): Response
|
||||
{
|
||||
$response = $response->withHeader('Content-Length', (string) $size);
|
||||
|
||||
return $response;
|
||||
return $response->withHeader('Content-Length', (string) $size);
|
||||
}
|
||||
|
||||
/** Return the path to a file with the preceding root path stripped. */
|
||||
|
@@ -60,7 +60,7 @@ class FinderFactory
|
||||
{
|
||||
if (! $this->pattern instanceof Pattern) {
|
||||
$this->pattern = Pattern::make(sprintf('%s{%s}', Pattern::escape(
|
||||
$this->config->get('base_path') . DIRECTORY_SEPARATOR
|
||||
$this->config->get('files_path') . DIRECTORY_SEPARATOR
|
||||
), $this->hiddenFiles->implode(',')));
|
||||
}
|
||||
|
||||
|
@@ -24,7 +24,7 @@ class Breadcrumbs extends ViewFunction
|
||||
public function __invoke(string $path): Collection
|
||||
{
|
||||
return Str::explode($path, $this->directorySeparator)->diffAssoc(
|
||||
explode($this->directorySeparator, $this->config->get('base_path'))
|
||||
explode($this->directorySeparator, $this->config->get('files_path'))
|
||||
)->filter(static function (string $crumb): bool {
|
||||
return ! in_array($crumb, [null, '.']);
|
||||
})->reduce(function (Collection $carry, string $crumb): Collection {
|
||||
|
@@ -9,12 +9,12 @@ class FileUrl extends Url
|
||||
/** Return the URL for a given path and action. */
|
||||
public function __invoke(string $path = '/'): string
|
||||
{
|
||||
$path = $this->stripLeadingSlashes($path);
|
||||
|
||||
if (is_file($path)) {
|
||||
return $this->escape($path);
|
||||
return sprintf('?file=%s', $this->escape($this->normalizePath($path)));
|
||||
}
|
||||
|
||||
$path = $this->normalizePath($path);
|
||||
|
||||
if ($path === '') {
|
||||
return '';
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\ViewFunctions;
|
||||
|
||||
use App\Config;
|
||||
use App\Support\Str;
|
||||
|
||||
class Url extends ViewFunction
|
||||
@@ -10,13 +11,34 @@ class Url extends ViewFunction
|
||||
|
||||
/** Create a new Url object. */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private string $directorySeparator = DIRECTORY_SEPARATOR
|
||||
) {}
|
||||
|
||||
/** Return the URL for a given path. */
|
||||
public function __invoke(string $path = '/'): string
|
||||
{
|
||||
return $this->escape($this->stripLeadingSlashes($path));
|
||||
return $this->escape($this->normalizePath($path));
|
||||
}
|
||||
|
||||
/** Strip base path and leading slashes (and a single dot) from a path */
|
||||
protected function normalizePath(string $path): string
|
||||
{
|
||||
return $this->stripLeadingSlashes($this->stripBasePath($path));
|
||||
}
|
||||
|
||||
/** Strip the base path from the beginning of a path. */
|
||||
protected function stripBasePath(string $path): string
|
||||
{
|
||||
$basePath = $this->config->get('files_path') . $this->directorySeparator;
|
||||
|
||||
$position = strpos($path, $basePath);
|
||||
|
||||
if ($position !== 0) {
|
||||
return $path;
|
||||
}
|
||||
|
||||
return (string) substr_replace($path, '', 0, strlen($basePath));
|
||||
}
|
||||
|
||||
/** Strip all leading slashes (and a single dot) from a path. */
|
||||
|
@@ -9,7 +9,7 @@ class ZipUrl extends Url
|
||||
/** Return the URL for a given path and action. */
|
||||
public function __invoke(string $path = '/'): string
|
||||
{
|
||||
$path = $this->stripLeadingSlashes($path);
|
||||
$path = $this->normalizePath($path);
|
||||
|
||||
if ($path === '') {
|
||||
return '?zip=.';
|
||||
|
@@ -13,7 +13,7 @@
|
||||
"issues": "https://github.com/DirectoryLister/DirectoryLister/issues"
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.1 || ^8.2 || ^8.3 || ^8.4",
|
||||
"php": ">= 8.1",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-zip": "*",
|
||||
|
@@ -6,12 +6,12 @@ use Dotenv\Dotenv;
|
||||
|
||||
require __DIR__ . '/app/vendor/autoload.php';
|
||||
|
||||
// Set file access restrictions
|
||||
ini_set('open_basedir', __DIR__);
|
||||
|
||||
// Initialize environment variable handler
|
||||
Dotenv::createUnsafeImmutable(__DIR__)->safeLoad();
|
||||
|
||||
// Set file access restrictions
|
||||
ini_set('open_basedir', implode(PATH_SEPARATOR, [__DIR__, getenv('FILES_PATH')]));
|
||||
|
||||
// Initialize the container
|
||||
$container = BootManager::createContainer(
|
||||
__DIR__ . '/app/config',
|
||||
|
@@ -24,12 +24,7 @@ class DirectoryControllerTest extends TestCase
|
||||
$this->container->set('hide_vcs_files', $hideVcsFiles);
|
||||
$this->container->set('display_readmes', $displayReadmes);
|
||||
|
||||
$controller = new DirectoryController(
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$controller = $this->container->get(DirectoryController::class);
|
||||
|
||||
chdir($this->filePath('.'));
|
||||
$response = $controller($this->createMock(Request::class), new Response);
|
||||
@@ -48,12 +43,7 @@ class DirectoryControllerTest extends TestCase
|
||||
$this->container->set('hide_vcs_files', $hideVcsFiles);
|
||||
$this->container->set('display_readmes', $displayReadmes);
|
||||
|
||||
$controller = new DirectoryController(
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$controller = $this->container->get(DirectoryController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['dir' => 'subdir']);
|
||||
@@ -68,6 +58,7 @@ class DirectoryControllerTest extends TestCase
|
||||
public function test_it_returns_a_404_error_when_not_found(): void
|
||||
{
|
||||
$controller = new DirectoryController(
|
||||
$this->container,
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
|
48
tests/Controllers/FileControllerTest.php
Normal file
48
tests/Controllers/FileControllerTest.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Controllers;
|
||||
|
||||
use App\Controllers\FileController;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
use Tests\TestCase;
|
||||
|
||||
/** @covers \App\Controllers\FileController */
|
||||
class FileControllerTest extends TestCase
|
||||
{
|
||||
public function test_it_returns_a_successful_response_for_a_file_request(): void
|
||||
{
|
||||
$controller = $this->container->get(FileController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['file' => 'README.md']);
|
||||
|
||||
$response = $controller($request, new Response);
|
||||
|
||||
$this->assertInstanceOf(ResponseInterface::class, $response);
|
||||
$this->assertSame(200, $response->getStatusCode());
|
||||
|
||||
$this->assertSame([
|
||||
'Content-Description' => ['File Transfer'],
|
||||
'Content-Disposition' => ['attachment; filename="README.md"'],
|
||||
'Content-Length' => ['30'],
|
||||
'Content-Type' => ['file']
|
||||
], $response->getHeaders());
|
||||
|
||||
$this->assertSame("Test README.md; please ignore\n", (string) $response->getBody());
|
||||
}
|
||||
|
||||
public function test_it_returns_a_404_error_when_not_found(): void
|
||||
{
|
||||
$controller = $this->container->get(FileController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['file' => '404']);
|
||||
|
||||
$response = $controller($request, new Response);
|
||||
|
||||
$this->assertInstanceOf(ResponseInterface::class, $response);
|
||||
$this->assertSame(404, $response->getStatusCode());
|
||||
}
|
||||
}
|
@@ -6,7 +6,6 @@ use App\Controllers\FileInfoController;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Tests\TestCase;
|
||||
|
||||
/** @covers \App\Controllers\FileInfoController */
|
||||
@@ -14,11 +13,7 @@ class FileInfoControllerTest extends TestCase
|
||||
{
|
||||
public function test_it_can_return_a_successful_response(): void
|
||||
{
|
||||
$handler = new FileInfoController(
|
||||
$this->config,
|
||||
$this->cache,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$handler = $this->container->get(FileInfoController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['info' => 'README.md']);
|
||||
@@ -38,11 +33,7 @@ class FileInfoControllerTest extends TestCase
|
||||
|
||||
public function test_it_can_return_a_not_found_response(): void
|
||||
{
|
||||
$handler = new FileInfoController(
|
||||
$this->config,
|
||||
$this->cache,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$handler = $this->container->get(FileInfoController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['info' => 'not_a_file.test']);
|
||||
@@ -56,11 +47,8 @@ class FileInfoControllerTest extends TestCase
|
||||
public function test_it_returns_an_error_when_file_size_is_too_large(): void
|
||||
{
|
||||
$this->container->set('max_hash_size', 10);
|
||||
$handler = new FileInfoController(
|
||||
$this->config,
|
||||
$this->cache,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
|
||||
$handler = $this->container->get(FileInfoController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['info' => 'README.md']);
|
||||
|
@@ -6,9 +6,6 @@ use App\Controllers\SearchController;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
use Slim\Views\Twig;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Tests\TestCase;
|
||||
|
||||
/** @covers \App\Controllers\SearchController */
|
||||
@@ -16,11 +13,7 @@ class SearchControllerTest extends TestCase
|
||||
{
|
||||
public function test_it_returns_a_successful_response_for_a_search_request(): void
|
||||
{
|
||||
$handler = new SearchController(
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$handler = $this->container->get(SearchController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['search' => 'charlie']);
|
||||
@@ -35,11 +28,7 @@ class SearchControllerTest extends TestCase
|
||||
|
||||
public function test_it_returns_no_results_found_when_there_are_no_results(): void
|
||||
{
|
||||
$handler = new SearchController(
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$handler = $this->container->get(SearchController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['search' => 'test search; please ignore']);
|
||||
@@ -54,11 +43,7 @@ class SearchControllerTest extends TestCase
|
||||
|
||||
public function test_it_returns_no_results_found_for_a_blank_search(): void
|
||||
{
|
||||
$handler = new SearchController(
|
||||
new Finder,
|
||||
$this->container->get(Twig::class),
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$handler = $this->container->get(SearchController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['search' => '']);
|
||||
|
@@ -6,8 +6,6 @@ use App\Controllers\ZipController;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Slim\Psr7\Request;
|
||||
use Slim\Psr7\Response;
|
||||
use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use Tests\TestCase;
|
||||
|
||||
/** @covers \App\Controllers\ZipController */
|
||||
@@ -15,11 +13,7 @@ class ZipControllerTest extends TestCase
|
||||
{
|
||||
public function test_it_returns_a_successful_response_for_a_zip_request(): void
|
||||
{
|
||||
$controller = new ZipController(
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$controller = $this->container->get(ZipController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['zip' => 'subdir']);
|
||||
@@ -34,11 +28,7 @@ class ZipControllerTest extends TestCase
|
||||
|
||||
public function test_it_returns_a_404_error_when_not_found(): void
|
||||
{
|
||||
$controller = new ZipController(
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
$controller = $this->container->get(ZipController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['zip' => '404']);
|
||||
@@ -53,11 +43,8 @@ class ZipControllerTest extends TestCase
|
||||
public function test_it_returns_a_404_error_when_disabled_via_config(): void
|
||||
{
|
||||
$this->container->set('zip_downloads', false);
|
||||
$controller = new ZipController(
|
||||
$this->config,
|
||||
new Finder,
|
||||
$this->container->get(TranslatorInterface::class)
|
||||
);
|
||||
|
||||
$controller = $this->container->get(ZipController::class);
|
||||
|
||||
$request = $this->createMock(Request::class);
|
||||
$request->method('getQueryParams')->willReturn(['zip' => 'subdir']);
|
||||
|
@@ -10,7 +10,7 @@ class FileUrlTest extends TestCase
|
||||
{
|
||||
public function test_it_can_return_a_url(): void
|
||||
{
|
||||
$url = new FileUrl;
|
||||
$url = $this->container->get(FileUrl::class);
|
||||
|
||||
$this->assertEquals('', $url('/'));
|
||||
$this->assertEquals('', $url('./'));
|
||||
@@ -26,7 +26,7 @@ class FileUrlTest extends TestCase
|
||||
|
||||
public function test_it_can_return_a_url_with_back_slashes(): void
|
||||
{
|
||||
$url = new FileUrl('\\');
|
||||
$url = $this->container->make(FileUrl::class, ['directorySeparator' => '\\']);
|
||||
|
||||
$this->assertEquals('', $url('\\'));
|
||||
$this->assertEquals('', $url('.\\'));
|
||||
@@ -40,7 +40,7 @@ class FileUrlTest extends TestCase
|
||||
|
||||
public function test_url_segments_are_url_encoded(): void
|
||||
{
|
||||
$url = new FileUrl;
|
||||
$url = $this->container->get(FileUrl::class);
|
||||
|
||||
$this->assertEquals('?dir=foo/bar%2Bbaz', $url('foo/bar+baz'));
|
||||
$this->assertEquals('?dir=foo/bar%23baz', $url('foo/bar#baz'));
|
||||
|
@@ -10,7 +10,7 @@ class UrlTest extends TestCase
|
||||
{
|
||||
public function test_it_can_return_a_url(): void
|
||||
{
|
||||
$url = new Url;
|
||||
$url = $this->container->get(Url::class);
|
||||
|
||||
$this->assertEquals('', $url('/'));
|
||||
$this->assertEquals('', $url('./'));
|
||||
@@ -26,7 +26,7 @@ class UrlTest extends TestCase
|
||||
|
||||
public function test_it_can_return_a_url_with_back_slashes(): void
|
||||
{
|
||||
$url = new Url('\\');
|
||||
$url = $this->container->make(Url::class, ['directorySeparator' => '\\']);
|
||||
|
||||
$this->assertEquals('', $url('\\'));
|
||||
$this->assertEquals('', $url('.\\'));
|
||||
@@ -40,7 +40,7 @@ class UrlTest extends TestCase
|
||||
|
||||
public function test_url_segments_are_url_encoded(): void
|
||||
{
|
||||
$url = new Url;
|
||||
$url = $this->container->get(Url::class);
|
||||
|
||||
$this->assertEquals('foo/bar%2Bbaz', $url('foo/bar+baz'));
|
||||
$this->assertEquals('foo/bar%23baz', $url('foo/bar#baz'));
|
||||
|
@@ -10,7 +10,7 @@ class ZipUrlTest extends TestCase
|
||||
{
|
||||
public function test_it_can_return_a_url(): void
|
||||
{
|
||||
$url = new ZipUrl;
|
||||
$url = $this->container->get(ZipUrl::class);
|
||||
|
||||
$this->assertEquals('?zip=.', $url('/'));
|
||||
$this->assertEquals('?zip=.', $url('./'));
|
||||
@@ -26,7 +26,7 @@ class ZipUrlTest extends TestCase
|
||||
|
||||
public function test_it_can_return_a_url_with_back_slashes(): void
|
||||
{
|
||||
$url = new ZipUrl('\\');
|
||||
$url = $this->container->make(ZipUrl::class, ['directorySeparator' => '\\']);
|
||||
|
||||
$this->assertEquals('?zip=.', $url('\\'));
|
||||
$this->assertEquals('?zip=.', $url('.\\'));
|
||||
@@ -38,7 +38,7 @@ class ZipUrlTest extends TestCase
|
||||
|
||||
public function test_url_segments_are_url_encoded(): void
|
||||
{
|
||||
$url = new ZipUrl;
|
||||
$url = $this->container->get(ZipUrl::class);
|
||||
|
||||
$this->assertEquals('?zip=foo/bar%2Bbaz', $url('foo/bar+baz'));
|
||||
$this->assertEquals('?zip=foo/bar%23baz', $url('foo/bar#baz'));
|
||||
|
Reference in New Issue
Block a user