Upload::getFingerprint()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.2
c 0
b 0
f 0
ccs 7
cts 7
cp 1
cc 4
eloc 7
nc 5
nop 1
crap 4
1
<?php
2
3
namespace LeadThread\Upload;
4
5
use Illuminate\Http\UploadedFile;
6
use Storage;
7
use Exception;
8
use LeadThread\Upload\Models\File;
9
10
class Upload
11
{
12
    protected $config = [];
13
    
14 24
    public function __construct()
15
    {
16 24
        $this->config = config('upload');
0 ignored issues
show
Documentation Bug introduced by
It seems like config('upload') of type * is incompatible with the declared type array of property $config.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
17 24
    }
18
19
    /**
20
     * Takes an UploadedFile, stores it to the disk and records it in the database.
21
     * @param  UploadedFile $file The file to handle
22
     * @return File               The Eloquent Model for the file
23
     */
24 15
    public function create(UploadedFile $file)
25
    {
26 15
        $fingerprint = $this->getFingerprint($file);
27
28 12
        if ($this->config['hash']['enabled'] === true) {
29 6
            $duplicate = File::where('fingerprint', $fingerprint)->first();
30
            
31 6
            if ($duplicate) {
32 3
                return $duplicate;
33
            }
34 6
        }
35
    
36 12
        $disk        = $this->config['disk'];
37 12
        $filename    = $this->getRandomString(32);
38 12
        $extension   = $file->extension();
39 12
        $directory   = $this->getRandomDirectory();
40 12
        $contents    = file_get_contents($file);
41 12
        $mime        = mime_content_type($file->path());
42
43 12
        $path = "/{$directory}/{$filename}.{$extension}";
44
45 12
        $result = $this->getDiskInstance()->put($path, $contents);
46
47 12
        if ($result === false) {
48
            throw new Exception("Could not save the file on the disk! Disk: ".$disk);
49
        }
50
51 12
        $model = new File(
52
            [
53 12
            "filename" => $filename,
54 12
            "mime" => $mime,
55 12
            "path" => $path,
56 12
            "disk" => $disk,
57 12
            "extension" => $extension,
58 12
            "fingerprint" => $fingerprint,
59
            ]
60 12
        );
61
62 12
        $model->save();
63
64 12
        return $model;
65
    }
66
67
    /**
68
     * Returns the storage disk instance to use
69
     * @return Storage The Storage disk
70
     */
71 12
    protected function getDiskInstance()
72
    {
73 12
        return Storage::disk($this->config['disk']);
74
    }
75
76
    /**
77
     * Produces a random alphanumberic string
78
     * @param  integer $len The length that you want
79
     * @return string       A random alphanumberic string
80
     */
81 18
    protected function getRandomString($len = 16)
82
    {
83 18
        $alphanum = array_merge(range('a', 'z'), range('0', '9'));
84 18
        $str = "";
85 18
        for ($i = 0; $i < $len; $i++) {
86 18
            $str.=$alphanum[array_rand($alphanum)];
87 18
        }
88 18
        return $str;
89
    }
90
91
    /**
92
     * Returns two random directories
93
     * @return string A path with two directories: 'a/b', '1/g', '9/4', etc...
94
     */
95 15
    protected function getRandomDirectory()
96
    {
97 15
        $directory1 = $this->getRandomString(1);
98 15
        $directory2 = $this->getRandomString(1);
99 15
        return "{$directory1}/{$directory2}";
100
    }
101
    
102
    /**
103
     * Returns the hash value of a file
104
     * @param  UploadedFile $file The file
105
     * @return string             The hash
106
     */
107 15
    protected function getFingerprint(UploadedFile $file)
108
    {
109 15
        if ($this->config['hash']['enabled'] !== true) {
110 6
            return null;
111
        }
112
113 9
        $algo = $this->config['hash']['algo'] ?: 'md5';
114
115 9
        if (!in_array($algo, hash_algos())) {
116 3
            throw new Exception("The hashing algorithm '{$algo}' is not supported on this system", 1);
117
        }
118
119 6
        return hash_file($algo, $file->path());
120
    }
121
}
122