Completed
Push — master ( c2f76d...03586b )
by Freek
11:35
created

DefaultFilesystem   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 21
lcom 1
cbo 7
dl 0
loc 151
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A renameFile() 0 7 1
A add() 0 8 1
B copyToMediaLibrary() 0 26 4
A addCustomRemoteHeaders() 0 4 1
A getRemoteHeadersForFile() 0 8 1
A getStream() 0 6 1
A copyFromMediaLibrary() 0 19 2
A removeAllFiles() 0 14 1
A removeFile() 0 4 1
B getMediaDirectory() 0 22 5
A getConversionDirectory() 0 4 1
A getResponsiveImagesDirectory() 0 4 1
1
<?php
2
3
namespace Spatie\MediaLibrary\Filesystem;
4
5
use Spatie\MediaLibrary\Models\Media;
6
use Spatie\MediaLibrary\Helpers\File;
7
use Spatie\MediaLibrary\FileManipulator;
8
use Illuminate\Contracts\Filesystem\Factory;
9
use Spatie\MediaLibrary\Events\MediaHasBeenAdded;
10
use Spatie\MediaLibrary\PathGenerator\PathGeneratorFactory;
11
12
class DefaultFilesystem implements Filesystem
13
{
14
    /** @var \Illuminate\Contracts\Filesystem\Factory */
15
    protected $filesystem;
16
17
    /** @var array */
18
    protected $customRemoteHeaders = [];
19
20
    public function __construct(Factory $filesystem)
21
    {
22
        $this->filesystem = $filesystem;
23
    }
24
25
    public function add(string $file, Media $media, ?string $targetFileName = null)
26
    {
27
        $this->copyToMediaLibrary($file, $media, null, $targetFileName);
28
29
        event(new MediaHasBeenAdded($media));
30
31
        app(FileManipulator::class)->createDerivedFiles($media);
32
    }
33
34
    public function copyToMediaLibrary(string $pathToFile, Media $media, ?string $type = null, ?string $targetFileName = null)
35
    {
36
        $destinationFileName = $targetFileName ?: pathinfo($pathToFile, PATHINFO_BASENAME);
37
38
        $destination = $this->getMediaDirectory($media, $type).$destinationFileName;
39
40
        $file = fopen($pathToFile, 'r');
41
42
        if ($media->getDiskDriverName() === 'local') {
43
            $this->filesystem
44
                ->disk($media->disk)
45
                ->put($destination, $file);
46
47
            fclose($file);
48
49
            return;
50
        }
51
52
        $this->filesystem
53
            ->disk($media->disk)
54
            ->put($destination, $file, $this->getRemoteHeadersForFile($pathToFile));
55
56
        if (is_resource($file)) {
57
            fclose($file);
58
        }
59
    }
60
61
    public function addCustomRemoteHeaders(array $customRemoteHeaders)
62
    {
63
        $this->customRemoteHeaders = $customRemoteHeaders;
64
    }
65
66
    public function getRemoteHeadersForFile(string $file) : array
67
    {
68
        $mimeTypeHeader = ['ContentType' => File::getMimeType($file)];
69
70
        $extraHeaders = config('medialibrary.remote.extra_headers');
71
72
        return array_merge($mimeTypeHeader, $extraHeaders, $this->customRemoteHeaders);
73
    }
74
75
    public function getStream(Media $media)
76
    {
77
        $sourceFile = $this->getMediaDirectory($media).'/'.$media->file_name;
78
79
        return $this->filesystem->disk($media->disk)->readStream($sourceFile);
80
    }
81
82
    public function copyFromMediaLibrary(Media $media, string $targetFile): string
83
    {
84
        touch($targetFile);
85
86
        $stream = $this->getStream($media);
87
88
        $targetFileStream = fopen($targetFile, 'a');
89
90
        while (! feof($stream)) {
91
            $chunk = fread($stream, 1024);
92
            fwrite($targetFileStream, $chunk);
93
        }
94
95
        fclose($stream);
96
97
        fclose($targetFileStream);
98
99
        return $targetFile;
100
    }
101
102
    public function removeAllFiles(Media $media)
103
    {
104
        $mediaDirectory = $this->getMediaDirectory($media);
105
106
        $conversionsDirectory = $this->getMediaDirectory($media, 'conversions');
107
108
        $responsiveImagesDirectory = $this->getMediaDirectory($media, 'responsiveImages');
109
110
        collect([$mediaDirectory, $conversionsDirectory, $responsiveImagesDirectory])
111
112
            ->each(function ($directory) use ($media) {
113
                $this->filesystem->disk($media->disk)->deleteDirectory($directory);
114
            });
115
    }
116
117
    public function removeFile(Media $media, string $path)
118
    {
119
        $this->filesystem->disk($media->disk)->delete($path);
120
    }
121
122
    public function renameFile(Media $media, string $oldName)
123
    {
124
        $oldFile = $this->getMediaDirectory($media).'/'.$oldName;
125
        $newFile = $this->getMediaDirectory($media).'/'.$media->file_name;
126
127
        $this->filesystem->disk($media->disk)->move($oldFile, $newFile);
128
    }
129
130
    public function getMediaDirectory(Media $media, ?string $type = null) : string
131
    {
132
        $pathGenerator = PathGeneratorFactory::create();
133
134
        if (!$type) {
135
            $directory = $pathGenerator->getPath($media);
136
        }
137
138
        if ($type === 'conversions') {
139
            $directory = $pathGenerator->getPathForConversions($media);
140
        }
141
142
        if ($type === 'responsiveImages') {
143
            $directory = $pathGenerator->getPathForResponsiveImages($media);
144
        }
145
146
        if (! in_array($media->getDiskDriverName(), ['s3'], true)) {
147
            $this->filesystem->disk($media->disk)->makeDirectory($directory);
0 ignored issues
show
Bug introduced by
The variable $directory does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
148
        }
149
150
        return $directory;
151
    }
152
153
    public function getConversionDirectory(Media $media) : string
154
    {
155
        return $this->getMediaDirectory($media, 'conversions');
156
    }
157
158
    public function getResponsiveImagesDirectory(Media $media) : string
159
    {
160
        return $this->getMediaDirectory($media, 'responsiveImages');
161
    }
162
}
163