You are here

function imagecache_actions_node_from_filepath in ImageCache Actions 6.2

Same name and namespace in other branches
  1. 6 utility.inc \imagecache_actions_node_from_filepath()

Given only a file filename, track back to see if we can detect the parent node and provide some context info.

This will be different in different cases. Supported : image.module image nodes imagefield cck fields (may be multiple) upload.module attachments

TODO: image_attach attachments

Parameters

$filepath:

$file_data MAY get some details filled in on it by reference if data: was found.

Return value

a loaded $node object

1 call to imagecache_actions_node_from_filepath()
imagecache_customactions_image in customactions/imagecache_customactions.module
Implementation of hook_image()
1 string reference to 'imagecache_actions_node_from_filepath'
imagecache_customactions_image in customactions/imagecache_customactions.module
Implementation of hook_image()

File

./utility.inc, line 221
Utility form, conversion and rendering functions for image processes

Code

function imagecache_actions_node_from_filepath($filepath, &$file_data = NULL) {

  // lookup upload.module attachments
  if (module_exists('upload')) {
    $sql = "SELECT nid, f.fid FROM {upload} AS u INNER JOIN {files} AS f ON u.fid = f.fid WHERE f.filepath = '%s'";
    $results = db_query_range($sql, $filepath, 0, 1);
    if ($row = db_fetch_array($results)) {

      // Return immediately
      $node = node_load($row['nid']);

      // also include the file description
      $file_data = $node->files[$row['fid']];
      return $node;
    }
  }

  // Lookup image.module nodes
  if (module_exists('image')) {
    $sql = "SELECT nid FROM {image} AS i INNER JOIN {files} AS f ON i.fid = f.fid WHERE f.filepath = '%s'";
    if ($nid = db_result(db_query_range($sql, $filepath, 0, 1))) {

      // Return immediately
      return node_load($nid);
    }
  }

  // Lookup filefield imagefield CCK attachments.
  //
  // Drupal 6 version here based largely on work done by mikeytown2
  // http://drupal.org/node/363434
  // This is a terrible way to retrieve information, but CCK doesn't provide a way to reverse-lookup like this
  // BAD CODE follows
  // If someone could roll these DBlookups into a smaller ball, that would be fun.
  // Due to CCKs use of dynamically created table names .. I don't know how.
  // Multiple file ID's might have the same name, get all
  // (but return just the first successful match)
  $result = db_query("SELECT fid FROM {files} WHERE filepath = '%s'", $filepath);
  $fids = array();
  while ($row = db_fetch_array($result)) {
    $fids[] = $row['fid'];
  }
  if (!empty($fids)) {

    // Find out if any filefield contains this file, and if so, which field
    // and node it belongs to. Required for later access checking.
    // CCK field analysis is in the outer loop,
    // fids are scanned in the inner loop for a little speed.
    // Get A List Of ALL CCK Fields and look for them individually,
    // it's the only way we can reverse the lookups
    foreach (content_fields() as $field) {

      // If Field is an Image (imagefield.module) or filefield then
      if ($field['type'] == 'image' || $field['type'] == 'filefield') {

        // Need to do lots of lookups to find out what the storage tables look like.
        // Grab All DB Column Names for that CCK Field
        $db_info = content_database_info($field);

        // Get Content Type DB name - FROM statement
        $tablename = $db_info['table'];

        //Get File ID DB Column Name - WHERE statement
        $fid_column = $db_info['columns']['fid']['column'];

        // Construct a Query that looks for all known fids in one go.
        // eg:
        // SELECT nid FROM content_type_story
        //   WHERE field_illustration_fid = 77
        //   OR field_illustration_fid = 99;
        $wheres = array();
        $query_args = array();
        foreach ($fids as $fid) {
          $wheres[] = " %s = %d ";
          $query_args[] = $fid_column;
          $query_args[] = $fid;
        }
        $result = db_query('SELECT nid FROM {' . $tablename . '} WHERE ' . join(' OR ', $wheres), $query_args);
        while ($row = db_fetch_array($result)) {

          // This while is a dummy loop - Just break out and return the first matching node.
          // If more than one node owns this image then ???
          $node = node_load($row['nid']);

          // Add even more info - the description "data" that MAY have been added
          // to this file on this node using filefield_meta and stuff.
          // Return the data associated specifically with this file also;
          // Do this via the handle on the file_data object we were passed in.
          // Slightly mushed together - I want it to mostly resemble the traditional file attachment object.
          // We have the node but lost track of the file in the process.
          // Need to scan again to make sure we got the right one :-{
          if ($file_fields = $node->{$field['field_name']}) {
            foreach ($file_fields as $file_field) {
              if ($file_field['fid'] == $fid) {
                $actual_file = $file_field;
              }
            }
            $file_data = (object) array_merge((array) $file_data, $actual_file['data'], $actual_file);
          }
          return $node;
        }
      }
    }
  }
}