From 8076862029e36a43213dbb2a8bd50a9c09f0a100 Mon Sep 17 00:00:00 2001 From: Chris Kankiewicz Date: Tue, 23 Feb 2021 21:36:28 -0700 Subject: [PATCH] Broken symlinks will no longer cause errors --- app/config/container.php | 1 + app/src/ViewFunctions/ModifiedTime.php | 32 ++++++++++++++++++++++++ app/src/ViewFunctions/SizeForHumans.php | 13 +++++++--- app/views/components/file.twig | 2 +- tests/ViewFunctions/ModifiedTimeTest.php | 32 ++++++++++++++++++++++++ tests/_files/somedir/broken.symlink | 1 + 6 files changed, 77 insertions(+), 4 deletions(-) create mode 100644 app/src/ViewFunctions/ModifiedTime.php create mode 100644 tests/ViewFunctions/ModifiedTimeTest.php create mode 120000 tests/_files/somedir/broken.symlink diff --git a/app/config/container.php b/app/config/container.php index e40f7e6..0bb233a 100644 --- a/app/config/container.php +++ b/app/config/container.php @@ -47,6 +47,7 @@ return [ ViewFunctions\FileUrl::class, ViewFunctions\Icon::class, ViewFunctions\Markdown::class, + ViewFunctions\ModifiedTime::class, ViewFunctions\ParentUrl::class, ViewFunctions\SizeForHumans::class, ViewFunctions\Translate::class, diff --git a/app/src/ViewFunctions/ModifiedTime.php b/app/src/ViewFunctions/ModifiedTime.php new file mode 100644 index 0000000..87d0009 --- /dev/null +++ b/app/src/ViewFunctions/ModifiedTime.php @@ -0,0 +1,32 @@ +config = $config; + } + + /** Get the modified time from a file object. */ + public function __invoke(SplFileInfo $file): string + { + try { + $modifiedTime = $file->getMTime(); + } catch (RuntimeException $exception) { + $modifiedTime = lstat($file->getPathname())['mtime']; + } + + return date($this->config->get('date_format'), $modifiedTime); + } +} diff --git a/app/src/ViewFunctions/SizeForHumans.php b/app/src/ViewFunctions/SizeForHumans.php index 6648458..8b92ad2 100644 --- a/app/src/ViewFunctions/SizeForHumans.php +++ b/app/src/ViewFunctions/SizeForHumans.php @@ -2,6 +2,7 @@ namespace App\ViewFunctions; +use RuntimeException; use Symfony\Component\Finder\SplFileInfo; class SizeForHumans extends ViewFunction @@ -12,9 +13,15 @@ class SizeForHumans extends ViewFunction /** Get the human readable file size from a file object. */ public function __invoke(SplFileInfo $file): string { - $sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; - $factor = (int) floor((strlen((string) $file->getSize()) - 1) / 3); + try { + $fileSize = $file->getSize(); + } catch (RuntimeException $exception) { + return 0; + } - return sprintf('%.2f', $file->getSize() / pow(1024, $factor)) . $sizes[$factor]; + $sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + $factor = (int) floor((strlen((string) $fileSize) - 1) / 3); + + return sprintf('%.2f', $fileSize / pow(1024, $factor)) . $sizes[$factor]; } } diff --git a/app/views/components/file.twig b/app/views/components/file.twig index cec665d..84f6cce 100644 --- a/app/views/components/file.twig +++ b/app/views/components/file.twig @@ -36,7 +36,7 @@ diff --git a/tests/ViewFunctions/ModifiedTimeTest.php b/tests/ViewFunctions/ModifiedTimeTest.php new file mode 100644 index 0000000..0cbcb3c --- /dev/null +++ b/tests/ViewFunctions/ModifiedTimeTest.php @@ -0,0 +1,32 @@ +createMock(SplFileInfo::class); + $file->method('getMTime')->willReturn(516976496); + + $modifiedTime = new ModifiedTime($this->config); + + $this->assertEquals('1986-05-20 12:34:56', $modifiedTime($file)); + } + + public function test_it_can_return_the_modified_time_for_a_symlink(): void + { + $file = $this->createMock(SplFileInfo::class); + $file->method('getMTime')->willThrowException(new RuntimeException); + $file->method('getPathname')->willReturn(dirname(__DIR__) . '/_files/somedir/broken.symlink'); + + $modifiedTime = new ModifiedTime($this->config); + + $this->assertEquals('1986-05-20 12:34:56', $modifiedTime($file)); + } +} diff --git a/tests/_files/somedir/broken.symlink b/tests/_files/somedir/broken.symlink new file mode 120000 index 0000000..122c58e --- /dev/null +++ b/tests/_files/somedir/broken.symlink @@ -0,0 +1 @@ +../broken.symlink \ No newline at end of file