This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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 Kunstmaan\MediaBundle\Helper\File; |
||
4 | |||
5 | use Gaufrette\Filesystem; |
||
6 | use Kunstmaan\MediaBundle\Entity\Media; |
||
7 | use Kunstmaan\MediaBundle\Form\File\FileType; |
||
8 | use Kunstmaan\MediaBundle\Helper\ExtensionGuesserFactoryInterface; |
||
9 | use Kunstmaan\MediaBundle\Helper\Media\AbstractMediaHandler; |
||
10 | use Kunstmaan\MediaBundle\Helper\MimeTypeGuesserFactoryInterface; |
||
11 | use Kunstmaan\UtilitiesBundle\Helper\SlugifierInterface; |
||
12 | use Symfony\Component\HttpFoundation\File\File; |
||
13 | use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser; |
||
14 | use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser; |
||
15 | use Symfony\Component\HttpFoundation\File\UploadedFile; |
||
16 | use Symfony\Component\Mime\MimeTypesInterface; |
||
17 | |||
18 | /** |
||
19 | * FileHandler |
||
20 | */ |
||
21 | class FileHandler extends AbstractMediaHandler |
||
22 | { |
||
23 | /** |
||
24 | * @var string |
||
25 | */ |
||
26 | const TYPE = 'file'; |
||
27 | |||
28 | /** |
||
29 | * @var string |
||
30 | */ |
||
31 | public $mediaPath; |
||
32 | |||
33 | /** |
||
34 | * @var Filesystem |
||
35 | */ |
||
36 | public $fileSystem; |
||
37 | |||
38 | /** |
||
39 | * @deprecated This property is deprecated since KunstmaanMediaBundle 5.7 and will be removed in KunstmaanMediaBundle 6.0. Use the `$mimeTypes` property instead. |
||
40 | * |
||
41 | * @var MimeTypeGuesser |
||
42 | */ |
||
43 | public $mimeTypeGuesser; |
||
44 | |||
45 | /** |
||
46 | * @deprecated This property is deprecated since KunstmaanMediaBundle 5.7 and will be removed in KunstmaanMediaBundle 6.0. Use the `$mimeTypes` property instead. |
||
47 | * |
||
48 | * @var ExtensionGuesser |
||
49 | */ |
||
50 | public $extensionGuesser; |
||
51 | |||
52 | /** @var MimeTypesInterface */ |
||
53 | private $mimeTypes; |
||
54 | |||
55 | /** |
||
56 | * Files with a blacklisted extension will be converted to txt |
||
57 | * |
||
58 | * @var array |
||
59 | */ |
||
60 | private $blacklistedExtensions = []; |
||
61 | |||
62 | /** |
||
63 | * @var SlugifierInterface |
||
64 | */ |
||
65 | private $slugifier; |
||
66 | |||
67 | /** |
||
68 | * Constructor |
||
69 | * |
||
70 | * @param int $priority |
||
71 | * @param MimeTypeGuesserFactoryInterface|MimeTypesInterface $mimeTypes |
||
72 | * @param ExtensionGuesserFactoryInterface $extensionGuesserFactoryInterface |
||
73 | */ |
||
74 | 5 | public function __construct($priority, /*MimeTypesInterface*/ $mimeTypes, ExtensionGuesserFactoryInterface $extensionGuesserFactoryInterface = null) |
|
75 | { |
||
76 | 5 | parent::__construct($priority); |
|
77 | |||
78 | // NEXT_MAJOR: remove type check and enable parameter typehint |
||
79 | 5 | if (!$mimeTypes instanceof MimeTypesInterface && !$mimeTypes instanceof MimeTypeGuesserFactoryInterface) { |
|
80 | throw new \InvalidArgumentException(sprintf('The "$mimeTypes" argument must implement the "%s" or "%s" interface', MimeTypesInterface::class, MimeTypeGuesserFactoryInterface::class)); |
||
81 | } |
||
82 | |||
83 | 5 | if (null !== $extensionGuesserFactoryInterface) { |
|
84 | @trigger_error(sprintf('Passing a value for "$extensionGuesserFactoryInterface" in "%s" is deprecated since KunstmaanMediaBundle 5.7 and this parameter will be removed in KunstmaanMediaBundle 6.0.', __METHOD__), E_USER_DEPRECATED); |
||
0 ignored issues
–
show
|
|||
85 | } |
||
86 | |||
87 | 5 | if ($mimeTypes instanceof MimeTypeGuesserFactoryInterface) { |
|
88 | @trigger_error(sprintf('Passing an instance of "%s" for "$mimeTypes" in "%s" is deprecated since KunstmaanMediaBundle 5.7 and this parameter will be removed in KunstmaanMediaBundle 6.0. Inject the an instance of "%s" instead.', MimeTypeGuesserFactoryInterface::class, __METHOD__, MimeTypesInterface::class), E_USER_DEPRECATED); |
||
0 ignored issues
–
show
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.
If you suppress an error, we recommend checking for the error condition explicitly: // For example instead of
@mkdir($dir);
// Better use
if (@mkdir($dir) === false) {
throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
|
|||
89 | |||
90 | $this->mimeTypeGuesser = $mimeTypes->get(); |
||
91 | } else { |
||
92 | 5 | $this->mimeTypes = $mimeTypes; |
|
93 | } |
||
94 | |||
95 | 5 | if ($extensionGuesserFactoryInterface instanceof ExtensionGuesserFactoryInterface) { |
|
96 | $this->extensionGuesser = $extensionGuesserFactoryInterface->get(); |
||
97 | } |
||
98 | 5 | } |
|
99 | |||
100 | /** |
||
101 | * @param SlugifierInterface $slugifier |
||
102 | */ |
||
103 | 1 | public function setSlugifier(SlugifierInterface $slugifier) |
|
104 | { |
||
105 | 1 | $this->slugifier = $slugifier; |
|
106 | 1 | } |
|
107 | |||
108 | /** |
||
109 | * Inject the blacklisted |
||
110 | * |
||
111 | * @param array $blacklistedExtensions |
||
112 | */ |
||
113 | public function setBlacklistedExtensions(array $blacklistedExtensions) |
||
114 | { |
||
115 | $this->blacklistedExtensions = $blacklistedExtensions; |
||
116 | } |
||
117 | |||
118 | /** |
||
119 | * Inject the path used in media urls. |
||
120 | * |
||
121 | * @param string $mediaPath |
||
122 | */ |
||
123 | public function setMediaPath($mediaPath) |
||
124 | { |
||
125 | $this->mediaPath = $mediaPath; |
||
126 | } |
||
127 | |||
128 | public function setFileSystem(Filesystem $fileSystem) |
||
129 | { |
||
130 | $this->fileSystem = $fileSystem; |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * @return string |
||
135 | */ |
||
136 | public function getName() |
||
137 | { |
||
138 | return 'File Handler'; |
||
139 | } |
||
140 | |||
141 | /** |
||
142 | * @return string |
||
143 | */ |
||
144 | public function getType() |
||
145 | { |
||
146 | return FileHandler::TYPE; |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * @return string |
||
151 | */ |
||
152 | public function getFormType() |
||
153 | { |
||
154 | return FileType::class; |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * @param mixed $object |
||
159 | * |
||
160 | * @return bool |
||
161 | */ |
||
162 | 2 | public function canHandle($object) |
|
163 | { |
||
164 | 2 | if ($object instanceof File || |
|
165 | 2 | ($object instanceof Media && |
|
166 | 2 | (is_file($object->getContent()) || $object->getLocation() == 'local')) |
|
167 | ) { |
||
168 | 1 | return true; |
|
169 | } |
||
170 | |||
171 | 1 | return false; |
|
172 | } |
||
173 | |||
174 | /** |
||
175 | * @param Media $media |
||
176 | * |
||
177 | * @return FileHelper |
||
178 | */ |
||
179 | public function getFormHelper(Media $media) |
||
180 | { |
||
181 | return new FileHelper($media); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * @param Media $media |
||
186 | * |
||
187 | * @throws \RuntimeException when the file does not exist |
||
188 | */ |
||
189 | 1 | public function prepareMedia(Media $media) |
|
190 | { |
||
191 | 1 | if (null === $media->getUuid()) { |
|
192 | 1 | $uuid = uniqid(); |
|
193 | 1 | $media->setUuid($uuid); |
|
194 | } |
||
195 | |||
196 | 1 | $content = $media->getContent(); |
|
197 | 1 | if (empty($content)) { |
|
198 | return; |
||
199 | } |
||
200 | |||
201 | 1 | if (!$content instanceof File) { |
|
202 | if (!is_file($content)) { |
||
203 | throw new \RuntimeException('Invalid file'); |
||
204 | } |
||
205 | |||
206 | $file = new File($content); |
||
207 | $media->setContent($file); |
||
208 | } |
||
209 | |||
210 | 1 | $contentType = $this->guessMimeType($content->getPathname()); |
|
211 | 1 | if ($content instanceof UploadedFile) { |
|
212 | $pathInfo = pathinfo($content->getClientOriginalName()); |
||
213 | |||
214 | if (!\array_key_exists('extension', $pathInfo)) { |
||
215 | $pathInfo['extension'] = $this->getExtensions($contentType); |
||
216 | } |
||
217 | |||
218 | $media->setOriginalFilename($this->slugifier->slugify($pathInfo['filename']).'.'.$pathInfo['extension']); |
||
219 | $name = $media->getName(); |
||
220 | |||
221 | if (empty($name)) { |
||
222 | $media->setName($media->getOriginalFilename()); |
||
223 | } |
||
224 | } |
||
225 | |||
226 | 1 | $media->setContentType($contentType); |
|
227 | 1 | $media->setFileSize(filesize($media->getContent())); |
|
228 | 1 | $media->setUrl($this->mediaPath.$this->getFilePath($media)); |
|
229 | 1 | $media->setLocation('local'); |
|
230 | 1 | } |
|
231 | |||
232 | /** |
||
233 | * @param Media $media |
||
234 | */ |
||
235 | public function removeMedia(Media $media) |
||
236 | { |
||
237 | $adapter = $this->fileSystem->getAdapter(); |
||
238 | |||
239 | // Remove the file from filesystem |
||
240 | $fileKey = $this->getFilePath($media); |
||
241 | if ($adapter->exists($fileKey)) { |
||
242 | $adapter->delete($fileKey); |
||
243 | } |
||
244 | |||
245 | // Remove the files containing folder if there's nothing left |
||
246 | $folderPath = $this->getFileFolderPath($media); |
||
247 | if ($adapter->exists($folderPath) && $adapter->isDirectory($folderPath) && !empty($folderPath)) { |
||
248 | $allMyKeys = $adapter->keys(); |
||
249 | $everythingfromdir = preg_grep('/'.$folderPath, $allMyKeys); |
||
250 | |||
251 | if (\count($everythingfromdir) === 1) { |
||
252 | $adapter->delete($folderPath); |
||
253 | } |
||
254 | } |
||
255 | |||
256 | $media->setRemovedFromFileSystem(true); |
||
257 | } |
||
258 | |||
259 | /** |
||
260 | * {@inheritdoc} |
||
261 | */ |
||
262 | public function updateMedia(Media $media) |
||
263 | { |
||
264 | $this->saveMedia($media); |
||
265 | } |
||
266 | |||
267 | /** |
||
268 | * @param Media $media |
||
269 | */ |
||
270 | public function saveMedia(Media $media) |
||
271 | { |
||
272 | if (!$media->getContent() instanceof File) { |
||
273 | return; |
||
274 | } |
||
275 | |||
276 | $originalFile = $this->getOriginalFile($media); |
||
277 | $originalFile->setContent(file_get_contents($media->getContent()->getRealPath())); |
||
278 | } |
||
279 | |||
280 | /** |
||
281 | * @param Media $media |
||
282 | * |
||
283 | * @return \Gaufrette\File |
||
284 | */ |
||
285 | public function getOriginalFile(Media $media) |
||
286 | { |
||
287 | return $this->fileSystem->get($this->getFilePath($media), true); |
||
288 | } |
||
289 | |||
290 | /** |
||
291 | * @param mixed $data |
||
292 | * |
||
293 | * @return Media |
||
294 | */ |
||
295 | public function createNew($data) |
||
296 | { |
||
297 | if ($data instanceof File) { |
||
298 | /** @var $data File */ |
||
299 | $media = new Media(); |
||
300 | if (method_exists($data, 'getClientOriginalName')) { |
||
301 | $media->setOriginalFilename($data->getClientOriginalName()); |
||
302 | } else { |
||
303 | $media->setOriginalFilename($data->getFilename()); |
||
304 | } |
||
305 | $media->setContent($data); |
||
306 | |||
307 | $contentType = $this->guessMimeType($media->getContent()->getPathname()); |
||
308 | $media->setContentType($contentType); |
||
309 | |||
310 | return $media; |
||
311 | } |
||
312 | |||
313 | return null; |
||
314 | } |
||
315 | |||
316 | /** |
||
317 | * {@inheritdoc} |
||
318 | */ |
||
319 | public function getShowTemplate(Media $media) |
||
320 | { |
||
321 | return '@KunstmaanMedia/Media/File/show.html.twig'; |
||
322 | } |
||
323 | |||
324 | /** |
||
325 | * @return array |
||
326 | */ |
||
327 | public function getAddFolderActions() |
||
328 | { |
||
329 | return [ |
||
330 | FileHandler::TYPE => [ |
||
331 | 'type' => FileHandler::TYPE, |
||
332 | 'name' => 'media.file.add', |
||
333 | ], |
||
334 | ]; |
||
335 | } |
||
336 | |||
337 | /** |
||
338 | * @param Media $media |
||
339 | * |
||
340 | * @return string |
||
341 | */ |
||
342 | 1 | private function getFilePath(Media $media) |
|
343 | { |
||
344 | 1 | $filename = $media->getOriginalFilename(); |
|
345 | 1 | $filename = str_replace(['/', '\\', '%'], '', $filename); |
|
346 | |||
347 | 1 | if (!empty($this->blacklistedExtensions)) { |
|
348 | $filename = preg_replace('/\.('.implode('|', $this->blacklistedExtensions).')$/', '.txt', $filename); |
||
349 | } |
||
350 | |||
351 | 1 | $parts = pathinfo($filename); |
|
352 | 1 | $filename = $this->slugifier->slugify($parts['filename']); |
|
353 | 1 | if (\array_key_exists('extension', $parts)) { |
|
354 | $filename .= '.'.strtolower($parts['extension']); |
||
355 | } |
||
356 | |||
357 | 1 | return sprintf( |
|
358 | 1 | '%s/%s', |
|
359 | 1 | $media->getUuid(), |
|
360 | $filename |
||
361 | ); |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * @param Media $media |
||
366 | * |
||
367 | * @return string |
||
368 | */ |
||
369 | private function getFileFolderPath(Media $media) |
||
370 | { |
||
371 | return substr($this->getFilePath($media), 0, strrpos($this->getFilePath($media), $media->getOriginalFilename())); |
||
372 | } |
||
373 | |||
374 | 1 | private function guessMimeType($pathName) |
|
375 | { |
||
376 | // NEXT_MAJOR: remove method and inline guessMimeType call |
||
377 | 1 | if ($this->mimeTypeGuesser instanceof MimeTypeGuesser) { |
|
378 | return $this->mimeTypeGuesser->guess($pathName); |
||
379 | } |
||
380 | |||
381 | 1 | return $this->mimeTypes->guessMimeType($pathName); |
|
382 | } |
||
383 | |||
384 | View Code Duplication | private function getExtensions($mimeType) |
|
385 | { |
||
386 | // NEXT_MAJOR: remove method and inline getExtensions call |
||
387 | if ($this->extensionGuesser instanceof ExtensionGuesser) { |
||
388 | return $this->extensionGuesser->guess($mimeType); |
||
389 | } |
||
390 | |||
391 | return $this->mimeTypes->getExtensions($mimeType)[0] ?? ''; |
||
392 | } |
||
393 | } |
||
394 |
If you suppress an error, we recommend checking for the error condition explicitly: