mirror of
https://github.com/DirectoryLister/DirectoryLister.git
synced 2025-08-19 12:22:00 +02:00
Static analysis fixes and code cleanup
This commit is contained in:
@@ -10,12 +10,15 @@ use Slim\App;
|
||||
|
||||
class AppManager
|
||||
{
|
||||
/** Create a new AppManager object. */
|
||||
public function __construct(
|
||||
private Container $container
|
||||
) {}
|
||||
|
||||
/** Setup and configure the application. */
|
||||
/**
|
||||
* Setup and configure the application.
|
||||
*
|
||||
* @return App<Container>
|
||||
*/
|
||||
public function __invoke(): App
|
||||
{
|
||||
$app = Bridge::create($this->container);
|
||||
|
@@ -6,11 +6,12 @@ namespace App\Bootstrap;
|
||||
|
||||
use App\Config;
|
||||
use App\Exceptions\ErrorHandler;
|
||||
use DI\Container;
|
||||
use Slim\App;
|
||||
|
||||
class ExceptionManager
|
||||
{
|
||||
/** Create a new ExceptionManager object. */
|
||||
/** @param App<Container> $app */
|
||||
public function __construct(
|
||||
private App $app,
|
||||
private Config $config
|
||||
|
@@ -5,11 +5,12 @@ declare(strict_types=1);
|
||||
namespace App\Bootstrap;
|
||||
|
||||
use App\Config;
|
||||
use DI\Container;
|
||||
use Slim\App;
|
||||
|
||||
class MiddlewareManager
|
||||
{
|
||||
/** Create a new MiddlwareManager object. */
|
||||
/** @param App<Container> $app */
|
||||
public function __construct(
|
||||
private App $app,
|
||||
private Config $config
|
||||
|
@@ -5,11 +5,12 @@ declare(strict_types=1);
|
||||
namespace App\Bootstrap;
|
||||
|
||||
use App\Controllers;
|
||||
use DI\Container;
|
||||
use Slim\App;
|
||||
|
||||
class RouteManager
|
||||
{
|
||||
/** Create a new RouteManager object. */
|
||||
/** @param App<Container> $app */
|
||||
public function __construct(
|
||||
private App $app
|
||||
) {}
|
||||
|
@@ -95,11 +95,11 @@ class CallbackStream implements StreamInterface
|
||||
* @see http://www.php.net/manual/en/function.fseek.php
|
||||
*
|
||||
* @param int $offset Stream offset
|
||||
* @param int $whence Specifies how the cursor position will be calculated
|
||||
* based on the seek offset. Valid values are identical to the built-in
|
||||
* PHP $whence values for `fseek()`. SEEK_SET: Set position equal to
|
||||
* offset bytes SEEK_CUR: Set position to current location plus offset
|
||||
* SEEK_END: Set position to end-of-stream plus offset.
|
||||
* @param int $whence Specifies how the cursor position will be calculated based on the seek offset.
|
||||
* Valid values are identical to the built-in PHP $whence values for `fseek()`.
|
||||
* - SEEK_SET: Set position equal to offset bytes
|
||||
* - SEEK_CUR: Set position to current location plus offset
|
||||
* - SEEK_END: Set position to end-of-stream plus offset.
|
||||
*/
|
||||
public function seek($offset, $whence = SEEK_SET): void {}
|
||||
|
||||
@@ -154,7 +154,6 @@ class CallbackStream implements StreamInterface
|
||||
|
||||
$this->called = true;
|
||||
|
||||
// Execute the callback
|
||||
call_user_func($this->callback);
|
||||
|
||||
return '';
|
||||
@@ -176,9 +175,9 @@ class CallbackStream implements StreamInterface
|
||||
*
|
||||
* @param string $key specific metadata to retrieve
|
||||
*
|
||||
* @return array|mixed|null Returns an associative array if no key is
|
||||
* provided. Returns a specific key value if a key is provided and the
|
||||
* value is found, or null if the key is not found.
|
||||
* @return array|mixed|null Returns an associative array if no key is provided.
|
||||
* Returns a specific key value if a key is provided and
|
||||
* the value is found, or null if the key is not found.
|
||||
*/
|
||||
public function getMetadata($key = null)
|
||||
{
|
||||
|
@@ -9,23 +9,16 @@ use DI\NotFoundException;
|
||||
|
||||
class Config
|
||||
{
|
||||
/** Create a new Config object. */
|
||||
public function __construct(
|
||||
private Container $container
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Get the value of a configuration variable.
|
||||
*
|
||||
* @param mixed $default
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function get(string $key, $default = null)
|
||||
/** Get the value of a configuration variable. */
|
||||
public function get(string $key, mixed $default = null): mixed
|
||||
{
|
||||
try {
|
||||
$value = $this->container->get($key);
|
||||
} catch (NotFoundException $exception) {
|
||||
} catch (NotFoundException) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
@@ -17,7 +17,6 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class DirectoryController
|
||||
{
|
||||
/** Create a new IndexController object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
@@ -26,7 +25,6 @@ class DirectoryController
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
/** Invoke the IndexController. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$relativePath = $request->getQueryParams()['dir'] ?? '.';
|
||||
@@ -57,11 +55,11 @@ class DirectoryController
|
||||
|
||||
$readmes = (clone $files)->name('/^README(?:\..+)?$/i');
|
||||
|
||||
$readmes->filter(static function (SplFileInfo $file) {
|
||||
return (bool) preg_match('/text\/.+/', (string) mime_content_type($file->getPathname()));
|
||||
})->sort(static function (SplFileInfo $file1, SplFileInfo $file2) {
|
||||
return $file1->getExtension() <=> $file2->getExtension();
|
||||
});
|
||||
$readmes->filter(
|
||||
static fn (SplFileInfo $file): bool => (bool) preg_match('/text\/.+/', (string) mime_content_type($file->getPathname()))
|
||||
)->sort(
|
||||
static fn (SplFileInfo $file1, SplFileInfo $file2): int => $file1->getExtension() <=> $file2->getExtension()
|
||||
);
|
||||
|
||||
if (! $readmes->hasResults()) {
|
||||
return null;
|
||||
|
@@ -15,7 +15,6 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class FileInfoController
|
||||
{
|
||||
/** Create a new FileInfoHandler object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
@@ -23,7 +22,6 @@ class FileInfoController
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
/** Invoke the FileInfoHandler. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $this->container->call('full_path', ['path' => $request->getQueryParams()['info']]);
|
||||
@@ -40,21 +38,23 @@ class FileInfoController
|
||||
|
||||
$response->getBody()->write($this->cache->get(
|
||||
sprintf('file-info-%s', sha1((string) $file->getRealPath())),
|
||||
function () use ($file): string {
|
||||
return (string) json_encode(['hashes' => $this->calculateHashes($file)]);
|
||||
}
|
||||
fn (): string => (string) json_encode(['hashes' => $this->calculateHashes($file)], flags: JSON_THROW_ON_ERROR)
|
||||
));
|
||||
|
||||
return $response->withHeader('Content-Type', 'application/json');
|
||||
}
|
||||
|
||||
/** Get an array of hashes for a file. */
|
||||
/**
|
||||
* Get an array of hashes for a file.
|
||||
*
|
||||
* @return array{md5: string, sha1: string, sha256: string}
|
||||
*/
|
||||
protected function calculateHashes(SplFileInfo $file): array
|
||||
{
|
||||
return [
|
||||
'md5' => hash_file('md5', (string) $file->getRealPath()),
|
||||
'sha1' => hash_file('sha1', (string) $file->getRealPath()),
|
||||
'sha256' => hash_file('sha256', (string) $file->getRealPath()),
|
||||
'md5' => (string) hash_file('md5', (string) $file->getRealPath()),
|
||||
'sha1' => (string) hash_file('sha1', (string) $file->getRealPath()),
|
||||
'sha256' => (string) hash_file('sha256', (string) $file->getRealPath()),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@@ -11,12 +11,10 @@ use Slim\Psr7\Response;
|
||||
|
||||
class IndexController
|
||||
{
|
||||
/** Create a new IndexController object. */
|
||||
public function __construct(
|
||||
private Container $container
|
||||
) {}
|
||||
|
||||
/** Invoke the IndexController. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$firstQueryParam = array_key_first($request->getQueryParams());
|
||||
|
@@ -13,14 +13,12 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class SearchController
|
||||
{
|
||||
/** Create a new SearchHandler object. */
|
||||
public function __construct(
|
||||
private Finder $finder,
|
||||
private Twig $view,
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
/** Invoke the SearchHandler. */
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$search = $request->getQueryParams()['search'];
|
||||
|
@@ -9,7 +9,6 @@ use App\Config;
|
||||
use App\Support\Str;
|
||||
use DateTime;
|
||||
use DI\Container;
|
||||
use Exception;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use RuntimeException;
|
||||
use Slim\Psr7\Request;
|
||||
@@ -18,12 +17,12 @@ use Symfony\Component\Finder\Finder;
|
||||
use Symfony\Component\Finder\SplFileInfo;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
use ZipStream\CompressionMethod;
|
||||
use ZipStream\Exception as ZipStreamException;
|
||||
use ZipStream\OperationMode;
|
||||
use ZipStream\ZipStream;
|
||||
|
||||
class ZipController
|
||||
{
|
||||
/** Create a new ZipHandler object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
@@ -31,11 +30,6 @@ class ZipController
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
/** Invoke the ZipHandler.
|
||||
* @throws \ZipStream\Exception\FileNotFoundException
|
||||
* @throws \ZipStream\Exception\FileNotReadableException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function __invoke(Request $request, Response $response): ResponseInterface
|
||||
{
|
||||
$path = $this->container->call('full_path', ['path' => $request->getQueryParams()['zip']]);
|
||||
@@ -54,24 +48,25 @@ class ZipController
|
||||
|
||||
$files = $this->finder->in($path)->files();
|
||||
|
||||
$zip = $this->createZip($path, $files);
|
||||
try {
|
||||
$zip = $this->createZip($path, $files);
|
||||
} catch (ZipStreamException) {
|
||||
return $response->withStatus(500, $this->translator->trans('error.unexpected'));
|
||||
}
|
||||
|
||||
$size = $zip->finish();
|
||||
|
||||
$response = $this->augmentHeadersWithEstimatedSize($response, $size)->withBody(
|
||||
new CallbackStream(static function () use ($zip) {
|
||||
return $response->withHeader('Content-Length', (string) $size)->withBody(
|
||||
new CallbackStream(static function () use ($zip): void {
|
||||
$zip->executeSimulation();
|
||||
})
|
||||
);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a zip stream from a directory.
|
||||
*
|
||||
* @throws \ZipStream\Exception\FileNotFoundException
|
||||
* @throws \ZipStream\Exception\FileNotReadableException
|
||||
* @throws Exception
|
||||
* @throws \ZipStream\Exception
|
||||
*/
|
||||
protected function createZip(string $path, Finder $files): ZipStream
|
||||
{
|
||||
@@ -102,11 +97,6 @@ class ZipController
|
||||
return $zip;
|
||||
}
|
||||
|
||||
protected function augmentHeadersWithEstimatedSize(Response $response, int $size): Response
|
||||
{
|
||||
return $response->withHeader('Content-Length', (string) $size);
|
||||
}
|
||||
|
||||
/** Return the path to a file with the preceding root path stripped. */
|
||||
protected function stripPath(SplFileInfo $file, string $path): string
|
||||
{
|
||||
@@ -118,7 +108,7 @@ class ZipController
|
||||
/** Generate the file name for a path. */
|
||||
protected function generateFileName(string $path): string
|
||||
{
|
||||
$filename = Str::explode($path, DIRECTORY_SEPARATOR)->last();
|
||||
$filename = (string) Str::explode($path, DIRECTORY_SEPARATOR)->last();
|
||||
|
||||
return $filename == '.' ? 'Home' : $filename;
|
||||
}
|
||||
|
@@ -14,13 +14,11 @@ use Throwable;
|
||||
|
||||
class ErrorHandler implements ErrorHandlerInterface
|
||||
{
|
||||
/** Create a new ErrorHandler object. */
|
||||
public function __construct(
|
||||
private Twig $view,
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
||||
/** Invoke the ErrorHandler class. */
|
||||
public function __invoke(
|
||||
ServerRequestInterface $request,
|
||||
Throwable $exception,
|
||||
|
@@ -8,12 +8,8 @@ use RuntimeException;
|
||||
|
||||
final class InvalidConfiguration extends RuntimeException
|
||||
{
|
||||
/**
|
||||
* Create an exception from a configuration option and value.
|
||||
*
|
||||
* @param mixed $value
|
||||
*/
|
||||
public static function fromConfig(string $option, $value): self
|
||||
/** Create an exception from a configuration option and value. */
|
||||
public static function fromConfig(string $option, mixed $value): self
|
||||
{
|
||||
return new static(
|
||||
sprintf("Unknown value %s for configuration option '%s'", var_export($value, true), $option)
|
||||
|
@@ -19,19 +19,14 @@ use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
class CacheFactory
|
||||
{
|
||||
/** @const Namespace for external cache drivers */
|
||||
protected const NAMESPACE_EXTERNAL = 'directory_lister';
|
||||
private const NAMESPACE_EXTERNAL = 'directory_lister';
|
||||
private const NAMESPACE_INTERNAL = 'app';
|
||||
|
||||
/** @const Namespace for internal cache drivers */
|
||||
protected const NAMESPACE_INTERNAL = 'app';
|
||||
|
||||
/** Create a new CacheFactory object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config
|
||||
) {}
|
||||
|
||||
/** Initialize and return a CacheInterface. */
|
||||
public function __invoke(): CacheInterface
|
||||
{
|
||||
return match ($this->config->get('cache_driver')) {
|
||||
|
@@ -16,17 +16,15 @@ use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
class FinderFactory
|
||||
{
|
||||
/** @var ?Pattern Hidden files pattern cache */
|
||||
/** Hidden files pattern cache */
|
||||
private ?Pattern $pattern = null;
|
||||
|
||||
/** Create a new FinderFactory object. */
|
||||
public function __construct(
|
||||
private Container $container,
|
||||
private Config $config,
|
||||
private HiddenFiles $hiddenFiles
|
||||
) {}
|
||||
|
||||
/** Initialize and return the Finder component. */
|
||||
public function __invoke(): Finder
|
||||
{
|
||||
$finder = Finder::create()->followLinks();
|
||||
|
@@ -15,13 +15,11 @@ use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class TranslationFactory
|
||||
{
|
||||
/** Create a new TranslationFactory object. */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private CacheInterface $cache
|
||||
) {}
|
||||
|
||||
/** Initialize and return the translation component. */
|
||||
public function __invoke(): TranslatorInterface
|
||||
{
|
||||
if (! in_array(
|
||||
@@ -43,7 +41,11 @@ class TranslationFactory
|
||||
return $translator;
|
||||
}
|
||||
|
||||
/** Get an array of available translation languages. */
|
||||
/**
|
||||
* Get an array of available translation languages.
|
||||
*
|
||||
* @return list<string>
|
||||
*/
|
||||
protected function translations(): array
|
||||
{
|
||||
return $this->cache->get('translations', function (): array {
|
||||
|
@@ -14,18 +14,16 @@ use Twig\TwigFunction;
|
||||
|
||||
class TwigFactory
|
||||
{
|
||||
/** Create a new TwigFactory object. */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private CallableResolver $callableResolver
|
||||
) {}
|
||||
|
||||
/** Initialize and return the Twig component. */
|
||||
public function __invoke(): Twig
|
||||
{
|
||||
$twig = new Twig(new FilesystemLoader(
|
||||
$this->config->get('views_path')
|
||||
), ['cache' => $this->config->get('view_cache')]);
|
||||
$twig = new Twig(new FilesystemLoader($this->config->get('views_path')), [
|
||||
'cache' => $this->config->get('view_cache'),
|
||||
]);
|
||||
|
||||
/** @var CoreExtension $core */
|
||||
$core = $twig->getEnvironment()->getExtension(CoreExtension::class);
|
||||
|
@@ -11,12 +11,10 @@ use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
|
||||
|
||||
class CacheControlMiddleware
|
||||
{
|
||||
/** Create a new CacheControlMiddleware object. */
|
||||
public function __construct(
|
||||
private Config $config
|
||||
) {}
|
||||
|
||||
/** Invoke the CacheControlMiddleware class. */
|
||||
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
|
@@ -13,13 +13,11 @@ use Symfony\Contracts\Cache\CacheInterface;
|
||||
|
||||
class PruneCacheMiddleware
|
||||
{
|
||||
/** Create a new CachePruneMiddleware object. */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private CacheInterface $cache
|
||||
) {}
|
||||
|
||||
/** Invoke the CachePruneMiddleware class. */
|
||||
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
|
||||
{
|
||||
$response = $handler->handle($request);
|
||||
|
@@ -11,14 +11,12 @@ use Slim\Views\Twig;
|
||||
|
||||
class RegisterGlobalsMiddleware
|
||||
{
|
||||
/** Array of valid theme strings. */
|
||||
private const VALID_THEMES = ['dark', 'light'];
|
||||
|
||||
public function __construct(
|
||||
private Twig $view
|
||||
) {}
|
||||
|
||||
/** Invoke the RegisterGlobalsMiddleware class. */
|
||||
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
|
||||
{
|
||||
$this->view->getEnvironment()->addGlobal('theme', $this->getThemeFromRequest($request));
|
||||
|
@@ -13,14 +13,12 @@ use Whoops\RunInterface;
|
||||
|
||||
class WhoopsMiddleware
|
||||
{
|
||||
/** Create a new WhoopseMiddleware object. */
|
||||
public function __construct(
|
||||
private RunInterface $whoops,
|
||||
private PrettyPageHandler $pageHandler,
|
||||
private JsonResponseHandler $jsonHandler
|
||||
) {}
|
||||
|
||||
/** Invoke the WhoopseMiddleware class. */
|
||||
public function __invoke(Request $request, RequestHandler $handler): ResponseInterface
|
||||
{
|
||||
$this->pageHandler->setPageTitle(
|
||||
|
@@ -8,7 +8,7 @@ use Symfony\Component\Finder\Finder;
|
||||
|
||||
class Changed extends SortMethod
|
||||
{
|
||||
/** Sory by file changed time. */
|
||||
/** Sort by file changed time. */
|
||||
public function __invoke(Finder $finder): void
|
||||
{
|
||||
$finder->sortByChangedTime();
|
||||
|
@@ -8,7 +8,7 @@ use Symfony\Component\Finder\Finder;
|
||||
|
||||
class Type extends SortMethod
|
||||
{
|
||||
/** Sory by file type. */
|
||||
/** Sort by file type. */
|
||||
public function __invoke(Finder $finder): void
|
||||
{
|
||||
$finder->sortByType();
|
||||
|
@@ -11,6 +11,8 @@ class Str
|
||||
/**
|
||||
* Explode a string by a string into a collection.
|
||||
*
|
||||
* @param non-empty-string $delimiter
|
||||
*
|
||||
* @return Collection<int, string>
|
||||
*/
|
||||
public static function explode(string $string, string $delimiter): Collection
|
||||
|
@@ -12,7 +12,7 @@ class Breadcrumbs extends ViewFunction
|
||||
{
|
||||
protected string $name = 'breadcrumbs';
|
||||
|
||||
/** Create a new Breadcrumbs object. */
|
||||
/** @param non-empty-string $directorySeparator */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private string $directorySeparator = DIRECTORY_SEPARATOR
|
||||
|
@@ -10,7 +10,6 @@ class Config extends ViewFunction
|
||||
{
|
||||
protected string $name = 'config';
|
||||
|
||||
/** Create a new Config object. */
|
||||
public function __construct(
|
||||
private AppConfig $config
|
||||
) {}
|
||||
|
@@ -11,7 +11,6 @@ class Icon extends ViewFunction
|
||||
{
|
||||
protected string $name = 'icon';
|
||||
|
||||
/** Create a new Config object. */
|
||||
public function __construct(
|
||||
private Config $config
|
||||
) {}
|
||||
@@ -21,8 +20,7 @@ class Icon extends ViewFunction
|
||||
{
|
||||
$icons = $this->config->get('icons');
|
||||
|
||||
$icon = $file->isDir() ? 'fas fa-folder'
|
||||
: $icons[strtolower($file->getExtension())] ?? 'fas fa-file';
|
||||
$icon = $file->isDir() ? 'fas fa-folder' : $icons[strtolower($file->getExtension())] ?? 'fas fa-file';
|
||||
|
||||
return "<i class=\"{$icon} fa-fw fa-lg\"></i>";
|
||||
}
|
||||
|
@@ -20,8 +20,9 @@ class ModifiedTime extends ViewFunction
|
||||
public function __invoke(SplFileInfo $file): string
|
||||
{
|
||||
try {
|
||||
/** @throws RuntimeException */
|
||||
$modifiedTime = $file->getMTime();
|
||||
} catch (RuntimeException $exception) {
|
||||
} catch (RuntimeException) {
|
||||
$modifiedTime = lstat($file->getPathname())['mtime'];
|
||||
}
|
||||
|
||||
|
@@ -10,7 +10,7 @@ class ParentUrl extends ViewFunction
|
||||
{
|
||||
protected string $name = 'parent_url';
|
||||
|
||||
/** Create a new ParentUrl object. */
|
||||
/** @param non-empty-string $directorySeparator */
|
||||
public function __construct(
|
||||
private string $directorySeparator = DIRECTORY_SEPARATOR
|
||||
) {}
|
||||
|
@@ -9,6 +9,8 @@ use Symfony\Component\Finder\SplFileInfo;
|
||||
|
||||
class SizeForHumans extends ViewFunction
|
||||
{
|
||||
private const array UNITS = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
|
||||
protected string $name = 'size_for_humans';
|
||||
|
||||
/** Get the human readable file size from a file object. */
|
||||
@@ -16,13 +18,12 @@ class SizeForHumans extends ViewFunction
|
||||
{
|
||||
try {
|
||||
$fileSize = $file->getSize();
|
||||
} catch (RuntimeException $exception) {
|
||||
} catch (RuntimeException) {
|
||||
return '0B';
|
||||
}
|
||||
|
||||
$sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
$factor = (int) floor((strlen((string) $fileSize) - 1) / 3);
|
||||
|
||||
return sprintf('%.2f%s', $fileSize / pow(1024, $factor), $sizes[$factor]);
|
||||
return sprintf('%.2f%s', $fileSize / pow(1024, $factor), self::UNITS[$factor]);
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,6 @@ class Translate extends ViewFunction
|
||||
{
|
||||
protected string $name = 'translate';
|
||||
|
||||
/** Create a new Translate object. */
|
||||
public function __construct(
|
||||
private TranslatorInterface $translator
|
||||
) {}
|
||||
|
@@ -11,7 +11,7 @@ class Url extends ViewFunction
|
||||
{
|
||||
protected string $name = 'url';
|
||||
|
||||
/** Create a new Url object. */
|
||||
/** @param non-empty-string $directorySeparator */
|
||||
public function __construct(
|
||||
private Config $config,
|
||||
private string $directorySeparator = DIRECTORY_SEPARATOR
|
||||
|
@@ -1,71 +1,5 @@
|
||||
parameters:
|
||||
ignoreErrors:
|
||||
-
|
||||
message: '#^Method App\\Bootstrap\\AppManager\:\:__invoke\(\) return type with generic class Slim\\App does not specify its types\: TContainerInterface$#'
|
||||
identifier: missingType.generics
|
||||
count: 1
|
||||
path: app/src/Bootstrap/AppManager.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Bootstrap\\ExceptionManager\:\:__construct\(\) has parameter \$app with generic class Slim\\App but does not specify its types\: TContainerInterface$#'
|
||||
identifier: missingType.generics
|
||||
count: 1
|
||||
path: app/src/Bootstrap/ExceptionManager.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Bootstrap\\MiddlewareManager\:\:__construct\(\) has parameter \$app with generic class Slim\\App but does not specify its types\: TContainerInterface$#'
|
||||
identifier: missingType.generics
|
||||
count: 1
|
||||
path: app/src/Bootstrap/MiddlewareManager.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Bootstrap\\RouteManager\:\:__construct\(\) has parameter \$app with generic class Slim\\App but does not specify its types\: TContainerInterface$#'
|
||||
identifier: missingType.generics
|
||||
count: 1
|
||||
path: app/src/Bootstrap/RouteManager.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\DirectoryController\:\:__invoke\(\) throws checked exception Twig\\Error\\LoaderError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/DirectoryController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\DirectoryController\:\:__invoke\(\) throws checked exception Twig\\Error\\RuntimeError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/DirectoryController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\DirectoryController\:\:__invoke\(\) throws checked exception Twig\\Error\\SyntaxError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/DirectoryController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\FileInfoController\:\:calculateHashes\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: app/src/Controllers/FileInfoController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\SearchController\:\:__invoke\(\) throws checked exception Twig\\Error\\LoaderError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/SearchController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\SearchController\:\:__invoke\(\) throws checked exception Twig\\Error\\RuntimeError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/SearchController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\SearchController\:\:__invoke\(\) throws checked exception Twig\\Error\\SyntaxError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 2
|
||||
path: app/src/Controllers/SearchController.php
|
||||
|
||||
-
|
||||
message: '#^Cannot access offset ''mtime'' on array\{0\: int, 1\: int, 2\: int, 3\: int, 4\: int, 5\: int, 6\: int, 7\: int, \.\.\.\}\|false\.$#'
|
||||
identifier: offsetAccess.nonOffsetAccessible
|
||||
@@ -73,35 +7,11 @@ parameters:
|
||||
path: app/src/Controllers/ZipController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Controllers\\ZipController\:\:generateFileName\(\) should return string but returns string\|null\.$#'
|
||||
identifier: return.type
|
||||
message: '#^Method App\\Controllers\\ZipController\:\:createZip\(\) throws checked exception DateMalformedStringException but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 1
|
||||
path: app/src/Controllers/ZipController.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Exceptions\\ErrorHandler\:\:__invoke\(\) throws checked exception Twig\\Error\\LoaderError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 1
|
||||
path: app/src/Exceptions/ErrorHandler.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Exceptions\\ErrorHandler\:\:__invoke\(\) throws checked exception Twig\\Error\\RuntimeError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 1
|
||||
path: app/src/Exceptions/ErrorHandler.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Exceptions\\ErrorHandler\:\:__invoke\(\) throws checked exception Twig\\Error\\SyntaxError but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 1
|
||||
path: app/src/Exceptions/ErrorHandler.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Factories\\TranslationFactory\:\:translations\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: app/src/Factories/TranslationFactory.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Factories\\TwigFactory\:\:__invoke\(\) throws checked exception ReflectionException but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
@@ -109,44 +19,8 @@ parameters:
|
||||
path: app/src/Factories/TwigFactory.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\Middlewares\\PruneCacheMiddleware\:\:winsLottery\(\) throws checked exception Random\\RandomException but it''s missing from the PHPDoc @throws tag\.$#'
|
||||
identifier: missingType.checkedException
|
||||
count: 1
|
||||
path: app/src/Middlewares/PruneCacheMiddleware.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$separator of function explode expects non\-empty\-string, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: app/src/Support/Str.php
|
||||
|
||||
-
|
||||
message: '#^Unable to resolve the template type TMakeKey in call to method static method Tightenco\\Collect\\Support\\Collection\<\(int\|string\),mixed\>\:\:make\(\)$#'
|
||||
identifier: argument.templateType
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/Asset.php
|
||||
|
||||
-
|
||||
message: '#^Unable to resolve the template type TMakeValue in call to method static method Tightenco\\Collect\\Support\\Collection\<\(int\|string\),mixed\>\:\:make\(\)$#'
|
||||
identifier: argument.templateType
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/Asset.php
|
||||
|
||||
-
|
||||
message: '#^Method App\\ViewFunctions\\Breadcrumbs\:\:__invoke\(\) should return Tightenco\\Collect\\Support\\Collection\<int, string\> but returns Tightenco\\Collect\\Support\\Collection\<\*NEVER\*, non\-falsy\-string\>\.$#'
|
||||
identifier: return.type
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/Breadcrumbs.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$separator of function explode expects non\-empty\-string, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/Breadcrumbs.php
|
||||
|
||||
-
|
||||
message: '#^Dead catch \- RuntimeException is never thrown in the try block\.$#'
|
||||
identifier: catch.neverThrown
|
||||
message: '#^Cannot access offset ''mtime'' on array\{0\: int, 1\: int, 2\: int, 3\: int, 4\: int, 5\: int, 6\: int, 7\: int, \.\.\.\}\|false\.$#'
|
||||
identifier: offsetAccess.nonOffsetAccessible
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/ModifiedTime.php
|
||||
|
||||
@@ -156,93 +30,8 @@ parameters:
|
||||
count: 1
|
||||
path: app/src/ViewFunctions/SizeForHumans.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\Controllers\\DirectoryControllerTest\:\:configOptions\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/Controllers/DirectoryControllerTest.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$finfo of function finfo_buffer expects finfo, finfo\|false given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: tests/Exceptions/ErrorHandlerTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\Factories\\CacheFactoryTest\:\:cacheAdapters\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/Factories/CacheFactoryTest.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$expected of method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) expects class\-string\<object\>, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: tests/Factories/CacheFactoryTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\Factories\\FinderFactoryTest\:\:getFilesArray\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/Factories/FinderFactoryTest.php
|
||||
|
||||
-
|
||||
message: '#^Cannot call method getCallable\(\) on Twig\\TwigFunction\|null\.$#'
|
||||
identifier: method.nonObject
|
||||
count: 11
|
||||
path: tests/Factories/TwigFactoryTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\HiddenFilesTest\:\:hiddenFilesProvider\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/HiddenFilesTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\HiddenFilesTest\:\:test_it_creates_a_collection_of_hidden_files\(\) has parameter \$expected with no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/HiddenFilesTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\HiddenFilesTest\:\:test_it_creates_a_collection_of_hidden_files\(\) has parameter \$hiddenFilesArray with no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/HiddenFilesTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\Middlewares\\PruneCacheMiddlewareTest\:\:nonPruneableCacheAdapters\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
-
|
||||
message: '#^Method Tests\\Middlewares\\PruneCacheMiddlewareTest\:\:pruneableCacheAdapters\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$className of method PHPUnit\\Framework\\TestCase\:\:getMockBuilder\(\) expects class\-string\<object\>, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$originalClassName of method PHPUnit\\Framework\\TestCase\:\:createMock\(\) expects class\-string\<object\>, string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
-
|
||||
message: '#^Unable to resolve the template type RealInstanceType in call to method PHPUnit\\Framework\\TestCase\:\:createMock\(\)$#'
|
||||
identifier: argument.templateType
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
-
|
||||
message: '#^Unable to resolve the template type RealInstanceType in call to method PHPUnit\\Framework\\TestCase\:\:getMockBuilder\(\)$#'
|
||||
identifier: argument.templateType
|
||||
count: 1
|
||||
path: tests/Middlewares/PruneCacheMiddlewareTest.php
|
||||
|
||||
|
@@ -4,3 +4,5 @@ parameters:
|
||||
path: tests/*
|
||||
- message: "#^Method .+ has parameter .+ with no value type specified in iterable type array\\.$#"
|
||||
path: tests/*
|
||||
- message: "#^Method .+ return type has no value type specified in iterable type array\\.$#"
|
||||
path: tests/*
|
||||
|
@@ -16,8 +16,6 @@ parameters:
|
||||
|
||||
checkFunctionNameCase: true
|
||||
|
||||
reportUnmatchedIgnoredErrors: false
|
||||
|
||||
exceptions:
|
||||
implicitThrows: false
|
||||
|
||||
@@ -31,11 +29,13 @@ parameters:
|
||||
- 'Invoker\Exception\NotCallableException'
|
||||
- 'JsonException'
|
||||
- 'LogicException'
|
||||
- 'RuntimeException'
|
||||
- 'PHPUnit\Framework\Exception'
|
||||
- 'Psr\Cache\InvalidArgumentException'
|
||||
- 'Random\RandomException'
|
||||
- 'RuntimeException'
|
||||
- 'SebastianBergmann\RecursionContext\InvalidArgumentException'
|
||||
- 'Symfony\Component\Cache\Exception\CacheException'
|
||||
- 'PHPUnit\Framework\Exception'
|
||||
- 'Twig\Error\Error'
|
||||
|
||||
includes:
|
||||
- phpstan-baseline.neon
|
||||
|
@@ -28,6 +28,7 @@ class CacheFactoryTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/** @param class-string $adapter */
|
||||
#[Test, DataProvider('cacheAdapters')]
|
||||
public function it_can_compose_an_adapter(string $config, string $adapter, bool $available = true): void
|
||||
{
|
||||
|
@@ -43,6 +43,7 @@ class PruneCacheMiddlewareTest extends TestCase
|
||||
];
|
||||
}
|
||||
|
||||
/** @param class-string $cacheAdapter */
|
||||
#[Test, DataProvider('pruneableCacheAdapters')]
|
||||
public function it_prunes_the_cache_whe_using_a_pruneable_adapter_and_winning_the_lottery(string $cacheAdapter): void
|
||||
{
|
||||
@@ -56,6 +57,7 @@ class PruneCacheMiddlewareTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
/** @param class-string $cacheAdapter */
|
||||
#[Test, DataProvider('nonPruneableCacheAdapters')]
|
||||
public function it_does_not_prune_the_cache_when_using_a_non_prunable_adapter(string $cacheAdapter): void
|
||||
{
|
||||
|
@@ -62,6 +62,7 @@ class WhoopsMiddlewareTest extends TestCase
|
||||
fn (Handler $parameter) => match ($matcher->numberOfInvocations()) {
|
||||
1 => $this->assertSame($pageHandler, $parameter),
|
||||
2 => $this->assertSame($jsonHandler, $parameter),
|
||||
default => $this->fail('Unexpected invocation')
|
||||
}
|
||||
);
|
||||
|
||||
|
Reference in New Issue
Block a user