Passed
Push — main ( 6686e2...8d438c )
by Alex
01:09
created

TraitUpload::mimetype()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
namespace Erykai\Upload;
4
5
use finfo;
6
use RuntimeException;
7
8
/**
9
 * Class Trait Upload
10
 */
11
trait TraitUpload
12
{
13
    /**
14
     * @param string $path
15
     */
16
    protected function createDir(string $path): void
17
    {
18
        $folders = explode("/", $path);
19
        $dir = dirname(__DIR__, 4);
20
        foreach ($folders as $folder) {
21
            $dir .= "/" . $folder;
22
            if (!file_exists($dir) && !mkdir($dir) && !is_dir($dir)) {
23
                throw new RuntimeException(sprintf('Directory "%s" was not created', $dir));
24
            }
25
        }
26
    }
27
28
    /**
29
     * @param string $name
30
     * @return string
31
     */
32
    protected function slug(string $name): string
33
    {
34
        $characters = array(
35
            'Š' => 'S', 'š' => 's', 'Đ' => 'Dj', 'đ' => 'dj', 'Ž' => 'Z', 'ž' => 'z', 'Č' => 'C', 'č' => 'c', 'Ć' => 'C', 'ć' => 'c',
36
            'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'Æ' => 'A', 'Ç' => 'C', 'È' => 'E', 'É' => 'E',
37
            'Ê' => 'E', 'Ë' => 'E', 'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'Ñ' => 'N', 'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O',
38
            'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'Ý' => 'Y', 'Þ' => 'B', 'ß' => 'Ss',
39
            'à' => 'a', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'æ' => 'a', 'ç' => 'c', 'è' => 'e', 'é' => 'e',
40
            'ê' => 'e', 'ë' => 'e', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'ð' => 'o', 'ñ' => 'n', 'ò' => 'o', 'ó' => 'o',
41
            'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ý' => 'y', 'þ' => 'b',
42
            'ÿ' => 'y', 'Ŕ' => 'R', 'ŕ' => 'r', '/' => '-', ' ' => '-'
43
        );
44
        $stripped = preg_replace(array('/\s{2,}/', '/[\t\n]/'), ' ', $name);
45
        return strtolower(strtr($stripped, $characters));
46
    }
47
48
    protected function upload(): bool
49
    {
50
        foreach ($this->getFiles() as $file) {
0 ignored issues
show
Bug introduced by
It seems like getFiles() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

50
        foreach ($this->/** @scrutinizer ignore-call */ getFiles() as $file) {
Loading history...
51
            $this->createDir($file->path);
52
            $archive = $file->name . "." . $file->ext;
53
            $directory = $file->directory . "/";
54
            $path = $file->path . "/";
55
            if (file_exists($directory . $archive)) {
56
                $archive = $file->name . "-" . time() . mt_rand() . "." . $file->ext;
57
            }
58
            $this->setData($file->key, $path . $archive);
0 ignored issues
show
Bug introduced by
It seems like setData() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
            $this->/** @scrutinizer ignore-call */ 
59
                   setData($file->key, $path . $archive);
Loading history...
59
            if (!empty($file->tmp_name)) {
60
                move_uploaded_file($file->tmp_name, $directory . $archive);
61
            }else{
62
                file_put_contents($directory . $archive, file_get_contents($this->url));
63
            }
64
        }
65
        return true;
66
    }
67
68
    /**
69
     * @return bool
70
     */
71
    protected function uploadFiles(): bool
72
    {
73
        $upload = $_FILES;
74
        foreach ($upload as $key => $file) {
75
            $this->file = new \stdClass();
0 ignored issues
show
Bug Best Practice introduced by
The property file does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
76
            if (!$this->mimetype($file)) {
77
                return false;
78
            }
79
            $this->mountFile($file, $key);
80
            $this->file->tmp_name = $file['tmp_name'];
81
            $files[$key] = (object)$this->file;
82
        }
83
        if (!empty($files)) {
84
            $this->files['upload_file'] = (object)$files;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $files seems to be defined by a foreach iteration on line 74. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
Bug Best Practice introduced by
The property files does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
85
            return true;
86
        }
87
        return false;
88
    }
89
90
    /**
91
     * @return bool
92
     */
93
    protected function uploadUrl(): bool
94
    {
95
        $this->file = new \stdClass();
0 ignored issues
show
Bug Best Practice introduced by
The property file does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
96
        $finfo = new finfo(FILEINFO_MIME_TYPE);
97
        $mime_type = $finfo->buffer(file_get_contents($this->url));
98
        $file['type'] = $mime_type;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$file was never initialized. Although not strictly required by PHP, it is generally a good practice to add $file = array(); before regardless.
Loading history...
99
        if (!$this->mimetype($file)) {
100
            return false;
101
        }
102
        $url_array = explode("/", $this->url);
103
        $file['name'] = end($url_array);
104
        $this->mountFile($file, $this->key);
105
        $files = (object)$this->file;
106
        $this->files['upload_url'] = (object)$files;
0 ignored issues
show
Bug Best Practice introduced by
The property files does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
107
        return true;
108
    }
109
110
    /**
111
     * @param array $file
112
     */
113
    private function mountFile(array $file, string $key)
114
    {
115
        [$type] = explode("/", $file['type']);
116
        $this->setPath($type);
0 ignored issues
show
Bug introduced by
It seems like setPath() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
        $this->/** @scrutinizer ignore-call */ 
117
               setPath($type);
Loading history...
117
118
        $this->file->key = $key;
119
        $this->file->ext = pathinfo($file['name'], PATHINFO_EXTENSION);
120
        $this->file->name = $this->slug(pathinfo($file['name'], PATHINFO_FILENAME));
0 ignored issues
show
Bug introduced by
It seems like pathinfo($file['name'], ...load\PATHINFO_FILENAME) can also be of type array; however, parameter $name of Erykai\Upload\TraitUpload::slug() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

120
        $this->file->name = $this->slug(/** @scrutinizer ignore-type */ pathinfo($file['name'], PATHINFO_FILENAME));
Loading history...
121
        $this->file->path = $this->getPath();
0 ignored issues
show
Bug introduced by
It seems like getPath() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

121
        /** @scrutinizer ignore-call */ 
122
        $this->file->path = $this->getPath();
Loading history...
122
        $this->file->directory = dirname(__DIR__, 4) . "/" . $this->getPath();
123
    }
124
125
    /**
126
     * @param array $type
127
     * @return bool
128
     */
129
    private function mimetype(array $type): bool
130
    {
131
        if (!in_array($type['type'], $this->getMimeType(), true)) {
0 ignored issues
show
Bug introduced by
It seems like getMimeType() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
        if (!in_array($type['type'], $this->/** @scrutinizer ignore-call */ getMimeType(), true)) {
Loading history...
132
            $this->files = null;
0 ignored issues
show
Bug Best Practice introduced by
The property files does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
133
            $this->setResponse(400, "error", "invalid file format " . $type['type'], "upload", dynamic: $type['type']);
0 ignored issues
show
Bug introduced by
It seems like setResponse() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

133
            $this->/** @scrutinizer ignore-call */ 
134
                   setResponse(400, "error", "invalid file format " . $type['type'], "upload", dynamic: $type['type']);
Loading history...
134
            return false;
135
        }
136
        return true;
137
    }
138
}