Actions: flush all, generate, generate all presets per node

mikeytown2 - February 13, 2009 - 22:44
Project:ImageCache
Version:6.x-2.x-dev
Component:Code
Category:feature request
Priority:normal
Assigned:Unassigned
Status:needs work
Description

Given a node, get's all files connected to that node. Selects image cck fields. Flushes all image derivatives & regenerates them. I've never done an action before so It might need some help? Seems to work though.

Using these 2 "external" functions; which I've included below.
http://drupal.org/node/373864
http://drupal.org/node/369560#comment-1255453

<?php
/**
* Implementation of hook_action_info().
*
*/
function imagecache_action_info() {
  return array(
   
'imagecache_node_refresh_action' => array(
      
'type' => 'node',
      
'description' => t('Regenerate nodes images (flush + generate)'),
      
'configurable' => FALSE,
      
'hooks' => array(
        
'nodeapi' => array('presave', 'insert', 'update', 'view'),
       )
    )
  );
}

/**
* Regenerate all pictures in a given node
* @param &$node
*  
*
* Notes
*   This is a slow function, since it waits for each derivative to be generated
*/
function imagecache_node_refresh_action(&$node, $context) {
 
$paths = imagecache_get_filepaths_via_nid($node->nid);
 
print_r($paths);
  foreach (
$paths as $path) {
    if (
$path['type'] == 'image') {
     
imagecache_image_flush($path['path']);
     
imagecache_generate_all_presets($path['path']);
      echo
$path['path'] . "\n";
    }
  }
}


/**
* 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 imagecache_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;
}

/**
* Request URI, thus generating pic
* @param $path
*   The path to the orginal file
*
* Notes
*   This is a slow function, since it waits for each derivative to be generated
*/
function imagecache_generate_all_presets($path) {
  foreach (
imagecache_presets() as $preset) {
   
file_get_contents(base_url.$base_path.imagecache_create_path($preset['presetname'], $path));
  }
}
?>

I'm just adding these functions at the end of the imagecache.module file.

#1

mikeytown2 - February 13, 2009 - 23:39

forgot to get rid of the print_r & echo lines in this function: imagecache_node_refresh_action

#2

drewish - February 17, 2009 - 21:45

the problem with the function as pasted is that it creates a dependency on cck. there's plenty of ways to use this module that dont' involve the cck. i think that this would actually a better contrib module.

also this isn't a proper patch. please see http://drupal.org/patch for info on how to create one.

#3

mikeytown2 - February 17, 2009 - 23:05

@drewish, thanks for looking at the code.

Ideally imagecache_get_filepaths_via_nid() gets integrated with FileField (as I hinted at with the link in the original post). That takes care of the cck dependency. The question is where should the action live? Does it belong in ImageCache or in FileField, or ...? The action involves both FileField & ImageCache. It uses FileField to find what files are attached to the node, the real "action" is done with ImageCache (flush & generate).

Here's the kinda pointless diff IMHO

AttachmentSize
imagecache-patch.diff 3.08 KB

#4

2noame - April 29, 2009 - 10:35

I don't know how to go about implementing this code. Do I just copy and paste it into the imagecache.module file and that's it? Do I need to run update.php or anything?

Also, what does this do exactly? I'm hoping what it does is makes Image smart enough to generate previews and thumbs in the same directory as the main image they are attached to, instead of in whatever directory is currently set as the default image path. Does it?

#5

drewish - April 29, 2009 - 14:13
Status:needs review» needs work

Okay so giving this some thought and I can see some cool usecases but before I'd commit it I want it to operate like the email presets. There needs to be a configuration form where you pick a file source (attached via upload.module or select from the filefields ) and checkboxes for presets that should be run.

#6

drewish - April 29, 2009 - 14:18

marked #375631: Rules integration as a duplicate.

#7

mikeytown2 - April 29, 2009 - 19:11

Been busy with boost #326515: Roadmap For stable 6.x-1.0 trying to get a stable release out. Making this configurable is the best way to do this. I can probably tackle this in late may.

#8

mikeytown2 - May 22, 2009 - 09:15
Title:Action: flush & regenerate per node» Actions: flush all, generate, generate all presets per node
Status:needs work» needs review

Here's my first go around at it. Adds in 3 actions, the generate one is configurable.

AttachmentSize
imagecache.module.patch 3.72 KB

#9

mshepherd - October 27, 2009 - 11:02

I've applied this patch and assigned the action correctly (to run the 'create all imagecache presets' action when a node is created or updated). I have a problem!

I get the following messages when I update a node.

  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/ib_thumbnail/image_field_images/3fishes.jpeg) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Large/image_field_images/3fishes.jpeg) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Medium/image_field_images/3fishes.jpeg) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Small/image_field_images/3fishes.jpeg) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/ib_thumbnail/image_field_images/theme.png) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Large/image_field_images/theme.png) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Medium/image_field_images/theme.png) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.
  • warning: file_get_contents(/sites/dev.wayc.org.uk/files/imagecache/Small/image_field_images/theme.png) [function.file-get-contents]: failed to open stream: No such file or directory in /home/server/websites/drupal/illuminate/live/drupal-6.14/sites/dev.wayc.org.uk/modules/imagecache/imagecache.module on line 1237.

An error for each preset and each attached image. Line 1237 is the file_get_contents($base_url . '/' . imagecache_create_path($preset['presetname'], $path)); line at the end of the patch.

I feel like it nearly works, but if you had some insight into what I could do to get it working properly, that would be great.

As a related note, my use case is that I use IMCE to browse and add previously added (cck imagefield) images to nodes. I'd like people to be able to choose between the presets, but unless they've been displayed before, they're not already generated. This patch would be useful in fixing that. Thanks.

#10

mikeytown2 - October 27, 2009 - 20:10

Here's a re-roll of the above patch, with a fix that should make it work; forgot global $base_url; at the top of that function.

AttachmentSize
imagecache-374202.patch 4.06 KB

#11

mshepherd - October 29, 2009 - 16:26

That works perfect! Many thanks,
Matthew

#12

mikeytown2 - October 29, 2009 - 18:29

Set this to RTBC if everything works as expected.

#13

mshepherd - October 30, 2009 - 08:31
Status:needs review» reviewed & tested by the community

#14

drewish - October 30, 2009 - 18:43
Status:reviewed & tested by the community» needs work

imagecache_action_info() has some indenting issues in the last action definition.

PHPDocs for imagecache_flush_action() and imagecache_generate_all_action() are incomplete.

imagecache_generate_action_form() is not really an implementation of hook form is it?

imagecache_generate_action_submit()'s PHPDocs are also incorrect.

Remove the extra new line between the docs and the function body:

+ */
+
+function imagecache_image_generate_preset($path, $preset_name) {

Why can't this just call imagecache_image_generate_preset()?

+  foreach (imagecache_presets() as $preset) {
+    file_get_contents($base_url . '/' . imagecache_create_path($preset['presetname'], $path));
+  }

 
 

Drupal is a registered trademark of Dries Buytaert.