-
Notifications
You must be signed in to change notification settings - Fork 37
/
uploader.php
323 lines (296 loc) · 9.01 KB
/
uploader.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
<?php
/**
* Uploader class handles a single file to be uploaded to the file system
*
* @author: Nick Baker
* @version: since 4.4.0
* @link: http://www.webtechnick.com
*/
class Uploader {
/**
* File to upload.
*/
var $file = array();
/**
* Global options
* fileTypes to allow to upload
*/
var $options = array();
/**
* errors holds any errors that occur as string values.
* this can be access to debug the FileUploadComponent
*
* @var array
* @access public
*/
var $errors = array();
/**
* Definitions of errors that could occur during upload
*
* @author Jon Langevin
* @var array
*/
var $uploadErrors = array(
UPLOAD_ERR_OK => 'There is no error, the file uploaded with success.',
UPLOAD_ERR_INI_SIZE => 'The uploaded file exceeds the upload_max_filesize directive in php.ini.',
UPLOAD_ERR_FORM_SIZE => 'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form.',
UPLOAD_ERR_PARTIAL => 'The uploaded file was only partially uploaded.',
UPLOAD_ERR_NO_FILE => 'No file was uploaded.',
UPLOAD_ERR_NO_TMP_DIR => 'Missing a temporary folder.', //Introduced in PHP 4.3.10 and PHP 5.0.3.
UPLOAD_ERR_CANT_WRITE => 'Failed to write file to disk.', //Introduced in PHP 5.1.0.
UPLOAD_ERR_EXTENSION => 'File upload stopped by extension.' //Introduced in PHP 5.2.0.
);
/**
* Final file is set on move_uploaded_file success.
* This is the file name of the final file that was uploaded
* to the uploadDir directory
*
* @var string of final file name uploaded
* @access public
*/
var $finalFile = null;
function __construct($options = array()){
$this->options = array_merge($this->options, $options);
}
/**
* Preform requested callbacks on the filename.
*
* @var string chosen filename
* @return string of resulting filename
* @access private
*/
function __handleFileNameCallback($fileName){
if($this->options['fileNameFunction']){
if($this->options['fileModel']){
$Model = ClassRegistry::init($this->options['fileModel']);
if(method_exists($Model, $this->options['fileNameFunction'])){
$fileName = $Model->{$this->options['fileNameFunction']}($fileName);
}
elseif(function_exists($this->options['fileNameFunction'])){
$fileName = call_user_func($this->options['fileNameFunction'], $fileName);
}
}
else {
if(function_exists($this->options['fileNameFunction'])){
$fileName = call_user_func($this->options['fileNameFunction'], $fileName);
}
}
if(!$fileName){
$this->_error('No filename resulting after parsing. Function: ' . $this->options['fileNameFunction']);
}
}
return $fileName;
}
/**
* Preform requested target patch checks depending on the unique setting
*
* @var string chosen filename target_path
* @return string of resulting target_path
* @access private
*/
function __handleUnique($target_path){
if($this->options['unique']){
$temp_path = substr($target_path, 0, strlen($target_path) - strlen($this->_ext())); //temp path without the ext
$i=1;
while(file_exists($target_path)){
$target_path = $temp_path . "-" . $i . $this->_ext();
$i++;
}
}
return $target_path;
}
/**
* processFile will take a file, or use the current file given to it
* and attempt to save the file to the file system.
* processFile will check to make sure the file is there, and its type is allowed to be saved.
*
* @param file array of uploaded file (optional)
* @return String | false String of finalFile name saved to the file system or false if unable to save to file system.
* @access public
*/
function processFile($file = null){
$this->setFile($file);
//check if we have a file and if we allow the type, return false otherwise.
if(!$this->checkFile() || !$this->checkType() || !$this->checkSize()){
return false;
}
//make sure the file doesn't already exist, if it does, add an itteration to it
$up_dir = $this->options['uploadDir'];
$fileName = $this->__handleFileNameCallback($this->file['name']);
$target_path = $up_dir . DS . $fileName;
$target_path = $this->__handleUnique($target_path);
//now move the file.
if(move_uploaded_file($this->file['tmp_name'], $target_path)){
$this->finalFile = basename($target_path);
return $this->finalFile;
}
else{
$this->_error('Unable to save temp file to file system.');
return false;
}
}
/**
* setFile will set a this->file if given one.
*
* @param file array of uploaded file. (optional)
* @return void
*/
function setFile($file = null){
if($file) $this->file = $file;
}
/**
* Returns the extension of the uploaded filename.
*
* @return string $extension A filename extension
* @param file array of uploaded file (optional)
* @access protected
*/
function _ext($file = null){
$this->setFile($file);
return strrchr($this->file['name'],".");
}
/**
* Adds error messages to the component
*
* @param string $text String of error message to save
* @return void
* @access protected
*/
function _error($text){
$this->errors[] = __($text,true);
}
/**
* Checks if the uploaded type is allowed defined in the allowedTypes
*
* @return boolean if type is accepted
* @param file array of uploaded file (optional)
* @access public
*/
function checkType($file = null){
$this->setFile($file);
foreach($this->options['allowedTypes'] as $value){
if(strtolower($this->file['type']) == strtolower($value) || $value == '*'){
return true;
}
}
$this->_error("{$this->file['type']} is not an allowed type.");
return false;
}
/**
* Checks if there is a file uploaded
*
* @return void
* @access public
* @param file array of uploaded file (optional)
*/
function checkFile($file = null){
$this->setFile($file);
if($this->hasUpload() && $this->file){
if(isset($this->file['error']) && $this->file['error'] == UPLOAD_ERR_OK ) {
return true;
}
else {
$this->_error($this->uploadErrors[$this->file['error']]);
}
}
return false;
}
/**
* Checks if the file uploaded exceeds the maxFileSize setting (if there is onw)
*
* @return boolean
* @access public
* @param file array of uploaded file (optional)
*/
function checkSize($file = null){
$this->setFile($file);
if($this->hasUpload() && $this->file){
if(!$this->options['maxFileSize']){ //We don't want to test maxFileSize
return true;
}
elseif($this->options['maxFileSize'] && $this->file['size'] < $this->options['maxFileSize']){
return true;
}
else {
$this->_error("File exceeds {$this->options['maxFileSize']} byte limit.");
}
}
return false;
}
/**
* removeFile removes a specific file from the uploaded directory
*
* @param string $name A reference to the filename to delete from the uploadDirectory
* @return boolean
* @access public
*/
function removeFile($name = null){
if(!$name || strpos($name, '://')){
return false;
}
$up_dir = $this->options['uploadDir'];
$target_path = $up_dir . DS . $name;
//delete main image -- $name
if(@unlink($target_path)){
return true;
} else {
return false;
}
}
/**
* hasUpload
*
* @return boolean true | false depending if a file was actually uploaded.
* @param file array of uploaded file (optional)
*/
function hasUpload($file = null){
$this->setFile($file);
return ($this->_multiArrayKeyExists("tmp_name", $this->file));
}
/**
* @return boolean true if errors were detected.
*/
function hasErrors(){
return count($this->errors);
}
/**
* showErrors itterates through the errors array
* and returns a concatinated string of errors sepearated by
* the $sep
*
* @param string $sep A seperated defaults to <br />
* @return string
* @access public
*/
function showErrors($sep = " "){
$retval = "";
foreach($this->errors as $error){
$retval .= "$error $sep";
}
return $retval;
}
/**
* Searches through the $haystack for a $key.
*
* @param string $needle String of key to search for in $haystack
* @param array $haystack Array of which to search for $needle
* @return boolean true if given key is in an array
* @access protected
*/
function _multiArrayKeyExists($needle, $haystack) {
if(is_array($haystack)){
foreach ($haystack as $key=>$value) {
if ($needle===$key && $value) {
return true;
}
if (is_array($value)) {
if($this->_multiArrayKeyExists($needle, $value)){
return true;
}
}
}
}
return false;
}
}
?>