Passed
Push — main ( 101f2d...06b8a6 )
by Emil
25:10
created

UploadManager::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 3
eloc 7
c 1
b 1
f 0
nc 4
nop 2
dl 0
loc 13
ccs 6
cts 8
cp 0.75
crap 3.1406
rs 10
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
            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
     * getTargetPath.
36
     */
37 1
    public function getTargetPath(): string
38
    {
39 1
        return $this->targetPath;
40
    }
41
42
    /**
43
     * getTargetDirectory.
44
     */
45 1
    public function getTargetDirectory(): string
46
    {
47 1
        return $this->targetDirectory;
48
    }
49
50
    /**
51
     * getTargetDirectoryPath.
52
     */
53 2
    public function getTargetDirectoryPath(): string
54
    {
55 2
        return $this->targetDirectoryPath;
56
    }
57
58
    /**
59
     * saveUploadedFile.
60
     *
61
     * Saves the uploaded file to the targetPath/targetFolder and returns the path
62
     *
63
     * @param array<string> $fileTypesSupported
64
     *
65
     * @return string|null string containing filePath if successful null if failed
66
     */
67 4
    public function saveUploadedFile(?UploadedFile $file, array $fileTypesSupported): ?string
68
    {
69 4
        $filePath = null;
70
71 4
        if ($file instanceof UploadedFile && $file->isValid()) {
72
            // Check if file is of allowed type
73 3
            $fileType = $file->getMimeType();
74 3
            if (!in_array($fileType, $fileTypesSupported)) {
75 1
                throw new \RuntimeException('Invalid file type. Filetype of '.$fileType.' is not allowed.');
76
            }
77
78
            /** @var string $originalFilename */
79 2
            $originalFilename = pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME);
80 2
            $safeFilename = transliterator_transliterate('Any-Latin; Latin-ASCII; [^A-Za-z0-9_] remove; Lower()', $originalFilename);
81 2
            $newFilename = $safeFilename.'-'.uniqid().'.'.$file->guessExtension();
82
83
            // Move the file to the directory
84
            try {
85 2
                $file->move($this->targetDirectoryPath, $newFilename);
86
                // Save $newFilename and path to database
87 1
                $filePath = '/'.$this->targetDirectory.'/'.$newFilename;
88 1
            } catch (\Exception $e) {
89 1
                throw new \RuntimeException('Error uploading file: '.$e->getMessage());
90
            }
91
        }
92
93 2
        return $filePath;
94
    }
95
96
    /**
97
     * deleteUploadedFile.
98
     *
99
     * Deletes the file at the given path within the target directory.
100
     *
101
     * @param string $filePath The relative path to the image, e.g., '/uploads/filename.jpg'
102
     *
103
     * @return bool True if deletion was successful, false otherwise
104
     */
105 1
    public function deleteUploadedFile(string $filePath): bool
106
    {
107
        // Full path to the file
108 1
        $fullPath = $this->targetPath.$filePath;
109
110
        // Check if file exists
111 1
        if (!file_exists($fullPath)) {
112
            // File does not exist
113 1
            return false;
114
        }
115
116
        // Attempt to delete the file
117 1
        return unlink($fullPath);
118
    }
119
}
120