Skip to content

Commit

Permalink
Merge pull request #362 from jorisvaesen/master
Browse files Browse the repository at this point in the history
Option to delete file on record deletion
  • Loading branch information
josegonzalez committed Mar 18, 2016
2 parents d3fed95 + e476219 commit b652f1c
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 6 deletions.
4 changes: 4 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,7 @@ passed in under each field in your behavior configuration.
- ``array $settings``: UploadBehavior settings for the current field

- Return: (string) the new name for the file

- ``keepFilesOnDelete``: Keep *all* files when uploading/deleting a record.

- Default: (boolean) ``true``
18 changes: 18 additions & 0 deletions src/File/Writer/DefaultWriter.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,23 @@ public function write(array $files)
return $results;
}

/**
* Deletes a set of files to an output
*
* @param array $files the files being written out
* @return array array of results
*/
public function delete(array $files)
{
$filesystem = $this->getFilesystem($this->field, $this->settings);
$results = [];
foreach ($files as $path) {
$results[] = $this->deletePath($filesystem, $path);
}

return $results;
}

/**
* Writes a set of files to an output
*
Expand Down Expand Up @@ -126,6 +143,7 @@ public function deletePath(FilesystemInterface $filesystem, $path)
} catch (FileNotFoundException $e) {
// TODO: log this?
}

return $success;
}

Expand Down
8 changes: 8 additions & 0 deletions src/File/Writer/WriterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,12 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin
* @return array array of results
*/
public function write(array $files);

/**
* Deletes a set of files to an output
*
* @param array $files the files being written out
* @return array array of results
*/
public function delete(array $files);
}
27 changes: 27 additions & 0 deletions src/Model/Behavior/UploadBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,33 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
}
}

/**
* Deletes the files after the entity is deleted
*
* @param \Cake\Event\Event $event The afterDelete event that was fired
* @param \Cake\ORM\Entity $entity The entity that was deleted
* @param \ArrayObject $options the options passed to the delete method
* @return void|false
*/
public function afterDelete(Event $event, Entity $entity, ArrayObject $options)
{
foreach ($this->config() as $field => $settings) {
if (Hash::get($settings, 'keepFilesOnDelete', true)) {
continue;
}

$dirField = Hash::get($settings, 'fields.dir', 'dir');

$file = [$entity->{$dirField} . $entity->{$field}];
$writer = $this->getWriter($entity, [], $field, $settings);
$success = $writer->delete($file);

if ((new Collection($success))->contains(false)) {
return false;
}
}
}

/**
* Retrieves an instance of a path processor which knows how to build paths
* for a given file upload
Expand Down
42 changes: 36 additions & 6 deletions tests/TestCase/File/Writer/DefaultWriterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,33 @@
class DefaultWriterTest extends TestCase
{
protected $vfs;
protected $writer;
protected $entity;
protected $table;
protected $data;
protected $field;
protected $settings;

public function setup()
{
$entity = $this->getMock('Cake\ORM\Entity');
$table = $this->getMock('Cake\ORM\Table');
$data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt'];
$field = 'field';
$settings = [
$this->entity = $this->getMock('Cake\ORM\Entity');
$this->table = $this->getMock('Cake\ORM\Table');
$this->data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt'];
$this->field = 'field';
$this->settings = [
'filesystem' => [
'adapter' => function () {
return new VfsAdapter(new Vfs);
}
]
];
$this->writer = new DefaultWriter($table, $entity, $data, $field, $settings);
$this->writer = new DefaultWriter(
$this->table,
$this->entity,
$this->data,
$this->field,
$this->settings
);

$this->vfs = new Vfs;
mkdir($this->vfs->path('/tmp'));
Expand All @@ -51,6 +63,24 @@ public function testInvoke()
], 'field', []));
}

public function testDelete()
{
$filesystem = $this->getMock('League\Flysystem\FilesystemInterface');
$filesystem->expects($this->at(0))->method('delete')->will($this->returnValue(true));
$filesystem->expects($this->at(1))->method('delete')->will($this->returnValue(false));
$writer = $this->getMock('Josegonzalez\Upload\File\Writer\DefaultWriter', ['getFilesystem'], [$this->table, $this->entity, $this->data, $this->field, $this->settings]);
$writer->expects($this->any())->method('getFilesystem')->will($this->returnValue($filesystem));

$this->assertEquals([], $writer->delete([]));
$this->assertEquals([true], $writer->delete([
$this->vfs->path('/tmp/tempfile')
]));

$this->assertEquals([false], $writer->delete([
$this->vfs->path('/tmp/invalid.txt')
]));
}

public function testWriteFile()
{
$filesystem = $this->getMock('League\Flysystem\FilesystemInterface');
Expand Down
49 changes: 49 additions & 0 deletions tests/TestCase/Model/Behavior/UploadBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public function setup()
'error' => UPLOAD_ERR_OK,
'size' => 1,
'type' => 'text',
'keepFilesOnDelete' => false
]
];
$this->dataError = [
Expand Down Expand Up @@ -201,6 +202,54 @@ public function testBeforeSaveOk()
$this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject));
}

public function testAfterDeleteOk()
{
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataOk]);
$behavior->config($this->dataOk);

$behavior->expects($this->any())
->method('getWriter')
->will($this->returnValue($this->writer));
$this->writer->expects($this->any())
->method('delete')
->will($this->returnValue([true]));

$this->assertNull($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
}

public function testAfterDeleteFail()
{
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataOk]);
$behavior->config($this->dataOk);

$behavior->expects($this->any())
->method('getWriter')
->will($this->returnValue($this->writer));
$this->writer->expects($this->any())
->method('delete')
->will($this->returnValue([false]));

$this->assertFalse($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
}

public function testAfterDeleteSkip()
{
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataError]);
$behavior->config($this->dataError);

$behavior->expects($this->any())
->method('getWriter')
->will($this->returnValue($this->writer));
$this->writer->expects($this->any())
->method('delete')
->will($this->returnValue([true]));

$this->assertNull($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
}

public function testGetWriter()
{
$processor = $this->behavior->getWriter($this->entity, [], 'field', []);
Expand Down

0 comments on commit b652f1c

Please sign in to comment.