Skip to content

Commit e260bef

Browse files
authored
Cleanup uploaded files (#87)
1 parent da2fb4a commit e260bef

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.
44

55
The format is based on [Keep a Changelog][keepachangelog] and this project adheres to [Semantic Versioning][semver].
66

7+
## UNRELEASED
8+
9+
### Added
10+
11+
- Listener `CleanupUploadedFilesListener` for removing temporary files, which was created during uploading _(should be enabled manually for the `AfterLoopIterationEvent` event)_ [#84]
12+
13+
[#84]:https://github.com/spiral/roadrunner-laravel/issues/84
14+
715
## v5.7.0
816

917
### Added

config/roadrunner.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
Events\AfterLoopIterationEvent::class => [
5252
...Defaults::afterLoopIteration(),
5353
Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
54+
// Listeners\CleanupUploadedFilesListener::class, // remove temporary files
5455
],
5556

5657
Events\AfterLoopStoppedEvent::class => [
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spiral\RoadRunnerLaravel\Listeners;
6+
7+
use Spiral\RoadRunnerLaravel\Events\Contracts\WithHttpRequest;
8+
9+
/**
10+
* @link https://github.com/spiral/roadrunner-laravel/issues/84
11+
*/
12+
class CleanupUploadedFilesListener implements ListenerInterface
13+
{
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
public function handle($event): void
18+
{
19+
if ($event instanceof WithHttpRequest) {
20+
foreach ($event->httpRequest()->files->all() as $file) {
21+
if ($file instanceof \SplFileInfo) {
22+
if (\is_string($path = $file->getRealPath())) {
23+
\clearstatcache(true, $path);
24+
25+
if (\is_file($path)) {
26+
\unlink($path);
27+
}
28+
}
29+
}
30+
}
31+
}
32+
}
33+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Spiral\RoadRunnerLaravel\Tests\Unit\Listeners;
6+
7+
use Mockery as m;
8+
use Illuminate\Support\Str;
9+
use Symfony\Component\HttpFoundation\Request;
10+
use Symfony\Component\HttpFoundation\File\UploadedFile;
11+
use Spiral\RoadRunnerLaravel\Events\Contracts\WithHttpRequest;
12+
use Spiral\RoadRunnerLaravel\Listeners\CleanupUploadedFilesListener;
13+
14+
/**
15+
* @covers \Spiral\RoadRunnerLaravel\Listeners\CleanupUploadedFilesListener
16+
*/
17+
class CleanupUploadedFilesListenerTest extends AbstractListenerTestCase
18+
{
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function testHandle(): void
23+
{
24+
$tmp_dir = $this->createTemporaryDirectory();
25+
26+
$this->assertNotFalse(
27+
\file_put_contents(
28+
$file_1_path = $tmp_dir . DIRECTORY_SEPARATOR . ($file_1_name = Str::random()),
29+
Str::random(),
30+
)
31+
);
32+
33+
$this->assertNotFalse(
34+
\file_put_contents(
35+
$file_2_path = $tmp_dir . DIRECTORY_SEPARATOR . ($file_2_name = Str::random()),
36+
Str::random(),
37+
)
38+
);
39+
40+
$this->assertNotFalse(
41+
\file_put_contents(
42+
$file_3_path = $tmp_dir . DIRECTORY_SEPARATOR . ($file_3_name = Str::random()),
43+
Str::random(),
44+
)
45+
);
46+
47+
$request = Request::create('http://127.0.0.1:123/foo');
48+
49+
$request->files->add([
50+
new UploadedFile($file_1_path, $file_1_name),
51+
new UploadedFile($file_2_path, $file_2_name),
52+
new UploadedFile($file_3_path, $file_3_name),
53+
]);
54+
55+
\rename($file_3_path, $file_3_new_path = $file_3_path . Str::random());
56+
57+
/** @var m\MockInterface|WithHttpRequest $event */
58+
$event = m::mock(WithHttpRequest::class)
59+
->makePartial()
60+
->expects('httpRequest')
61+
->atLeast()
62+
->once()
63+
->andReturn($request)
64+
->getMock();
65+
66+
$this->assertFileExists($file_1_path);
67+
$this->assertFileExists($file_2_path);
68+
$this->assertFileExists($file_3_new_path);
69+
70+
$this->listenerFactory()->handle($event);
71+
72+
$this->assertFileDoesNotExist($file_1_path);
73+
$this->assertFileDoesNotExist($file_2_path);
74+
$this->assertFileExists($file_3_new_path); // still exists
75+
}
76+
77+
/**
78+
* @return CleanupUploadedFilesListener
79+
*/
80+
protected function listenerFactory(): CleanupUploadedFilesListener
81+
{
82+
return new CleanupUploadedFilesListener();
83+
}
84+
}

0 commit comments

Comments
 (0)