Index: private_upload.module
===================================================================
--- private_upload.module
+++ private_upload.module
@@ -1,4 +1,5 @@
 <?php
+// $Id: private_upload.module,v 1.13.2.11 2009/11/29 18:42:14 lynn Exp $
 
 /**
  * @file
@@ -217,6 +218,22 @@
   
   return $requirements;
 }
+/*
+function private_upload_filefield_access($file) {
+  $result = -1;
+  $all_fields = content_fields();
+  //$filefields = array();
+  foreach ($all_fields as $field) {
+    if ($fields['type'] = 'filefield') {
+      
+      //$filefields[] = $field['name'];
+    }
+  }
+  
+  dsm($all_fields);
+  return $result;
+   
+}*/
 
 /**
  * hook_file_download: hook to veto file downloads.
@@ -237,13 +254,22 @@
     $filepath = file_create_path($file);
     $result = db_query("SELECT DISTINCT(u.nid) FROM {upload} u INNER JOIN {files} f ON u.fid = f.fid ".
                        "WHERE f.filepath = '%s'", $filepath);
+    //check if there are any upload module nodes associated with this file, if not the pass on
+    //to do this we'll use a bool and trip it to TRUE when a node is found.
+    $is_upload = FALSE;
     while ($row = db_fetch_array($result)) {
+      $is_upload = TRUE;
       $node = node_load($row['nid']);
       if (node_access('view', $node)) {
         return; // Access is ok as far as we are concerned.
       }
     }
-    return -1; // No nodes are granting access, so veto download.
+    if ($is_upload) {
+      return -1;
+    }
+    else {
+      return;
+    }
   }
 }
 
@@ -364,513 +390,4 @@
           );
           if (!realpath($file->filepath)) {
             $form['attachments']['wrapper']['files'][$fid]['msg'] = array(
-              '#value' => ' <span style="color:red">*Missing*</span>',
-            );
-            drupal_set_message("File is not where it should be: $file->filepath", 'warning');
-          }
-         
-          // Overwrite URL in description with special URL if file is private.
-          $href = _private_upload_create_url($file);
-          $description = "<small>". check_plain($href) ."</small>";
-          $form['attachments']['wrapper']['files'][$fid]['description'] = array(
-            '#type' => 'textfield', 
-            '#default_value' => (strlen($file->description)) ? $file->description : $file->filename, 
-            '#maxlength' => 256, 
-            '#description' => $description, 
-          );
-         }
-      }     
-    }
-  }  
-  elseif ($form_id == 'upload_js') {
-    $form['files']['#theme'] = 'private_upload_form';
-//    $form['#submit'][] = 'private_upload_form_submit'; // ???
-    
-    foreach ($form['files'] as $fid => $file) {
-      if (!_private_upload_starts_with($fid, '#')) { // Ignore the properties.
-        if ($_POST['files'][$fid]) { 
-          $private = $_POST['files'][$fid]['private'];
-          // While I am here lets fix the problem with delete and list as well.
-          // Q: Do I still need this fix in D6?
-          $form['files'][$fid]['list']['#default_value'] = $_POST['files'][$fid]['list'];
-          $form['files'][$fid]['remove']['#default_value'] = $_POST['files'][$fid]['remove'];
-        }
-        else { // File is newly uploaded so set private to default.
-          $private = (variable_get('private_upload_default', 'private') == 'private');
-        }
-        
-        $form['files'][$fid]['private'] = array(
-            '#type' => 'checkbox', 
-            '#default_value' => $private,
-        );
-      }
-    }
-  }
-}
-
-/**
- * Called to validate the upload form.
- */
-function private_upload_form_validate($form_id, $form_values) {
-  if (is_array($form_values['files']) && count($form_values['files'])) {
-    $file = array_shift($form_values['files']);
-    if (!isset($file['private'])) {
-      drupal_set_message( t("Private Upload cannot find privacy settings."), 'error' );
-      // Be sure we are going after core upload.module.
-      $upload_weight = (int)db_result(db_query("SELECT weight FROM {system} WHERE name = 'upload'"));
-      $private_weight = (int)db_result(db_query("SELECT weight FROM {system} WHERE name = 'private_upload'"));
-      if ($private_weight <= $upload_weight) {
-        $new_weight = $upload_weight + 1;
-        drupal_set_message(t("Adjusting private_upload's weight to !new_weight", array('!new_weight' => $new_weight)), 'warning');
-        db_query("UPDATE {system} SET weight = '%d' WHERE name = 'private_upload'", $new_weight);
-      }
-      else {
-        drupal_set_message(t("Please check for modules that conflicts with Private Upload."), error);
-      }
-    }
-  }
-}
-
-/**
- * Fixes edge case: When the node is first being created, the file->private info does not
- *  get moved automatically into the node. So we need to copy it by hand.
- * This seems like a bug in Drupal 6, but might just represent my limited understanding of
- *  the FormAPI changes.
- *
- * @param $form
- * @param $form_state
- */
-function private_upload_form_submit($form, &$form_state) {
-  if ($form_state['values'] && $form_state['values']['files']) {
-    foreach ($form_state['values']['files'] as $fid => $file) {
-      if (!isset($file->private)) { // Newly inserted file.
-        if (isset($form['attachments']['wrapper']['files'])) {
-          // I know it is naughty to look at the $_POST, but I can't find this value anywhere else.
-          // Seems like it should be in $form_state somewhere.
-          $private = $_POST['files'][$fid]['private']; 
-        }
-        else {
-          $private = (variable_get('private_upload_default', 'private') == 'private'); // Sumbit before Attach
-        }
-        $form_state['values']['files'][$fid]['private'] = $private;
-      }
-    }
-  }
-}
-// *****************************************************************************
-// Settings Functions **********************************************************
-// *****************************************************************************
-
-/**
- * Setting page.
- * Also reports status and acts as launching point for migration.
- */
-function private_upload_admin() {
-  drupal_set_title('Private Upload Settings');
-    
-  $form['settings'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Private Upload Settings'),
-    '#collapsible' => TRUE,
-  );
-
-  $public = file_directory_path();
-  
-  $form['settings']['private_upload_path'] = array(
-    '#type' => 'textfield',
-    '#title' => t('Private Upload Path'),
-    '#default_value' => variable_get('private_upload_path', 'private'),
-    '#description' => t('This folder will be inside of "!public".', array( '!public' => $public)),
-  );
-
-  $form['settings']['private_upload_default'] = array(
-    '#type' => 'select',
-    '#title' => t('Default Upload Privacy Setting'),
-    '#default_value' => variable_get('private_upload_default', 'private' ),
-    '#options' => array('private' => 'private', 'public' => 'public'),
-    '#description' => t('Are uploads public or private by default?'),
-  );
-  
-  // STATUS REPORT ***************************************************************
-  
-  $form['status'] = array(
-    '#type' => 'fieldset',
-    '#title' => t('Private Upload Status'),
-    '#collapsible' => TRUE,
-  );
-  
-  $public = file_directory_path();
-  $status[] = "Public File Folder: '$public'";
-  $private_path = _private_upload_path();
-  $output = "Private File Folder: '$private_path'";
-  $status[] = $output;
-  
-  // get status messages from the requirements hook.
-  _private_upload_requirements('runtime', $status);  
-    
-  // loop through all the file in private folder & collect stats.
-  $private_file_count = 0;
-  $d = opendir( $private_path );
-  if ($d) {
-    while ($f = readdir($d)) {
-      if ($f != '.' && $f != '..' && $f != '.htaccess' && $f != 'privacy_test.txt') {
-        $private_file_count++;
-      }
-    }
-    closedir( $d );
-   
-    $db_private_file_count = db_result( db_query("SELECT COUNT(fid) FROM {files} WHERE filepath REGEXP '^%s'", $private_path) );
-    $output = t("There are !fs_count files in the private folder, and the DB thinks there are !db_count private files.", array('!fs_count' => $private_file_count, '!db_count' => $db_private_file_count));
-    if ($db_private_file_count != $private_file_count) {
-      $status[] = '<div class="error">'. $output .'</div>';  
-    }
-    else {
-      $status[] = '<div class="ok">'. $output . t(" Great.") . '</div>';
-    }
-  }
-  else { // unable to open folder!
-    $status[] = '<div class="error">'. t("!private_path is not a valid directory (!is).", array('!private_path' => $private_path, '!is' => is_dir($private_path))) .'</div>';  
-  }
-  
-  // check for public files attached to private nodes.
-  $count = db_result( db_query('SELECT COUNT(DISTINCT(f.fid)) '. 
-                     'FROM {files} f INNER JOIN {upload} u ON f.fid=u.fid INNER JOIN {node_access} na ON u.nid=na.nid '.
-                     'WHERE na.gid != 0 AND f.filepath NOT REGEXP "^%s"', $private_path));
-  if ($count) {
-    $status[] = t("There are !count public files attached to private nodes. ", array('!count' => $count)) . l( 'Click here to make them all private.', 'admin/private_upload/migrate_private');
-  }
-  else {
-    $status[] = t("There are no public files attached to private nodes. Great.");
-  }
-
-  $result = db_fetch_array( db_query('SELECT COUNT(f.fid) as fids, COUNT(DISTINCT(u.nid)) as nids '.
-                                     'FROM {files} f INNER JOIN {upload} u ON f.fid = u.fid') );
-  $status[] = t("Uploaded files in db: !files files attached to !nodes nodes.", array('!files' => $result['fids'], '!nodes' => $result['nids']));
-  
-  $form['status']['info'] = array(
-    '#value' => '<ul><li>' . implode('</li><li>', $status) . '</li></ul>',
-  );
-  
-  return system_settings_form($form);
-}
-
-/**
- * Make sure the new private_upload_path can be created and writen to.
- */
-function private_upload_admin_validate($form_id, $form_values) {
-  variable_set('private_upload_path', $form_values['private_upload_path'] );
-  $private_upload_path = file_create_path($form_values['private_upload_path']);
-  
-  // FILE_CREATE_DIRECTORY and FILE_MODIFY_PERMISSIONS
-  if (!file_check_directory($private_upload_path, TRUE, 'private_upload_path')) {
-    return FALSE;
-  }
-}
-
-// *****************************************************************************
-// Callback Functions **********************************************************
-// *****************************************************************************
-
-/**
- * Callback to inject an .htaccess file into the private_upload_path folder
- */
-function _private_upload_add_htacess() {
-  $path = file_create_path( _private_upload_path() .'/.htaccess' );  
-  file_save_data( "SetHandler This_is_a_Drupal_security_line_do_not_remove
-Deny from all", $path, FILE_EXISTS_REPLACE );
-  drupal_set_message("Added .htaccess file at $path");
-}
-
-/**
- * Callback to make public file attached to private nodes also be private.
- *
- * @return: html info string
- */
-function _private_upload_migrate_private() {
-  $private_path = _private_upload_path();
-  $result = db_query('SELECT f.* FROM {files} f, {node_access} na '.
-                     ' WHERE f.nid = na.nid AND na.gid != 0 AND f.filepath NOT REGEXP "^%s" '.
-                     ' GROUP BY f.fid', $private_path  );
-  while ($file = db_fetch_object($result)) {
-    // file is attached to a private node, but is a public file, so move it.
-    $filepath = $file->filepath;
-    $filepath_orig = $filepath;
-    if (file_move($filepath, $private_path, FILE_EXISTS_RENAME)) {
-      // update the file path
-      $file->filepath = $filepath;
-      // check whether the file was renamed
-      if ($filepath_orig != $filepath) {
-        // update the filename in the object if so
-        $file->filename = basename($filepath);
-      }
-      $output .= t("Making !filename private", array('!filename' => $file->filename)) . "<br />";     
-      _private_upload_update_filepath($file);
-    }
-    else {
-      $output .= t("Could not move %filepath to private directory (fid: %fid attached to node: !nid).", array('%filepath' => $file->filepath, '%fid' => $file->fid, '!nid' => $file->nid)) . "<br />";          
-    }                        
-  }
-  return $output;
-}
-
-/**
- * Set the filepath for the file in the db.
- *
- * @param object $file
- */
-function _private_upload_update_filepath($file) {
-  db_query("UPDATE {files} SET filepath = '%s', filename = '%s' WHERE fid=%d", 
-           $file->filepath, $file->filename, $file->fid); 
-}
-
-// *****************************************************************************
-// Theme functions ***********************************************************
-// *****************************************************************************
-
-/**
- * hook_theme - theme registry.
- * New for D6 
- */
-function private_upload_theme() {
-  return array(
-    'private_upload_form' => array(
-       'arguments' => array('form' => NULL),
-     ),
-    'private_upload_attachments'  => array(
-       'arguments' => array('files' => NULL),
-    ),
-  );
-}
-
-/**
- *  Based on theme_upload_form_current.
- *  Adding the Private checkbox.
- */
-function theme_private_upload_form(&$form) {
-  $header = array(t('Delete'), t('List'), t('Private'), t('Description'), t('Weight'), t('Size'), '');
-  drupal_add_tabledrag('upload-attachments', 'order', 'sibling', 'upload-weight');
-  
-  foreach (element_children($form) as $key) {
-    // Add class to group weight fields for drag and drop.
-    $form[$key]['weight']['#attributes']['class'] = 'upload-weight';
-    
-    $row = array();
-    $row[] = drupal_render($form[$key]['remove']);
-    $row[] = drupal_render($form[$key]['list']);
-    $row[] = drupal_render($form[$key]['private']);
-    $row[] = drupal_render($form[$key]['description']);
-    $row[] = drupal_render($form[$key]['weight']);
-    $row[] = drupal_render($form[$key]['size']);
-    $row[] = drupal_render($form[$key]['msg']);
-    $rows[] = array('data' => $row, 'class' => 'draggable');
-  }
-  $output = theme('table', $header, $rows, array('id' => 'upload-attachments'));
-  $output .= drupal_render($form);
-  return $output;  
-}
-
-/**
- * Displays file attachments in table.
- * Taken from theme_upload_attachments.
- */
-function theme_private_upload_attachments($files) {
-  $header = array(t('Attachment'), t('Size'));
-  $rows = array();
-  if (is_array($files)) {
-    foreach ($files as $file) {
-      $file = (object)$file;
-      if ($file->list && !$file->remove) {
-        $href = _private_upload_create_url($file); // this is the changed line
-        $text = $file->description ? $file->description : $file->filename;
-        $rows[] = array(l($text, $href), format_size($file->filesize));
-      }
-    }
-    if (count($rows)) {
-      return theme('table', $header, $rows, array('id' => 'attachments'));
-    }
-  }
-}
-
-// *****************************************************************************
-// Utility functions ***********************************************************
-// *****************************************************************************
-
-/**
- * Returns the system path for the private folder,
- * Or false if the folder is invalid.
- * 
- */
-function _private_upload_path() {
-  return file_create_path( variable_get('private_upload_path', 'private') );
-}
-
-/**
- * Utility
- * @return bool: does str1 start with str2
- */
-function _private_upload_starts_with( $str, $start ) {
-  if (count($str) == 0) return FALSE; // avoid false positive.
-  return strstr($str, $start) == $str;  
-}
-
-/**
- * Utility: replace start with new in str1.
- * @return string: the modified string.
- */
-function _private_upload_replace_start_with( $str, $start, $new ) {
-  return substr_replace( $str, $new, 0, strlen($start) );
-}  
-
-/**
- * @param $filepath
- * @return boolean - if the $filepath refers to a private file
- */
-function _private_upload_is_file_private( $filepath ) {
-//  $private_prefix = 'private_upload'; // fake path of private file (for public consumption and menu)
-  $private_path = _private_upload_path();
-  $is_in = _private_upload_starts_with($filepath, $private_path );
-  return $is_in;              
-}
-
-
-/**
- * Create a URL for the file that changes if the file is public or private.
- * TODO - Push to get a file_create_url hook into Drupal7.
- *
- * @param file object $file
- * @return str: the correct URL
- */
-function _private_upload_create_url($file) {
-  global $conf;
-  if (_private_upload_is_file_private($file->filepath)) {
-    $download_method = variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC); // this should be PUBLIC, but don't break misconfigured systems
-    $conf['file_downloads'] = FILE_DOWNLOADS_PRIVATE;
-  }
-  // Generate valid URL for both existing attachments and preview of new attachments (these have 'upload' in fid)     
-  $href = file_create_url((strpos($file->fid, 'upload') === FALSE ? $file->filepath : file_create_filename($file->filename, file_create_path())));
-  if (_private_upload_is_file_private($file->filepath)) {
-    $conf['file_downloads'] = $download_method;
-  }
-  return $href;
-}
-
-/**
- * _private_upload_is_url_protected()
- *
- * Based on work by schultkl: http://drupal.org/node/201547
- * fsockopen used b/c get_headers() fails when allow_url_fopen disabled.
- *
- * Status codes checked:
- * 
- *   200 OK:    The request has succeeded.
- *   302 Found: The requested resource resides temporarily under a different URI
- *   See: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
- *
- * @param $url: url to check if publicly accessible
- * @return boolean true if proven to be non-publically accessible, else false (public, or unknown)
- */
-function _private_upload_is_url_protected($url) {
- 
-  $return_val          = FALSE; 
-  $socket_open_timeout = 30;
-  $read_data_timeout   = 10;
-  $max_chunk           = 1024;
-  $status_codes        = array("200", "302"); // see function header for code details
-  
-  // parse and open a socket to the requested resource
-  $url_info=parse_url($url); 
-  $port=isset($url_info['port']) ? $url_info['port'] : 80;
-  $fp=fsockopen($url_info['host'], $port, $errno, $errstr, $socket_open_timeout);
-
-  if (!$fp) {
-    drupal_set_message( t("Unable to test file access: !errstr", array('!errstr' => $errstr)), 'error' );
-    return FALSE; // Failure - file status is unknown.
-  }
-
-  stream_set_timeout($fp, $read_data_timeout);
-
-  // Request resource headers
-  $head = "HEAD ". @$url_info['path'] ."?". @$url_info['query'];
-  $head .= " HTTP/1.0\r\nHost: ". @$url_info['host'] ."\r\n\r\n";
-  fputs($fp, $head);
-
-  // Read resource headers
-  if ($header=trim(fgets($fp, $max_chunk))) {
-    $header_array = explode(': ', $header);
-    $header_type = $header_array[0];
-    
-    foreach ($status_codes as $status_code) {
-      if (strstr($header_type, $status_code)) {
-        fclose($fp);
-        return FALSE; // Falure - file is publically accessable.
-      }
-    } 
-  }
-
-  fclose($fp);
-  return TRUE; // good
-}
-
-
-// *****************************************************************************
-// Views 1.x Integration   *****************************************************
-// *****************************************************************************
-
-function private_upload_views_tables_alter(&$table_data) {
-  $table_data['files']['fields']['filepath']['handler'] = 'private_upload_views_handler_filepath'; 
-  $table_data['files']['fields']['filepath']['option'] = array(
-    '#type' => 'select',
-    '#options' => array(
-      'raw' => t('Show the true pathname'),
-      'usable' => t('Show the usable pathname'),
-    ),
-  );
-    
-  $table_data['files']['fields']['all_files']['handler'] = array(
-    'private_upload_views_handler_all_files' => t('All files'),
-    'private_upload_views_handler_listed_files' => t('Listed files')
-  );
-}
-
-function private_upload_views_handler_filepath($fieldinfo, $fielddata, $value, $data) {
-  if ($fielddata['options'] == 'usable') {
-    if (_private_upload_is_file_private($value)) {
-      $value = _private_upload_replace_start_with($value, _private_upload_path(), 'system/files' );
-    }
-  }
-  return $value;
-}
-
-/**
- * Display all files attached to a given node.
- */
-function private_upload_views_handler_all_files($fieldinfo, $fielddata, $value, $data, $listed = FALSE) {
-  if ($listed) {
-    $and = " AND list = 1";
-  }
-  $links = array();
-
-  $result = db_query("SELECT f.*, fr.* FROM {upload} fr INNER JOIN {files} f ON f.fid = fr.fid ".
-                     "WHERE fr.vid = %d $and", $data->vid);
-  while ($file = db_fetch_object($result)) {
-    // link/nolink use file filename; linkdesc/nolinkdesc use file description
-    if ($fielddata['options'] == 'link' || $fielddata['options'] == 'nolink') {
-      $display_string = $file->filename;
-    } 
-    else {
-      $display_string = $file->description;
-    }
-    if ($fielddata['options'] == 'nolink' || $fielddata['options'] == 'nolinkdesc') {
-      $links[] = check_plain($display_string);
-    } 
-    else {
-//      $links[] = l($display_string, check_url(file_create_url($file->filepath))); // original
-      $links[] = l($display_string, _private_upload_create_url($file)); // the change
-    }
-  }
-  return implode(' | ', $links);
-}
-
-function private_upload_views_handler_listed_files($fieldinfo, $fielddata, $value, $data) {
-  return private_upload_views_handler_all_files($fieldinfo, $fielddata, $value, $data, TRUE);
-}
+       
\ No newline at end of file
