Passed
Push — main ( 06b8a6...5a482c )
by Emil
05:26
created

UploadManager::sanitizeFilename()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 8
rs 10
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
3
namespace App;
4
5
use Symfony\Component\HttpFoundation\File\UploadedFile;
6
7
class UploadManager
8
{
9
    private string $targetPath;
10
    private string $targetDirectory;
11
    private string $targetDirectoryPath;
12
13
    /**
14
     * __construct.
15
     *
16
     * @return void
17
     */
18 7
    public function __construct(string $targetPath, string $targetDirectory = '/uploads')
19
    {
20 7
        $this->targetPath = $targetPath;
21 7
        $this->targetDirectory = ltrim($targetDirectory, '/');
22 7
        $this->targetDirectoryPath = rtrim($this->targetPath.'/'.$this->targetDirectory, '/');
23
24
        // Make sure the directory exists
25 7
        if (!is_dir($this->targetDirectoryPath)) {
26 6
            mkdir($this->targetDirectoryPath, 0777, true);
27
        }
28
        // Check write permissions
29 7
        if (!is_writable($this->targetDirectoryPath)) {
30
            throw new \RuntimeException($this->targetDirectory.' directory is not writable.');
31
        }
32
    }
33
34
    /**
35
     * sanitizeFilename.
36
     */
37 2
    private function sanitizeFilename(string $filename): string
38
    {
39
        // Replace all non-alphanumeric characters with underscores
40
        /** @var string $sanitized */
41 2
        $sanitized = preg_replace('/[^A-Za-z0-9_]/', '_', $filename);
42
43
        // Convert to lowercase
44 2
        return strtolower($sanitized);
45
    }
46
47
    /**
48
     * getTargetPath.
49
     */
50 1
    public function getTargetPath(): string
51
    {
52 1
        return $this->targetPath;
53
    }
54
55
    /**
56
     * getTargetDirectory.
57
     */
58 1
    public function getTargetDirectory(): string
59
    {
60 1
        return $this->targetDirectory;
61
    }
62
63
    /**
64
     * getTargetDirectoryPath.
65
     */
66 2
    public function getTargetDirectoryPath(): string
67
    {
68 2
        return $this->targetDirectoryPath;
69
    }
70
71
    /**
72
     * saveUploadedFile.
73
     *
74
     * Saves the uploaded file to the targetPath/targetFolder and returns the path
75
     *
76
     * @param array<string> $fileTypesSupported
77
     *
78
     * @return string|null string containing filename if successful null if failed
79
     */
80 4
    public function saveUploadedFile(?UploadedFile $file, array $fileTypesSupported): ?string
81
    {
82 4
        $newFilename = null;
83
84 4
        if ($file instanceof UploadedFile && $file->isValid()) {
85
            // Check if file is of allowed type
86 3
            $fileType = $file->getMimeType();
87 3
            if (!in_array($fileType, $fileTypesSupported)) {
88 1
                throw new \RuntimeException('Invalid file type. Filetype of '.$fileType.' is not allowed.');
89
            }
90
91
            /** @var string $originalFilename */
92 2
            $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
93 2
            $safeFilename = $this->sanitizeFilename($originalFilename);
94 2
            $newFilename = $safeFilename.'-'.uniqid().'.'.$file->guessExtension();
95
96
            // Move the file to the directory
97
            try {
98 2
                $file->move($this->targetDirectoryPath, $newFilename);
99 1
            } catch (\Exception $e) {
100 1
                throw new \RuntimeException('Error uploading file: '.$e->getMessage());
101
            }
102
        }
103
104 2
        return $newFilename;
105
    }
106
107
    /**
108
     * deleteUploadedFile.
109
     *
110
     * Deletes the file at the given path within the target directory.
111
     *
112
     * @param string $fileName The filename filename.jpg'
113
     *
114
     * @return bool True if deletion was successful, false otherwise
115
     */
116 1
    public function deleteUploadedFile(string $fileName): bool
117
    {
118
        // Full path to the file
119 1
        $fullPath = $this->targetDirectoryPath.'/'.$fileName;
120
121
        // Check if file exists
122 1
        if (!file_exists($fullPath)) {
123
            // File does not exist
124 1
            return false;
125
        }
126
127
        // Attempt to delete the file
128 1
        return unlink($fullPath);
129
    }
130
}
131