AbstractUpload   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 14
eloc 37
c 2
b 0
f 0
dl 0
loc 90
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A checkAllowedExtensions() 0 8 3
A setAllowedExtensions() 0 4 1
A getFileName() 0 3 1
A do() 0 32 6
A setFormFieldName() 0 4 1
A __construct() 0 5 1
A getFileMimeType() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WebServCo\Framework\Files\Upload;
6
7
use WebServCo\Framework\Exceptions\UploadException;
8
9
/**
10
 * Initial functionality: simple upload.
11
 */
12
abstract class AbstractUpload
13
{
14
    /**
15
    * Allowed extensions.
16
    * mime / extension
17
    *
18
    * @var array<string,string>
19
    */
20
    protected array $allowedExtensions;
21
    protected string $fileName;
22
    protected string $fileMimeType;
23
    protected string $formFieldName;
24
    protected string $uploadDirectory;
25
26
    abstract protected function generateUploadedFileName(string $uploadFileName, string $uploadFileMimeType): string;
27
28
    public function __construct(string $uploadDirectory)
29
    {
30
        $this->allowedExtensions = []; // default all
31
        $this->formFieldName = 'upload';
32
        $this->uploadDirectory = $uploadDirectory;
33
    }
34
35
    public function getFileName(): string
36
    {
37
        return $this->fileName;
38
    }
39
40
    public function getFileMimeType(): string
41
    {
42
        return $this->fileMimeType;
43
    }
44
45
    final public function do(): bool
46
    {
47
        if (!$_FILES) {
48
            return false;
49
        }
50
51
        if (!isset($_FILES[$this->formFieldName]['error'])) {
52
            throw new UploadException(Codes::NO_FILE);
53
        }
54
55
        if (Codes::OK !== $_FILES[$this->formFieldName]['error']) {
56
            throw new UploadException($_FILES[$this->formFieldName]['error']);
57
        }
58
        $this->checkAllowedExtensions();
59
        $this->fileName = $this->generateUploadedFileName(
60
            $_FILES[$this->formFieldName]['name'],
61
            $_FILES[$this->formFieldName]['type'],
62
        );
63
64
        $this->fileMimeType = $_FILES[$this->formFieldName]['type'];
65
66
        if (!\move_uploaded_file($_FILES[$this->formFieldName]['tmp_name'], $this->uploadDirectory . $this->fileName)) {
67
            throw new UploadException(Codes::CANT_WRITE);
68
        }
69
70
        try {
71
            \chmod($this->uploadDirectory . $this->fileName, 0664);
72
        } catch (\Throwable $e) {
73
            // Operation not permitted
74
        }
75
76
        return true;
77
    }
78
79
    /**
80
    * @param array<string,string> $allowedExtensions
81
    */
82
    final public function setAllowedExtensions(array $allowedExtensions): bool
83
    {
84
        $this->allowedExtensions = $allowedExtensions;
85
        return true;
86
    }
87
88
    final public function setFormFieldName(string $formFieldName): bool
89
    {
90
        $this->formFieldName = $formFieldName;
91
        return true;
92
    }
93
94
    final protected function checkAllowedExtensions(): bool
95
    {
96
        if ($this->allowedExtensions) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->allowedExtensions of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
97
            if (!\array_key_exists($_FILES[$this->formFieldName]['type'], $this->allowedExtensions)) {
98
                throw new UploadException(Codes::TYPE_NOT_ALLOWED);
99
            }
100
        }
101
        return true;
102
    }
103
}
104