It would be very nice if you could flush all images from a preset attached to a single node via the Rules Module.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mikeytown2’s picture

Title: Integrate with rules module » Action: Flush node pics on node update; integration with rules module

Create an action that allows one to flush the node's pics on update. Comes in handy when you use node data in the pic; thus when the node changes, the pic needs to change as well.

mikeytown2’s picture

Title: Action: Flush node pics on node update; integration with rules module » Get array of files attached to node
Project: ImageCache » FileField
Version: 6.x-2.x-dev » 6.x-3.x-dev

First Step: How do I get an array of all pics that are connected to a node?
CCK?

function get_files_via_node($nid)
...
return array_of_files['fid'] => ['filename']['filepath']['type'];
mikeytown2’s picture

Status: Active » Needs review

This gives an array of all files that are connected to that node

/**
 * Get all filefield files connected to a node id.
 * @param $nid
 *   The Node ID.
 * 
 * Returns array()
 *   ['fid'] = file id
 *   ['type'] = type of cck field
 *   ['path'] = path to file
 *
 * Notes
 *   Does not return imagecache child files, only the base file.
 */
function get_filepaths_via_nid($nid)
{
  $fids = array();
  $filepaths = array();
  foreach (content_fields() as $field) {
    // If Field is an Image (imagefield.module) or filefield then
    if ($field['type'] == 'image' || $field['type'] == 'filefield') {
      $db_info = content_database_info($field);
      // Get Content Type DB name - FROM statement
      $tablename = $db_info['table'];
      //Get File ID DB Column Name - SELECT statement
      $fid_column = $db_info['columns']['fid']['column'];
      
      //get file id's
      $sql = "SELECT ".$fid_column." FROM ".$tablename." WHERE nid = '%s'";
      $result = db_query($sql, array($nid));
      while ($fileid_row = db_fetch_array($result)) {
        $fids[] = array('fid' => $fileid_row[$fid_column], 'type' => $field['type']);
      }
    }
  }
  foreach ($fids as $fid) {
    //get paths for file id
    $sql = "SELECT filepath FROM files WHERE fid = '%s'";
    $result = db_query($sql, array($fid['fid']));
    while ($filepath_row = db_fetch_array($result)) {
      $filepaths[] = array('fid' => $fid['fid'], 'type' => $fid['type'], 'path' => $filepath_row['filepath']);
    }
  }
  return $filepaths;
}

EDIT: give an hierarchical array to include type & fid

Array
(
    [0] => Array
        (
            [fid] => 138
            [type] => image
            [path] => sites/default/files/...jpg
        )

    [1] => Array
        (
            [fid] => 357
            [type] => image
            [path] => sites/default/files/...jpg
        )

    [2] => Array
        (
            [fid] => 356
            [type] => image
            [path] => sites/default/files/...jpg
        )
)
dopry’s picture

Status: Needs review » Active

There isn't a patch to review here... please restated your issue or proposal and write a proper patch.

mikeytown2’s picture

Being able to grab all the files that are attached to a node is quite handy.
http://drupal.org/node/374202

I thought that this code belongs in FileField.

mikeytown2’s picture

Status: Active » Needs review

hmmm new site isn't liking attachments right now

--- filefield\filefield-old.module	Fri Feb  6 02:56:30 2009
+++ filefield\filefield.module	Thu Feb 19 02:25:31 2009
@@ -714,3 +714,50 @@
 function filefield_validate_is_image_help($arguments = null) {
   return t('Must be a JPEG, PNG or GIF image');
 }
+
+<?php
+/**
+* Get all filefield files connected to a node id.
+* @param $nid
+*   The Node ID.
+*
+* Returns array()
+*   ['fid'] = file id
+*   ['type'] = type of cck field
+*   ['path'] = path to file
+*
+* Notes
+*   Does not return imagecache child files, only the base file.
+*/
+function filefield_get_paths_via_nid($nid)
+{
+  $fids = array();
+  $filepaths = array();
+  foreach (content_fields() as $field) {
+    // If Field is an Image (imagefield.module) or filefield then
+    if ($field['type'] == 'image' || $field['type'] == 'filefield') {
+      $db_info = content_database_info($field);
+      // Get Content Type DB name - FROM statement
+      $tablename = $db_info['table'];
+      //Get File ID DB Column Name - SELECT statement
+      $fid_column = $db_info['columns']['fid']['column'];
+     
+      //get file id's
+      $sql = "SELECT ".$fid_column." FROM ".$tablename." WHERE nid = '%s'";
+      $result = db_query($sql, array($nid));
+      while ($fileid_row = db_fetch_array($result)) {
+        $fids[] = array('fid' => $fileid_row[$fid_column], 'type' => $field['type']);
+      }
+    }
+  }
+  foreach ($fids as $fid) {
+    //get paths for file id
+    $sql = "SELECT filepath FROM files WHERE fid = '%s'";
+    $result = db_query($sql, array($fid['fid']));
+    while ($filepath_row = db_fetch_array($result)) {
+      $filepaths[] = array('fid' => $fid['fid'], 'type' => $fid['type'], 'path' => $filepath_row['filepath']);
+    }
+  }
+  return $filepaths;
+}
+?>
\ No newline at end of file
mikeytown2’s picture

or editing posts...

--- filefield\filefield-old.module	Fri Feb  6 02:56:30 2009
+++ filefield\filefield.module	Thu Feb 19 02:34:51 2009
@@ -714,3 +714,48 @@
 function filefield_validate_is_image_help($arguments = null) {
   return t('Must be a JPEG, PNG or GIF image');
 }
+
+/**
+* Get all filefield files connected to a node id.
+* @param $nid
+*   The Node ID.
+*
+* Returns array()
+*   ['fid'] = file id
+*   ['type'] = type of cck field
+*   ['path'] = path to file
+*
+* Notes
+*   Does not return imagecache child files, only the base file.
+*/
+function filefield_get_paths_via_nid($nid)
+{
+  $fids = array();
+  $filepaths = array();
+  foreach (content_fields() as $field) {
+    // If Field is an Image (imagefield.module) or filefield then
+    if ($field['type'] == 'image' || $field['type'] == 'filefield') {
+      $db_info = content_database_info($field);
+      // Get Content Type DB name - FROM statement
+      $tablename = $db_info['table'];
+      //Get File ID DB Column Name - SELECT statement
+      $fid_column = $db_info['columns']['fid']['column'];
+     
+      //get file id's
+      $sql = "SELECT ".$fid_column." FROM ".$tablename." WHERE nid = '%s'";
+      $result = db_query($sql, array($nid));
+      while ($fileid_row = db_fetch_array($result)) {
+        $fids[] = array('fid' => $fileid_row[$fid_column], 'type' => $field['type']);
+      }
+    }
+  }
+  foreach ($fids as $fid) {
+    //get paths for file id
+    $sql = "SELECT filepath FROM files WHERE fid = '%s'";
+    $result = db_query($sql, array($fid['fid']));
+    while ($filepath_row = db_fetch_array($result)) {
+      $filepaths[] = array('fid' => $fid['fid'], 'type' => $fid['type'], 'path' => $filepath_row['filepath']);
+    }
+  }
+  return $filepaths;
+}
\ No newline at end of file
quicksketch’s picture

Status: Needs review » Needs work

Hey mikeytown2, not sure if you're still interested in this or not. I think it'd be useful to include such an API function in FileField, especially for all those people that think the content_fields() function is just too scary and can't find a way out of the simplicity of Image module's $node->image method of checking for images.

However, there will need to be some changes before this API function is acceptable:
- It should be part of field_file.inc, so it should probably be something like field_file_node_files().
- It shouldn't be specific to getting filepaths, rather we should just return the whole file row, right now it's odd the function is called "*_get_paths_*" but returns much more than that.
- The current approach is inefficient, instead of doing individual selects, a JOIN would be better.
- This function should have the flexibility to limit itself to an individual field, rather than always targeting all fields.
- Please just attach the patch rather than posting right in the issue

I hope we can get these changes into FileField, like I said, I think it'd be very helpful for developers trying to get off of Image.

mikeytown2’s picture

OK cool, thanks for the input. Sorry for the ugly above, this was posted hrs after the d.o 6.x upgrade. Might be a week or 2 with my schedule, will do the join optimization last most likely.

- Nuke 2nd loop, replace with JOIN in first loop.
- SELECT * FROM files would grab [fid, uid, filename, filepath, filemime, filesize, status, timestamp] throw that into the sub-array.
- Optional $field variable in order to grab an individual field.
- Renaming the function to field_file_node_files() sounds like a good plan.

Anything else?

quicksketch’s picture

That's all I can think of at the moment. Thanks for taking this on!

quicksketch’s picture

I've been looking over the field_file.inc file and I realized this new function should not be placed in there. In fact, the field_file_references() function shouldn't be in there either. That file is meant to be the public APIs for file handling. There's no mention of anything CCK or FileField specific in the entire file (other than field_file_references).

So let's keep this in filefield.module. filefield_node_files() should do.

mikeytown2’s picture

FileSize
2.4 KB
mikeytown2’s picture

Status: Needs work » Needs review
FileSize
2.23 KB

working on the join. one of the added benefits of the join is I can include nid & vid in the array; which is helpful when the nid is not passed. also forgot the filemime. Do you see anyway to simplify the //get cck info code block; I have some repeating code in there still.

quicksketch’s picture

How does this look? I made the first parameter $node instead of $nid (and made it required) since I found that we can be more efficient by only getting the fields that apply to a specific node type. I also did the filtering based on the $node->vid, to reduce the duplicate rows. This also means that this function will only retrieve the current files attached to a node and not all previous revisions.

mikeytown2’s picture

FileSize
1.27 KB
1.36 KB

here's my take on your patch. for anyone else following this thread, call this function like the last one via filefield_get_node_files(node_load($nid));

quicksketch’s picture

Status: Needs review » Fixed
FileSize
5.84 KB

I generalized the approach used here so we could use it for #380200: Get node referencing a file also. I've combined both these issues into a single patch which is attached. The signature is still the same, but now it can accept both a field array (if you've already loaded it) or just the field name.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

sinasalek’s picture

I tried to apply your patch but it couldn't it says :

The patch seems outdated! The file line
 * Implementation of hook_file_references().
and the patchline
    // We prefer the PECL extension uploadprogress because it supports multiple
do not match!

I'm using 3.1, any idea?