Skip to content

Commit

Permalink
Merge pull request #573 from FriendsOfCake/6.0
Browse files Browse the repository at this point in the history
6.0
  • Loading branch information
ADmad authored Aug 6, 2021
2 parents 09e74b9 + 3fd416b commit 67b7e7b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 49 deletions.
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
],
"require": {
"cakephp/orm": "^4.0.2",
"league/flysystem": "^1.0"
"league/flysystem": "^2.2"
},
"require-dev": {
"cakephp/cakephp": "^4.0.2",
"phpunit/phpunit": "~8.5.0",
"league/flysystem-vfs": "*",
"cakephp/cakephp-codesniffer": "^4.0"
"cakephp/cakephp-codesniffer": "^4.0",
"league/flysystem-memory": "^2.0",
"php-vfs/php-vfs": "^1.4.2"
},
"autoload": {
"psr-4": {
Expand Down
47 changes: 29 additions & 18 deletions src/File/Writer/DefaultWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
use Cake\Datasource\EntityInterface;
use Cake\ORM\Table;
use Cake\Utility\Hash;
use League\Flysystem\Adapter\Local;
use League\Flysystem\AdapterInterface;
use League\Flysystem\FileNotFoundException;
use League\Flysystem\Filesystem;
use League\Flysystem\FilesystemInterface;
use League\Flysystem\FilesystemAdapter;
use League\Flysystem\FilesystemException;
use League\Flysystem\FilesystemOperator;
use League\Flysystem\Local\LocalFilesystemAdapter;
use League\Flysystem\Visibility;
use Psr\Http\Message\UploadedFileInterface;
use UnexpectedValueException;

Expand Down Expand Up @@ -111,12 +112,12 @@ public function delete(array $files): array
/**
* Writes a set of files to an output
*
* @param \League\Flysystem\FilesystemInterface $filesystem a filesystem wrapper
* @param \League\Flysystem\FilesystemOperator $filesystem a filesystem wrapper
* @param string $file a full path to a temp file
* @param string $path that path to which the file should be written
* @return bool
*/
public function writeFile(FilesystemInterface $filesystem, $file, $path): bool
public function writeFile(FilesystemOperator $filesystem, $file, $path): bool
{
// phpcs:ignore
$stream = @fopen($file, 'r');
Expand All @@ -127,10 +128,19 @@ public function writeFile(FilesystemInterface $filesystem, $file, $path): bool
$success = false;
$tempPath = $path . '.temp';
$this->deletePath($filesystem, $tempPath);
if ($filesystem->writeStream($tempPath, $stream)) {
try {
$filesystem->writeStream($tempPath, $stream);
$this->deletePath($filesystem, $path);
$success = $filesystem->rename($tempPath, $path);
try {
$filesystem->move($tempPath, $path);
$success = true;
} catch (FilesystemException $e) {
// noop
}
} catch (FilesystemException $e) {
// noop
}

$this->deletePath($filesystem, $tempPath);
is_resource($stream) && fclose($stream);

Expand All @@ -140,16 +150,17 @@ public function writeFile(FilesystemInterface $filesystem, $file, $path): bool
/**
* Deletes a path from a filesystem
*
* @param \League\Flysystem\FilesystemInterface $filesystem a filesystem writer
* @param \League\Flysystem\FilesystemOperator $filesystem a filesystem writer
* @param string $path the path that should be deleted
* @return bool
*/
public function deletePath(FilesystemInterface $filesystem, string $path): bool
public function deletePath(FilesystemOperator $filesystem, string $path): bool
{
$success = false;
$success = true;
try {
$success = $filesystem->delete($path);
} catch (FileNotFoundException $e) {
$filesystem->delete($path);
} catch (FilesystemException $e) {
$success = false;
// TODO: log this?
}

Expand All @@ -161,19 +172,19 @@ public function deletePath(FilesystemInterface $filesystem, string $path): bool
*
* @param string $field the field for which data will be saved
* @param array $settings the settings for the current field
* @return \League\Flysystem\FilesystemInterface
* @return \League\Flysystem\FilesystemOperator
*/
public function getFilesystem(string $field, array $settings = []): FilesystemInterface
public function getFilesystem(string $field, array $settings = []): FilesystemOperator
{
$adapter = new Local(Hash::get($settings, 'filesystem.root', ROOT . DS));
$adapter = new LocalFilesystemAdapter(Hash::get($settings, 'filesystem.root', ROOT . DS));
$adapter = Hash::get($settings, 'filesystem.adapter', $adapter);
if (is_callable($adapter)) {
$adapter = $adapter();
}

if ($adapter instanceof AdapterInterface) {
if ($adapter instanceof FilesystemAdapter) {
return new Filesystem($adapter, Hash::get($settings, 'filesystem.options', [
'visibility' => AdapterInterface::VISIBILITY_PUBLIC,
'visibility' => Visibility::PUBLIC,
]));
}

Expand Down
58 changes: 30 additions & 28 deletions tests/TestCase/File/Writer/DefaultWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
use Cake\TestSuite\TestCase;
use Josegonzalez\Upload\File\Writer\DefaultWriter;
use Laminas\Diactoros\UploadedFile;
use League\Flysystem\Adapter\NullAdapter;
use League\Flysystem\Vfs\VfsAdapter;
use League\Flysystem\InMemory\InMemoryFilesystemAdapter;
use League\Flysystem\UnableToDeleteFile;
use League\Flysystem\UnableToMoveFile;
use League\Flysystem\UnableToWriteFile;
use VirtualFileSystem\FileSystem as Vfs;

class DefaultWriterTest extends TestCase
Expand All @@ -29,7 +31,7 @@ public function setUp(): void
$this->settings = [
'filesystem' => [
'adapter' => function () {
return new VfsAdapter(new Vfs());
return new InMemoryFilesystemAdapter();
},
],
];
Expand Down Expand Up @@ -65,9 +67,9 @@ public function testInvoke()

public function testDelete()
{
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->at(0))->method('delete')->will($this->returnValue(true));
$filesystem->expects($this->at(1))->method('delete')->will($this->returnValue(false));
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->at(0))->method('delete');
$filesystem->expects($this->at(1))->method('delete')->will($this->throwException(new UnableToDeleteFile()));
$writer = $this->getMockBuilder('Josegonzalez\Upload\File\Writer\DefaultWriter')
->setMethods(['getFilesystem'])
->setConstructorArgs([$this->table, $this->entity, $this->data, $this->field, $this->settings])
Expand All @@ -86,51 +88,51 @@ public function testDelete()

public function testWriteFile()
{
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->once())->method('writeStream')->will($this->returnValue(true));
$filesystem->expects($this->exactly(3))->method('delete')->will($this->returnValue(true));
$filesystem->expects($this->once())->method('rename')->will($this->returnValue(true));
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->once())->method('writeStream');
$filesystem->expects($this->exactly(3))->method('delete');
$filesystem->expects($this->once())->method('move');
$this->assertTrue($this->writer->writeFile($filesystem, $this->vfs->path('/tmp/tempfile'), 'path'));

$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->once())->method('writeStream')->will($this->returnValue(false));
$filesystem->expects($this->exactly(2))->method('delete')->will($this->returnValue(true));
$filesystem->expects($this->never())->method('rename');
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->once())->method('writeStream')->will($this->throwException(new UnableToWriteFile()));
$filesystem->expects($this->exactly(2))->method('delete');
$filesystem->expects($this->never())->method('move');
$this->assertFalse($this->writer->writeFile($filesystem, $this->vfs->path('/tmp/tempfile'), 'path'));

$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->once())->method('writeStream')->will($this->returnValue(true));
$filesystem->expects($this->exactly(3))->method('delete')->will($this->returnValue(true));
$filesystem->expects($this->once())->method('rename')->will($this->returnValue(false));
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->once())->method('writeStream');
$filesystem->expects($this->exactly(3))->method('delete');
$filesystem->expects($this->once())->method('move')->will($this->throwException(new UnableToMoveFile()));
$this->assertFalse($this->writer->writeFile($filesystem, $this->vfs->path('/tmp/tempfile'), 'path'));
}

public function testDeletePath()
{
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->any())->method('delete')->will($this->returnValue(true));
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->any())->method('delete');
$this->assertTrue($this->writer->deletePath($filesystem, 'path'));

$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemInterface')->getMock();
$filesystem->expects($this->any())->method('delete')->will($this->returnValue(false));
$filesystem = $this->getMockBuilder('League\Flysystem\FilesystemOperator')->getMock();
$filesystem->expects($this->any())->method('delete')->will($this->throwException(new UnableToDeleteFile()));
$this->assertFalse($this->writer->deletePath($filesystem, 'path'));
}

public function testGetFilesystem()
{
$this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', []));
$this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [
$this->assertInstanceOf('League\Flysystem\FilesystemOperator', $this->writer->getFilesystem('field', []));
$this->assertInstanceOf('League\Flysystem\FilesystemOperator', $this->writer->getFilesystem('field', [
'key' => 'value',
]));
$this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [
$this->assertInstanceOf('League\Flysystem\FilesystemOperator', $this->writer->getFilesystem('field', [
'filesystem' => [
'adapter' => new NullAdapter(),
'adapter' => new InMemoryFilesystemAdapter(),
],
]));
$this->assertInstanceOf('League\Flysystem\FilesystemInterface', $this->writer->getFilesystem('field', [
$this->assertInstanceOf('League\Flysystem\FilesystemOperator', $this->writer->getFilesystem('field', [
'filesystem' => [
'adapter' => function () {
return new NullAdapter();
return new InMemoryFilesystemAdapter();
},
],
]));
Expand Down

0 comments on commit 67b7e7b

Please sign in to comment.