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
/**
* 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.
Comments
Comment #1
mikeytown2 commentedforgot to get rid of the print_r & echo lines in this function: imagecache_node_refresh_action
Comment #2
drewish commentedthe 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.
Comment #3
mikeytown2 commented@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
Comment #4
2noame commentedI 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?
Comment #5
drewish commentedOkay 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.
Comment #6
drewish commentedmarked #375631: Rules integration as a duplicate.
Comment #7
mikeytown2 commentedBeen 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.
Comment #8
mikeytown2 commentedHere's my first go around at it. Adds in 3 actions, the generate one is configurable.
Comment #9
mshepherd commentedI'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.
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.
Comment #10
mikeytown2 commentedHere'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.Comment #11
mshepherd commentedThat works perfect! Many thanks,
Matthew
Comment #12
mikeytown2 commentedSet this to RTBC if everything works as expected.
Comment #13
mshepherd commentedComment #14
drewish commentedimagecache_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:
Why can't this just call imagecache_image_generate_preset()?
Comment #15
justintime commentedI would love to see this patch make it mainline, so I'll bite. I'm still pretty green to Drupal and PHPDoc and I'll take any criticism constructively.
Fixed.
Fixed.
No, it isn't. It doesn't look to me like simple FAPI form functions have PHPDocs by looking at node.module, so I just removed them.
I also removed PHPDocs from here, I couldn't find any FAPI submit handlers in imagecache or node.module that had PHPDocs.
Fixed.
It can, and it does now.
Comment #16
justintime commentedActually attaching the patch would probably help it get accepted faster -- sorry!
Comment #17
shiva7663 commentedsubscribe
Comment #18
robin van emden commentedJust tested the imagecache-374202-1 patch, works. Now using it on a live site. Would be great if this patch can be added to the next release.
Comment #19
justintime commentedJust a note that using this patch with Views Bulk Operations makes for a very powerful way of generating all thumbnails for all images using batch API.
Comment #20
shiva7663 commentedDid using it with VBO chew up a big bunch of memory?
Comment #21
justintime commentedNope, that's the beauty of it. You can tell VBO to use Batch API with actions, so it calls the action once per node. If you can run the action on one node, you can run it on 100,000 nodes in this manner - memory footprint will not be any different. From VBO's homepage:
This is a perfect marriage if you ask me - after a huge import of images, you can prime imagecache so that your users don't have to wait for it.
Comment #22
ocanzillon commentedI have an issue with generating imagecache presets (all or some) for a node. This is probably due to call to file_get_contents function, which should be deactivated on my hosting. Does it should not call imagecache internal function, such as imagecache_build_derivative instead?
Comment #23
mikeytown2 commented@ocanzillon
Try this
Comment #24
mikeytown2 commentedHere's a better attempt
Comment #25
mikeytown2 commentedthis one works
Comment #26
mikeytown2 commentedThe real deal.
Comment #27
mikeytown2 commentedFixes the Generate All action
Comment #28
mikeytown2 commentedSorry, wrong patch; this one fixes the generate all
Comment #29
mikeytown2 commented@drewish
What are the odds of this getting accepted? I'm tempted to create a module just for this. One of the main reasons is it does not work correctly with core's trigger module because the trigger is fired too soon; the files are not there. OTOH using it with rules/VBO & the results are quite remarkable.
Comment #30
ocanzillon commentedThat's ok for me: imagecache_build_derivative works perfectly in my case, where file_get_contents did not work before.
Moreover code is clean and very understandable! Thanks a lot!
Comment #31
drewish commentedthis looks really good. couple of small nits before we can commit it.
the action functions take $node by reference but don't make any changes to it. and since we require PHP 5 $node is an object and always passed by reference. so lets drop that.
I don't think the default value for checkboxes should be a string:
The Forms API Reference makes me think it should be an array.
I think that imagecache_generate_action_submit() could be simplified by using array_filter().
Could we change $dst to $destination?
Comment #32
drewish commentedmikeytown2, this will go in. it's really close and i appreciate your persistance in spite of my inattention.
Comment #33
mikeytown2 commentedi got $dst from
function imagecache_build_derivative($actions, $src, $dst)Changes made, please review.
Comment #34
drewish commentedI added some documentation to make it clearer that there are two types of actions in the module now. Also added some @see tags to link things together a bit more.
The bigger change is that I realized we don't have a hard dependency on the filefield module so we need to conditionally check if it exists. We should probably change the action text to make it clearer that it only affects file and image fields.
I made some changes to imagecache_generate_image() to have it return a value indicating success and to validate the presetname. I'm not sure that we should be checking file_exists(), it might be best to just always regenerate the image...
Comment #35
drewish commentedmikeytown2, any thoughts on this?
Comment #36
mikeytown2 commentedWhat do you think about generate preset (check file_exists) & the regenerate preset (doesn't check file_exists)? This would bring us up to 5 actions. 2 generate, 2 regenerate & 1 delete.
Is there anyway to detect other things in the node using imagecache? If it does all, that would be ideal.
Comment #37
drewish commentedno, i'd rather not add more variations, they just tend to clutter up the list. we should pick sane defaults and just go with those. i suppose that file_exists() is the sane default since you could have a flush all action ahead of that if you really wanted to regenerate them.
yeah file/imagefields are all we could really hit... though we could add upload module... we should add some messaging to make it clear whatever we decide to operate on.
Comment #38
mikeytown2 commentedI've never played with the upload module, always been a filefield man myself. So if you can/want to add integration with the upload module, I would be +1 for that. Rewording the action, to let the admin know what files this action will work on would be a good idea. Who's going to make the wording changes, me or you?
Comment #39
drewish commentedWell lets get the filefield stuff in and word it appropriately for that and if someone wants to add upload.module support we can change the messaging then. If you've got the time to reroll I'd appreciate it.
Comment #40
mikeytown2 commentedRewrote the 3 actions so they point to a new function imagecache_get_images_in_node. Right now this just gets the filefield images; but we can use this for things like the image module in the future. This reduced some code duplication between the 3 actions.
Made sure the $node object is passed by reference.
Renamed the actions so they all start with
ImageCache:. Example: "ImageCache: Generate ALL presets for this nodes filefield images".Comment #41
mikeytown2 commentedforgot the return $files in the new function
Comment #42
drewish commentedCoule of small things:
Should be "node's" right?
I think we can drop imagecache_generate_action_submit() and instead just add the following to imagecache_generate_action_form():
We should add a node in the comment for imagecache_get_images_in_node() that it, currently, only supports images stored in filefields.
Comment #43
drewish commented+ 'description' => t('ImageCache: Generate Configured preset(s) for this nodes filefield images'),
Configured should probably be lower case.
Comment #44
mikeytown2 commentedis $form['array_filter'] correct? anyway re-roll of the patch with the 2 changes.
Comment #45
mikeytown2 commentedlowercase c
Comment #46
drewish commentedMade a few comment changes and committed the attached. Thanks for your patience... I now realize I put a typo in the commit message... oh well.
Comment #48
protoplasm commentedThis is amazing. The only feature missing is the check all button.
For instance, if I have a 1000 nodes that I want to prepopulate, one click and all the nodes are selected. Thanks for your good efforts on this dev version. Imagecache rocks.Oh--I see. If you enter a large number and add a pager, the select all button appears! Fantastic! Thanks all.
Comment #49
protoplasm commentedThe latest dev version isn't generating these images for me. I get messages that the presets have been generated when, in fact, they aren't being generated. I thought maybe it was a permissions problem, so I went to the permissions page and checked off the actions_permission for administrator for vbo flush and generate actions. The permissions page says it is an illegal choice and won't permit the check mark. I don't have this problem with any of my other vbo actions. Also, I've noticed that the permissions on the preset files is now automatically 775 instead of 755--I don't know if that is by design or what.
This module feature has great potential for me if I can get it to work. Hope someone has an idea why this isn't working for me.
--a quick addendum--I looked for perms for the action_permissions but didn't find them.
Comment #50
Coupon Code Swap commentedI'm getting an error with latest Imagecache dev after attempting to save a Rule with - ImageCache: Generate configured preset(s) for this node's filefield images
the bug is reported here:
http://drupal.org/node/813804
is there any way to get this working?