Subversion-Projekte lars-tiefland.webanos.zeldi.de

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
4 lars 1
<?php
2
/*
3
 * jQuery File Upload Plugin PHP Example 5.2.7
4
 * https://github.com/blueimp/jQuery-File-Upload
5
 *
6
 * Copyright 2010, Sebastian Tschan
7
 * https://blueimp.net
8
 *
9
 * Licensed under the MIT license:
10
 * http://creativecommons.org/licenses/MIT/
11
 */
12
 
13
error_reporting(E_ALL | E_STRICT);
14
 
15
class UploadHandler
16
{
17
    private $options;
18
 
19
    function __construct($options=null) {
20
        $this->options = array(
21
            'script_url' => $_SERVER['PHP_SELF'],
22
            'upload_dir' => dirname(__FILE__).'/files/',
23
            'upload_url' => dirname($_SERVER['PHP_SELF']).'/files/',
24
            'param_name' => 'files',
25
            // The php.ini settings upload_max_filesize and post_max_size
26
            // take precedence over the following max_file_size setting:
27
            'max_file_size' => null,
28
            'min_file_size' => 1,
29
            'accept_file_types' => '/.+$/i',
30
            'max_number_of_files' => null,
31
            'discard_aborted_uploads' => true,
32
            'image_versions' => array(
33
                // Uncomment the following version to restrict the size of
34
                // uploaded images. You can also add additional versions with
35
                // their own upload directories:
36
                /*
37
                'large' => array(
38
                    'upload_dir' => dirname(__FILE__).'/files/',
39
                    'upload_url' => dirname($_SERVER['PHP_SELF']).'/files/',
40
                    'max_width' => 1920,
41
                    'max_height' => 1200
42
                ),
43
                */
44
                'thumbnail' => array(
45
                    'upload_dir' => dirname(__FILE__).'/thumbnails/',
46
                    'upload_url' => dirname($_SERVER['PHP_SELF']).'/thumbnails/',
47
                    'max_width' => 80,
48
                    'max_height' => 80
49
                )
50
            )
51
        );
52
        if ($options) {
53
            $this->options = array_replace_recursive($this->options, $options);
54
        }
55
    }
56
 
57
    private function get_file_object($file_name) {
58
        $file_path = $this->options['upload_dir'].$file_name;
59
        if (is_file($file_path) && $file_name[0] !== '.') {
60
            $file = new stdClass();
61
            $file->name = $file_name;
62
            $file->size = filesize($file_path);
63
            $file->url = $this->options['upload_url'].rawurlencode($file->name);
64
            foreach($this->options['image_versions'] as $version => $options) {
65
                if (is_file($options['upload_dir'].$file_name)) {
66
                    $file->{$version.'_url'} = $options['upload_url']
67
                        .rawurlencode($file->name);
68
                }
69
            }
70
            $file->delete_url = $this->options['script_url']
71
                .'?file='.rawurlencode($file->name);
72
            $file->delete_type = 'DELETE';
73
            return $file;
74
        }
75
        return null;
76
    }
77
 
78
    private function get_file_objects() {
79
        return array_values(array_filter(array_map(
80
            array($this, 'get_file_object'),
81
            scandir($this->options['upload_dir'])
82
        )));
83
    }
84
 
85
    private function create_scaled_image($file_name, $options) {
86
        $file_path = $this->options['upload_dir'].$file_name;
87
        $new_file_path = $options['upload_dir'].$file_name;
88
        list($img_width, $img_height) = @getimagesize($file_path);
89
        if (!$img_width || !$img_height) {
90
            return false;
91
        }
92
        $scale = min(
93
            $options['max_width'] / $img_width,
94
            $options['max_height'] / $img_height
95
        );
96
        if ($scale > 1) {
97
            $scale = 1;
98
        }
99
        $new_width = $img_width * $scale;
100
        $new_height = $img_height * $scale;
101
        $new_img = @imagecreatetruecolor($new_width, $new_height);
102
        switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
103
            case 'jpg':
104
            case 'jpeg':
105
                $src_img = @imagecreatefromjpeg($file_path);
106
                $write_image = 'imagejpeg';
107
                break;
108
            case 'gif':
109
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
110
                $src_img = @imagecreatefromgif($file_path);
111
                $write_image = 'imagegif';
112
                break;
113
            case 'png':
114
                @imagecolortransparent($new_img, @imagecolorallocate($new_img, 0, 0, 0));
115
                @imagealphablending($new_img, false);
116
                @imagesavealpha($new_img, true);
117
                $src_img = @imagecreatefrompng($file_path);
118
                $write_image = 'imagepng';
119
                break;
120
            default:
121
                $src_img = $image_method = null;
122
        }
123
        $success = $src_img && @imagecopyresampled(
124
            $new_img,
125
            $src_img,
126
            0, 0, 0, 0,
127
            $new_width,
128
            $new_height,
129
            $img_width,
130
            $img_height
131
        ) && $write_image($new_img, $new_file_path);
132
        // Free up memory (imagedestroy does not delete files):
133
        @imagedestroy($src_img);
134
        @imagedestroy($new_img);
135
        return $success;
136
    }
137
 
138
    private function has_error($uploaded_file, $file, $error) {
139
        if ($error) {
140
            return $error;
141
        }
142
        if (!preg_match($this->options['accept_file_types'], $file->name)) {
143
            return 'acceptFileTypes';
144
        }
145
        if ($uploaded_file && is_uploaded_file($uploaded_file)) {
146
            $file_size = filesize($uploaded_file);
147
        } else {
148
            $file_size = $_SERVER['CONTENT_LENGTH'];
149
        }
150
        if ($this->options['max_file_size'] && (
151
                $file_size > $this->options['max_file_size'] ||
152
                $file->size > $this->options['max_file_size'])
153
            ) {
154
            return 'maxFileSize';
155
        }
156
        if ($this->options['min_file_size'] &&
157
            $file_size < $this->options['min_file_size']) {
158
            return 'minFileSize';
159
        }
160
        if (is_int($this->options['max_number_of_files']) && (
161
                count($this->get_file_objects()) >= $this->options['max_number_of_files'])
162
            ) {
163
            return 'maxNumberOfFiles';
164
        }
165
        return $error;
166
    }
167
 
168
    private function handle_file_upload($uploaded_file, $name, $size, $type, $error) {
169
        $file = new stdClass();
170
        // Remove path information and dots around the filename, to prevent uploading
171
        // into different directories or replacing hidden system files.
172
        // Also remove control characters and spaces (\x00..\x20) around the filename:
173
        $file->name = trim(basename(stripslashes($name)), ".\x00..\x20");
174
        $file->size = intval($size);
175
        $file->type = $type;
176
        $error = $this->has_error($uploaded_file, $file, $error);
177
        if (!$error && $file->name) {
178
            $file_path = $this->options['upload_dir'].$file->name;
179
            $append_file = !$this->options['discard_aborted_uploads'] &&
180
                is_file($file_path) && $file->size > filesize($file_path);
181
            clearstatcache();
182
            if ($uploaded_file && is_uploaded_file($uploaded_file)) {
183
                // multipart/formdata uploads (POST method uploads)
184
                if ($append_file) {
185
                    file_put_contents(
186
                        $file_path,
187
                        fopen($uploaded_file, 'r'),
188
                        FILE_APPEND
189
                    );
190
                } else {
191
                    move_uploaded_file($uploaded_file, $file_path);
192
                }
193
            } else {
194
                // Non-multipart uploads (PUT method support)
195
                file_put_contents(
196
                    $file_path,
197
                    fopen('php://input', 'r'),
198
                    $append_file ? FILE_APPEND : 0
199
                );
200
            }
201
            $file_size = filesize($file_path);
202
            if ($file_size === $file->size) {
203
                $file->url = $this->options['upload_url'].rawurlencode($file->name);
204
                foreach($this->options['image_versions'] as $version => $options) {
205
                    if ($this->create_scaled_image($file->name, $options)) {
206
                        $file->{$version.'_url'} = $options['upload_url']
207
                            .rawurlencode($file->name);
208
                    }
209
                }
210
            } else if ($this->options['discard_aborted_uploads']) {
211
                unlink($file_path);
212
                $file->error = 'abort';
213
            }
214
            $file->size = $file_size;
215
            $file->delete_url = $this->options['script_url']
216
                .'?file='.rawurlencode($file->name);
217
            $file->delete_type = 'DELETE';
218
        } else {
219
            $file->error = $error;
220
        }
221
        return $file;
222
    }
223
 
224
    public function get() {
225
        $file_name = isset($_REQUEST['file']) ?
226
            basename(stripslashes($_REQUEST['file'])) : null;
227
        if ($file_name) {
228
            $info = $this->get_file_object($file_name);
229
        } else {
230
            $info = $this->get_file_objects();
231
        }
232
        header('Content-type: application/json');
233
        echo json_encode($info);
234
    }
235
 
236
    public function post() {
237
        $upload = isset($_FILES[$this->options['param_name']]) ?
238
            $_FILES[$this->options['param_name']] : array(
239
                'tmp_name' => null,
240
                'name' => null,
241
                'size' => null,
242
                'type' => null,
243
                'error' => null
244
            );
245
        $info = array();
246
        if (is_array($upload['tmp_name'])) {
247
            foreach ($upload['tmp_name'] as $index => $value) {
248
                $info[] = $this->handle_file_upload(
249
                    $upload['tmp_name'][$index],
250
                    isset($_SERVER['HTTP_X_FILE_NAME']) ?
251
                        $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'][$index],
252
                    isset($_SERVER['HTTP_X_FILE_SIZE']) ?
253
                        $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'][$index],
254
                    isset($_SERVER['HTTP_X_FILE_TYPE']) ?
255
                        $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'][$index],
256
                    $upload['error'][$index]
257
                );
258
            }
259
        } else {
260
            $info[] = $this->handle_file_upload(
261
                $upload['tmp_name'],
262
                isset($_SERVER['HTTP_X_FILE_NAME']) ?
263
                    $_SERVER['HTTP_X_FILE_NAME'] : $upload['name'],
264
                isset($_SERVER['HTTP_X_FILE_SIZE']) ?
265
                    $_SERVER['HTTP_X_FILE_SIZE'] : $upload['size'],
266
                isset($_SERVER['HTTP_X_FILE_TYPE']) ?
267
                    $_SERVER['HTTP_X_FILE_TYPE'] : $upload['type'],
268
                $upload['error']
269
            );
270
        }
271
        header('Vary: Accept');
272
        if (isset($_SERVER['HTTP_ACCEPT']) &&
273
            (strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
274
            header('Content-type: application/json');
275
        } else {
276
            header('Content-type: text/plain');
277
        }
278
        echo json_encode($info);
279
    }
280
 
281
    public function delete() {
282
        $file_name = isset($_REQUEST['file']) ?
283
            basename(stripslashes($_REQUEST['file'])) : null;
284
        $file_path = $this->options['upload_dir'].$file_name;
285
        $success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
286
        if ($success) {
287
            foreach($this->options['image_versions'] as $version => $options) {
288
                $file = $options['upload_dir'].$file_name;
289
                if (is_file($file)) {
290
                    unlink($file);
291
                }
292
            }
293
        }
294
        header('Content-type: application/json');
295
        echo json_encode($success);
296
    }
297
}
298
 
299
$upload_handler = new UploadHandler();
300
 
301
header('Pragma: no-cache');
302
header('Cache-Control: private, no-cache');
303
header('Content-Disposition: inline; filename="files.json"');
304
header('X-Content-Type-Options: nosniff');
305
 
306
switch ($_SERVER['REQUEST_METHOD']) {
307
    case 'HEAD':
308
    case 'GET':
309
        $upload_handler->get();
310
        break;
311
    case 'POST':
312
        $upload_handler->post();
313
        break;
314
    case 'DELETE':
315
        $upload_handler->delete();
316
        break;
317
    case 'OPTIONS':
318
        break;
319
    default:
320
        header('HTTP/1.0 405 Method Not Allowed');
321
}
322
?>