You are here

function _download_count_get_nodes_by_filefield in Download Count 6.2

Same name and namespace in other branches
  1. 7.2 download_count.module \_download_count_get_nodes_by_filefield()
2 calls to _download_count_get_nodes_by_filefield()
download_count_file_download in ./download_count.module
Implementation of hook_file_download().
_download_count_is_accessible_by_filefield in ./download_count.module

File

./download_count.module, line 334
Tracks file downloads for files stored in the drupal files table using the private files setting or custom private filefield.

Code

function _download_count_get_nodes_by_filefield($file) {

  // check if FileField is enabled
  if (!function_exists('filefield_view_access')) {
    return NULL;
  }

  // not enabled
  // The following logic is snipped from filefield.module 1.209 2009/10/20 17:46:22
  // which is part of CCK FileField 6.x-3.2 release, see http://drupal.org/project/filefield
  $result = db_query("SELECT * FROM {files} WHERE filepath = '%s'", $file);
  if (!($file = db_fetch_object($result))) {

    // We don't really care about this file.
    return NULL;

    // not known
  }

  // Find out if any file field contains this file, and if so, which field
  // and node it belongs to. Required for later access checking.
  $cck_files = array();
  foreach (content_fields() as $field) {
    if ($field['type'] == 'filefield' || $field['type'] == 'image') {
      $db_info = content_database_info($field);
      $table = $db_info['table'];
      $fid_column = $db_info['columns']['fid']['column'];
      $columns = array(
        'vid',
        'nid',
      );
      foreach ($db_info['columns'] as $property_name => $column_info) {
        $columns[] = $column_info['column'] . ' AS ' . $property_name;
      }
      $result = db_query("SELECT " . implode(', ', $columns) . "\n                          FROM {" . $table . "}\n                          WHERE " . $fid_column . " = %d", $file->fid);
      while ($content = db_fetch_array($result)) {
        $content['field'] = $field;
        $cck_files[$field['field_name']][$content['vid']] = $content;
      }
    }
  }

  // If no file field item is involved with this file, we don't care about it.
  if (empty($cck_files)) {
    return NULL;

    // not known
  }

  // If any node includes this file but the user may not view this field,
  // then deny the download.
  foreach ($cck_files as $field_name => $field_files) {
    if (!filefield_view_access($field_name)) {
      return FALSE;

      // inaccessible
    }
  }

  // So the overall field view permissions are not denied, but if access is
  // denied for ALL nodes containing the file, deny the download as well.
  // Node access checks also include checking for 'access content'.
  $nodes = array();
  $denied = FALSE;
  foreach ($cck_files as $field_name => $field_files) {
    foreach ($field_files as $revision_id => $content) {

      // Checking separately for each revision is probably not the best idea -
      // what if 'view revisions' is disabled? So, let's just check for the
      // current revision of that node.
      if (isset($nodes[$content['nid']])) {
        continue;

        // Don't check the same node twice.
      }
      if ($denied == FALSE && ($node = node_load($content['nid'])) && node_access('view', $node) == FALSE) {

        // You don't have permission to view the node this file is attached to.
        $denied = TRUE;
      }
      $nodes[$content['nid']] = $node;
    }
    if ($denied) {
      return FALSE;

      // inaccessible
    }
  }

  // Access is granted.
  return $nodes;
}