Completed
Pull Request — master (#41)
by Nicolas
07:53
created

FileStorage   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 14
lcom 1
cbo 2
dl 0
loc 83
ccs 0
cts 62
cp 0
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A start() 0 5 1
A ensureTempDirectoryExists() 0 7 2
A computeFilepath() 0 4 1
A createFile() 0 19 3
A store() 0 13 2
A finish() 0 19 4
1
<?php
2
3
namespace Puzzle\AMQP\Workers\Chunks\ChunkAssemblyStorages;
4
5
use Puzzle\AMQP\Workers\Chunks\ChunkAssemblyStorage;
6
use Puzzle\ValueObjects\Uuid;
7
use Puzzle\AMQP\Messages\Chunks\ChunkMetadata;
8
use Puzzle\AMQP\Messages\Chunks\ChunkedMessageMetadata;
9
10
class FileStorage implements ChunkAssemblyStorage
11
{
12
    private
13
        $tempDirPath;
14
15
    public function __construct($varPath)
16
    {
17
        $this->tempDirPath = $varPath . 'tmp' . DIRECTORY_SEPARATOR;
18
    }
19
20
    public function start(ChunkedMessageMetadata $metadata)
21
    {
22
        $this->ensureTempDirectoryExists();
23
        $this->createFile($metadata);
24
    }
25
26
    private function ensureTempDirectoryExists()
27
    {
28
        if(! is_dir($this->tempDirPath))
29
        {
30
            mkdir($this->tempDirPath, 0755, true);
31
        }
32
    }
33
34
    private function computeFilepath(Uuid $uuid)
35
    {
36
        return $this->tempDirPath . sprintf("%s.tmp", $uuid);
37
    }
38
39
    private function createFile(ChunkedMessageMetadata $metadata)
40
    {
41
        $filepath = $this->computeFilepath($metadata->uuid());
42
43
        if(is_file($filepath))
44
        {
45
            throw new \LogicException("File $filepath already exists");
46
        }
47
48
        $success = touch($filepath);
49
50
        if($success === false)
51
        {
52
            throw new \RuntimeException("Cannot create temporary file ($filepath)");
53
        }
54
55
        // FIXME
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task
Loading history...
56
        chmod($filepath, 0666);
57
    }
58
59
    public function store(Uuid $uuid, ChunkMetadata $metadata, $content)
60
    {
61
        $filepath = $this->computeFilepath($uuid);
62
63
        if(! $stream = fopen($filepath, 'r+'))
64
        {
65
            throw new \RuntimeException("Unable to open file $filepath");
66
        }
67
68
        fseek($stream, $metadata->offset());
69
        fwrite($stream, $content);
70
        fclose($stream);
71
    }
72
73
    public function finish(ChunkedMessageMetadata $metadata, array $headers)
74
    {
75
        $filepath = $this->computeFilepath($metadata->uuid());
76
        $checksum = sha1_file($filepath);
77
78
        if($checksum !== $metadata->checksum())
79
        {
80
            unlink($filepath);
81
            throw new \RuntimeException("Invalid checksum for chunked message " . $metadata->uuid());
82
        }
83
84
        if(isset($headers['file']))
85
        {
86
            if(isset($headers['file']['filename']))
87
            {
88
                rename($filepath, $this->tempDirPath . $headers['file']['filename']);
89
            }
90
        }
91
    }
92
}
93