Completed
Push — master ( a50e59...22377b )
by Freek
10:42
created

src/FileManipulator.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Spatie\MediaLibrary;
4
5
use Storage;
6
use Illuminate\Support\Facades\File;
7
use Spatie\MediaLibrary\Models\Media;
8
use Illuminate\Contracts\Bus\Dispatcher;
9
use Spatie\MediaLibrary\Helpers\ImageFactory;
10
use Spatie\MediaLibrary\Conversion\Conversion;
11
use Spatie\MediaLibrary\Filesystem\Filesystem;
12
use Spatie\MediaLibrary\Jobs\PerformConversions;
13
use Spatie\MediaLibrary\Events\ConversionWillStart;
14
use Spatie\MediaLibrary\Helpers\TemporaryDirectory;
15
use Spatie\MediaLibrary\ImageGenerators\ImageGenerator;
16
use Spatie\MediaLibrary\Conversion\ConversionCollection;
17
use Spatie\MediaLibrary\Events\ConversionHasBeenCompleted;
18
use Spatie\MediaLibrary\Helpers\File as MediaLibraryFileHelper;
19
use Spatie\MediaLibrary\ResponsiveImages\ResponsiveImageGenerator;
20
21
class FileManipulator
22
{
23
    /**
24
     * Create all derived files for the given media.
25
     *
26
     * @param \Spatie\MediaLibrary\Models\Media $media
27
     * @param array $only
28
     * @param bool $onlyIfMissing
29
     */
30
    public function createDerivedFiles(Media $media, array $only = [], $onlyIfMissing = false)
31
    {
32
        $profileCollection = ConversionCollection::createForMedia($media);
33
34
        if (! empty($only)) {
35
            $profileCollection = $profileCollection->filter(function ($collection) use ($only) {
36
                return in_array($collection->getName(), $only);
37
            });
38
        }
39
40
        $this->performConversions(
41
            $profileCollection->getNonQueuedConversions($media->collection_name),
42
            $media,
43
            $onlyIfMissing
44
        );
45
46
        $queuedConversions = $profileCollection->getQueuedConversions($media->collection_name);
47
48
        if ($queuedConversions->isNotEmpty()) {
49
            $this->dispatchQueuedConversions($media, $queuedConversions);
50
        }
51
    }
52
53
    /**
54
     * Perform the given conversions for the given media.
55
     *
56
     * @param \Spatie\MediaLibrary\Conversion\ConversionCollection $conversions
57
     * @param \Spatie\MediaLibrary\Models\Media $media
58
     * @param bool $onlyIfMissing
59
     */
60
    public function performConversions(ConversionCollection $conversions, Media $media, $onlyIfMissing = false)
61
    {
62
        if ($conversions->isEmpty()) {
63
            return;
64
        }
65
66
        $imageGenerator = $this->determineImageGenerator($media);
67
68
        if (! $imageGenerator) {
69
            return;
70
        }
71
72
        $temporaryDirectory = TemporaryDirectory::create();
73
74
        $copiedOriginalFile = app(Filesystem::class)->copyFromMediaLibrary(
75
            $media,
76
            $temporaryDirectory->path(str_random(16).'.'.$media->extension)
0 ignored issues
show
Deprecated Code introduced by
The function str_random() has been deprecated with message: Str::random() should be used directly instead. Will be removed in Laravel 5.9.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
77
        );
78
79
        $conversions
80
            ->reject(function (Conversion $conversion) use ($onlyIfMissing, $media) {
81
                $relativePath = $media->getPath($conversion->getName());
82
83
                $rootPath = config('filesystems.disks.'.$media->disk.'.root');
84
85
                if ($rootPath) {
86
                    $relativePath = str_replace($rootPath, '', $relativePath);
87
                }
88
89
                return $onlyIfMissing && Storage::disk($media->disk)->exists($relativePath);
90
            })
91
            ->each(function (Conversion $conversion) use ($media, $imageGenerator, $copiedOriginalFile) {
92
                event(new ConversionWillStart($media, $conversion, $copiedOriginalFile));
93
94
                $copiedOriginalFile = $imageGenerator->convert($copiedOriginalFile, $conversion);
95
96
                $manipulationResult = $this->performManipulations($media, $conversion, $copiedOriginalFile);
97
98
                $newFileName = pathinfo($media->file_name, PATHINFO_FILENAME).
99
                    '-'.$conversion->getName().
100
                    '.'.$conversion->getResultExtension(pathinfo($copiedOriginalFile, PATHINFO_EXTENSION));
101
102
                $renamedFile = MediaLibraryFileHelper::renameInDirectory($manipulationResult, $newFileName);
103
104
                if ($conversion->shouldGenerateResponsiveImages()) {
105
                    app(ResponsiveImageGenerator::class)->generateResponsiveImagesForConversion(
106
                        $media,
107
                        $conversion,
108
                        $renamedFile
109
                    );
110
                }
111
112
                app(Filesystem::class)->copyToMediaLibrary($renamedFile, $media, 'conversions');
113
114
                $media->markAsConversionGenerated($conversion->getName(), true);
115
116
                event(new ConversionHasBeenCompleted($media, $conversion));
117
            });
118
119
        $temporaryDirectory->delete();
120
    }
121
122
    public function performManipulations(Media $media, Conversion $conversion, string $imageFile): string
123
    {
124
        if ($conversion->getManipulations()->isEmpty()) {
125
            return $imageFile;
126
        }
127
128
        $conversionTempFile = pathinfo($imageFile, PATHINFO_DIRNAME).'/'.str_random(16)
0 ignored issues
show
Deprecated Code introduced by
The function str_random() has been deprecated with message: Str::random() should be used directly instead. Will be removed in Laravel 5.9.

This function has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead.

Loading history...
129
            .$conversion->getName()
130
            .'.'
131
            .$media->extension;
132
133
        File::copy($imageFile, $conversionTempFile);
134
135
        $supportedFormats = ['jpg', 'pjpg', 'png', 'gif'];
136
        if ($conversion->shouldKeepOriginalImageFormat() && in_array($media->extension, $supportedFormats)) {
137
            $conversion->format($media->extension);
138
        }
139
140
        ImageFactory::load($conversionTempFile)
141
            ->manipulate($conversion->getManipulations())
142
            ->save();
143
144
        return $conversionTempFile;
145
    }
146
147
    protected function dispatchQueuedConversions(Media $media, ConversionCollection $queuedConversions)
148
    {
149
        $performConversionsJobClass = config('medialibrary.jobs.perform_conversions', PerformConversions::class);
150
151
        $job = new $performConversionsJobClass($queuedConversions, $media);
152
153
        if ($customQueue = config('medialibrary.queue_name')) {
154
            $job->onQueue($customQueue);
155
        }
156
157
        app(Dispatcher::class)->dispatch($job);
158
    }
159
160
    /**
161
     * @param \Spatie\MediaLibrary\Models\Media $media
162
     *
163
     * @return \Spatie\MediaLibrary\ImageGenerators\ImageGenerator|null
164
     */
165
    public function determineImageGenerator(Media $media)
166
    {
167
        return $media->getImageGenerators()
168
            ->map(function (string $imageGeneratorClassName) {
169
                return app($imageGeneratorClassName);
170
            })
171
            ->first(function (ImageGenerator $imageGenerator) use ($media) {
172
                return $imageGenerator->canConvert($media);
173
            });
174
    }
175
}
176