diff --git a/.env.example b/.env.example
index af202e7..11b1785 100644
--- a/.env.example
+++ b/.env.example
@@ -2,6 +2,8 @@ DARK_MODE=false
DISPLAY_READMES=true
+ZIP_DOWNLOADS=true
+
GOOGLE_ANALYTICS_ID=false
SORT_ORDER=type
diff --git a/app/config/app.php b/app/config/app.php
index 7792ac8..cd7fe27 100644
--- a/app/config/app.php
+++ b/app/config/app.php
@@ -17,6 +17,13 @@ return [
*/
'display_readmes' => Helpers::env('DISPLAY_READMES'),
+ /**
+ * Enable downloading of directories as a zip archive.
+ *
+ * Default value: true
+ */
+ 'zip_downloads' => Helpers::env('ZIP_DOWNLOADS'),
+
/**
* Your Google analytics tracking ID.
* Expected format: 'UA-123456789-0'.
diff --git a/app/src/Handlers/ZipHandler.php b/app/src/Handlers/ZipHandler.php
index 9d3d8c2..bb8b223 100644
--- a/app/src/Handlers/ZipHandler.php
+++ b/app/src/Handlers/ZipHandler.php
@@ -4,6 +4,7 @@ namespace App\Handlers;
use App\TemporaryFile;
use DI\Container;
+use PHLAK\Config\Config;
use Psr\Http\Message\ResponseInterface;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
@@ -17,6 +18,9 @@ class ZipHandler
/** @var Container The application container */
protected $container;
+ /** @var Config The application config */
+ protected $config;
+
/** @var Finder The Finder Component */
protected $finder;
@@ -26,9 +30,10 @@ class ZipHandler
* @param \DI\Container $container
* @param \PhpCsFixer\Finder $finder
*/
- public function __construct(Container $container, Finder $finder)
+ public function __construct(Container $container, Config $config, Finder $finder)
{
$this->container = $container;
+ $this->config = $config;
$this->finder = $finder;
}
@@ -44,7 +49,7 @@ class ZipHandler
{
$path = $request->getQueryParams()['zip'];
- if (! realpath($path)) {
+ if (! $this->config->get('app.zip_downloads', true) || ! realpath($path)) {
return $response->withStatus(404, 'File not found');
}
diff --git a/app/views/components/header.twig b/app/views/components/header.twig
index 3b7740a..0a7205f 100644
--- a/app/views/components/header.twig
+++ b/app/views/components/header.twig
@@ -11,7 +11,7 @@
- {% if path %}
+ {% if path and config('zip_downloads', true) %}
diff --git a/tests/Handlers/ZipHandlerTest.php b/tests/Handlers/ZipHandlerTest.php
index f737601..d686a7a 100644
--- a/tests/Handlers/ZipHandlerTest.php
+++ b/tests/Handlers/ZipHandlerTest.php
@@ -13,7 +13,7 @@ class ZipHandlerTest extends TestCase
{
public function test_it_returns_a_successful_response_for_a_zip_request(): void
{
- $handler = new ZipHandler($this->container, new Finder);
+ $handler = new ZipHandler($this->container, $this->config, new Finder);
$request = $this->createMock(Request::class);
$request->method('getQueryParams')->willReturn(['zip' => 'subdir']);
@@ -30,7 +30,7 @@ class ZipHandlerTest extends TestCase
public function test_it_returns_a_404_error_when_not_found(): void
{
- $handler = new ZipHandler($this->container, new Finder);
+ $handler = new ZipHandler($this->container, $this->config, new Finder);
$request = $this->createMock(Request::class);
$request->method('getQueryParams')->willReturn(['zip' => '404']);
@@ -41,4 +41,19 @@ class ZipHandlerTest extends TestCase
$this->assertInstanceOf(ResponseInterface::class, $response);
$this->assertEquals(404, $response->getStatusCode());
}
+
+ public function test_it_returns_a_404_error_when_disabled_via_config(): void
+ {
+ $this->config->set('app.zip_downloads', false);
+ $handler = new ZipHandler($this->container, $this->config, new Finder);
+
+ $request = $this->createMock(Request::class);
+ $request->method('getQueryParams')->willReturn(['zip' => 'subdir']);
+
+ chdir($this->filePath('.'));
+ $response = $handler($request, new Response);
+
+ $this->assertInstanceOf(ResponseInterface::class, $response);
+ $this->assertEquals(404, $response->getStatusCode());
+ }
}
diff --git a/tests/TestCase.php b/tests/TestCase.php
index 1a0fc6e..5c446cd 100644
--- a/tests/TestCase.php
+++ b/tests/TestCase.php
@@ -28,12 +28,16 @@ class TestCase extends PHPUnitTestCase
$this->config = new Config([
'app' => [
+ 'dark_mode' => false,
+ 'display_readmes' => true,
+ 'zip_downloads' => true,
+ 'google_analytics_id' => false,
'sort_order' => 'type',
'reverse_sort' => false,
'hidden_files' => [],
'hide_app_files' => true,
'hide_vcs_files' => false,
- 'display_readmes' => true,
+ 'date_format' => 'Y-m-d H:i:s',
'max_hash_size' => 1000000000,
'view_cache' => false,
]