• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

RonasIT / laravel-media / 18832341854

27 Oct 2025 06:48AM UTC coverage: 94.634% (+0.3%) from 94.301%
18832341854

Pull #73

github

web-flow
Merge 17d3b59d9 into 969b383d4
Pull Request #73: [72]: change file upload to streaming method Storage::putFile

18 of 21 new or added lines in 2 files covered. (85.71%)

3 existing lines in 1 file now uncovered.

194 of 205 relevant lines covered (94.63%)

19.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.74
/src/Services/MediaService.php
1
<?php
2

3
namespace RonasIT\Media\Services;
4

5
use Bepsvpt\Blurhash\BlurHash;
6
use Illuminate\Http\UploadedFile;
7
use League\Flysystem\Local\LocalFilesystemAdapter;
8
use RonasIT\Media\Enums\PreviewDriverEnum;
9
use RonasIT\Media\Repositories\MediaRepository;
10
use Illuminate\Database\Eloquent\Model;
11
use Illuminate\Pagination\LengthAwarePaginator;
12
use Illuminate\Support\Facades\Auth;
13
use Illuminate\Support\Facades\Storage;
14
use RonasIT\Media\Contracts\Services\MediaServiceContract;
15
use RonasIT\Support\Services\EntityService;
16
use RonasIT\Support\Traits\FilesUploadTrait;
17
use Spatie\Image\Image;
18
use Spatie\MediaLibrary\InteractsWithMedia;
19

20
/**
21
 * @property MediaRepository $repository
22
 * @mixin MediaRepository
23
 */
24
class MediaService extends EntityService implements MediaServiceContract
25
{
26
    use FilesUploadTrait;
27
    use InteractsWithMedia;
28

29
    protected BlurHash $blurHash;
30

31
    public function __construct()
32
    {
33
        $this->setRepository(MediaRepository::class);
42✔
34
    }
35

36
    public function search(array $filters): LengthAwarePaginator
37
    {
38
        if (!Auth::check()) {
7✔
39
            $filters['is_public'] = true;
2✔
40
        } else {
41
            $filters['owner_id'] = Auth::id();
5✔
42
        }
43

44
        return $this
7✔
45
            ->searchQuery($filters)
7✔
46
            ->filterByQuery(['name'])
7✔
47
            ->getSearchResults();
7✔
48
    }
49

50
    public function create($content, string $fileName, array $data = [], PreviewDriverEnum ...$previewDrivers): Model
51
    {
52
        $fileName = $this->saveFile($fileName, $content);
4✔
53

54
        $data = $this->prepareMediaData($data, $fileName);
4✔
55

56
        $this->createImagePreviews($fileName, $data, $previewDrivers);
4✔
57

58
        return $this->repository
4✔
59
            ->create($data)
4✔
60
            ->load('preview');
4✔
61
    }
62

63
    public function bulkCreate(array $data, PreviewDriverEnum ...$previewDrivers): array
64
    {
65
        return array_map(function ($media) use ($previewDrivers) {
3✔
66
            $file = $media['file'];
3✔
67
            $content = file_get_contents($file->getPathname());
3✔
68

69
            return $this->create($content, $file->getClientOriginalName(), $media, ...$previewDrivers);
3✔
70
        }, $data);
3✔
71
    }
72

73
    public function createFromStream(UploadedFile $uploadedFile, array $data = [], PreviewDriverEnum ...$previewDrivers): Model
74
    {
75
        $fileName = $this->generateName($uploadedFile->getClientOriginalName());
22✔
76

77
        $filePath = Storage::putFileAs('', $uploadedFile, $fileName);
22✔
78

79
        $data = $this->prepareMediaData($data, $filePath);
22✔
80

81
        $this->createImagePreviews($filePath, $data, $previewDrivers);
22✔
82

83
        return $this->repository
22✔
84
            ->create($data)
22✔
85
            ->load('preview');
22✔
86
    }
87

88
    public function bulkCreateFromStream(array $data, PreviewDriverEnum ...$previewDrivers): array
89
    {
90
        return array_map(function ($media) use ($previewDrivers) {
2✔
91
            return $this->createFromStream($media['file'], $media, ...$previewDrivers);
2✔
92
        }, $data);
2✔
93
    }
94

95
    public function delete($where): int
96
    {
97
        $entity = $this->first($where);
3✔
98

99
        if (!empty($entity->preview_id)) {
3✔
100
            $this->delete($entity->preview_id);
3✔
101
        }
102

103
        Storage::delete($entity->name);
3✔
104

105
        return $this->repository->delete($where);
3✔
106
    }
107

108
    public function first(array|int $where = []): ?Model
109
    {
110
        return $this->repository->first($where);
9✔
111
    }
112

113
    protected function createFilePreview(string $filename, ?int $ownerId = null): Model
114
    {
115
        $this->createTempDir(Storage::disk('local')->path('temp_files'));
24✔
116

117
        $filePath = Storage::path($filename);
24✔
118
        $previewFilename = "preview_{$filename}";
24✔
119
        $tempPreviewFilePath = "/temp_files/{$previewFilename}";
24✔
120

121
        $tempFilePath = "/temp_files/{$filename}";
24✔
122

123
        $content = Storage::get($filename);
24✔
124

125
        if (!$this->isLocalStorageUsing()) {
24✔
NEW
UNCOV
126
            Storage::disk('local')->put($tempFilePath, $content);
×
127

NEW
UNCOV
128
            $filePath = Storage::disk('local')->path($tempFilePath);
×
129
        }
130

131
        Image::load($filePath)
24✔
132
            ->width(config('media.preview.width'))
24✔
133
            ->height(config('media.preview.height'))
24✔
134
            ->save(Storage::disk('local')->path($tempPreviewFilePath));
24✔
135

136
        Storage::put($previewFilename, Storage::disk('local')->get($tempPreviewFilePath));
24✔
137

138
        if (!$this->isLocalStorageUsing()) {
24✔
NEW
UNCOV
139
            Storage::disk('local')->delete(Storage::path($tempFilePath));
×
140
        }
141

142
        Storage::disk('local')->delete($tempPreviewFilePath);
24✔
143

144
        $data['name'] = $previewFilename;
24✔
145
        $data['link'] = Storage::url($previewFilename);
24✔
146
        $data['owner_id'] = $ownerId;
24✔
147

148
        return $this->repository->create($data);
24✔
149
    }
150

151
    private function isLocalStorageUsing(): bool
152
    {
153
        return Storage::getAdapter() instanceof (LocalFilesystemAdapter::class);
24✔
154
    }
155

156
    protected function createTempDir(string $name): void
157
    {
158
        if (!is_dir($name)) {
24✔
159
            mkdir(
24✔
160
                directory: $name,
24✔
161
                recursive: true,
24✔
162
            );
24✔
163
        }
164
    }
165

166
    protected function createHashPreview(string $fileName): string
167
    {
168
        $localStorage = Storage::disk('local');
3✔
169

170
        $tmpFilename = "tmp_{$fileName}";
3✔
171

172
        $localStorage->put($tmpFilename, Storage::get($fileName));
3✔
173

174
        $blurHash = $this
3✔
175
            ->getBlurHashEncoder()
3✔
176
            ->encode($localStorage->path($tmpFilename));
3✔
177

178
        $localStorage->delete($tmpFilename);
3✔
179

180
       return $blurHash;
3✔
181
    }
182

183
    protected function getBlurHashEncoder(): BlurHash
184
    {
185
        return $this->blurHash ??= new BlurHash(
3✔
186
            config('blurhash.driver'),
3✔
187
            config('blurhash.components-x'),
3✔
188
            config('blurhash.components-y'),
3✔
189
            config('blurhash.resized-max-size')
3✔
190
        );
3✔
191
    }
192

193
    protected function createPreviews(string $fileName, array &$data, int $ownerId = null, PreviewDriverEnum ...$previewTypes): void
194
    {
195
        if (empty($previewTypes)) {
25✔
196
            $previewTypes = config('media.drivers');
21✔
197
        }
198

199
        foreach ($previewTypes as $type) {
25✔
200
            if ($type === PreviewDriverEnum::File) {
25✔
201
                $preview = $this->createFilePreview($fileName, $ownerId);
24✔
202

203
                $data['preview_id'] = $preview->id;
24✔
204
            }
205

206
            if ($type === PreviewDriverEnum::Hash) {
25✔
207
                $data['blur_hash'] = $this->createHashPreview($fileName);
3✔
208
            }
209
        }
210
    }
211

212
    protected function prepareMediaData(array $data, string $filePath): array
213
    {
214
        if (empty($data['owner_id'])) {
26✔
215
            $data['owner_id'] = Auth::check() ? Auth::id() : null;
23✔
216
        }
217

218
        $data['name'] = $filePath;
26✔
219
        $data['link'] = Storage::url($data['name']);
26✔
220

221
        return $data;
26✔
222
    }
223

224
    protected function createImagePreviews(string $fileName, array &$data, array $previewDrivers): void
225
    {
226
        $isImage = str_starts_with(Storage::mimeType($fileName), 'image');
26✔
227

228
        if ($isImage) {
26✔
229
            $this->createPreviews($fileName, $data, $data['owner_id'], ...$previewDrivers);
25✔
230
        }
231
    }
232
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc