Skip to content

Commit b652f1c

Browse files
committed
Merge pull request #362 from jorisvaesen/master
Option to delete file on record deletion
2 parents d3fed95 + e476219 commit b652f1c

File tree

6 files changed

+142
-6
lines changed

6 files changed

+142
-6
lines changed

docs/configuration.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,3 +61,7 @@ passed in under each field in your behavior configuration.
6161
- ``array $settings``: UploadBehavior settings for the current field
6262

6363
- Return: (string) the new name for the file
64+
65+
- ``keepFilesOnDelete``: Keep *all* files when uploading/deleting a record.
66+
67+
- Default: (boolean) ``true``

src/File/Writer/DefaultWriter.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,23 @@ public function write(array $files)
8484
return $results;
8585
}
8686

87+
/**
88+
* Deletes a set of files to an output
89+
*
90+
* @param array $files the files being written out
91+
* @return array array of results
92+
*/
93+
public function delete(array $files)
94+
{
95+
$filesystem = $this->getFilesystem($this->field, $this->settings);
96+
$results = [];
97+
foreach ($files as $path) {
98+
$results[] = $this->deletePath($filesystem, $path);
99+
}
100+
101+
return $results;
102+
}
103+
87104
/**
88105
* Writes a set of files to an output
89106
*
@@ -126,6 +143,7 @@ public function deletePath(FilesystemInterface $filesystem, $path)
126143
} catch (FileNotFoundException $e) {
127144
// TODO: log this?
128145
}
146+
129147
return $success;
130148
}
131149

src/File/Writer/WriterInterface.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,12 @@ public function __construct(Table $table, Entity $entity, $data, $field, $settin
2424
* @return array array of results
2525
*/
2626
public function write(array $files);
27+
28+
/**
29+
* Deletes a set of files to an output
30+
*
31+
* @param array $files the files being written out
32+
* @return array array of results
33+
*/
34+
public function delete(array $files);
2735
}

src/Model/Behavior/UploadBehavior.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,33 @@ public function beforeSave(Event $event, Entity $entity, ArrayObject $options)
9595
}
9696
}
9797

98+
/**
99+
* Deletes the files after the entity is deleted
100+
*
101+
* @param \Cake\Event\Event $event The afterDelete event that was fired
102+
* @param \Cake\ORM\Entity $entity The entity that was deleted
103+
* @param \ArrayObject $options the options passed to the delete method
104+
* @return void|false
105+
*/
106+
public function afterDelete(Event $event, Entity $entity, ArrayObject $options)
107+
{
108+
foreach ($this->config() as $field => $settings) {
109+
if (Hash::get($settings, 'keepFilesOnDelete', true)) {
110+
continue;
111+
}
112+
113+
$dirField = Hash::get($settings, 'fields.dir', 'dir');
114+
115+
$file = [$entity->{$dirField} . $entity->{$field}];
116+
$writer = $this->getWriter($entity, [], $field, $settings);
117+
$success = $writer->delete($file);
118+
119+
if ((new Collection($success))->contains(false)) {
120+
return false;
121+
}
122+
}
123+
}
124+
98125
/**
99126
* Retrieves an instance of a path processor which knows how to build paths
100127
* for a given file upload

tests/TestCase/File/Writer/DefaultWriterTest.php

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,33 @@
1313
class DefaultWriterTest extends TestCase
1414
{
1515
protected $vfs;
16+
protected $writer;
17+
protected $entity;
18+
protected $table;
19+
protected $data;
20+
protected $field;
21+
protected $settings;
1622

1723
public function setup()
1824
{
19-
$entity = $this->getMock('Cake\ORM\Entity');
20-
$table = $this->getMock('Cake\ORM\Table');
21-
$data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt'];
22-
$field = 'field';
23-
$settings = [
25+
$this->entity = $this->getMock('Cake\ORM\Entity');
26+
$this->table = $this->getMock('Cake\ORM\Table');
27+
$this->data = ['tmp_name' => 'path/to/file', 'name' => 'foo.txt'];
28+
$this->field = 'field';
29+
$this->settings = [
2430
'filesystem' => [
2531
'adapter' => function () {
2632
return new VfsAdapter(new Vfs);
2733
}
2834
]
2935
];
30-
$this->writer = new DefaultWriter($table, $entity, $data, $field, $settings);
36+
$this->writer = new DefaultWriter(
37+
$this->table,
38+
$this->entity,
39+
$this->data,
40+
$this->field,
41+
$this->settings
42+
);
3143

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

66+
public function testDelete()
67+
{
68+
$filesystem = $this->getMock('League\Flysystem\FilesystemInterface');
69+
$filesystem->expects($this->at(0))->method('delete')->will($this->returnValue(true));
70+
$filesystem->expects($this->at(1))->method('delete')->will($this->returnValue(false));
71+
$writer = $this->getMock('Josegonzalez\Upload\File\Writer\DefaultWriter', ['getFilesystem'], [$this->table, $this->entity, $this->data, $this->field, $this->settings]);
72+
$writer->expects($this->any())->method('getFilesystem')->will($this->returnValue($filesystem));
73+
74+
$this->assertEquals([], $writer->delete([]));
75+
$this->assertEquals([true], $writer->delete([
76+
$this->vfs->path('/tmp/tempfile')
77+
]));
78+
79+
$this->assertEquals([false], $writer->delete([
80+
$this->vfs->path('/tmp/invalid.txt')
81+
]));
82+
}
83+
5484
public function testWriteFile()
5585
{
5686
$filesystem = $this->getMock('League\Flysystem\FilesystemInterface');

tests/TestCase/Model/Behavior/UploadBehaviorTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public function setup()
2222
'error' => UPLOAD_ERR_OK,
2323
'size' => 1,
2424
'type' => 'text',
25+
'keepFilesOnDelete' => false
2526
]
2627
];
2728
$this->dataError = [
@@ -201,6 +202,54 @@ public function testBeforeSaveOk()
201202
$this->assertNull($behavior->beforeSave(new Event('fake.event'), $this->entity, new ArrayObject));
202203
}
203204

205+
public function testAfterDeleteOk()
206+
{
207+
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
208+
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataOk]);
209+
$behavior->config($this->dataOk);
210+
211+
$behavior->expects($this->any())
212+
->method('getWriter')
213+
->will($this->returnValue($this->writer));
214+
$this->writer->expects($this->any())
215+
->method('delete')
216+
->will($this->returnValue([true]));
217+
218+
$this->assertNull($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
219+
}
220+
221+
public function testAfterDeleteFail()
222+
{
223+
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
224+
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataOk]);
225+
$behavior->config($this->dataOk);
226+
227+
$behavior->expects($this->any())
228+
->method('getWriter')
229+
->will($this->returnValue($this->writer));
230+
$this->writer->expects($this->any())
231+
->method('delete')
232+
->will($this->returnValue([false]));
233+
234+
$this->assertFalse($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
235+
}
236+
237+
public function testAfterDeleteSkip()
238+
{
239+
$methods = array_diff($this->behaviorMethods, ['config', 'afterDelete']);
240+
$behavior = $this->getMock('Josegonzalez\Upload\Model\Behavior\UploadBehavior', $methods, [$this->table, $this->dataError]);
241+
$behavior->config($this->dataError);
242+
243+
$behavior->expects($this->any())
244+
->method('getWriter')
245+
->will($this->returnValue($this->writer));
246+
$this->writer->expects($this->any())
247+
->method('delete')
248+
->will($this->returnValue([true]));
249+
250+
$this->assertNull($behavior->afterDelete(new Event('fake.event'), $this->entity, new ArrayObject));
251+
}
252+
204253
public function testGetWriter()
205254
{
206255
$processor = $this->behavior->getWriter($this->entity, [], 'field', []);

0 commit comments

Comments
 (0)