Skip to content

Commit

Permalink
add downloader
Browse files Browse the repository at this point in the history
  • Loading branch information
Warxcell committed Jan 17, 2025
1 parent 7eed2a2 commit 6c44af1
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 16 deletions.
22 changes: 10 additions & 12 deletions .idea/php.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,11 @@
"psr-4": {
"Arxy\\FilesBundle\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"dealerdirect/phpcodesniffer-composer-installer": true,
"infection/extension-installer": true
}
}
}
13 changes: 10 additions & 3 deletions src/ErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
class ErrorHandler
{
/**
* @return mixed
* @template T
* @param callable(): (T|false) $callable
* @return T
* @throws ErrorException
*/
public static function wrap(callable $callable)
public static function wrap(callable $callable): mixed
{
set_error_handler(
static function (int $errno, string $message, string $file, int $line): bool {
Expand All @@ -29,7 +31,12 @@ static function (int $errno, string $message, string $file, int $line): bool {
}
);
try {
return $callable();
$value = $callable();
if ($value === false) {
throw new ErrorException('Unknown error');
}

return $value;
} finally {
restore_error_handler();
}
Expand Down
1 change: 0 additions & 1 deletion src/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use SplFileInfo;
use SplFileObject;
use Symfony\Component\HttpFoundation\File\UploadedFile;

use Throwable;

use function clearstatcache;
Expand Down
43 changes: 43 additions & 0 deletions src/Utility/FileDownloader.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Arxy\FilesBundle\Utility;

use Arxy\FilesBundle\ErrorHandler;
use Arxy\FilesBundle\ManagerInterface;
use Arxy\FilesBundle\Model\File;
use SplFileInfo;

use function fclose;
use function fopen;
use function stream_copy_to_stream;

class FileDownloader
{
private ManagerInterface $manager;

public function __construct(ManagerInterface $manager)
{
$this->manager = $manager;
}

/**
* @throws \ErrorException
*/
public function downloadAsSplFile(File $file): SplFileInfo
{
$tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid('file-downloader', true);

ErrorHandler::wrap(static fn (): bool => mkdir($tempDir));

$tmpFile = $tempDir . DIRECTORY_SEPARATOR . $file->getOriginalFilename();

$destinationStream = ErrorHandler::wrap(static fn () => fopen($tmpFile, 'w'));
ErrorHandler::wrap(fn () => stream_copy_to_stream($this->manager->readStream($file), $destinationStream));

fclose($destinationStream);

return new SplFileInfo($tmpFile);
}
}
69 changes: 69 additions & 0 deletions tests/FileDownloaderTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php

declare(strict_types=1);

namespace Arxy\FilesBundle\Tests;

use Arxy\FilesBundle\Manager;
use Arxy\FilesBundle\ManagerInterface;
use Arxy\FilesBundle\NamingStrategy;
use Arxy\FilesBundle\Storage\FlysystemStorage;
use Arxy\FilesBundle\Utility\FileDownloader;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemOperator;
use League\Flysystem\InMemory\InMemoryFilesystemAdapter;
use PHPUnit\Framework\TestCase;

class FileDownloaderTest extends TestCase
{
private ManagerInterface $manager;
private FilesystemOperator $filesystem;

private FileDownloader $downloader;

protected function setUp(): void
{
parent::setUp();

$this->filesystem = new Filesystem(new InMemoryFilesystemAdapter());

$this->manager = new Manager(
File::class,
new FlysystemStorage($this->filesystem),
/** @implements NamingStrategy<File> */
new class implements NamingStrategy {
public function getDirectoryName(\Arxy\FilesBundle\Model\File $file): ?string
{
return null;
}

public function getFileName(\Arxy\FilesBundle\Model\File $file): string
{
return (string)$file->getId();
}
},
new FileRepository(),
);

$this->downloader = new FileDownloader($this->manager);
}

public function testDownloadAsSplFilePersisted(): void
{
$file = $this->manager->upload(new \SplFileObject(__DIR__ . '/files/image1.jpg'));
$this->manager->moveFile($file);

$splFile = $this->downloader->downloadAsSplFile($file);

self::assertFileEquals($splFile->getPathname(), __DIR__ . '/files/image1.jpg');
}

public function testDownloadAsSplFileNotPersisted(): void
{
$file = $this->manager->upload(new \SplFileObject(__DIR__ . '/files/image1.jpg'));

$splFile = $this->downloader->downloadAsSplFile($file);

self::assertFileEquals($splFile->getPathname(), __DIR__ . '/files/image1.jpg');
}
}

Check failure on line 69 in tests/FileDownloaderTest.php

View workflow job for this annotation

GitHub Actions / build

Expected 1 newline at end of file; 0 found

0 comments on commit 6c44af1

Please sign in to comment.