[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** This file is part of KCFinder project 4 * 5 * @desc Uploader class 6 * @package KCFinder 7 * @version 2.21 8 * @author Pavel Tzonkov <[email protected]> 9 * @copyright 2010 KCFinder Project 10 * @license http://www.opensource.org/licenses/gpl-2.0.php GPLv2 11 * @license http://www.opensource.org/licenses/lgpl-2.1.php LGPLv2 12 * @link http://kcfinder.sunhater.com 13 */ 14 15 class uploader { 16 protected $config = array(); 17 protected $opener = array(); 18 protected $type; 19 protected $typeDir; 20 protected $typeURL; 21 protected $types = array(); 22 protected $typeSettings = array('disabled', 'theme', 'dirPerms', 'filePerms', 'denyZipDownload', 'maxImageWidth', 'maxImageHeight', 'thumbWidth', 'thumbHeight', 'jpegQuality'); 23 protected $charset; 24 protected $lang = 'en'; 25 protected $langInputNames = array('lang', 'langCode', 'lng', 'language', 'lang_code'); 26 protected $file; 27 protected $dateTimeFull; // Currently not used 28 protected $dateTimeMid; // Currently not used 29 protected $dateTimeSmall; 30 protected $labels = array(); 31 protected $get; 32 protected $post; 33 protected $cookie; 34 protected $session; 35 36 public function __get($property) { 37 return property_exists($this, $property) ? $this->$property : null; 38 } 39 40 public function __construct() { 41 42 // DISABLE MAGIC QUOTES 43 if (function_exists('set_magic_quotes_runtime')) 44 @set_magic_quotes_runtime(false); 45 46 // INPUT INIT 47 $input = new input(); 48 $this->get = &$input->get; 49 $this->post = &$input->post; 50 $this->cookie = &$input->cookie; 51 52 // LINKING UPLOADED FILE 53 if (count($_FILES)) 54 $this->file = &$_FILES[key($_FILES)]; 55 56 // LOAD DEFAULT CONFIGURATION 57 require "config.php"; 58 59 // SETTING UP SESSION 60 if (isset($_CONFIG['_sessionLifetime'])) 61 ini_set('session.gc_maxlifetime', $_CONFIG['_sessionLifetime'] * 60); 62 if (isset($_CONFIG['_sessionDir'])) 63 ini_set('session.save_path', $_CONFIG['_sessionDir']); 64 if (isset($_CONFIG['_sessionDomain'])) 65 ini_set('session.cookie_domain', $_CONFIG['_sessionDomain']); 66 session_start(); 67 68 // RELOAD DEFAULT CONFIGURATION 69 require "config.php"; 70 $this->config = $_CONFIG; 71 72 // LOAD SESSION CONFIGURATION IF EXISTS 73 if (isset($_CONFIG['_sessionVar']) && 74 is_array($_CONFIG['_sessionVar']) 75 ) { 76 foreach ($_CONFIG['_sessionVar'] as $key => $val) 77 if ((substr($key, 0, 1) != "_") && isset($_CONFIG[$key])) 78 $this->config[$key] = $val; 79 if (!isset($this->config['_sessionVar']['self'])) 80 $this->config['_sessionVar']['self'] = array(); 81 $this->session = &$this->config['_sessionVar']['self']; 82 } else 83 $this->session = &$_SESSION; 84 85 // GET TYPE DIRECTORY 86 $this->types = &$this->config['types']; 87 $firstType = array_keys($this->types); 88 $firstType = $firstType[0]; 89 $this->type = ( 90 isset($this->get['type']) && 91 isset($this->types[$this->get['type']]) 92 ) 93 ? $this->get['type'] : $firstType; 94 95 // LOAD DIRECTORY TYPE SPECIFIC CONFIGURATION IF EXISTS 96 if (is_array($this->types[$this->type])) { 97 foreach ($this->types[$this->type] as $key => $val) 98 if (in_array($key, $this->typeSettings)) 99 $this->config[$key] = $val; 100 $this->types[$this->type] = isset($this->types[$this->type]['type']) 101 ? $this->types[$this->type]['type'] : ""; 102 } 103 104 // COOKIES INIT 105 if (!strlen($this->config['cookieDomain'])) 106 $this->config['cookieDomain'] = $_SERVER['HTTP_HOST']; 107 if (!strlen($this->config['cookiePath'])) 108 $this->config['cookiePath'] = "/"; 109 110 // UPLOAD FOLDER INIT 111 if ($this->config['uploadURL'] == "/") { 112 $this->config['uploadDir'] = strlen($this->config['uploadDir']) 113 ? path::normalize($this->config['uploadDir']) 114 : path::normalize($_SERVER['DOCUMENT_ROOT']); 115 $this->typeDir = "{$this->config['uploadDir']}/{$this->type}"; 116 $this->typeURL = "/{$this->type}"; 117 } else { 118 $this->config['uploadURL'] = (substr($this->config['uploadURL'], 0, 1) === "/") 119 ? path::normalize($this->config['uploadURL']) 120 : path::rel2abs_url($this->config['uploadURL']); 121 $this->config['uploadDir'] = strlen($this->config['uploadDir']) 122 ? path::normalize($this->config['uploadDir']) 123 : path::url2fullPath($this->config['uploadURL']); 124 $this->typeDir = "{$this->config['uploadDir']}/{$this->type}"; 125 $this->typeURL = "{$this->config['uploadURL']}/{$this->type}"; 126 } 127 if (!is_dir($this->config['uploadDir'])) 128 @mkdir($this->config['uploadDir'], $this->config['dirPerms']); 129 130 // HOST APPLICATIONS INIT 131 if (isset($this->get['CKEditorFuncNum'])) 132 $this->opener['CKEditor']['funcNum'] = $this->get['CKEditorFuncNum']; 133 if (isset($this->get['opener']) && 134 (strtolower($this->get['opener']) == "tinymce") && 135 isset($this->config['_tinyMCEPath']) && 136 strlen($this->config['_tinyMCEPath']) 137 ) 138 $this->opener['TinyMCE'] = true; 139 140 // LOCALIZATION 141 foreach ($this->langInputNames as $key) 142 if (isset($this->get[$key]) && 143 preg_match('/^[a-z][a-z\._\-]*$/i', $this->get[$key]) && 144 file_exists("lang/" . strtolower($this->get[$key]) . ".php") 145 ) { 146 $this->lang = $this->get[$key]; 147 break; 148 } 149 $this->localize($this->lang); 150 151 // CHECK & MAKE DEFAULT .htaccess 152 $htaccess = "{$this->config['uploadDir']}/.htaccess"; 153 if (isset($this->config['_check4htaccess']) && 154 $this->config['_check4htaccess'] 155 ) { 156 if (!file_exists($htaccess)) { 157 if (!@file_put_contents($htaccess, $this->get_htaccess())) 158 $this->backMsg("Cannot write to upload folder."); 159 } else { 160 if (false === ($data = @file_get_contents($htaccess))) 161 $this->backMsg("Cannot read .htaccess"); 162 if (($data != $this->get_htaccess()) && !@file_put_contents($htaccess, $data)) 163 $this->backMsg("Incorrect .htaccess file. Cannot rewrite it!"); 164 } 165 } 166 167 // CHECK & CREATE UPLOAD FOLDER 168 if (!is_dir($this->typeDir)) { 169 if (!mkdir($this->typeDir, $this->config['dirPerms'])) 170 $this->backMsg("Cannot create {dir} folder.", array('dir' => $this->type)); 171 } elseif (!is_readable($this->typeDir)) 172 $this->backMsg("Cannot read upload folder."); 173 } 174 175 public function upload() { 176 $config = &$this->config; 177 $file = &$this->file; 178 $url = $message = ""; 179 180 if ($config['disabled'] || $config['readonly']) { 181 if (isset($file['tmp_name'])) @unlink($file['tmp_name']); 182 $message = $this->label("You don't have permissions to upload files."); 183 184 } elseif (true === ($message = $this->checkUploadedFile())) { 185 $message = ""; 186 187 $dir = "{$this->typeDir}/"; 188 if (isset($this->get['dir']) && 189 (false !== ($gdir = $this->checkInputDir($this->get['dir']))) 190 ) { 191 $udir = path::normalize("$dir$gdir"); 192 if (substr($udir, 0, strlen($dir)) !== $dir) 193 $message = $this->label("Unknown error."); 194 else { 195 $l = strlen($dir); 196 $dir = "$udir/"; 197 $udir = substr($udir, $l); 198 } 199 } 200 201 if (!strlen($message)) { 202 if (!is_dir(path::normalize($dir))) 203 @mkdir(path::normalize($dir), $this->config['dirPerms'], true); 204 205 $target = file::getInexistantFilename("$dir{$file['name']}"); 206 207 if (!@move_uploaded_file($file['tmp_name'], $target) && 208 !@rename($file['tmp_name'], $target) && 209 !@copy($file['tmp_name'], $target) 210 ) 211 $message = $this->label("Cannot move uploaded file to target folder."); 212 else { 213 if (function_exists('chmod')) 214 @chmod($target, $this->config['filePerms']); 215 $this->makeThumb($target); 216 $url = $this->typeURL; 217 if (isset($udir)) $url .= "/$udir"; 218 $url .= "/" . path::urlPathEncode(basename($target)); 219 } 220 } 221 } 222 223 if (strlen($message) && 224 isset($this->file['tmp_name']) && 225 file_exists($this->file['tmp_name']) 226 ) 227 @unlink($this->file['tmp_name']); 228 229 if (strlen($message) && method_exists($this, 'errorMsg')) 230 $this->errorMsg($message); 231 $this->callBack($url, $message); 232 } 233 234 protected function checkUploadedFile() { 235 $config = &$this->config; 236 $file = &$this->file; 237 238 if (!is_array($file) || !isset($file['name'])) 239 return $this->label("Unknown error"); 240 241 $extension = file::getExtension($file['name']); 242 $typePatt = strtolower(text::clearWhitespaces($this->types[$this->type])); 243 244 // CHECK FOR UPLOAD ERRORS 245 if ($file['error']) 246 return 247 ($file['error'] == UPLOAD_ERR_INI_SIZE) ? 248 $this->label("The uploaded file exceeds {size} bytes.", 249 array('size' => ini_get('upload_max_filesize'))) : ( 250 ($file['error'] == UPLOAD_ERR_FORM_SIZE) ? 251 $this->label("The uploaded file exceeds {size} bytes.", 252 array('size' => $this->get['MAX_FILE_SIZE'])) : ( 253 ($file['error'] == UPLOAD_ERR_PARTIAL) ? 254 $this->label("The uploaded file was only partially uploaded.") : ( 255 ($file['error'] == UPLOAD_ERR_NO_FILE) ? 256 $this->label("No file was uploaded.") : ( 257 ($file['error'] == UPLOAD_ERR_NO_TMP_DIR) ? 258 $this->label("Missing a temporary folder.") : ( 259 ($file['error'] == UPLOAD_ERR_CANT_WRITE) ? 260 $this->label("Failed to write file.") : 261 $this->label("Unknown error.") 262 ))))); 263 264 // HIDDEN FILENAMES CHECK 265 elseif (substr($file['name'], 0, 1) == ".") 266 return $this->label("File name shouldn't begins with '.'"); 267 268 // EXTENSION CHECK 269 elseif (!$this->validateExtension($extension, $this->type)) 270 return $this->label("Denied file extension."); 271 272 // SPECIAL DIRECTORY TYPES CHECK (e.g. *img) 273 elseif (preg_match('/^\*([^ ]+)(.*)?$/s', $typePatt, $patt)) { 274 list($typePatt, $type, $params) = $patt; 275 if (class_exists("type_$type")) { 276 $class = "type_$type"; 277 $type = new $class(); 278 $cfg = $config; 279 if (strlen($params)) 280 $cfg['params'] = trim($params); 281 $response = $type->checkFile($file['tmp_name'], $cfg); 282 if ($response !== true) 283 return $this->label($response); 284 } else 285 return $this->label("Non-existing directory type."); 286 } 287 288 // IMAGE RESIZE 289 $gd = new gd($file['tmp_name']); 290 if (!$gd->init_error && !$this->imageResize($gd, $file['tmp_name'])) 291 return $this->label("The image is too big and/or cannot be resized."); 292 293 return true; 294 } 295 296 protected function checkInputDir($dir, $inclType=true, $existing=true) { 297 $dir = path::normalize($dir); 298 if (substr($dir, 0, 1) == "/") 299 $dir = substr($dir, 1); 300 301 if ((substr($dir, 0, 1) == ".") || (substr(basename($dir), 0, 1) == ".")) 302 return false; 303 304 if ($inclType) { 305 $first = explode("/", $dir); 306 $first = $first[0]; 307 if ($first != $this->type) 308 return false; 309 $return = $this->removeTypeFromPath($dir); 310 } else { 311 $return = $dir; 312 $dir = "{$this->type}/$dir"; 313 } 314 315 if (!$existing) 316 return $return; 317 318 $path = "{$this->config['uploadDir']}/$dir"; 319 return (is_dir($path) && is_readable($path)) ? $return : false; 320 } 321 322 protected function validateExtension($ext, $type) { 323 $ext = trim(strtolower($ext)); 324 if (!isset($this->types[$type])) 325 return false; 326 327 $exts = strtolower(text::clearWhitespaces($this->config['deniedExts'])); 328 if (strlen($exts)) { 329 $exts = explode(" ", $exts); 330 if (in_array($ext, $exts)) 331 return false; 332 } 333 334 $exts = trim($this->types[$type]); 335 if (!strlen($exts) || substr($exts, 0, 1) == "*") 336 return true; 337 338 if (substr($exts, 0, 1) == "!") { 339 $exts = explode(" ", trim(strtolower(substr($exts, 1)))); 340 return !in_array($ext, $exts); 341 } 342 343 $exts = explode(" ", trim(strtolower($exts))); 344 return in_array($ext, $exts); 345 } 346 347 protected function getTypeFromPath($path) { 348 return preg_match('/^([^\/]*)\/.*$/', $path, $patt) 349 ? $patt[1] : $path; 350 } 351 352 protected function removeTypeFromPath($path) { 353 return preg_match('/^[^\/]*\/(.*)$/', $path, $patt) 354 ? $patt[1] : ""; 355 } 356 357 protected function imageResize($image, $file=null) { 358 if (!($image instanceof gd)) { 359 $gd = new gd($image); 360 if ($gd->init_error) return false; 361 $file = $image; 362 } elseif ($file === null) 363 return false; 364 else 365 $gd = $image; 366 367 if ((!$this->config['maxImageWidth'] && !$this->config['maxImageHeight']) || 368 ( 369 ($gd->get_width() <= $this->config['maxImageWidth']) && 370 ($gd->get_height() <= $this->config['maxImageHeight']) 371 ) 372 ) 373 return true; 374 375 return ( 376 $gd->resize_fit($this->config['maxImageWidth'], $this->config['maxImageHeight']) && 377 $gd->imagejpeg($file, $this->config['jpegQuality']) 378 ); 379 } 380 381 protected function makeThumb($file, $overwrite=true) { 382 $gd = new gd($file); 383 384 // Drop files which are not GD handled images 385 if ($gd->init_error) 386 return true; 387 388 $thumb = substr($file, strlen($this->config['uploadDir'])); 389 $thumb = $this->config['uploadDir'] . "/" . $this->config['thumbsDir'] . "/" . $thumb; 390 $thumb = path::normalize($thumb); 391 $thumbDir = dirname($thumb); 392 if (!is_dir($thumbDir) && !@mkdir($thumbDir, $this->config['dirPerms'], true)) 393 return false; 394 395 if (!$overwrite && is_file($thumb)) 396 return true; 397 398 // Images with smaller resolutions than thumbnails 399 if (($gd->get_width() <= $this->config['thumbWidth']) && 400 ($gd->get_height() <= $this->config['thumbHeight']) 401 ) { 402 $browsable = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_JPEG2000, IMAGETYPE_PNG); 403 // Drop only browsable types 404 if (in_array($gd->type, $browsable)) 405 return true; 406 407 // Resize image 408 } elseif (!$gd->resize_fit($this->config['thumbWidth'], $this->config['thumbHeight'])) 409 return false; 410 411 // Save thumbnail 412 return $gd->imagejpeg($thumb, $this->config['jpegQuality']); 413 } 414 415 protected function localize($langCode) { 416 require "lang/{$langCode}.php"; 417 setlocale(LC_ALL, $lang['_locale']); 418 $this->charset = $lang['_charset']; 419 $this->dateTimeFull = $lang['_dateTimeFull']; 420 $this->dateTimeMid = $lang['_dateTimeMid']; 421 $this->dateTimeSmall = $lang['_dateTimeSmall']; 422 unset($lang['_locale']); 423 unset($lang['_charset']); 424 unset($lang['_dateTimeFull']); 425 unset($lang['_dateTimeMid']); 426 unset($lang['_dateTimeSmall']); 427 $this->labels = $lang; 428 } 429 430 protected function label($string, array $data=null) { 431 $return = isset($this->labels[$string]) ? $this->labels[$string] : $string; 432 if (is_array($data)) 433 foreach ($data as $key => $val) 434 $return = str_replace("{{$key}}", $val, $return); 435 return $return; 436 } 437 438 protected function backMsg($message, array $data=null) { 439 $message = $this->label($message, $data); 440 if (isset($this->file['tmp_name']) && file_exists($this->file['tmp_name'])) 441 @unlink($this->file['tmp_name']); 442 $this->callBack("", $message); 443 die; 444 } 445 446 protected function callBack($url, $message="") { 447 $message = text::jsValue($message); 448 $CKfuncNum = isset($this->opener['CKEditor']['funcNum']) 449 ? $this->opener['CKEditor']['funcNum'] : 0; 450 if (!$CKfuncNum) $CKfuncNum = 0; 451 header("Content-Type: text/html; charset={$this->charset}"); 452 453 ?><html> 454 <body> 455 <script type='text/javascript'> 456 var kc_CKEditor = (window.parent && window.parent.CKEDITOR) 457 ? window.parent.CKEDITOR.tools.callFunction 458 : ((window.opener && window.opener.CKEDITOR) 459 ? window.opener.CKEDITOR.tools.callFunction 460 : false); 461 var kc_FCKeditor = (window.opener && window.opener.OnUploadCompleted) 462 ? window.opener.OnUploadCompleted 463 : ((window.parent && window.parent.OnUploadCompleted) 464 ? window.parent.OnUploadCompleted 465 : false); 466 var kc_Custom = (window.parent && window.parent.KCFinder) 467 ? window.parent.KCFinder.callBack 468 : ((window.opener && window.opener.KCFinder) 469 ? window.opener.KCFinder.callBack 470 : false); 471 if (kc_CKEditor) 472 kc_CKEditor(<?php echo $CKfuncNum ?>, '<?php echo $url ?>', '<?php echo $message ?>'); 473 if (kc_FCKeditor) 474 kc_FCKeditor(<?php echo strlen($message) ? 1 : 0 ?>, '<?php echo $url ?>', '', '<?php echo $message ?>'); 475 if (kc_Custom) { 476 if (<?php echo strlen($message) ?>) alert('<?php echo $message ?>'); 477 kc_Custom('<?php echo $url ?>'); 478 } 479 if (!kc_CKEditor && !kc_FCKeditor && !kc_Custom) 480 alert("<?php echo $message ?>"); 481 </script> 482 </body> 483 </html><?php 484 485 } 486 487 protected function get_htaccess() { 488 return "<IfModule mod_php4.c> 489 php_value engine off 490 </IfModule> 491 <IfModule mod_php5.c> 492 php_value engine off 493 </IfModule> 494 "; 495 } 496 } 497 498 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |