Completed
Push — master ( 0d0ae6...7c7732 )
by Stone
19s
created

ImageUpload::fileInputPostUpload()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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