[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/admin/modules/forum/ -> attachments.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$
  10   */
  11  
  12  // Disallow direct access to this file for security reasons
  13  if(!defined("IN_MYBB"))
  14  {
  15      die("Direct initialization of this file is not allowed.<br /><br />Please make sure IN_MYBB is defined.");
  16  }
  17  
  18  $page->add_breadcrumb_item($lang->attachments, "index.php?module=forum-attachments");
  19  
  20  if($mybb->input['action'] == "stats" || $mybb->input['action'] == "orphans" || !$mybb->input['action'])
  21  {
  22      $sub_tabs['find_attachments'] = array(
  23          'title' => $lang->find_attachments,
  24          'link' => "index.php?module=forum-attachments",
  25          'description' => $lang->find_attachments_desc
  26      );
  27  
  28      $sub_tabs['find_orphans'] = array(
  29          'title' => $lang->find_orphans,
  30          'link' => "index.php?module=forum-attachments&amp;action=orphans",
  31          'description' => $lang->find_orphans_desc
  32      );
  33  
  34      $sub_tabs['stats'] = array(
  35          'title' => $lang->attachment_stats,
  36          'link' => "index.php?module=forum-attachments&amp;action=stats",
  37          'description' => $lang->attachment_stats_desc
  38      );
  39  }
  40  
  41  $plugins->run_hooks("admin_forum_attachments_begin");
  42  
  43  if($mybb->input['action'] == "delete")
  44  {
  45      $plugins->run_hooks("admin_forum_attachments_delete");
  46      
  47      if(!is_array($mybb->input['aids']))
  48      {
  49          $mybb->input['aids'] = array(intval($mybb->input['aid']));
  50      }
  51      else
  52      {
  53          $mybb->input['aids'] = array_map("intval", $mybb->input['aids']);
  54      }
  55  
  56      if(count($mybb->input['aids']) < 1)
  57      {
  58          flash_message($lang->error_nothing_selected, 'error');
  59          admin_redirect("index.php?module=forum-attachments");
  60      }
  61  
  62      if($mybb->request_method == "post")
  63      {
  64          require_once  MYBB_ROOT."inc/functions_upload.php";
  65  
  66          $query = $db->simple_select("attachments", "aid,pid,posthash, filename", "aid IN (".implode(",", $mybb->input['aids']).")");
  67          while($attachment = $db->fetch_array($query))
  68          {
  69              if(!$attachment['pid'])
  70              {
  71                  remove_attachment(null, $attachment['posthash'], $attachment['aid']);
  72                  // Log admin action
  73                  log_admin_action($attachment['aid'], $attachment['filename']);
  74              }
  75              else
  76              {
  77                  remove_attachment($attachment['pid'], null, $attachment['aid']);
  78                  // Log admin action
  79                  log_admin_action($attachment['aid'], $attachment['filename'], $attachment['pid']);
  80              }
  81          }
  82          
  83          $plugins->run_hooks("admin_forum_attachments_delete_commit");
  84  
  85          flash_message($lang->success_deleted, 'success');
  86          admin_redirect("index.php?module=forum-attachments");
  87      }
  88      else
  89      {
  90          foreach($mybb->input['aids'] as $aid)
  91          {
  92              $aids .= "&amp;aids[]=$aid";
  93          }
  94          $page->output_confirm_action("index.php?module=forum-attachments&amp;action=delete&amp;aids={$aids}", $lang->confirm_delete); 
  95      }
  96  }
  97  
  98  if($mybb->input['action'] == "stats")
  99  {
 100      $plugins->run_hooks("admin_forum_attachments_stats");
 101  
 102      $query = $db->simple_select("attachments", "COUNT(*) AS total_attachments, SUM(filesize) as disk_usage, SUM(downloads*filesize) as bandwidthused", "visible='1'");
 103      $attachment_stats = $db->fetch_array($query);
 104  
 105          $page->add_breadcrumb_item($lang->stats);
 106          $page->output_header($lang->stats_attachment_stats);
 107          
 108          $page->output_nav_tabs($sub_tabs, 'stats');
 109  
 110      if($attachment_stats['total_attachments'] == 0)
 111      {
 112          $page->output_inline_error(array($lang->error_no_attachments));
 113          $page->output_footer();
 114          exit;
 115      }
 116  
 117      $table = new Table;
 118  
 119      $table->construct_cell($lang->num_uploaded, array('width' => '25%'));
 120      $table->construct_cell(my_number_format($attachment_stats['total_attachments']), array('width' => '25%'));
 121      $table->construct_cell($lang->space_used, array('width' => '200'));
 122      $table->construct_cell(get_friendly_size($attachment_stats['disk_usage']), array('width' => '200'));
 123      $table->construct_row();
 124      
 125      $table->construct_cell($lang->bandwidth_used, array('width' => '25%'));
 126      $table->construct_cell(get_friendly_size(round($attachment_stats['bandwidthused'])), array('width' => '25%'));
 127      $table->construct_cell($lang->average_size, array('width' => '25%'));
 128      $table->construct_cell(get_friendly_size(round($attachment_stats['disk_usage']/$attachment_stats['total_attachments'])), array('width' => '25%'));
 129      $table->construct_row();
 130      
 131      $table->output($lang->general_stats);
 132  
 133      // Fetch the most popular attachments
 134      $table = new Table;
 135      $table->construct_header($lang->attachments, array('colspan' => 2));
 136      $table->construct_header($lang->size, array('width' => '10%', 'class' => 'align_center'));
 137      $table->construct_header($lang->posted_by, array('width' => '20%', 'class' => 'align_center'));
 138      $table->construct_header($lang->thread, array('width' => '25%', 'class' => 'align_center'));
 139      $table->construct_header($lang->downloads, array('width' => '10%', 'class' => 'align_center'));
 140      $table->construct_header($lang->date_uploaded, array("class" => "align_center"));
 141  
 142      $query = $db->query("
 143          SELECT a.*, p.tid, p.fid, t.subject, p.uid, p.username, u.username AS user_username
 144          FROM ".TABLE_PREFIX."attachments a
 145          LEFT JOIN ".TABLE_PREFIX."posts p ON (p.pid=a.pid)
 146          LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
 147          LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)
 148          ORDER BY a.downloads DESC
 149          LIMIT 5
 150      ");
 151      while($attachment = $db->fetch_array($query))
 152      {
 153          build_attachment_row($attachment, $table);
 154      }
 155      $table->output($lang->popular_attachments);
 156  
 157      // Fetch the largest attachments
 158      $table = new Table;
 159      $table->construct_header($lang->attachments, array('colspan' => 2));
 160      $table->construct_header($lang->size, array('width' => '10%', 'class' => 'align_center'));
 161      $table->construct_header($lang->posted_by, array('width' => '20%', 'class' => 'align_center'));
 162      $table->construct_header($lang->thread, array('width' => '25%', 'class' => 'align_center'));
 163      $table->construct_header($lang->downloads, array('width' => '10%', 'class' => 'align_center'));
 164      $table->construct_header($lang->date_uploaded, array("class" => "align_center"));
 165  
 166      $query = $db->query("
 167          SELECT a.*, p.tid, p.fid, t.subject, p.uid, p.username, u.username AS user_username
 168          FROM ".TABLE_PREFIX."attachments a
 169          LEFT JOIN ".TABLE_PREFIX."posts p ON (p.pid=a.pid)
 170          LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
 171          LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)
 172          ORDER BY a.filesize DESC
 173          LIMIT 5
 174      ");
 175      while($attachment = $db->fetch_array($query))
 176      {
 177          build_attachment_row($attachment, $table);
 178      }
 179      $table->output($lang->largest_attachments);
 180  
 181      // Fetch users who've uploaded the most attachments
 182      $table = new Table;
 183      $table->construct_header($lang->username);
 184      $table->construct_header($lang->total_size, array('width' => '20%', 'class' => 'align_center'));
 185  
 186      switch($db->type)
 187      {
 188          case "pgsql":
 189              $query = $db->query("
 190                  SELECT a.*, u.uid AS useruid, u.username, SUM(a.filesize) as totalsize
 191                  FROM ".TABLE_PREFIX."attachments a  
 192                  LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)
 193                  GROUP BY ".$db->build_fields_string("attachments", "a.").",u.uid,u.username
 194                  ORDER BY totalsize DESC
 195                  LIMIT 5
 196              ");
 197              break;
 198          default:
 199              $query = $db->query("
 200                  SELECT a.*, u.uid AS useruid, u.username, SUM(a.filesize) as totalsize
 201                  FROM ".TABLE_PREFIX."attachments a  
 202                  LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)
 203                  GROUP BY a.uid
 204                  ORDER BY totalsize DESC
 205                  LIMIT 5
 206              ");
 207      }
 208      while($user = $db->fetch_array($query))
 209      {
 210          if(!$user['useruid'])
 211          {
 212              $user['username'] = $lang->na;
 213          }
 214          $table->construct_cell(build_profile_link($user['username'], $user['useruid'], "_blank"));
 215          $table->construct_cell("<a href=\"index.php?module=forum-attachments&amp;results=1&amp;username=".urlencode($user['username'])."\" target=\"_blank\">".get_friendly_size($user['totalsize'])."</a>", array('class' => 'align_center'));
 216          $table->construct_row();
 217      }
 218      $table->output($lang->users_diskspace);
 219  
 220      $page->output_footer();
 221  }
 222  
 223  if($mybb->input['action'] == "delete_orphans" && $mybb->request_method == "post")
 224  {
 225      $plugins->run_hooks("admin_forum_attachments_delete_orphans");
 226      
 227      // Deleting specific attachments from uploads directory
 228      if(is_array($mybb->input['orphaned_files']))
 229      {
 230  		function clean_filename($string)
 231          {
 232              return str_replace(array(".."), "", $string);
 233          }
 234          $mybb->input['orphaned_files'] = array_map("clean_filename", $mybb->input['orphaned_files']);
 235          foreach($mybb->input['orphaned_files'] as $file)
 236          {
 237              if(!@unlink(MYBB_ROOT.$mybb->settings['uploadspath']."/".$file))
 238              {
 239                  $error = true;
 240              }
 241          }
 242      }
 243  
 244      // Deleting physical attachments which exist in database
 245      if(is_array($mybb->input['orphaned_attachments']))
 246      {
 247          $mybb->input['orphaned_attachments'] = array_map("intval", $mybb->input['orphaned_attachments']);
 248          require_once  MYBB_ROOT."inc/functions_upload.php";
 249  
 250          $query = $db->simple_select("attachments", "aid,pid,posthash", "aid IN (".implode(",", $mybb->input['orphaned_attachments']).")");
 251          while($attachment = $db->fetch_array($query))
 252          {
 253              if(!$attachment['pid'])
 254              {
 255                  remove_attachment(null, $attachment['posthash'], $attachment['aid']);
 256              }
 257              else
 258              {
 259                  remove_attachment($attachment['pid'], null, $attachment['aid']);
 260              }
 261          }
 262      }
 263      
 264      $plugins->run_hooks("admin_forum_attachments_delete_orphans_commit");
 265  
 266      // Log admin action
 267      log_admin_action();
 268  
 269      if($error == true)
 270      {
 271          flash_message($lang->error_not_all_removed, 'error');
 272      }
 273      else
 274      {
 275          flash_message($lang->success_orphan_deleted, 'success');
 276      }
 277      admin_redirect("index.php?module=forum-attachments");
 278  }
 279  
 280  if($mybb->input['action'] == "orphans")
 281  {
 282      $plugins->run_hooks("admin_forum_attachments_orphans");
 283      
 284      // Oprhans are defined as:
 285      // - Uploaded files in the uploads directory that don't exist in the database
 286      // - Attachments for which the uploaded file is missing
 287      // - Attachments for which the thread or post has been deleted
 288      // - Files uploaded > 24h ago not attached to a real post
 289  
 290      // This process is quite intensive so we split it up in to 2 steps, one which scans the file system and the other which scans the database.
 291  
 292      // Finished second step, show results
 293      if($mybb->input['step'] == 3)
 294      {
 295          $plugins->run_hooks("admin_forum_attachments_step3");
 296          
 297          $reults = 0;
 298          // Incoming attachments which exist as files but not in database
 299          if($mybb->input['bad_attachments'])
 300          {
 301              $bad_attachments = unserialize($mybb->input['bad_attachments']);
 302              $results = count($bad_attachments);
 303          }
 304  
 305          $aids = array();
 306          if($mybb->input['missing_attachment_files'])
 307          {
 308              $missing_attachment_files = unserialize($mybb->input['missing_attachment_files']);
 309              $aids = array_merge($aids, $missing_attachment_files);
 310          }
 311  
 312          if($mybb->input['missing_threads'])
 313          {
 314              $missing_threads = unserialize($mybb->input['missing_threads']);
 315              $aids = array_merge($aids, $missing_threads);
 316          }
 317  
 318          if($mybb->input['incomplete_attachments'])
 319          {
 320              $incomplete_attachments = unserialize($mybb->input['incomplete_attachments']);
 321              $aids = array_merge($aids, $incomplete_attachments);
 322          }
 323          
 324          foreach($aids as $key => $aid)
 325          {
 326              $aids[$key] = intval($aid);
 327          }
 328          
 329          $results += count($aids);
 330  
 331          if($results == 0)
 332          {
 333              flash_message($lang->success_no_orphans, 'success');
 334              admin_redirect("index.php?module=forum-attachments");
 335          }
 336  
 337          $page->output_header($lang->orphan_results);
 338          $page->output_nav_tabs($sub_tabs, 'find_orphans');
 339  
 340          $form = new Form("index.php?module=forum-attachments&amp;action=delete_orphans", "post");
 341  
 342          $table = new Table;
 343          $table->construct_header($form->generate_check_box('checkall', '1', '', array('class' => 'checkall')), array( 'width' => 1));
 344          $table->construct_header($lang->size_attachments, array('colspan' => 2));
 345          $table->construct_header($lang->reason_orphaned, array('width' => '20%', 'class' => 'align_center'));
 346          $table->construct_header($lang->date_uploaded, array("class" => "align_center"));
 347  
 348          if(is_array($bad_attachments))
 349          {
 350              foreach($bad_attachments as $file)
 351              {
 352                  $file_path = MYBB_ROOT.$mybb->settings['uploadspath']."/".$file;
 353                  $filesize = get_friendly_size(filesize($file_path));
 354                  $table->construct_cell($form->generate_check_box('orphaned_files[]', $file, '', array('checked' => true)));
 355                  $table->construct_cell(get_attachment_icon(get_extension($attachment['filename'])), array('width' => 1));
 356                  $table->construct_cell("<span class=\"float_right\">{$filesize}</span>{$file}");
 357                  $table->construct_cell($lang->reason_not_in_table, array('class' => 'align_center'));
 358                  $table->construct_cell(my_date($mybb->settings['dateformat'], filemtime($file_path)).", ".my_date($mybb->settings['timeformat'], filemtime($file_path)), array('class' => 'align_center'));
 359                  $table->construct_row();
 360              }
 361          }
 362  
 363          if(count($aids) > 0)
 364          {
 365              $query = $db->simple_select("attachments", "*", "aid IN (".implode(",", $aids).")");
 366              while($attachment = $db->fetch_array($query))
 367              {
 368                  $attachment['filename'] = htmlspecialchars_uni($attachment['filename']);
 369  
 370                  if($missing_attachment_files[$attachment['aid']])
 371                  {
 372                      $reason = $lang->reason_file_missing;
 373                  }
 374                  else if($missing_threads[$attachment['aid']])
 375                  {
 376                      $reason = $lang->reason_thread_deleted;
 377                  }
 378                  else if($incomplete_attachments[$attachment['aid']])
 379                  {
 380                      $reason = $lang->reason_post_never_made;
 381                  }
 382                  $table->construct_cell($form->generate_check_box('orphaned_attachments[]', $attachment['aid'], '', array('checked' => true)));
 383                  $table->construct_cell(get_attachment_icon(get_extension($attachment['filename'])), array('width' => 1));
 384                  $table->construct_cell("<span class=\"float_right\">".get_friendly_size($attachment['filesize'])."</span>{$attachment['filename']}", array('class' => $cell_class));
 385                  $table->construct_cell($reason, array('class' => 'align_center'));
 386                  if($attachment['dateuploaded'])
 387                  {
 388                      $table->construct_cell(my_date($mybb->settings['dateformat'], $attachment['dateuploaded']).", ".my_date($mybb->settings['timeformat'], $attachment['dateuploaded']), array('class' => 'align_center'));
 389                  }
 390                  else
 391                  {
 392                      $table->construct_cell($lang->unknown, array('class' => 'align_center'));
 393                  }
 394                  $table->construct_row();
 395              }
 396          }
 397  
 398          $table->output("{$lang->orphan_attachments_search} - {$results} {$lang->results}");
 399  
 400          $buttons[] = $form->generate_submit_button($lang->button_delete_orphans);
 401          $form->output_submit_wrapper($buttons);
 402          $form->end();
 403          $page->output_footer();
 404      }
 405  
 406      // Running second step - scan the database
 407      else if($mybb->input['step'] == 2)
 408      {
 409          $plugins->run_hooks("admin_forum_attachments_orphans_step2");
 410          
 411          $page->output_header("{$lang->orphan_attachments_search} - {$lang->step2}");
 412      
 413          $page->output_nav_tabs($sub_tabs, 'find_orphans');
 414          echo "<h3>{$lang->step2of2}</h3>";
 415          echo "<p class=\"align_center\">{$lang->step2of2_line1}</p>";
 416          echo "<p class=\"align_center\">{$lang->step_line2}</p>";
 417          echo "<p class=\"align_center\"><img src=\"styles/{$page->style}/images/spinner_big.gif\" alt=\"Scanning..\" id=\"spinner\" /></p>";
 418  
 419          $page->output_footer(false);
 420          flush();
 421  
 422          $missing_attachment_files = array();
 423          $missing_threads = array();
 424          $incomplete_attachments = array();
 425  
 426          $query = $db->query("
 427              SELECT a.*, a.pid AS attachment_pid, p.pid
 428              FROM ".TABLE_PREFIX."attachments a
 429              LEFT JOIN ".TABLE_PREFIX."posts p ON (p.pid=a.pid)
 430              ORDER BY a.aid");
 431          while($attachment = $db->fetch_array($query))
 432          {
 433              // Check if the attachment exists in the file system
 434              if(!file_exists(MYBB_ROOT.$mybb->settings['uploadspath']."/{$attachment['attachname']}"))
 435              {
 436                  $missing_attachment_files[$attachment['aid']] = $attachment['aid'];
 437              }
 438              // Check if the thread/post for this attachment is missing
 439              else if(!$attachment['pid'] && $attachment['attachment_pid'])
 440              {
 441                  $missing_threads[$attachment['aid']] = $attachment['aid'];
 442              }
 443              // Check if the attachment was uploaded > 24 hours ago but not assigned to a thread
 444              else if(!$attachment['attachment_pid'] && $attachment['dateuploaded'] < TIME_NOW-60*60*24 && $attachment['dateuploaded'] != 0)
 445              {
 446                  $incomplete_attachments[$attachment['aid']] = $attachment['aid'];
 447              }
 448          }
 449  
 450          // Now send the user to the final page
 451          $form = new Form("index.php?module=forum-attachments&amp;action=orphans&amp;step=3", "post", "redirect_form", 0, "");
 452          // Scan complete
 453          if($mybb->input['bad_attachments'])
 454          {
 455              echo $form->generate_hidden_field("bad_attachments", $mybb->input['bad_attachments']);
 456          }
 457          if(is_array($missing_attachment_files) && count($missing_attachment_files) > 0)
 458          {
 459              $missing_attachment_files = serialize($missing_attachment_files);
 460              echo $form->generate_hidden_field("missing_attachment_files", $missing_attachment_files);
 461          }
 462          if(is_array($missing_threads) && count($missing_threads) > 0)
 463          {
 464              $missing_threads = serialize($missing_threads);
 465              echo $form->generate_hidden_field("missing_threads", $missing_threads);
 466          }
 467          if(is_array($incomplete_attachments) && count($incomplete_attachments) > 0)
 468          {
 469              $incomplete_attachments = serialize($incomplete_attachments);
 470              echo $form->generate_hidden_field("incomplete_attachments", $incomplete_attachments);
 471          }
 472          $form->end();
 473          echo "<script type=\"text/javascript\">Event.observe(window, 'load', function() {
 474                  window.setTimeout(
 475                      function() {
 476                          $('redirect_form').submit();
 477                      }, 100
 478                  );
 479              });</script>";
 480          exit;
 481      }
 482      // Running first step, scan the file system
 483      else
 484      {
 485          $plugins->run_hooks("admin_forum_attachments_orphans_step1");
 486          
 487  		function scan_attachments_directory($dir="")
 488          {
 489              global $db, $mybb, $bad_attachments, $attachments_to_check;
 490              
 491              $real_dir = MYBB_ROOT.$mybb->settings['uploadspath'];
 492              $false_dir = "";
 493              if($dir)
 494              {
 495                  $real_dir .= "/".$dir;
 496                  $false_dir = $dir."/";
 497              }
 498  
 499              if($dh = opendir($real_dir))
 500              {
 501                  while(false !== ($file = readdir($dh)))
 502                  {
 503                      if($file == "." || $file == ".." || $file == ".svn")
 504                      {
 505                          continue;
 506                      }
 507                      
 508                      if(is_dir($real_dir.'/'.$file))
 509                      {
 510                          scan_attachments_directory($false_dir.$file);
 511                      }
 512                      else if(my_substr($file, -7, 7) == ".attach")
 513                      {
 514                          $attachments_to_check["$false_dir$file"] = $false_dir.$file;
 515                          // In allotments of 20, query the database for these attachments
 516                          if(count($attachments_to_check) >= 20)
 517                          {
 518                              $attachments_to_check = array_map(array($db, "escape_string"), $attachments_to_check);
 519                              $attachment_names = "'".implode("','", $attachments_to_check)."'";
 520                              $query = $db->simple_select("attachments", "aid, attachname", "attachname IN ($attachment_names)");
 521                              while($attachment = $db->fetch_array($query))
 522                              {
 523                                  unset($attachments_to_check[$attachment['attachname']]);
 524                              }
 525  
 526                              // Now anything left is bad!
 527                              if(count($attachments_to_check) > 0)
 528                              {
 529                                  if($bad_attachments)
 530                                  {
 531                                      $bad_attachments = @array_merge($bad_attachments, $attachments_to_check);
 532                                  }
 533                                  else
 534                                  {
 535                                      $bad_attachments = $attachments_to_check;
 536                                  }
 537                              }
 538                              $attachments_to_check = array();
 539                          }
 540                      }
 541                  }
 542                  closedir($dh);
 543                  // Any reamining to check?
 544                  if(count($attachments_to_check) > 0)
 545                  {
 546                      $attachments_to_check = array_map(array($db, "escape_string"), $attachments_to_check);
 547                      $attachment_names = "'".implode("','", $attachments_to_check)."'";
 548                      $query = $db->simple_select("attachments", "aid, attachname", "attachname IN ($attachment_names)");
 549                      while($attachment = $db->fetch_array($query))
 550                      {
 551                          unset($attachments_to_check[$attachment['attachname']]);
 552                      }
 553  
 554                      // Now anything left is bad!
 555                      if(count($attachments_to_check) > 0)
 556                      {
 557                          if($bad_attachments)
 558                          {
 559                              $bad_attachments = @array_merge($bad_attachments, $attachments_to_check);
 560                          }
 561                          else
 562                          {
 563                              $bad_attachments = $attachments_to_check;
 564                          }
 565                      }
 566                  }
 567              }
 568          }
 569      
 570          $page->output_header("{$lang->orphan_attachments_search} - {$lang->step1}");
 571      
 572          $page->output_nav_tabs($sub_tabs, 'find_orphans');
 573          echo "<h3>{$lang->step1of2}</h3>";
 574          echo "<p class=\"align_center\">{$lang->step1of2_line1}</p>";
 575          echo "<p class=\"align_center\">{$lang->step_line2}</p>";
 576          echo "<p class=\"align_center\"><img src=\"styles/{$page->style}/images/spinner_big.gif\" alt=\"Scanning..\" id=\"spinner\" /></p>";
 577  
 578          $page->output_footer(false);
 579          
 580          flush();
 581          
 582          scan_attachments_directory();
 583          global $bad_attachments;
 584  
 585          $form = new Form("index.php?module=forum-attachments&amp;action=orphans&amp;step=2", "post", "redirect_form", 0, "");
 586          // Scan complete
 587          if(is_array($bad_attachments) && count($bad_attachments) > 0)
 588          {
 589              $bad_attachments = serialize($bad_attachments);
 590              echo $form->generate_hidden_field("bad_attachments", $bad_attachments);
 591          }
 592          $form->end();
 593          echo "<script type=\"text/javascript\">Event.observe(window, 'load', function() {
 594                  window.setTimeout(
 595                      function() {
 596                          $('redirect_form').submit();
 597                      }, 100
 598                  );
 599              });</script>";
 600          exit;
 601      }
 602  }
 603  
 604  if(!$mybb->input['action'])
 605  {
 606      $plugins->run_hooks("admin_forum_attachments_start");
 607      
 608      if($mybb->request_method == "post" || $mybb->input['results'] == 1)
 609      {
 610          $search_sql = '1=1';
 611  
 612          // Build the search SQL for users
 613  
 614          // List of valid LIKE search fields
 615          $user_like_fields = array("filename", "filetype");
 616          foreach($user_like_fields as $search_field)
 617          {
 618              if($mybb->input[$search_field])
 619              {
 620                  $search_sql .= " AND a.{$search_field} LIKE '%".$db->escape_string_like($mybb->input[$search_field])."%'";
 621              }
 622          }
 623  
 624          // Username matching
 625          if($mybb->input['username'])
 626          {
 627              $query = $db->simple_select("users", "uid", "LOWER(username)='".$db->escape_string(my_strtolower($mybb->input['username']))."'");
 628              $user = $db->fetch_array($query);
 629              if(!$user['uid'])
 630              {
 631                  $errors[] = $lang->error_invalid_username;
 632              }
 633              else
 634              {
 635                  $search_sql .= " AND a.uid='{$user['uid']}'";
 636              }
 637          }
 638  
 639          $forum_cache = cache_forums();
 640  
 641          // Searching for attachments in a specific forum, we need to fetch all child forums too
 642          if($mybb->input['forum'])
 643          {
 644              if(!is_array($mybb->input['forum']))
 645              {
 646                  $mybb->input['forum'] = array($mybb->input['forum']);
 647              }
 648  
 649              $fid_in = array();
 650              foreach($mybb->input['forum'] as $fid)
 651              {
 652                  if(!$forum_cache[$fid])
 653                  {
 654                      $errors[] = $lang->error_invalid_forums;
 655                      break;
 656                  }
 657                  $child_forums = get_child_list($fid);
 658                  $child_forums[] = $fid;
 659                  $fid_in = array_merge($fid_in, $child_forums);
 660              }
 661  
 662              if(count($fid_in) > 0)
 663              {
 664                  $search_sql .= " AND p.fid IN (".implode(",", $fid_in).")";
 665              }
 666          }
 667  
 668          // LESS THAN or GREATER THAN
 669          if($mybb->input['dateuploaded'] && $mybb->request_method == "post")
 670          {
 671              $mybb->input['dateuploaded'] = TIME_NOW-$mybb->input['dateuploaded']*60*60*24;
 672          }
 673          if($mybb->input['filesize'] && $mybb->request_method == "post")
 674          {
 675              $mybb->input['filesize'] *= 1024;
 676          }
 677  
 678          $direction_fields = array("dateuploaded", "filesize", "downloads");
 679          foreach($direction_fields as $search_field)
 680          {
 681              $direction_field = $search_field."_dir";
 682              if($mybb->input[$search_field] && $mybb->input[$direction_field])
 683              {
 684                  switch($mybb->input[$direction_field])
 685                  {
 686                      case "greater_than":
 687                          $direction = ">";
 688                          break;
 689                      case "less_than":
 690                          $direction = "<";
 691                          break;
 692                      default:
 693                          $direction = "=";
 694                  }
 695                  $search_sql .= " AND a.{$search_field}{$direction}'".$db->escape_string($mybb->input[$search_field])."'";
 696              }
 697          }
 698          if(!$errors)
 699          {
 700              // Lets fetch out how many results we have
 701              $query = $db->query("
 702                  SELECT COUNT(a.aid) AS num_results
 703                  FROM ".TABLE_PREFIX."attachments a
 704                  LEFT JOIN ".TABLE_PREFIX."posts p ON (p.pid=a.pid)
 705                  WHERE {$search_sql}
 706              ");
 707              $num_results = $db->fetch_field($query, "num_results");
 708  
 709              // No matching results then show an error
 710              if(!$num_results)
 711              {
 712                  $errors[] = $lang->error_no_results;
 713              }
 714          }
 715  
 716          // Now we fetch the results if there were 100% no errors
 717          if(!$errors)
 718          {
 719              $mybb->input['perpage'] = intval($mybb->input['perpage']);
 720              if(!$mybb->input['perpage'])
 721              {
 722                  $mybb->input['perpage'] = 20;
 723              }
 724  
 725              $mybb->input['page'] = intval($mybb->input['page']);
 726              if($mybb->input['page'])
 727              {
 728                  $start = ($mybb->input['page'] - 1) * $mybb->input['perpage'];
 729              }
 730              else
 731              {
 732                  $start = 0;
 733                  $mybb->input['page'] = 1;
 734              }
 735  
 736              switch($mybb->input['sortby'])
 737              {
 738                  case "lastactive":
 739                      $sort_field = "a.filesize";
 740                      break;
 741                  case "downloads":
 742                      $sort_field = "a.downloads";
 743                      break;
 744                  case "dateuploaded":
 745                      $sort_field = "a.dateuploaded";
 746                      break;
 747                  case "username":
 748                      $sort_field = "u.username";
 749                      break;
 750                  default:
 751                      $sort_field = "a.filename";
 752                      $mybb->input['sortby'] = "filename";
 753              }
 754  
 755              if($mybb->input['sortorder'] != "desc")
 756              {
 757                  $mybb->input['sortorder'] = "asc";
 758              }
 759  
 760              $page->add_breadcrumb_item($lang->results);
 761              $page->output_header($lang->index_find_attachments);
 762              
 763              $page->output_nav_tabs($sub_tabs, 'find_attachments');
 764              
 765              $form = new Form("index.php?module=forum-attachments&amp;action=delete", "post");
 766  
 767              $table = new Table;
 768              $table->construct_header($form->generate_check_box('checkall', '1', '', array('class' => 'checkall')), array( 'width' => 1));
 769              $table->construct_header($lang->attachments, array('colspan' => 2));
 770              $table->construct_header($lang->size, array('width' => '10%', 'class' => 'align_center'));
 771              $table->construct_header($lang->posted_by, array('width' => '20%', 'class' => 'align_center'));
 772              $table->construct_header($lang->thread, array('width' => '25%', 'class' => 'align_center'));
 773              $table->construct_header($lang->downloads, array('width' => '10%', 'class' => 'align_center'));
 774              $table->construct_header($lang->date_uploaded, array("class" => "align_center"));
 775  
 776              // Fetch matching attachments
 777              $query = $db->query("
 778                  SELECT a.*, p.tid, p.fid, t.subject, p.uid, p.username, u.username AS user_username
 779                  FROM ".TABLE_PREFIX."attachments a
 780                  LEFT JOIN ".TABLE_PREFIX."posts p ON (p.pid=a.pid)
 781                  LEFT JOIN ".TABLE_PREFIX."threads t ON (t.tid=p.tid)
 782                  LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=a.uid)
 783                  WHERE {$search_sql}
 784                  ORDER BY {$sort_field} {$mybb->input['sortorder']}
 785                  LIMIT {$start}, {$mybb->input['perpage']}
 786              ");
 787              while($attachment = $db->fetch_array($query))
 788              {
 789                  build_attachment_row($attachment, $table, true);
 790              }
 791  
 792              // Need to draw pagination for this result set
 793              if($num_results > $mybb->input['perpage'])
 794              {
 795                  $pagination_url = "index.php?module=forum-attachments&amp;results=1";
 796                  $pagination_vars = array('filename', 'mimetype', 'username', 'fid', 'downloads', 'downloads_dir', 'dateuploaded', 'dateuploaded_dir', 'filesize', 'filesize_dir');
 797                  foreach($pagination_vars as $var)
 798                  {
 799                      if($mybb->input[$var])
 800                      {
 801                          $pagination_url .= "&{$var}=".urlencode($mybb->input[$var]);
 802                      }
 803                  }
 804                  $pagination = draw_admin_pagination($mybb->input['page'], $mybb->input['perpage'], $num_results, $pagination_url);
 805              }
 806  
 807              echo $pagination;
 808              $table->output($lang->results);
 809              echo $pagination;
 810              
 811              $buttons[] = $form->generate_submit_button($lang->button_delete_attachments);
 812  
 813              $form->output_submit_wrapper($buttons);
 814              $form->end();
 815  
 816              $page->output_footer();
 817          }
 818      }
 819  
 820      $page->output_header($lang->find_attachments);
 821      
 822      $page->output_nav_tabs($sub_tabs, 'find_attachments');
 823  
 824      // If we have any error messages, show them
 825      if($errors)
 826      {
 827          $page->output_inline_error($errors);
 828      }
 829  
 830      $form = new Form("index.php?module=forum-attachments", "post");
 831  
 832      $form_container = new FormContainer($lang->find_where);
 833      $form_container->output_row($lang->name_contains, $lang->name_contains_desc, $form->generate_text_box('filename', $mybb->input['filename'], array('id' => 'filename')), 'filename');
 834      $form_container->output_row($lang->type_contains, "", $form->generate_text_box('mimetype', $mybb->input['mimetype'], array('id' => 'mimetype')), 'mimetype');
 835      $form_container->output_row($lang->forum_is, "", $form->generate_forum_select('forum[]', $mybb->input['forum'], array('multiple' => true, 'size' => 5, 'id' => 'forum')), 'forum');
 836      $form_container->output_row($lang->username_is, "", $form->generate_text_box('username', $mybb->input['username'], array('id' => 'username')), 'username');
 837  
 838      $more_options = array(
 839          "less_than" => $lang->more_than,
 840          "greater_than" => $lang->less_than
 841      );
 842  
 843      $greater_options = array(
 844          "greater_than" => $lang->greater_than,
 845          "is_exactly" => $lang->is_exactly,
 846          "less_than" => $lang->less_than
 847      );
 848  
 849      $form_container->output_row($lang->date_posted_is, "", $form->generate_select_box('dateuploaded_dir', $more_options, $mybb->input['dateuploaded_dir'], array('id' => 'dateuploaded_dir'))." ".$form->generate_text_box('dateuploaded', $mybb->input['dateuploaded'], array('id' => 'dateuploaded'))." {$lang->days_ago}", 'dateuploaded');
 850      $form_container->output_row($lang->file_size_is, "", $form->generate_select_box('filesize_dir', $greater_options, $mybb->input['filesize_dir'], array('id' => 'filesize_dir'))." ".$form->generate_text_box('filesize', $mybb->input['filesize'], array('id' => 'filesize'))." {$lang->kb}", 'dateuploaded');
 851      $form_container->output_row($lang->download_count_is, "", $form->generate_select_box('downloads_dir', $greater_options, $mybb->input['downloads_dir'], array('id' => 'downloads_dir'))." ".$form->generate_text_box('downloads', $mybb->input['downloads'], array('id' => 'downloads'))."", 'dateuploaded');
 852      $form_container->end();
 853  
 854      $form_container = new FormContainer($lang->display_options);
 855      $sort_options = array(
 856          "filename" => $lang->filename,
 857          "filesize" => $lang->filesize,
 858          "downloads" => $lang->download_count,
 859          "dateuploaded" => $lang->date_uploaded,
 860          "username" => $lang->post_username
 861      );
 862      $sort_directions = array(
 863          "asc" => $lang->asc,
 864          "desc" => $lang->desc
 865      );
 866      $form_container->output_row($lang->sort_results_by, "", $form->generate_select_box('sortby', $sort_options, $mybb->input['sortby'], array('id' => 'sortby'))." {$lang->in} ".$form->generate_select_box('order', $sort_directions, $mybb->input['order'], array('id' => 'order')), 'sortby');
 867      $form_container->output_row($lang->results_per_page, "", $form->generate_text_box('perpage', $mybb->input['perpage'], array('id' => 'perpage')), 'perpage');
 868      $form_container->end();
 869  
 870      $buttons[] = $form->generate_submit_button($lang->button_find_attachments);
 871      $form->output_submit_wrapper($buttons);
 872      $form->end();
 873  
 874      $page->output_footer();
 875  }
 876  
 877  function build_attachment_row($attachment, &$table, $use_form=false)
 878  {
 879      global $mybb, $form;
 880      $attachment['filename'] = htmlspecialchars_uni($attachment['filename']);
 881  
 882      // Here we do a bit of detection, we want to automatically check for removal any missing attachments and any not assigned to a post uploaded > 24hours ago
 883      // Check if the attachment exists in the file system
 884      $checked = false;
 885      $title = $cell_class = '';
 886      if(!file_exists(MYBB_ROOT.$mybb->settings['uploadspath']."/{$attachment['attachname']}"))
 887      {
 888          $cell_class = "bad_attachment";
 889          $title = $lang->error_not_found;
 890          $checked = true;
 891      }
 892      elseif(!$attachment['pid'] && $attachment['dateuploaded'] < TIME_NOW-60*60*24 && $attachment['dateuploaded'] != 0)
 893      {
 894          $cell_class = "bad_attachment";
 895          $title = $lang->error_not_attached;
 896          $checked = true;
 897      }
 898      else if(!$attachment['tid'] && $attachment['pid'])
 899      {
 900          $cell_class = "bad_attachment";
 901          $title = $lang->error_does_not_exist;
 902          $checked = true;
 903      }
 904      else if($attachment['visible'] == 0)
 905      {
 906          $cell_class = "invisible_attachment";
 907      }
 908      
 909      if($cell_class)
 910      {
 911          $cell_class .= " align_center";
 912      }
 913      else
 914      {
 915          $cell_class = "align_center";
 916      }
 917  
 918      if($use_form == true && is_object($form))
 919      {
 920          $table->construct_cell($form->generate_check_box('aids[]', $attachment['aid'], '', array('checked' => $checked)));
 921      }
 922      $table->construct_cell(get_attachment_icon(get_extension($attachment['filename'])), array('width' => 1));
 923      $table->construct_cell("<a href=\"../attachment.php?aid={$attachment['aid']}\" target=\"_blank\">{$attachment['filename']}</a>");
 924      $table->construct_cell(get_friendly_size($attachment['filesize']), array('class' => $cell_class));
 925  
 926      if($attachment['user_username'])
 927      {
 928          $attachment['username'] = $attachment['username'];
 929      }
 930      $table->construct_cell(build_profile_link($attachment['username'], $attachment['uid'], "_blank"), array("class" => "align_center"));
 931      $table->construct_cell("<a href=\"../".get_post_link($attachment['pid'])."\" target=\"_blank\">".htmlspecialchars_uni($attachment['subject'])."</a>", array("class" => "align_center"));
 932      $table->construct_cell(my_number_format($attachment['downloads']), array("class" => "align_center"));
 933      if($attachment['dateuploaded'] > 0)
 934      {
 935          $date = my_date($mybb->settings['dateformat'], $attachment['dateuploaded']).", ".my_date($mybb->settings['timeformat'], $attachment['dateuploaded']);
 936      }
 937      else
 938      {
 939          $date = $lang->unknown;
 940      }
 941      $table->construct_cell($date, array("class" => "align_center"));
 942      $table->construct_row();
 943  }
 944  ?>


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1