[ Index ] |
PHP Cross Reference of MyBB 1.8.38 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.8 4 * Copyright 2014 MyBB Group, All Rights Reserved 5 * 6 * Website: http://www.mybb.com 7 * License: http://www.mybb.com/about/license 8 * 9 */ 10 11 /** 12 * Get maximum upload filesize limit set in PHP 13 * @since MyBB 1.8.27 14 * @return int maximum allowed filesize 15 */ 16 function get_php_upload_limit() 17 { 18 $maxsize = array(return_bytes(ini_get('upload_max_filesize')), return_bytes(ini_get('post_max_size'))); 19 $maxsize = array_filter($maxsize); // Remove empty values 20 21 if(empty($maxsize)) 22 { 23 return 0; 24 } 25 else 26 { 27 return (int)min($maxsize); 28 } 29 } 30 31 /** 32 * Remove an attachment from a specific post 33 * 34 * @param int $pid The post ID 35 * @param string $posthash The posthash if available 36 * @param int $aid The attachment ID 37 */ 38 function remove_attachment($pid, $posthash, $aid) 39 { 40 global $db, $mybb, $plugins; 41 $aid = (int)$aid; 42 $posthash = $db->escape_string($posthash); 43 if(!empty($posthash)) 44 { 45 $query = $db->simple_select("attachments", "aid, attachname, thumbnail, visible", "aid='{$aid}' AND posthash='{$posthash}'"); 46 $attachment = $db->fetch_array($query); 47 } 48 else 49 { 50 $query = $db->simple_select("attachments", "aid, attachname, thumbnail, visible", "aid='{$aid}' AND pid='{$pid}'"); 51 $attachment = $db->fetch_array($query); 52 } 53 54 $plugins->run_hooks("remove_attachment_do_delete", $attachment); 55 56 if($attachment === false) 57 { 58 // no attachment found with the given details 59 return; 60 } 61 62 $db->delete_query("attachments", "aid='{$attachment['aid']}'"); 63 64 $uploadspath_abs = mk_path_abs($mybb->settings['uploadspath']); 65 66 // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file. 67 $query = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='".$db->escape_string($attachment['attachname'])."'"); 68 if($db->fetch_field($query, "numreferences") == 0) 69 { 70 delete_uploaded_file($uploadspath_abs."/".$attachment['attachname']); 71 if($attachment['thumbnail'] && $attachment['thumbnail'] !== 'SMALL') 72 { 73 delete_uploaded_file($uploadspath_abs."/".$attachment['thumbnail']); 74 } 75 76 $date_directory = explode('/', $attachment['attachname']); 77 $query_indir = $db->simple_select("attachments", "COUNT(aid) as indir", "attachname LIKE '".$db->escape_string_like($date_directory[0])."/%'"); 78 if($db->fetch_field($query_indir, 'indir') == 0 && @is_dir($uploadspath_abs."/".$date_directory[0])) 79 { 80 delete_upload_directory($uploadspath_abs."/".$date_directory[0]); 81 } 82 } 83 84 if($attachment['visible'] == 1 && $pid) 85 { 86 $post = get_post($pid); 87 update_thread_counters($post['tid'], array("attachmentcount" => "-1")); 88 } 89 } 90 91 /** 92 * Remove all of the attachments from a specific post 93 * 94 * @param int $pid The post ID 95 * @param string $posthash The posthash if available 96 */ 97 function remove_attachments($pid, $posthash="") 98 { 99 global $db, $mybb, $plugins; 100 101 if($pid) 102 { 103 $post = get_post($pid); 104 } 105 $posthash = $db->escape_string($posthash); 106 if($posthash != "" && !$pid) 107 { 108 $query = $db->simple_select("attachments", "*", "posthash='$posthash'"); 109 } 110 else 111 { 112 $query = $db->simple_select("attachments", "*", "pid='$pid'"); 113 } 114 115 $uploadspath_abs = mk_path_abs($mybb->settings['uploadspath']); 116 117 $num_attachments = 0; 118 while($attachment = $db->fetch_array($query)) 119 { 120 if($attachment['visible'] == 1) 121 { 122 $num_attachments++; 123 } 124 125 $plugins->run_hooks("remove_attachments_do_delete", $attachment); 126 127 $db->delete_query("attachments", "aid='".$attachment['aid']."'"); 128 129 // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file. 130 $query2 = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='".$db->escape_string($attachment['attachname'])."'"); 131 if($db->fetch_field($query2, "numreferences") == 0) 132 { 133 delete_uploaded_file($uploadspath_abs."/".$attachment['attachname']); 134 if($attachment['thumbnail']) 135 { 136 delete_uploaded_file($uploadspath_abs."/".$attachment['thumbnail']); 137 } 138 139 $date_directory = explode('/', $attachment['attachname']); 140 $query_indir = $db->simple_select("attachments", "COUNT(aid) as indir", "attachname LIKE '".$db->escape_string_like($date_directory[0])."/%'"); 141 if($db->fetch_field($query_indir, 'indir') == 0 && @is_dir($uploadspath_abs."/".$date_directory[0])) 142 { 143 delete_upload_directory($uploadspath_abs."/".$date_directory[0]); 144 } 145 } 146 } 147 148 if($post['tid']) 149 { 150 update_thread_counters($post['tid'], array("attachmentcount" => "-{$num_attachments}")); 151 } 152 } 153 154 /** 155 * Remove any matching avatars for a specific user ID 156 * 157 * @param int $uid The user ID 158 * @param string $exclude A file name to be excluded from the removal 159 */ 160 function remove_avatars($uid, $exclude="") 161 { 162 global $mybb, $plugins; 163 164 if(defined('IN_ADMINCP')) 165 { 166 $avatarpath = '../'.$mybb->settings['avataruploadpath']; 167 } 168 else 169 { 170 $avatarpath = $mybb->settings['avataruploadpath']; 171 } 172 173 $dir = opendir($avatarpath); 174 if($dir) 175 { 176 while($file = @readdir($dir)) 177 { 178 $plugins->run_hooks("remove_avatars_do_delete", $file); 179 180 if(preg_match("#avatar_".$uid."\.#", $file) && is_file($avatarpath."/".$file) && $file != $exclude) 181 { 182 delete_uploaded_file($avatarpath."/".$file); 183 } 184 } 185 186 @closedir($dir); 187 } 188 } 189 190 /** 191 * Create the attachment directory index file. 192 * 193 * @param string $path The path to the attachment directory to create the file in. 194 */ 195 function create_attachment_index($path) 196 { 197 $index = @fopen(rtrim($path, '/').'/index.html', 'w'); 198 @fwrite($index, '<html>\n<head>\n<title></title>\n</head>\n<body>\n \n</body>\n</html>'); 199 @fclose($index); 200 } 201 202 /** 203 * Upload a new avatar in to the file system 204 * 205 * @param array $avatar Incoming FILE array, if we have one - otherwise takes $_FILES['avatarupload'] 206 * @param int $uid User ID this avatar is being uploaded for, if not the current user 207 * @return array Array of errors if any, otherwise filename of successful. 208 */ 209 function upload_avatar($avatar=array(), $uid=0) 210 { 211 global $db, $mybb, $lang, $plugins, $cache; 212 213 $ret = array(); 214 215 if(!$uid) 216 { 217 $uid = $mybb->user['uid']; 218 } 219 220 if(empty($avatar['name']) || empty($avatar['tmp_name'])) 221 { 222 $avatar = $_FILES['avatarupload']; 223 } 224 225 if(!is_uploaded_file($avatar['tmp_name'])) 226 { 227 $ret['error'] = $lang->error_uploadfailed; 228 return $ret; 229 } 230 231 // Check we have a valid extension 232 $ext = get_extension(my_strtolower($avatar['name'])); 233 if(!preg_match("#^(gif|jpg|jpeg|jpe|bmp|png)$#i", $ext)) 234 { 235 $ret['error'] = $lang->error_avatartype; 236 return $ret; 237 } 238 239 if(defined('IN_ADMINCP')) 240 { 241 $avatarpath = '../'.$mybb->settings['avataruploadpath']; 242 $lang->load("messages", true); 243 } 244 else 245 { 246 $avatarpath = $mybb->settings['avataruploadpath']; 247 } 248 249 $filename = "avatar_".$uid.".".$ext; 250 $file = upload_file($avatar, $avatarpath, $filename); 251 if(!empty($file['error'])) 252 { 253 delete_uploaded_file($avatarpath."/".$filename); 254 $ret['error'] = $lang->error_uploadfailed; 255 return $ret; 256 } 257 258 // Lets just double check that it exists 259 if(!file_exists($avatarpath."/".$filename)) 260 { 261 $ret['error'] = $lang->error_uploadfailed; 262 delete_uploaded_file($avatarpath."/".$filename); 263 return $ret; 264 } 265 266 // Check if this is a valid image or not 267 $img_dimensions = @getimagesize($avatarpath."/".$filename); 268 if(!is_array($img_dimensions)) 269 { 270 delete_uploaded_file($avatarpath."/".$filename); 271 $ret['error'] = $lang->error_uploadfailed; 272 return $ret; 273 } 274 275 // Check avatar dimensions 276 if($mybb->settings['maxavatardims'] != '') 277 { 278 list($maxwidth, $maxheight) = @preg_split('/[|x]/', $mybb->settings['maxavatardims']); 279 if(($maxwidth && $img_dimensions[0] > $maxwidth) || ($maxheight && $img_dimensions[1] > $maxheight)) 280 { 281 // Automatic resizing enabled? 282 if($mybb->settings['avatarresizing'] == "auto" || ($mybb->settings['avatarresizing'] == "user" && $mybb->input['auto_resize'] == 1)) 283 { 284 require_once MYBB_ROOT."inc/functions_image.php"; 285 $thumbnail = generate_thumbnail($avatarpath."/".$filename, $avatarpath, $filename, $maxheight, $maxwidth); 286 if(empty($thumbnail['filename'])) 287 { 288 $ret['error'] = $lang->sprintf($lang->error_avatartoobig, $maxwidth, $maxheight); 289 $ret['error'] .= "<br /><br />".$lang->error_avatarresizefailed; 290 delete_uploaded_file($avatarpath."/".$filename); 291 return $ret; 292 } 293 else 294 { 295 // Copy scaled image to CDN 296 copy_file_to_cdn($avatarpath . '/' . $thumbnail['filename']); 297 // Reset filesize 298 $avatar['size'] = filesize($avatarpath."/".$filename); 299 // Reset dimensions 300 $img_dimensions = @getimagesize($avatarpath."/".$filename); 301 } 302 } 303 else 304 { 305 $ret['error'] = $lang->sprintf($lang->error_avatartoobig, $maxwidth, $maxheight); 306 if($mybb->settings['avatarresizing'] == "user") 307 { 308 $ret['error'] .= "<br /><br />".$lang->error_avataruserresize; 309 } 310 delete_uploaded_file($avatarpath."/".$filename); 311 return $ret; 312 } 313 } 314 } 315 316 // Check a list of known MIME types to establish what kind of avatar we're uploading 317 $attachtypes = (array)$cache->read('attachtypes'); 318 319 $allowed_mime_types = array(); 320 foreach($attachtypes as $attachtype) 321 { 322 if(defined('IN_ADMINCP') || is_member($attachtype['groups']) && $attachtype['avatarfile']) 323 { 324 $allowed_mime_types[$attachtype['mimetype']] = $attachtype['maxsize']; 325 } 326 } 327 328 $avatar['type'] = my_strtolower($avatar['type']); 329 330 switch($avatar['type']) 331 { 332 case "image/gif": 333 $img_type = 1; 334 break; 335 case "image/jpeg": 336 case "image/x-jpg": 337 case "image/x-jpeg": 338 case "image/pjpeg": 339 case "image/jpg": 340 $img_type = 2; 341 break; 342 case "image/png": 343 case "image/x-png": 344 $img_type = 3; 345 break; 346 case "image/bmp": 347 case "image/x-bmp": 348 case "image/x-windows-bmp": 349 $img_type = 6; 350 break; 351 default: 352 $img_type = 0; 353 } 354 355 // Check if the uploaded file type matches the correct image type (returned by getimagesize) 356 if(empty($allowed_mime_types[$avatar['type']]) || $img_dimensions[2] != $img_type || $img_type == 0) 357 { 358 $ret['error'] = $lang->error_uploadfailed; 359 delete_uploaded_file($avatarpath."/".$filename); 360 return $ret; 361 } 362 363 // Next check the file size 364 if(($mybb->settings['avatarsize'] > 0 && $avatar['size'] > ($mybb->settings['avatarsize']*1024)) || $avatar['size'] > ($allowed_mime_types[$avatar['type']]*1024)) 365 { 366 delete_uploaded_file($avatarpath."/".$filename); 367 $ret['error'] = $lang->error_uploadsize; 368 return $ret; 369 } 370 371 // Everything is okay so lets delete old avatars for this user 372 remove_avatars($uid, $filename); 373 374 $ret = array( 375 "avatar" => $mybb->settings['avataruploadpath']."/".$filename, 376 "width" => (int)$img_dimensions[0], 377 "height" => (int)$img_dimensions[1] 378 ); 379 $ret = $plugins->run_hooks("upload_avatar_end", $ret); 380 return $ret; 381 } 382 383 /** 384 * Upload an attachment in to the file system 385 * 386 * @param array $attachment Attachment data (as fed by PHPs $_FILE) 387 * @param boolean $update_attachment Whether or not we are updating a current attachment or inserting a new one 388 * @return array Array of attachment data if successful, otherwise array of error data 389 */ 390 function upload_attachment($attachment, $update_attachment=false) 391 { 392 global $mybb, $db, $theme, $templates, $posthash, $pid, $tid, $forum, $mybb, $lang, $plugins, $cache; 393 394 $posthash = $db->escape_string($mybb->get_input('posthash')); 395 $pid = (int)$pid; 396 397 if(!is_uploaded_file($attachment['tmp_name']) || empty($attachment['tmp_name'])) 398 { 399 $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_php4; 400 return $ret; 401 } 402 403 $attachtypes = (array)$cache->read('attachtypes'); 404 $attachment = $plugins->run_hooks("upload_attachment_start", $attachment); 405 406 $allowed_mime_types = array(); 407 foreach($attachtypes as $ext => $attachtype) 408 { 409 if(!is_member($attachtype['groups']) || ($attachtype['forums'] != -1 && strpos(','.$attachtype['forums'].',', ','.$forum['fid'].',') === false)) 410 { 411 unset($attachtypes[$ext]); 412 } 413 } 414 415 $ext = get_extension($attachment['name']); 416 // Check if we have a valid extension 417 if(!isset($attachtypes[$ext])) 418 { 419 $ret['error'] = $lang->error_attachtype; 420 return $ret; 421 } 422 else 423 { 424 $attachtype = $attachtypes[$ext]; 425 } 426 427 // check the length of the filename 428 $maxFileNameLength = 255; 429 if(my_strlen($attachment['name']) > $maxFileNameLength) 430 { 431 $ret['error'] = $lang->sprintf($lang->error_attach_filename_length, htmlspecialchars_uni($attachment['name']), $maxFileNameLength); 432 return $ret; 433 } 434 435 // Check the size 436 if($attachment['size'] > $attachtype['maxsize']*1024 && $attachtype['maxsize'] != "") 437 { 438 $ret['error'] = $lang->sprintf($lang->error_attachsize, htmlspecialchars_uni($attachment['name']), $attachtype['maxsize']); 439 return $ret; 440 } 441 442 // Double check attachment space usage 443 if($mybb->usergroup['attachquota'] > 0) 444 { 445 $query = $db->simple_select("attachments", "SUM(filesize) AS ausage", "uid='".$mybb->user['uid']."'"); 446 $usage = $db->fetch_array($query); 447 $usage = $usage['ausage']+$attachment['size']; 448 if($usage > ($mybb->usergroup['attachquota']*1024)) 449 { 450 $friendlyquota = get_friendly_size($mybb->usergroup['attachquota']*1024); 451 $ret['error'] = $lang->sprintf($lang->error_reachedattachquota, $friendlyquota); 452 return $ret; 453 } 454 } 455 456 // Gather forum permissions 457 $forumpermissions = forum_permissions($forum['fid']); 458 459 // Check if an attachment with this name is already in the post 460 if($pid != 0) 461 { 462 $uploaded_query = "pid='{$pid}'"; 463 } 464 else 465 { 466 $uploaded_query = "posthash='{$posthash}'"; 467 } 468 $query = $db->simple_select("attachments", "*", "filename='".$db->escape_string($attachment['name'])."' AND ".$uploaded_query); 469 $prevattach = $db->fetch_array($query); 470 if($prevattach && $update_attachment == false) 471 { 472 if(!$mybb->usergroup['caneditattachments'] && !$forumpermissions['caneditattachments']) 473 { 474 $ret['error'] = $lang->error_alreadyuploaded_perm; 475 return $ret; 476 } 477 478 $ret['error'] = $lang->sprintf($lang->error_alreadyuploaded, htmlspecialchars_uni($attachment['name'])); 479 return $ret; 480 } 481 482 // Check to see how many attachments exist for this post already 483 if($mybb->settings['maxattachments'] > 0 && $update_attachment == false) 484 { 485 $query = $db->simple_select("attachments", "COUNT(aid) AS numattachs", $uploaded_query); 486 $attachcount = $db->fetch_field($query, "numattachs"); 487 if($attachcount >= $mybb->settings['maxattachments']) 488 { 489 $ret['error'] = $lang->sprintf($lang->error_maxattachpost, $mybb->settings['maxattachments']); 490 return $ret; 491 } 492 } 493 494 $uploadspath_abs = mk_path_abs($mybb->settings['uploadspath']); 495 $month_dir = ''; 496 if($mybb->safemode == false) 497 { 498 // Check if the attachment directory (YYYYMM) exists, if not, create it 499 $month_dir = gmdate("Ym"); 500 if(!@is_dir($uploadspath_abs."/".$month_dir)) 501 { 502 @mkdir($uploadspath_abs."/".$month_dir); 503 // Still doesn't exist - oh well, throw it in the main directory 504 if(!@is_dir($uploadspath_abs."/".$month_dir)) 505 { 506 $month_dir = ''; 507 } 508 else 509 { 510 create_attachment_index($uploadspath_abs."/".$month_dir); 511 } 512 } 513 } 514 515 // All seems to be good, lets move the attachment! 516 $filename = "post_".$mybb->user['uid']."_".TIME_NOW."_".md5(random_str()).".attach"; 517 518 $file = upload_file($attachment, $uploadspath_abs."/".$month_dir, $filename); 519 520 // Failed to create the attachment in the monthly directory, just throw it in the main directory 521 if(!empty($file['error']) && $month_dir) 522 { 523 $file = upload_file($attachment, $uploadspath_abs.'/', $filename); 524 } 525 elseif($month_dir) 526 { 527 $filename = $month_dir."/".$filename; 528 } 529 530 if(!empty($file['error'])) 531 { 532 $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_detail; 533 switch($file['error']) 534 { 535 case 1: 536 $ret['error'] .= $lang->error_uploadfailed_nothingtomove; 537 break; 538 case 2: 539 $ret['error'] .= $lang->error_uploadfailed_movefailed; 540 break; 541 } 542 return $ret; 543 } 544 545 // Lets just double check that it exists 546 if(!file_exists($uploadspath_abs."/".$filename)) 547 { 548 $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_detail.$lang->error_uploadfailed_lost; 549 return $ret; 550 } 551 552 // Generate the array for the insert_query 553 $attacharray = array( 554 "pid" => $pid, 555 "posthash" => $posthash, 556 "uid" => $mybb->user['uid'], 557 "filename" => $db->escape_string($file['original_filename']), 558 "filetype" => $db->escape_string($file['type']), 559 "filesize" => (int)$file['size'], 560 "attachname" => $filename, 561 "downloads" => 0, 562 "dateuploaded" => TIME_NOW 563 ); 564 565 // If we're uploading an image, check the MIME type compared to the image type and attempt to generate a thumbnail 566 if($ext == "gif" || $ext == "png" || $ext == "jpg" || $ext == "jpeg" || $ext == "jpe") 567 { 568 // Check a list of known MIME types to establish what kind of image we're uploading 569 switch(my_strtolower($file['type'])) 570 { 571 case "image/gif": 572 $img_type = 1; 573 break; 574 case "image/jpeg": 575 case "image/x-jpg": 576 case "image/x-jpeg": 577 case "image/pjpeg": 578 case "image/jpg": 579 $img_type = 2; 580 break; 581 case "image/png": 582 case "image/x-png": 583 $img_type = 3; 584 break; 585 default: 586 $img_type = 0; 587 } 588 589 $supported_mimes = array(); 590 foreach($attachtypes as $attachtype) 591 { 592 if(!empty($attachtype['mimetype'])) 593 { 594 $supported_mimes[] = $attachtype['mimetype']; 595 } 596 } 597 598 // Check if the uploaded file type matches the correct image type (returned by getimagesize) 599 $img_dimensions = @getimagesize($uploadspath_abs."/".$filename); 600 601 $mime = ""; 602 $file_path = $uploadspath_abs."/".$filename; 603 if(function_exists("finfo_open")) 604 { 605 $file_info = finfo_open(FILEINFO_MIME); 606 list($mime, ) = explode(';', finfo_file($file_info, $file_path), 1); 607 finfo_close($file_info); 608 } 609 else if(function_exists("mime_content_type")) 610 { 611 $mime = mime_content_type($file_path); 612 } 613 614 if(!is_array($img_dimensions) || ($img_dimensions[2] != $img_type && !in_array($mime, $supported_mimes))) 615 { 616 delete_uploaded_file($uploadspath_abs."/".$filename); 617 $ret['error'] = $lang->error_uploadfailed; 618 return $ret; 619 } 620 require_once MYBB_ROOT."inc/functions_image.php"; 621 $thumbname = str_replace(".attach", "_thumb.$ext", $filename); 622 623 $attacharray = $plugins->run_hooks("upload_attachment_thumb_start", $attacharray); 624 625 $thumbnail = generate_thumbnail($uploadspath_abs."/".$filename, $uploadspath_abs, $thumbname, $mybb->settings['attachthumbh'], $mybb->settings['attachthumbw']); 626 627 if(!empty($thumbnail['filename'])) 628 { 629 $attacharray['thumbnail'] = $thumbnail['filename']; 630 } 631 elseif($thumbnail['code'] == 4) 632 { 633 $attacharray['thumbnail'] = "SMALL"; 634 } 635 } 636 if($forumpermissions['modattachments'] == 1 && !is_moderator($forum['fid'], "canapproveunapproveattachs")) 637 { 638 $attacharray['visible'] = 0; 639 } 640 else 641 { 642 $attacharray['visible'] = 1; 643 } 644 645 $attacharray = $plugins->run_hooks("upload_attachment_do_insert", $attacharray); 646 647 if($prevattach && $update_attachment == true) 648 { 649 unset($attacharray['downloads']); // Keep our download count if we're updating an attachment 650 $db->update_query("attachments", $attacharray, "aid='".$db->escape_string($prevattach['aid'])."'"); 651 652 // Remove old attachment file 653 // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file. 654 $query = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='".$db->escape_string($prevattach['attachname'])."'"); 655 if($db->fetch_field($query, "numreferences") == 0) 656 { 657 delete_uploaded_file($uploadspath_abs."/".$prevattach['attachname']); 658 if($prevattach['thumbnail']) 659 { 660 delete_uploaded_file($uploadspath_abs."/".$prevattach['thumbnail']); 661 } 662 663 $date_directory = explode('/', $prevattach['attachname']); 664 $query_indir = $db->simple_select("attachments", "COUNT(aid) as indir", "attachname LIKE '".$db->escape_string_like($date_directory[0])."/%'"); 665 if($db->fetch_field($query_indir, 'indir') == 0 && @is_dir($uploadspath_abs."/".$date_directory[0])) 666 { 667 delete_upload_directory($uploadspath_abs."/".$date_directory[0]); 668 } 669 } 670 671 $aid = $prevattach['aid']; 672 } 673 else 674 { 675 $aid = $db->insert_query("attachments", $attacharray); 676 if($pid) 677 { 678 update_thread_counters($tid, array("attachmentcount" => "+1")); 679 } 680 } 681 $ret['aid'] = $aid; 682 return $ret; 683 } 684 685 /** 686 * Check whether the input $FILE variable indicates a PHP file upload error, 687 * and if so, return an appropriate user-friendly error message. 688 * 689 * @param array $FILE File data (as fed by PHP's $_FILE). 690 * 691 * @return string Error message or empty if no error detected. 692 */ 693 function check_parse_php_upload_err($FILE) 694 { 695 global $lang; 696 697 $err = ''; 698 699 if(isset($FILE['error']) && $FILE['error'] != 0 && ($FILE['error'] != UPLOAD_ERR_NO_FILE || $FILE['name'])) 700 { 701 $err = $lang->error_uploadfailed.$lang->error_uploadfailed_detail; 702 switch($FILE['error']) 703 { 704 case 1: // UPLOAD_ERR_INI_SIZE 705 $err .= $lang->error_uploadfailed_php1; 706 break; 707 case 2: // UPLOAD_ERR_FORM_SIZE 708 $err .= $lang->error_uploadfailed_php2; 709 break; 710 case 3: // UPLOAD_ERR_PARTIAL 711 $err .= $lang->error_uploadfailed_php3; 712 break; 713 case 4: // UPLOAD_ERR_NO_FILE 714 $err .= $lang->error_uploadfailed_php4; 715 break; 716 case 6: // UPLOAD_ERR_NO_TMP_DIR 717 $err .= $lang->error_uploadfailed_php6; 718 break; 719 case 7: // UPLOAD_ERR_CANT_WRITE 720 $err .= $lang->error_uploadfailed_php7; 721 break; 722 default: 723 $err .= $lang->sprintf($lang->error_uploadfailed_phpx, $FILE['error']); 724 break; 725 } 726 } 727 728 return $err; 729 } 730 731 /** 732 * Process adding attachment(s) when the "Add Attachment" button is pressed. 733 * 734 * @param int $pid The ID of the post. 735 * @param array $forumpermission The permissions for the forum. 736 * @param string $attachwhere Search string "pid='$pid'" or "posthash='".$db->escape_string($mybb->get_input('posthash'))."'" 737 * @param string $action Where called from: "newthread", "newreply", or "editpost" 738 * 739 * @return array Array of errors if any, empty array otherwise 740 */ 741 function add_attachments($pid, $forumpermissions, $attachwhere, $action=false) 742 { 743 global $db, $mybb, $editdraftpid, $lang; 744 745 $ret = array(); 746 747 if($forumpermissions['canpostattachments']) 748 { 749 $attachments = array(); 750 $fields = array ('name', 'type', 'tmp_name', 'error', 'size'); 751 $aid = array(); 752 753 $total = isset($_FILES['attachments']['name']) ? count($_FILES['attachments']['name']) : 0; 754 $filenames = ""; 755 $delim = ""; 756 for($i=0; $i<$total; ++$i) 757 { 758 foreach($fields as $field) 759 { 760 $attachments[$i][$field] = $_FILES['attachments'][$field][$i]; 761 } 762 763 $FILE = $attachments[$i]; 764 if(!empty($FILE['name']) && !empty($FILE['type']) && $FILE['size'] > 0) 765 { 766 $filenames .= $delim . "'" . $db->escape_string($FILE['name']) . "'"; 767 $delim = ","; 768 } 769 } 770 771 if ($filenames != '') 772 { 773 $query = $db->simple_select("attachments", "filename", "{$attachwhere} AND filename IN (".$filenames.")"); 774 775 while ($row = $db->fetch_array($query)) 776 { 777 $aid[$row['filename']] = true; 778 } 779 } 780 781 foreach($attachments as $FILE) 782 { 783 if($err = check_parse_php_upload_err($FILE)) 784 { 785 $ret['errors'][] = $err; 786 $mybb->input['action'] = $action; 787 } 788 else if(!empty($FILE['name']) && !empty($FILE['type'])) 789 { 790 if($FILE['size'] > 0) 791 { 792 $filename = $db->escape_string($FILE['name']); 793 $exists = !empty($aid[$filename]); 794 795 $update_attachment = false; 796 if($action == "editpost") 797 { 798 if($exists && $mybb->get_input('updateattachment') && ($mybb->usergroup['caneditattachments'] || $forumpermissions['caneditattachments'])) 799 { 800 $update_attachment = true; 801 } 802 } 803 else 804 { 805 if($exists && $mybb->get_input('updateattachment')) 806 { 807 $update_attachment = true; 808 } 809 } 810 811 if(!$exists && $mybb->get_input('updateattachment') && $mybb->get_input('updateconfirmed', MyBB::INPUT_INT) != 1) 812 { 813 $ret['errors'][] = $lang->sprintf($lang->error_updatefailed, $filename); 814 } 815 else 816 { 817 $attachedfile = upload_attachment($FILE, $update_attachment); 818 819 if(!empty($attachedfile['error'])) 820 { 821 $ret['errors'][] = $attachedfile['error']; 822 $mybb->input['action'] = $action; 823 } 824 else if(isset($attachedfile['aid']) && $mybb->get_input('ajax', MyBB::INPUT_INT) == 1) 825 { 826 $ret['success'][] = array($attachedfile['aid'], get_attachment_icon(get_extension($filename)), htmlspecialchars_uni($filename), get_friendly_size($FILE['size'])); 827 } 828 } 829 } 830 else 831 { 832 $ret['errors'][] = $lang->sprintf($lang->error_uploadempty, htmlspecialchars_uni($FILE['name'])); 833 $mybb->input['action'] = $action; 834 } 835 } 836 } 837 } 838 839 return $ret; 840 } 841 842 /** 843 * Delete an uploaded file both from the relative path and the CDN path if a CDN is in use. 844 * 845 * @param string $path The relative path to the uploaded file. 846 * 847 * @return bool Whether the file was deleted successfully. 848 */ 849 function delete_uploaded_file($path = '') 850 { 851 global $mybb, $plugins; 852 853 $deleted = false; 854 855 $deleted = @unlink($path); 856 857 $cdn_base_path = rtrim($mybb->settings['cdnpath'], '/'); 858 $path = ltrim($path, '/'); 859 $cdn_path = realpath($cdn_base_path . '/' . $path); 860 861 if(!empty($mybb->settings['usecdn']) && !empty($cdn_base_path)) 862 { 863 $deleted = $deleted && @unlink($cdn_path); 864 } 865 866 $hook_params = array( 867 'path' => &$path, 868 'deleted' => &$deleted, 869 ); 870 871 $plugins->run_hooks('delete_uploaded_file', $hook_params); 872 873 return $deleted; 874 } 875 876 /** 877 * Delete an upload directory on both the local filesystem and the CDN filesystem. 878 * 879 * @param string $path The directory to delete. 880 * 881 * @return bool Whether the directory was deleted. 882 */ 883 function delete_upload_directory($path = '') 884 { 885 global $mybb, $plugins; 886 887 $deleted = false; 888 889 $deleted_index = @unlink(rtrim($path, '/').'/index.html'); 890 891 $deleted = @rmdir($path); 892 893 $cdn_base_path = rtrim($mybb->settings['cdnpath'], '/'); 894 $path = ltrim($path, '/'); 895 $cdn_path = rtrim(realpath($cdn_base_path . '/' . $path), '/'); 896 897 if(!empty($mybb->settings['usecdn']) && !empty($cdn_base_path)) 898 { 899 $deleted = $deleted && @rmdir($cdn_path); 900 } 901 902 $hook_params = array( 903 'path' => &$path, 904 'deleted' => &$deleted, 905 ); 906 907 $plugins->run_hooks('delete_upload_directory', $hook_params); 908 909 // If not successfully deleted then reinstante the index file 910 if(!$deleted && $deleted_index) 911 { 912 create_attachment_index($path); 913 } 914 915 return $deleted; 916 } 917 918 /** 919 * Actually move a file to the uploads directory 920 * 921 * @param array $file The PHP $_FILE array for the file 922 * @param string $path The path to save the file in 923 * @param string $filename The filename for the file (if blank, current is used) 924 * @return array The uploaded file 925 */ 926 function upload_file($file, $path, $filename="") 927 { 928 global $plugins, $mybb; 929 930 $upload = array(); 931 932 if(empty($file['name']) || $file['name'] == "none" || $file['size'] < 1) 933 { 934 $upload['error'] = 1; 935 return $upload; 936 } 937 938 if(!$filename) 939 { 940 $filename = $file['name']; 941 } 942 943 $upload['original_filename'] = preg_replace("#/$#", "", $file['name']); // Make the filename safe 944 $filename = preg_replace("#/$#", "", $filename); // Make the filename safe 945 $moved = @move_uploaded_file($file['tmp_name'], $path."/".$filename); 946 947 $cdn_path = ''; 948 949 $moved_cdn = copy_file_to_cdn($path."/".$filename, $cdn_path); 950 951 if(!$moved) 952 { 953 $upload['error'] = 2; 954 return $upload; 955 } 956 @my_chmod($path."/".$filename, '0644'); 957 $upload['filename'] = $filename; 958 $upload['path'] = $path; 959 $upload['type'] = $file['type']; 960 $upload['size'] = $file['size']; 961 $upload = $plugins->run_hooks("upload_file_end", $upload); 962 963 if($moved_cdn) 964 { 965 $upload['cdn_path'] = $cdn_path; 966 } 967 968 return $upload; 969 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
2005 - 2021 © MyBB.de | Alle Rechte vorbehalten! | Sponsor: netcup | Cross-referenced by PHPXref |