Passed
Push — Auth ( a6c03c...4ce6d9 )
by Stone
02:10
created

ImageUpload::fileInputUserUpload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace App\Controllers\Ajax;
4
5
use Cocur\Slugify\Slugify;
6
use Core\AjaxController;
7
8
class ImageUpload extends AjaxController
9
{
10
    /**
11
     * @var string the image upload folder, must be writable
12
     */
13
    private $imageFolder = "uploaded_images/";
14
    private $configFolder = "config_images/";
15
    private $userFolder = "user_images/";
16
17
    /**
18
     * check if the image name is valid
19
     * @param $image string filename to check
20
     * @return bool if image name is valid
21
     *
22
     */
23
    private function isImageValid($image): bool
24
    {
25
        // Sanitize input
26
        if (preg_match("/([^\w\s\d\-_~,;:\[\]\(\).])|([\.]{2,})/", $image)) {
27
            return false;
28
        }
29
30
        // Verify extension
31
        if (!in_array(strtolower(pathinfo($image, PATHINFO_EXTENSION)), array("gif", "jpg", "png"))) {
32
            return false;
33
        }
34
35
        return true;
36
    }
37
38
    /**
39
     * Check if file exists and add a number to avoid overwrite
40
     * @param string $folder destination folder
41
     * @param string $file destination filename
42
     * @return string the unique file name
43
     */
44
    private function getFilename(string $folder, string $file): string
45
    {
46
        //slugify the file name to avoid security errors or bugs with special characters.
47
        $fileName = pathinfo($file, PATHINFO_FILENAME );
48
        $fileExtension = pathinfo($file, PATHINFO_EXTENSION );
49
        $slugify = new Slugify();
50
        $fileName = $slugify->slugify($fileName);
51
        //if the filename has only special chars, the slugify will be empty, create a unique ID
52
        if($fileName ==="")
53
        {
54
            $fileName = uniqid();
55
        }
56
        $file = $fileName.".".$fileExtension;
57
        $fileUrl = $folder . $file;
58
        $docRoot = $this->request->getDocumentRoot();
59
        $filePath = $docRoot . "/public/" . $fileUrl;
60
        if (file_exists($filePath) !== 1) {
61
            $fileNum = 0;
62
            while (file_exists($filePath)) {
63
                $fileUrl = $folder . $fileNum . "_" . $file;
64
                $filePath = $docRoot . "/public/" . $fileUrl;
65
                $fileNum += 1;
66
            }
67
        }
68
        return $fileUrl;
69
    }
70
71
    /**
72
     * @param $tempFile array
73
     * @param $folder string
74
     */
75
    private function fileInputUpload(array $tempFile, string $folder)
76
    {
77
        if (is_uploaded_file($tempFile['tmp_name'])) {
78
            if (!$this->isImageValid($tempFile['name'])) {
79
                echo json_encode(array('error' => 'Invalid name or file extension'));
80
                return;
81
            }
82
83
            $filetowrite = $this->getFilename($folder, basename($tempFile['name']));
84
            move_uploaded_file($tempFile['tmp_name'], $filetowrite);
85
86
            // Respond to the successful upload with JSON.
87
            echo json_encode(array('location' => $filetowrite));
88
        } else {
89
            // Notify editor that the upload failed
90
            echo json_encode(array('error' => 'Upload failed, file might be too big'));
91
92
        }
93
94
    }
95
96
    /**
97
     * Upload images from TinyMCE
98
     * grabbed from https://www.codexworld.com/tinymce-upload-image-to-server-using-php/
99
     */
100
    public function tinymceUpload()
101
    {
102
        //security checks, only admins can upload images to posts
103
        $this->onlyAdmin();
104
        $this->onlyPost();
105
106
        $tempFile = $this->request->getUploadedFiles();
107
108
        //need to clean up
109
        if (is_uploaded_file($tempFile['tmp_name'])) {
110
            if (!$this->isImageValid($tempFile['name'])) {
111
                header("HTTP/1.1 400 Invalid file name or file extension.");
112
                return;
113
            }
114
115
            $filetowrite = $this->getFilename($this->imageFolder, basename($tempFile['name']));
116
            move_uploaded_file($tempFile['tmp_name'], $filetowrite);
117
118
            // Respond to the successful upload with JSON.
119
            echo json_encode(array('location' => $filetowrite));
120
        } else {
121
            // Notify editor that the upload failed
122
            header("HTTP/1.1 500 Server Error");
123
        }
124
    }
125
126
127
    /**
128
     * Upload for the file input in the configuration
129
     */
130
    public function fileInputConfigUpload()
131
    {
132
        //security checks, only admins can upload images to config
133
        $this->onlyAdmin();
134
        $this->onlyPost();
135
        $tempFile = $this->request->getUploadedFiles();
136
137
        $this->fileInputUpload($tempFile, $this->configFolder);
138
139
    }
140
141
    /**
142
     * Upload for the file input in the configuration
143
     */
144
    public function fileInputPostUpload()
145
    {
146
        //security checks, only admins can upload images to config
147
        $this->onlyAdmin();
148
        $this->onlyPost();
149
        $tempFile = $this->request->getUploadedFiles();
150
        $this->fileInputUpload($tempFile, $this->imageFolder);
151
    }
152
153
    /**
154
     * Upload for the file input in the configuration
155
     */
156
    public function fileInputUserUpload()
157
    {
158
        //security checks, only admins can upload images to config
159
        $this->onlyUser();
160
        $this->onlyPost();
161
        $tempFile = $this->request->getUploadedFiles();
162
        $this->fileInputUpload($tempFile, $this->userFolder);
163
    }
164
165
}