[ Index ]

PHP Cross Reference of MyBB 1.6.5

title

Body

[close]

/inc/ -> functions_upload.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.6
   4   * Copyright 2010 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://mybb.com
   7   * License: http://mybb.com/about/license
   8   *
   9   * $Id: functions_upload.php 5623 2011-10-01 02:46:09Z ralgith $
  10   */
  11  
  12  
  13  /**
  14   * Remove an attachment from a specific post
  15   *
  16   * @param int The post ID
  17   * @param string The posthash if available
  18   * @param int The attachment ID
  19   */
  20  function remove_attachment($pid, $posthash, $aid)
  21  {
  22      global $db, $mybb, $plugins;
  23      $aid = intval($aid);
  24      $posthash = $db->escape_string($posthash);
  25      if($posthash != "")
  26      {
  27          $query = $db->simple_select("attachments", "aid, attachname, thumbnail, visible", "aid='{$aid}' AND posthash='{$posthash}'");
  28          $attachment = $db->fetch_array($query);
  29      }
  30      else
  31      {
  32          $query = $db->simple_select("attachments", "aid, attachname, thumbnail, visible", "aid='{$aid}' AND pid='{$pid}'");
  33          $attachment = $db->fetch_array($query);
  34      }
  35      
  36      $plugins->run_hooks("remove_attachment_do_delete", $attachment);
  37      
  38      $db->delete_query("attachments", "aid='{$attachment['aid']}'");
  39      
  40      if(defined('IN_ADMINCP'))
  41      {
  42          $uploadpath = '../'.$mybb->settings['uploadspath'];
  43      }
  44      else
  45      {
  46          $uploadpath = $mybb->settings['uploadspath'];
  47      }
  48      
  49      // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file.
  50      $query = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='".$db->escape_string($attachment['attachname'])."'");
  51      if($db->fetch_field($query, "numreferences") == 0)
  52      {
  53          @unlink($uploadpath."/".$attachment['attachname']);
  54          if($attachment['thumbnail'])
  55          {
  56              @unlink($uploadpath."/".$attachment['thumbnail']);
  57          }
  58  
  59          $date_directory = explode('/', $attachment['attachname']);
  60          if(@is_dir($uploadpath."/".$date_directory[0]))
  61          {
  62              @rmdir($uploadpath."/".$date_directory[0]);
  63          }
  64      }
  65  
  66      if($attachment['visible'] == 1 && $pid)
  67      {
  68          $post = get_post($pid);
  69          update_thread_counters($post['tid'], array("attachmentcount" => "-1"));
  70      }
  71  }
  72  
  73  /**
  74   * Remove all of the attachments from a specific post
  75   *
  76   * @param int The post ID
  77   * @param string The posthash if available
  78   */
  79  function remove_attachments($pid, $posthash="")
  80  {
  81      global $db, $mybb, $plugins;
  82      
  83      if($pid)
  84      {
  85          $post = get_post($pid);
  86      }
  87      $posthash = $db->escape_string($posthash);
  88      if($posthash != "" && !$pid)
  89      {
  90          $query = $db->simple_select("attachments", "*", "posthash='$posthash'");
  91      }
  92      else
  93      {
  94          $query = $db->simple_select("attachments", "*", "pid='$pid'");
  95      }
  96      
  97      if(defined('IN_ADMINCP'))
  98      {
  99          $uploadpath = '../'.$mybb->settings['uploadspath'];
 100      }
 101      else
 102      {
 103          $uploadpath = $mybb->settings['uploadspath'];
 104      }
 105  
 106      $num_attachments = 0;
 107      while($attachment = $db->fetch_array($query))
 108      {
 109          if($attachment['visible'] == 1)
 110          {
 111              $num_attachments++;
 112          }
 113          
 114          $plugins->run_hooks("remove_attachments_do_delete", $attachment);
 115          
 116          $db->delete_query("attachments", "aid='".$attachment['aid']."'");
 117          
 118          // Check if this attachment is referenced in any other posts. If it isn't, then we are safe to delete the actual file.
 119          $query2 = $db->simple_select("attachments", "COUNT(aid) as numreferences", "attachname='".$db->escape_string($attachment['attachname'])."'");
 120          if($db->fetch_field($query2, "numreferences") == 0)
 121          {
 122              @unlink($uploadpath."/".$attachment['attachname']);
 123              if($attachment['thumbnail'])
 124              {
 125                  @unlink($uploadpath."/".$attachment['thumbnail']);
 126              }
 127  
 128              $date_directory = explode('/', $attachment['attachname']);
 129              if(@is_dir($uploadpath."/".$date_directory[0]))
 130              {
 131                  @rmdir($uploadpath."/".$date_directory[0]);
 132              }
 133          }
 134      }
 135      
 136      if($post['tid'])
 137      {
 138          update_thread_counters($post['tid'], array("attachmentcount" => "-{$num_attachments}"));
 139      }
 140  }
 141  
 142  /**
 143   * Remove any matching avatars for a specific user ID
 144   *
 145   * @param int The user ID
 146   * @param string A file name to be excluded from the removal
 147   */
 148  function remove_avatars($uid, $exclude="")
 149  {
 150      global $mybb, $plugins;
 151      
 152      if(defined('IN_ADMINCP'))
 153      {
 154          $avatarpath = '../'.$mybb->settings['avataruploadpath'];
 155      }
 156      else
 157      {
 158          $avatarpath = $mybb->settings['avataruploadpath'];
 159      }
 160      
 161      $dir = opendir($avatarpath);
 162      if($dir)
 163      {
 164          while($file = @readdir($dir))
 165          {
 166              $plugins->run_hooks("remove_avatars_do_delete", $file);
 167              
 168              if(preg_match("#avatar_".$uid."\.#", $file) && is_file($avatarpath."/".$file) && $file != $exclude)
 169              {
 170                  @unlink($avatarpath."/".$file);
 171              }
 172          }
 173  
 174          @closedir($dir);
 175      }
 176  }
 177  
 178  /**
 179   * Upload a new avatar in to the file system
 180   *
 181   * @param srray incoming FILE array, if we have one - otherwise takes $_FILES['avatarupload']
 182   * @param string User ID this avatar is being uploaded for, if not the current user
 183   * @return array Array of errors if any, otherwise filename of successful.
 184   */
 185  function upload_avatar($avatar=array(), $uid=0)
 186  {
 187      global $db, $mybb, $lang, $plugins;
 188      
 189      if(!$uid)
 190      {
 191          $uid = $mybb->user['uid'];
 192      }
 193  
 194      if(!$avatar['name'] || !$avatar['tmp_name'])
 195      {
 196          $avatar = $_FILES['avatarupload'];
 197      }
 198  
 199      if(!is_uploaded_file($avatar['tmp_name']))
 200      {
 201          $ret['error'] = $lang->error_uploadfailed;
 202          return $ret;
 203      }
 204  
 205      // Check we have a valid extension
 206      $ext = get_extension(my_strtolower($avatar['name']));
 207      if(!preg_match("#^(gif|jpg|jpeg|jpe|bmp|png)$#i", $ext)) 
 208      {
 209          $ret['error'] = $lang->error_avatartype;
 210          return $ret;
 211      }
 212      
 213      if(defined('IN_ADMINCP'))
 214      {
 215          $avatarpath = '../'.$mybb->settings['avataruploadpath'];
 216          $lang->load("messages", true);
 217      }
 218      else
 219      {
 220          $avatarpath = $mybb->settings['avataruploadpath'];
 221      }
 222      
 223      $filename = "avatar_".$uid.".".$ext;
 224      $file = upload_file($avatar, $avatarpath, $filename);
 225      if($file['error'])
 226      {
 227          @unlink($avatarpath."/".$filename);        
 228          $ret['error'] = $lang->error_uploadfailed;
 229          return $ret;
 230      }    
 231  
 232  
 233      // Lets just double check that it exists
 234      if(!file_exists($avatarpath."/".$filename))
 235      {
 236          $ret['error'] = $lang->error_uploadfailed;
 237          @unlink($avatarpath."/".$filename);
 238          return $ret;
 239      }
 240      
 241      // Check if this is a valid image or not
 242      $img_dimensions = @getimagesize($avatarpath."/".$filename);
 243      if(!is_array($img_dimensions))
 244      {
 245          @unlink($avatarpath."/".$filename);
 246          $ret['error'] = $lang->error_uploadfailed;
 247          return $ret;
 248      }
 249      
 250      // Check avatar dimensions
 251      if($mybb->settings['maxavatardims'] != '')
 252      {
 253          list($maxwidth, $maxheight) = @explode("x", $mybb->settings['maxavatardims']);
 254          if(($maxwidth && $img_dimensions[0] > $maxwidth) || ($maxheight && $img_dimensions[1] > $maxheight))
 255          {
 256              // Automatic resizing enabled?
 257              if($mybb->settings['avatarresizing'] == "auto" || ($mybb->settings['avatarresizing'] == "user" && $mybb->input['auto_resize'] == 1))
 258              {
 259                  require_once  MYBB_ROOT."inc/functions_image.php";
 260                  $thumbnail = generate_thumbnail($avatarpath."/".$filename, $avatarpath, $filename, $maxheight, $maxwidth);
 261                  if(!$thumbnail['filename'])
 262                  {
 263                      $ret['error'] = $lang->sprintf($lang->error_avatartoobig, $maxwidth, $maxheight);
 264                      $ret['error'] .= "<br /><br />".$lang->error_avatarresizefailed;
 265                      @unlink($avatarpath."/".$filename);
 266                      return $ret;                
 267                  }
 268                  else
 269                  {
 270                      // Reset filesize
 271                      $avatar['size'] = filesize($avatarpath."/".$filename);
 272                      // Reset dimensions
 273                      $img_dimensions = @getimagesize($avatarpath."/".$filename);
 274                  }
 275              }
 276              else
 277              {
 278                  $ret['error'] = $lang->sprintf($lang->error_avatartoobig, $maxwidth, $maxheight);
 279                  if($mybb->settings['avatarresizing'] == "user")
 280                  {
 281                      $ret['error'] .= "<br /><br />".$lang->error_avataruserresize;
 282                  }
 283                  @unlink($avatarpath."/".$filename);
 284                  return $ret;
 285              }            
 286          }
 287      }
 288      
 289      // Next check the file size
 290      if($avatar['size'] > ($mybb->settings['avatarsize']*1024) && $mybb->settings['avatarsize'] > 0)
 291      {
 292          @unlink($avatarpath."/".$filename);
 293          $ret['error'] = $lang->error_uploadsize;
 294          return $ret;
 295      }    
 296  
 297      // Check a list of known MIME types to establish what kind of avatar we're uploading
 298      switch(my_strtolower($avatar['type']))
 299      {
 300          case "image/gif":
 301              $img_type =  1;
 302              break;
 303          case "image/jpeg":
 304          case "image/x-jpg":
 305          case "image/x-jpeg":
 306          case "image/pjpeg":
 307          case "image/jpg":
 308              $img_type = 2;
 309              break;
 310          case "image/png":
 311          case "image/x-png":
 312              $img_type = 3;
 313              break;
 314          default:
 315              $img_type = 0;
 316      }
 317      
 318      // Check if the uploaded file type matches the correct image type (returned by getimagesize)
 319      if($img_dimensions[2] != $img_type || $img_type == 0)
 320      {
 321          $ret['error'] = $lang->error_uploadfailed;
 322          @unlink($avatarpath."/".$filename);
 323          return $ret;        
 324      }
 325      // Everything is okay so lets delete old avatars for this user
 326      remove_avatars($uid, $filename);
 327  
 328      $ret = array(
 329          "avatar" => $mybb->settings['avataruploadpath']."/".$filename,
 330          "width" => intval($img_dimensions[0]),
 331          "height" => intval($img_dimensions[1])
 332      );
 333      $ret = $plugins->run_hooks("upload_avatar_end", $ret);
 334      return $ret;
 335  }
 336  
 337  /**
 338   * Upload an attachment in to the file system
 339   *
 340   * @param array Attachment data (as fed by PHPs $_FILE)
 341   * @param boolean Whether or not we are updating a current attachment or inserting a new one
 342   * @return array Array of attachment data if successful, otherwise array of error data
 343   */
 344  function upload_attachment($attachment, $update_attachment=false)
 345  {
 346      global $db, $theme, $templates, $posthash, $pid, $tid, $forum, $mybb, $lang, $plugins, $cache;
 347      
 348      $posthash = $db->escape_string($mybb->input['posthash']);
 349  
 350      if(isset($attachment['error']) && $attachment['error'] != 0)
 351      {
 352          $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_detail;
 353          switch($attachment['error'])
 354          {
 355              case 1: // UPLOAD_ERR_INI_SIZE
 356                  $ret['error'] .= $lang->error_uploadfailed_php1;
 357                  break;
 358              case 2: // UPLOAD_ERR_FORM_SIZE
 359                  $ret['error'] .= $lang->error_uploadfailed_php2;
 360                  break;
 361              case 3: // UPLOAD_ERR_PARTIAL
 362                  $ret['error'] .= $lang->error_uploadfailed_php3;
 363                  break;
 364              case 4: // UPLOAD_ERR_NO_FILE
 365                  $ret['error'] .= $lang->error_uploadfailed_php4;
 366                  break;
 367              case 6: // UPLOAD_ERR_NO_TMP_DIR
 368                  $ret['error'] .= $lang->error_uploadfailed_php6;
 369                  break;
 370              case 7: // UPLOAD_ERR_CANT_WRITE
 371                  $ret['error'] .= $lang->error_uploadfailed_php7;
 372                  break;
 373              default:
 374                  $ret['error'] .= $lang->sprintf($lang->error_uploadfailed_phpx, $attachment['error']);
 375                  break;
 376          }
 377          return $ret;
 378      }
 379      
 380      if(!is_uploaded_file($attachment['tmp_name']) || empty($attachment['tmp_name']))
 381      {
 382          $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_php4;
 383          return $ret;
 384      }
 385      
 386      $ext = get_extension($attachment['name']);
 387      // Check if we have a valid extension
 388      $query = $db->simple_select("attachtypes", "*", "extension='".$db->escape_string($ext)."'");
 389      $attachtype = $db->fetch_array($query);
 390      if(!$attachtype['atid'])
 391      {
 392          $ret['error'] = $lang->error_attachtype;
 393          return $ret;
 394      }
 395      
 396      // Check the size
 397      if($attachment['size'] > $attachtype['maxsize']*1024 && $attachtype['maxsize'] != "")
 398      {
 399          $ret['error'] = $lang->sprintf($lang->error_attachsize, $attachtype['maxsize']);
 400          return $ret;
 401      }
 402  
 403      // Double check attachment space usage
 404      if($mybb->usergroup['attachquota'] > 0)
 405      {
 406          $query = $db->simple_select("attachments", "SUM(filesize) AS ausage", "uid='".$mybb->user['uid']."'");
 407          $usage = $db->fetch_array($query);
 408          $usage = $usage['ausage']+$attachment['size'];
 409          if($usage > ($mybb->usergroup['attachquota']*1024))
 410          {
 411              $friendlyquota = get_friendly_size($mybb->usergroup['attachquota']*1024);
 412              $ret['error'] = $lang->sprintf($lang->error_reachedattachquota, $friendlyquota);
 413              return $ret;
 414          }
 415      }
 416  
 417      // Gather forum permissions
 418      $forumpermissions = forum_permissions($forum['fid']);
 419  
 420      // Check if an attachment with this name is already in the post
 421      $query = $db->simple_select("attachments", "*", "filename='".$db->escape_string($attachment['name'])."' AND (posthash='$posthash' OR (pid='".intval($pid)."' AND pid!='0'))");
 422      $prevattach = $db->fetch_array($query);
 423      if($prevattach['aid'] && $update_attachment == false)
 424      {
 425          if(!$mybb->usergroup['caneditattachments'] && !$forumpermissions['caneditattachments'])
 426          {
 427              $ret['error'] = $lang->error_alreadyuploaded_perm;
 428              return $ret;
 429          }
 430  
 431          $ret['error'] = $lang->error_alreadyuploaded;
 432          return $ret;
 433      }
 434  
 435      // Check if the attachment directory (YYYYMM) exists, if not, create it
 436      $month_dir = gmdate("Ym");
 437      if(!@is_dir($mybb->settings['uploadspath']."/".$month_dir))
 438      {
 439          @mkdir($mybb->settings['uploadspath']."/".$month_dir);
 440          // Still doesn't exist - oh well, throw it in the main directory
 441          if(!@is_dir($mybb->settings['uploadspath']."/".$month_dir))
 442          {
 443              $month_dir = '';
 444          }
 445      }
 446      
 447      // All seems to be good, lets move the attachment!
 448      $filename = "post_".$mybb->user['uid']."_".TIME_NOW."_".md5(random_str()).".attach";
 449      
 450      $file = upload_file($attachment, $mybb->settings['uploadspath']."/".$month_dir, $filename);
 451      
 452      // Failed to create the attachment in the monthly directory, just throw it in the main directory
 453      if($file['error'] && $month_dir)
 454      {
 455          $file = upload_file($attachment, $mybb->settings['uploadspath'].'/', $filename);        
 456      }
 457  
 458      if($month_dir)
 459      {
 460          $filename = $month_dir."/".$filename;
 461      }
 462      
 463      if($file['error'])
 464      {
 465          $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_detail;
 466          switch($file['error'])
 467          {
 468              case 1:
 469                  $ret['error'] .= $lang->error_uploadfailed_nothingtomove;
 470                  break;
 471              case 2:
 472                  $ret['error'] .= $lang->error_uploadfailed_movefailed;
 473                  break;
 474          }
 475          return $ret;
 476      }
 477  
 478      // Lets just double check that it exists
 479      if(!file_exists($mybb->settings['uploadspath']."/".$filename))
 480      {
 481          $ret['error'] = $lang->error_uploadfailed.$lang->error_uploadfailed_detail.$lang->error_uploadfailed_lost;
 482          return $ret;
 483      }
 484  
 485      // Generate the array for the insert_query
 486      $attacharray = array(
 487          "pid" => intval($pid),
 488          "posthash" => $posthash,
 489          "uid" => $mybb->user['uid'],
 490          "filename" => $db->escape_string($file['original_filename']),
 491          "filetype" => $db->escape_string($file['type']),
 492          "filesize" => intval($file['size']),
 493          "attachname" => $filename,
 494          "downloads" => 0,
 495          "dateuploaded" => TIME_NOW
 496      );
 497  
 498      // If we're uploading an image, check the MIME type compared to the image type and attempt to generate a thumbnail
 499      if($ext == "gif" || $ext == "png" || $ext == "jpg" || $ext == "jpeg" || $ext == "jpe")
 500      {
 501          // Check a list of known MIME types to establish what kind of image we're uploading
 502          switch(my_strtolower($file['type']))
 503          {
 504              case "image/gif":
 505                  $img_type =  1;
 506                  break;
 507              case "image/jpeg":
 508              case "image/x-jpg":
 509              case "image/x-jpeg":
 510              case "image/pjpeg":
 511              case "image/jpg":
 512                  $img_type = 2;
 513                  break;
 514              case "image/png":
 515              case "image/x-png":
 516                  $img_type = 3;
 517                  break;
 518              default:
 519                  $img_type = 0;
 520          }
 521          
 522          $supported_mimes = array();
 523          $attachtypes = $cache->read("attachtypes");
 524          foreach($attachtypes as $attachtype)
 525          {
 526              if(!empty($attachtype['mimetype']))
 527              {
 528                  $supported_mimes[] = $attachtype['mimetype'];
 529              }
 530          }
 531  
 532          // Check if the uploaded file type matches the correct image type (returned by getimagesize)
 533          $img_dimensions = @getimagesize($mybb->settings['uploadspath']."/".$filename);
 534  
 535          $mime = "";
 536          $file_path = $mybb->settings['uploadspath']."/".$filename;
 537          if(function_exists("finfo_open"))
 538          {
 539              $file_info = finfo_open(FILEINFO_MIME);
 540              list($mime, ) = explode(';', finfo_file($file_info, MYBB_ROOT.$file_path), 1);
 541              finfo_close($file_info);
 542          }
 543          else if(function_exists("mime_content_type"))
 544          {
 545              $mime = mime_content_type(MYBB_ROOT.$file_path);
 546          }
 547  
 548          if(!is_array($img_dimensions) || ($img_dimensions[2] != $img_type && !in_array($mime, $supported_mimes)))
 549          {
 550              @unlink($mybb->settings['uploadspath']."/".$filename);
 551              $ret['error'] = $lang->error_uploadfailed;
 552              return $ret;        
 553          }        
 554          require_once  MYBB_ROOT."inc/functions_image.php";
 555          $thumbname = str_replace(".attach", "_thumb.$ext", $filename);
 556          $thumbnail = generate_thumbnail($mybb->settings['uploadspath']."/".$filename, $mybb->settings['uploadspath'], $thumbname, $mybb->settings['attachthumbh'], $mybb->settings['attachthumbw']);
 557          
 558          if($thumbnail['filename'])
 559          {
 560              $attacharray['thumbnail'] = $thumbnail['filename'];
 561          }
 562          elseif($thumbnail['code'] == 4)
 563          {
 564              $attacharray['thumbnail'] = "SMALL";
 565          }
 566      }
 567      if($forum['modattachments'] == 1 && !is_moderator($forum['fid'], "", $mybb->user['uid']))
 568      {
 569          $attacharray['visible'] = 0;
 570      }
 571      else
 572      {
 573          $attacharray['visible'] = 1;
 574      }
 575      
 576      $attacharray = $plugins->run_hooks("upload_attachment_do_insert", $attacharray);
 577      
 578      if($prevattach['aid'] && $update_attachment == true)
 579      {
 580          unset($attacharray['downloads']); // Keep our download count if we're updating an attachment
 581          $db->update_query("attachments", $attacharray, "aid='".$db->escape_string($prevattach['aid'])."'");
 582          $aid = $prevattach['aid'];
 583      }
 584      else
 585      {
 586          $aid = $db->insert_query("attachments", $attacharray);
 587      }
 588  
 589      if($tid)
 590      {
 591          update_thread_counters($tid, array("attachmentcount" => "+1"));
 592      }
 593      $ret['aid'] = $aid;
 594      return $ret;
 595  }
 596  
 597  /**
 598   * Actually move a file to the uploads directory
 599   *
 600   * @param array The PHP $_FILE array for the file
 601   * @param string The path to save the file in
 602   * @param string The filename for the file (if blank, current is used)
 603   */
 604  function upload_file($file, $path, $filename="")
 605  {
 606      global $plugins;
 607      
 608      if(empty($file['name']) || $file['name'] == "none" || $file['size'] < 1)
 609      {
 610          $upload['error'] = 1;
 611          return $upload;
 612      }
 613  
 614      if(!$filename)
 615      {
 616          $filename = $file['name'];
 617      }
 618      
 619      $upload['original_filename'] = preg_replace("#/$#", "", $file['name']); // Make the filename safe
 620      $filename = preg_replace("#/$#", "", $filename); // Make the filename safe
 621      $moved = @move_uploaded_file($file['tmp_name'], $path."/".$filename);
 622      
 623      if(!$moved)
 624      {
 625          $upload['error'] = 2;
 626          return $upload;
 627      }
 628      @my_chmod($path."/".$filename, '0644');
 629      $upload['filename'] = $filename;
 630      $upload['path'] = $path;
 631      $upload['type'] = $file['type'];
 632      $upload['size'] = $file['size'];
 633      $upload = $plugins->run_hooks("upload_file_end", $upload);
 634      return $upload;
 635  }
 636  ?>


Generated: Sun Dec 11 14:16:27 2011 Cross-referenced by PHPXref 0.7.1