00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 class Varien_File_Uploader
00036 {
00037
00038
00039
00040
00041
00042
00043 protected $_file;
00044
00045
00046
00047
00048
00049
00050
00051 protected $_fileMimeType;
00052
00053
00054
00055
00056
00057
00058
00059 protected $_uploadType;
00060
00061
00062
00063
00064
00065
00066
00067
00068 protected $_uploadedFileName;
00069
00070
00071
00072
00073
00074
00075
00076 protected $_uploadedFileDir;
00077
00078
00079
00080
00081
00082
00083
00084
00085 protected $_allowCreateFolders = true;
00086
00087
00088
00089
00090
00091
00092
00093
00094 protected $_allowRenameFiles = false;
00095
00096
00097
00098
00099
00100
00101
00102 protected $_enableFilesDispersion = false;
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 protected $_caseInsensitiveFilenames = true;
00113
00114
00115
00116
00117
00118 protected $_dispretionPath = null;
00119
00120 protected $_fileExists = false;
00121
00122 protected $_allowedExtensions = null;
00123
00124 const SINGLE_STYLE = 0;
00125 const MULTIPLE_STYLE = 1;
00126
00127 function __construct($fileId)
00128 {
00129 $this->_setUploadFileId($fileId);
00130 if( !file_exists($this->_file['tmp_name']) ) {
00131 throw new Exception('File was not uploaded.');
00132 return;
00133 } else {
00134 $this->_fileExists = true;
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 public function save($destinationFolder, $newFileName=null)
00148 {
00149 if( $this->_fileExists === false ) {
00150 return;
00151 }
00152
00153 if( $this->_allowCreateFolders ) {
00154 $this->_createDestinationFolder($destinationFolder);
00155 }
00156
00157 if( !is_writable($destinationFolder) ) {
00158 throw new Exception('Destination folder is not writable or does not exists.');
00159 }
00160
00161 $result = false;
00162
00163 $destFile = $destinationFolder;
00164 $fileName = ( isset($newFileName) ) ? $newFileName : self::getCorrectFileName($this->_file['name']);
00165 $fileExtension = substr($fileName, strrpos($fileName, '.')+1);
00166
00167 if( !$this->chechAllowedExtension($fileExtension) ) {
00168 throw new Exception('Disallowed file type.');
00169 }
00170
00171 if( $this->_enableFilesDispersion ) {
00172 $fileName = $this->correctFileNameCase($fileName);
00173 $this->setAllowCreateFolders(true);
00174 $this->_dispretionPath = self::getDispretionPath($fileName);
00175 $destFile.= $this->_dispretionPath;
00176 $this->_createDestinationFolder($destFile);
00177 }
00178
00179 if( $this->_allowRenameFiles ) {
00180 $fileName = self::getNewFileName(self::_addDirSeparator($destFile).$fileName);
00181 }
00182
00183 $destFile = self::_addDirSeparator($destFile) . $fileName;
00184
00185 $result = move_uploaded_file($this->_file['tmp_name'], $destFile);
00186
00187 if( $result ) {
00188 chmod($destFile, 0777);
00189 if ( $this->_enableFilesDispersion ) {
00190 $fileName = str_replace(DIRECTORY_SEPARATOR, '/', self::_addDirSeparator($this->_dispretionPath)) . $fileName;
00191 }
00192 $this->_uploadedFileName = $fileName;
00193 $this->_uploadedFileDir = $destinationFolder;
00194 $result = $this->_file;
00195 $result['path'] = $destinationFolder;
00196 $result['file'] = $fileName;
00197 return $result;
00198 } else {
00199 return $result;
00200 }
00201 }
00202
00203 static public function getCorrectFileName($fileName)
00204 {
00205 if (preg_match('/[^a-z0-9_\\-\\.]/i', $fileName)) {
00206 $fileName = 'file' . substr($fileName, strrpos($fileName, '.'));
00207 }
00208
00209 return $fileName;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 public function correctFileNameCase($fileName)
00219 {
00220 if ($this->_caseInsensitiveFilenames) {
00221 return strtolower($fileName);
00222 }
00223 return $fileName;
00224 }
00225
00226 static protected function _addDirSeparator($dir)
00227 {
00228 if (substr($dir,-1) != DIRECTORY_SEPARATOR) {
00229 $dir.= DIRECTORY_SEPARATOR;
00230 }
00231 return $dir;
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241 public function checkMimeType($validTypes=Array())
00242 {
00243 if( count($validTypes) > 0 ) {
00244 if( !in_array($this->_getMimeType(), $validTypes) ) {
00245 return false;
00246 }
00247 }
00248 return true;
00249 }
00250
00251
00252
00253
00254
00255
00256
00257 public function getUploadedFileName()
00258 {
00259 return $this->_uploadedFileName;
00260 }
00261
00262
00263
00264
00265
00266
00267
00268
00269 public function setAllowCreateFolders($flag)
00270 {
00271 $this->_allowCreateFolders = $flag;
00272 return $this;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 public function setAllowRenameFiles($flag)
00283 {
00284 $this->_allowRenameFiles = $flag;
00285 return $this;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 public function setFilesDispersion($flag)
00296 {
00297 $this->_enableFilesDispersion = $flag;
00298 return $this;
00299 }
00300
00301
00302
00303
00304
00305
00306
00307 public function setFilenamesCaseSensitivity($flag)
00308 {
00309 $this->_caseInsensitiveFilenames = $flag;
00310 return $this;
00311 }
00312
00313 public function setAllowedExtensions($extensions=array())
00314 {
00315 foreach ((array)$extensions as $extension) {
00316 $this->_allowedExtensions[] = strtolower($extension);
00317 }
00318 return $this;
00319 }
00320
00321 public function chechAllowedExtension($extension)
00322 {
00323 if (is_null($this->_allowedExtensions)) {
00324 return true;
00325 }
00326 elseif (in_array(strtolower($extension), $this->_allowedExtensions)) {
00327 return true;
00328 }
00329 return false;
00330 }
00331
00332 private function _getMimeType()
00333 {
00334 return $this->_file['type'];
00335 }
00336
00337 private function _setUploadFileId($fileId)
00338 {
00339 if (empty($_FILES)) {
00340 throw new Exception('$_FILES array is empty');
00341 }
00342
00343 if (is_array($fileId)) {
00344 $this->_uploadType = self::MULTIPLE_STYLE;
00345 $this->_file = $fileId;
00346 } else {
00347 preg_match("/^(.*?)\[(.*?)\]$/", $fileId, $file);
00348
00349 if( count($file) > 0 && (count($file[0]) > 0) && (count($file[1]) > 0) ) {
00350 array_shift($file);
00351 $this->_uploadType = self::MULTIPLE_STYLE;
00352
00353 $fileAttributes = $_FILES[$file[0]];
00354 $tmp_var = array();
00355
00356 foreach( $fileAttributes as $attributeName => $attributeValue ) {
00357 $tmp_var[$attributeName] = $attributeValue[$file[1]];
00358 }
00359
00360 $fileAttributes = $tmp_var;
00361 $this->_file = $fileAttributes;
00362 } elseif( count($fileId) > 0 && isset($_FILES[$fileId])) {
00363 $this->_uploadType = self::SINGLE_STYLE;
00364 $this->_file = $_FILES[$fileId];
00365 } elseif( $fileId == '' ) {
00366 throw new Exception('Invalid parameter given. A valid $_FILES[] identifier is expected.');
00367 }
00368 }
00369 }
00370
00371 private function _createDestinationFolder($destinationFolder)
00372 {
00373 if( !$destinationFolder ) {
00374 return $this;
00375 }
00376
00377 if (substr($destinationFolder, -1) == DIRECTORY_SEPARATOR) {
00378 $destinationFolder = substr($destinationFolder, 0, -1);
00379 }
00380
00381 if (!(@is_dir($destinationFolder) || @mkdir($destinationFolder, 0777, true))) {
00382 throw new Exception("Unable to create directory '{$destinationFolder}'.");
00383 }
00384 return $this;
00385
00386 $destinationFolder = str_replace('/', DIRECTORY_SEPARATOR, $destinationFolder);
00387 $path = explode(DIRECTORY_SEPARATOR, $destinationFolder);
00388 $newPath = null;
00389 $oldPath = null;
00390 foreach( $path as $key => $directory ) {
00391 if (trim($directory)=='') {
00392 continue;
00393 }
00394 if (strlen($directory)===2 && $directory{1}===':') {
00395 $newPath = $directory;
00396 continue;
00397 }
00398 $newPath.= ( $newPath != DIRECTORY_SEPARATOR ) ? DIRECTORY_SEPARATOR . $directory : $directory;
00399 if( is_dir($newPath) ) {
00400 $oldPath = $newPath;
00401 continue;
00402 } else {
00403 if( is_writable($oldPath) ) {
00404 mkdir($newPath, 0777);
00405 } else {
00406 throw new Exception("Unable to create directory '{$newPath}'. Access forbidden.");
00407 }
00408 }
00409 $oldPath = $newPath;
00410 }
00411 return $this;
00412 }
00413
00414 static public function getNewFileName($destFile)
00415 {
00416 $fileInfo = pathinfo($destFile);
00417 if( file_exists($destFile) ) {
00418 $index = 1;
00419 $baseName = $fileInfo['filename'] . '.' . $fileInfo['extension'];
00420 while( file_exists($fileInfo['dirname'] . DIRECTORY_SEPARATOR . $baseName) ) {
00421 $baseName = $fileInfo['filename']. '_' . $index . '.' . $fileInfo['extension'];
00422 $index ++;
00423 }
00424 $destFileName = $baseName;
00425 } else {
00426 return $fileInfo['basename'];
00427 }
00428
00429 return $destFileName;
00430 }
00431
00432 static public function getDispretionPath($fileName)
00433 {
00434 $char = 0;
00435 $dispretionPath = '';
00436 while( ($char < 2) && ($char < strlen($fileName)) ) {
00437 if (empty($dispretionPath)) {
00438 $dispretionPath = DIRECTORY_SEPARATOR.('.' == $fileName[$char] ? '_' : $fileName[$char]);
00439 }
00440 else {
00441 $dispretionPath = self::_addDirSeparator($dispretionPath) . ('.' == $fileName[$char] ? '_' : $fileName[$char]);
00442 }
00443 $char ++;
00444 }
00445 return $dispretionPath;
00446 }
00447 }