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

plank / laravel-mediable / 13689748990

06 Mar 2025 02:19AM UTC coverage: 94.72%. Remained the same
13689748990

push

github

web-flow
Fix template type definition in MediableCollection (#378)

1489 of 1572 relevant lines covered (94.72%)

153.81 hits per line

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

85.33
/src/MediaMover.php
1
<?php
2
declare(strict_types=1);
3

4
namespace Plank\Mediable;
5

6
use Illuminate\Contracts\Filesystem\FileNotFoundException;
7
use Illuminate\Filesystem\FilesystemManager;
8
use Plank\Mediable\Exceptions\MediaMoveException;
9
use Plank\Mediable\Helpers\File;
10

11
/**
12
 * Media Mover Class.
13
 */
14
class MediaMover
15
{
16
    protected FilesystemManager $filesystem;
17

18
    public function __construct(FilesystemManager $filesystem)
19
    {
20
        $this->filesystem = $filesystem;
42✔
21
    }
22

23
    /**
24
     * Move the file to a new location on disk.
25
     *
26
     * Will invoke the `save()` method on the model after the associated file has been moved to prevent synchronization errors
27
     * @param  Media $media
28
     * @param  string $directory directory relative to disk root
29
     * @param  string $filename filename. Do not include extension
30
     * @return void
31
     * @throws MediaMoveException If attempting to change the file extension or a file with the same name already exists at the destination
32
     */
33
    public function move(Media $media, string $directory, ?string $filename = null): void
34
    {
35
        $storage = $this->filesystem->disk($media->disk);
12✔
36

37
        $filename = $this->cleanFilename($media, $filename);
12✔
38
        $directory = File::sanitizePath($directory);
12✔
39
        $targetPath = $directory . '/' . $filename . '.' . $media->extension;
12✔
40

41
        if ($storage->exists($targetPath)) {
12✔
42
            throw MediaMoveException::destinationExists($targetPath);
6✔
43
        }
44

45
        $storage->move($media->getDiskPath(), $targetPath);
6✔
46

47
        $media->filename = $filename;
6✔
48
        $media->directory = $directory;
6✔
49
        $media->save();
6✔
50
    }
51

52
    /**
53
     * Move the file to a new location on another disk.
54
     *
55
     * Will invoke the `save()` method on the model after the associated file has been moved to prevent synchronization errors
56
     * @param  Media $media
57
     * @param  string $disk the disk to move the file to
58
     * @param  string $directory directory relative to disk root
59
     * @param  string $filename filename. Do not include extension
60
     * @param  array $options additional options to pass to the disk driver when uploading the file
61
     * @return void
62
     * @throws MediaMoveException If attempting to change the file extension or a file with the same name already exists at the destination
63
     */
64
    public function moveToDisk(
65
        Media $media,
66
        string $disk,
67
        string $directory,
68
        ?string $filename = null,
69
        array $options = []
70
    ): void {
71
        if ($media->disk === $disk) {
12✔
72
            $this->move($media, $directory, $filename);
×
73
            return;
×
74
        }
75

76
        $currentStorage = $this->filesystem->disk($media->disk);
12✔
77
        $targetStorage = $this->filesystem->disk($disk);
12✔
78

79
        $filename = $this->cleanFilename($media, $filename);
12✔
80
        $directory = File::sanitizePath($directory);
12✔
81
        $targetPath = $directory . '/' . $filename . '.' . $media->extension;
12✔
82

83
        if ($targetStorage->exists($targetPath)) {
12✔
84
            throw MediaMoveException::destinationExistsOnDisk($disk, $targetPath);
×
85
        }
86

87
        try {
88
            if (!isset($options['visibility'])) {
12✔
89
                $options['visibility'] = $currentStorage->getVisibility($media->getDiskPath());
12✔
90
            }
91

92
            $targetStorage->put($targetPath, $currentStorage->readStream($media->getDiskPath()), $options);
12✔
93
            $currentStorage->delete($media->getDiskPath());
12✔
94
        } catch (FileNotFoundException $e) {
×
95
            throw MediaMoveException::fileNotFound($media->disk, $media->getDiskPath(), $e);
×
96
        }
97

98
        $media->disk = $disk;
12✔
99
        $media->filename = $filename;
12✔
100
        $media->directory = $directory;
12✔
101
        $media->save();
12✔
102
    }
103

104
    /**
105
     * Copy the file from one Media object to another one.
106
     *
107
     * This method creates a new Media object as well as duplicates the associated file on the disk.
108
     *
109
     * @param  Media $media The media to copy from
110
     * @param  string $directory directory relative to disk root
111
     * @param  string $filename optional filename. Do not include extension
112
     *
113
     * @return Media
114
     * @throws MediaMoveException If a file with the same name already exists at the destination or it fails to copy the file
115
     */
116
    public function copyTo(Media $media, string $directory, ?string $filename = null): Media
117
    {
118
        $storage = $this->filesystem->disk($media->disk);
6✔
119

120
        $filename = $this->cleanFilename($media, $filename);
6✔
121
        $directory = File::sanitizePath($directory);
6✔
122

123
        $targetPath = $directory . '/' . $filename . '.' . $media->extension;
6✔
124

125
        if ($storage->exists($targetPath)) {
6✔
126
            throw MediaMoveException::destinationExists($targetPath);
6✔
127
        }
128

129
        try {
130
            $storage->copy($media->getDiskPath(), $targetPath);
6✔
131
        } catch (\Exception $e) {
×
132
            throw MediaMoveException::failedToCopy($media->getDiskPath(), $targetPath, $e);
×
133
        }
134

135
        // now we copy the Media object
136
        /** @var Media $newMedia */
137
        $newMedia = $media->replicate();
6✔
138
        $newMedia->filename = $filename;
6✔
139
        $newMedia->directory = $directory;
6✔
140

141
        $newMedia->save();
6✔
142

143
        return $newMedia;
6✔
144
    }
145

146
    /**
147
     * Copy the file from one Media object to another one on a different disk.
148
     *
149
     * This method creates a new Media object as well as duplicates the associated file on the disk.
150
     *
151
     * @param  Media $media The media to copy from
152
     * @param  string $disk the disk to copy the file to
153
     * @param  string $directory directory relative to disk root
154
     * @param  string $filename optional filename. Do not include extension
155
     *
156
     * @return Media
157
     * @throws MediaMoveException If a file with the same name already exists at the destination or it fails to copy the file
158
     */
159
    public function copyToDisk(
160
        Media $media,
161
        string $disk,
162
        string $directory,
163
        ?string $filename = null,
164
        array $options = []
165
    ): Media {
166
        if ($media->disk === $disk) {
12✔
167
            return $this->copyTo($media, $directory, $filename);
×
168
        }
169

170
        $currentStorage = $this->filesystem->disk($media->disk);
12✔
171
        $targetStorage = $this->filesystem->disk($disk);
12✔
172

173
        $filename = $this->cleanFilename($media, $filename);
12✔
174
        $directory = File::sanitizePath($directory);
12✔
175
        $targetPath = $directory . '/' . $filename . '.' . $media->extension;
12✔
176

177
        if ($targetStorage->exists($targetPath)) {
12✔
178
            throw MediaMoveException::destinationExistsOnDisk($disk, $targetPath);
×
179
        }
180

181
        try {
182
            if (!isset($options['visibility'])) {
12✔
183
                $options['visibility'] = $currentStorage->getVisibility($media->getDiskPath());
12✔
184
            }
185
            $targetStorage->put($targetPath, $currentStorage->readStream($media->getDiskPath()), $options);
12✔
186
        } catch (FileNotFoundException $e) {
×
187
            throw MediaMoveException::fileNotFound($media->disk, $media->getDiskPath(), $e);
×
188
        }
189

190
        // now we copy the Media object
191
        /** @var Media $newMedia */
192
        $newMedia = $media->replicate();
12✔
193
        $newMedia->disk = $disk;
12✔
194
        $newMedia->filename = $filename;
12✔
195
        $newMedia->directory = $directory;
12✔
196

197
        $newMedia->save();
12✔
198

199
        return $newMedia;
12✔
200
    }
201

202
    protected function cleanFilename(Media $media, ?string $filename): string
203
    {
204
        if ($filename) {
42✔
205
            return File::sanitizeFileName(
42✔
206
                $this->removeExtensionFromFilename($filename, $media->extension)
42✔
207
            );
42✔
208
        }
209

210
        return $media->filename;
12✔
211
    }
212

213
    /**
214
     * Remove the media's extension from a filename.
215
     * @param  string $filename
216
     * @param  string $extension
217
     * @return string
218
     */
219
    protected function removeExtensionFromFilename(string $filename, string $extension): string
220
    {
221
        $extension = '.' . $extension;
42✔
222
        $extensionLength = mb_strlen($filename) - mb_strlen($extension);
42✔
223
        if (mb_strrpos($filename, $extension) === $extensionLength) {
42✔
224
            $filename = mb_substr($filename, 0, $extensionLength);
12✔
225
        }
226

227
        return $filename;
42✔
228
    }
229
}
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