This is about 5.x-2.2 with recent dynamic text support addition.

I have imagefield attached to node.
If I understand it correctly, I should see $node object as $caption['node']. But the following code inside evaluated php code box

$pre =  "<pre>". var_export($caption['node'],TRUE). "</pre>";
drupal_set_message($pre);

reports $caption['node'] as NULL

Comments

dman’s picture

Version: 5.x-2.2 » 6.x-1.x-dev

I can't say.
The code looks extremely fragile to me - doing a text match on the stored filename, analyzing the database to see if it's got any imagefield data tables...
Looks to me like it's getting the filename, but then matching that against the database filepath - which I'd expect to be longer. But I don't know imagefield.
Needs work.

/**
 * Generate the dynamic text for this image.
 * Was textactions caption - now merged as an option of text2canvas
 * 
 * TODO further code review for safety etc
 * 
 * @param $image object, such as it is
 * @param $action definition
 * 
 * @return $text Plain string to be placed on the imagecache process.
 */
function textactions_evaluate_text($image, $action) {
  // store our variables here
  $caption=array();
  
  // Find the image name
  $caption['path'] = substr($image->source, strrpos($image->source, '/') + 1);

  // If the image is a cck imagefield,
  // Find the image's optional title and alt text, as well as its node
  if (module_exists('imagefield')) {
    // a lot of work to find if the content_field_image_cache actually exists yet
    $table_found = false;
    $r = mysql_query("SHOW TABLES");
    while($row = mysql_fetch_array($r)) {
      if($row[0] == 'content_field_image_cache') {
        $table_found = true;
        break;
      }
    }
    if($table_found) {
      // if content_field_image_cache exists,
      // see if we can find info on the current image
      $result = db_fetch_object(db_query("SELECT c.nid, c.field_image_cache_title, c.field_image_cache_alt FROM {content_field_image_cache} c INNER JOIN {files} f ON c.field_image_cache_fid=f.fid WHERE f.filepath = '%s'", $caption['path']));
    }
    if ($result) {
      $caption['title']=$result->field_image_cache_title;
      $caption['alt']=$result->field_image_cache_alt;
      $caption['node']=node_load($result->nid);
    }
  }
  // TODO more info, like supporting data for image.module image info
  
  // Process the php using drupal_eval (rather than eval), but with GLOBAL variables, so they can be passed successfully
  $GLOBALS['caption'] = $caption;
  
  $text = drupal_eval('<'.'?php global $caption; '.$action['text'].' ?'.'>');
  $text = eval($action['text']);
  $text = check_plain($text);

  return $text;
}

dman’s picture

Version: 5.x-1.x-dev » 5.x-2.2
Category: bug » task
crea’s picture

Version: 6.x-1.x-dev » 5.x-2.2
Category: task » bug

why is it task ? The code is there, its just not working. Clearly the bug.

dman’s picture

Status: Active » Fixed

When I looked at it, I thought the task was to document it better or make it work in more situations. I thought 'needs work'
But OK, I've updated the docs: THIS DOESN'T WORK against the most recent imagefield changes. So I removed the reference to it.

Until such time as it can be made to work again?
I don't know. But there's no more documentation 'bug'.

crea’s picture

Status: Fixed » Active

Do you have any ideas how to pass info from node to this evaluated code ? I need this feature badly, was only reason I set this up... :(

crea’s picture

dman’s picture

Status: Active » Fixed

You can insert a WORKING version of the code I pasted above in your own php area. It's open for you to do the logic yourself.
Unfortunately I don't know what a working version would look like.

Basically - at the point imagecache gets called, we have no context information. imagecache works by getting a file request on the server and making up the rest. Usually the name of the preset and the name of the file is enough.

So you have a file name. You need to work back from there to find:
- what info, if any, about that file is in the DB
- which, if any, fields it is present in
- which node(s) that field is attached to
- retrieve info from that node.

This is why the previous effort probably only worked some time. It doesn't help that imagefield/cck changed the way it stores data at least twice since then.
:-(
This is why I can't see a quick fix and had to disable it. CCK provided APIs to retrieve the information for nodes, but doesn't AFAIK have a way to retrieve nodes backwards just from that info. It took some hoopy SQL, and that's what broke.

It may be possible, but would need serious hacking to solve for imagefield 5--1, 5--2, 6--x

crea’s picture

I guess I could just use node_load() in evaluated code block...If only I could know exact node id the field attached to...
Is it possible to name imagecache result files using some pattern, and extract node id straight from the URL ? ( assuming one to one node<->field relationship )
I understand it is some sort of hack and not general solution but it would solve my problem...

crea’s picture

Am I right, in understanding that imagecache doesn't change file name, but instead uses requested file name to get original uploaded image from imagefield and applies transformations ? So I can programmatically attach images named like {node_id}.jpg ( where {node_id} is actual #nid of node containing the field ) to imagefields and use file name in evaluated php code block.

dman’s picture

Well, yes.
I wouldn't trust it, but it's possible.
Stick a few checks in and it could be done.

The real path, eg for normal file attachments) is
filename -> fid (file table id) -> rid (node revision?) -> nid -> node_load()
but I'm not sure what the tables are, or if cck has further abstraction hidden in there.

If you think you can get something meaningful from magic filenames... give it a go.

crea’s picture

Now I have my custom solution.
Using example from http://drupal.org/node/201594 and my custom hook_nodeapi() I can now set image filenames programmatically according to pattern and then preg_match URL in php evaluated code block of Caption action to find out exact node id.

Although, there is different solution: you can have user info straight from URL without any custom code: in imagefield settings there is setting "Image path:" to set option sub-dir inside files directory for this field's images. What is great about it - it can accept user tokens so you can have file path like "[uid]/blablabla.jpg". Ofcourse, this won't give full node info or even node id, but it does give user info, which can be useful in some cases as mine - when you have 1 node per user. My case was user profile - I needed to get profile info to put it on widget image, and knowing exact user name or user id its easy to find exact profile node id.
This solution has one more small limitation - it doesn't work with 'default' image of imagefield - it is always saved in temp folder ( in my case having default image autosaved in different folders using [uid] token would be useful ).

I hope this will be useful to someone...

crea’s picture

dman, pls see http://drupal.org/node/288308
I think it is best solution

dman’s picture

(I think this post will re-post after a few hours, so ignore it if it doubles up)

Well, I really don't think that hiding metadata in the filename is a robust answer to this problem. It's at the opposite end of the pipeline. And imagecache (much less imagecache_actions) has no influence on it, so cannot encode anything that requires this approach.
I've never actually used imagefield much, but on the other hand, I totally support tokens in filenames. But to assist storage, not as a medium for data handling.

You, today, want it to identify a user ID.

I, in general, want it to be possible to render a full caption, or an upload date, or an arbitrary field added to that node.

So the ANSWER is to figure out the actual node data, and have that available. Requiring that to be be encoded in a filename is just not a great way forward. There IS an SQL answer to this ... I just don't know it yet, and have not worked enough with imagefield to investigate.

crea’s picture

dman, ofcourse there is sql answer, but this aproach saves us 1 query ( looking up node id in file table ). There is lot of info passing in url in drupal - like arg(N) checking everywhere, and there is generally no problem about it :)
Think of it like this: from the point of imagecache the only thing you know first about file is URL - so you gonna parse it anyway, and in your SQL case you gotta do more steps (which involve more complexity and more stress on the system). Token solution, on the other hand, saves queries and steps, while allowing to pass most needed info straight. My 2 cents

dman’s picture

Well, I really don't think that hiding metadata in the filename is a robust answer to this problem. It's at the opposite end of the pipeline. And imagecache (much less imagecache_actions) has no influence on it, so cannot encode anything that requires this approach.
I've never actually used imagefield much, but on the other hand, I totally support tokens in filenames. But to assist storage, not as a medium for data handling.

You, today, want it to identify a user ID.

I, in general, want it to be possible to render a full caption, or an upload date, or an arbitrary field added to that node.

So the ANSWER is to figure out the actual node data, and have that available. Requiring that to be be encoded in a filename is just not a great way forward. There IS an SQL answer to this ... I just don't know it yet, and have not worked enough with imagefield to investigate.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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

asak’s picture

This whole issue is very interesting. I'm looking for a way to add a watermark to imagefield images of nodes with specific taxonomy terms. I'm pretty sure this thread is where things get messy. For now, i've managed to test custom actions, and found this and there are a couple of patches for using tokens to 'secretly' pass valuable info using the filename (here and here).

So - what would be the best approach?

I was thinking of partly solving my problem by using php on node-type.tpl so that it checks if specific terms are associated with the node, and calls a preset with a specific image to overlay if so (if not - load the regular preset). that could solve things nicely when viewing one node, but what I really need this for is for marking specific nodes in views outputs by watermarking the image - and i have no idea how that could be done without creating the cached image in the first place according to the terms associated. which means - back to zero.

Unless there is some way to pass to the custom action module the nid of the node from which that image is comming from - it seems the only way to go would be to use the token solution. If i put all images in /files/images/[nid]/ - how would i call the [nid] part of the location for using in the custom actions php box?

This would be a pretty amazing feature.

dman’s picture

Yes, you can now use http://drupal.org/node/363434#comment-1243988 in 6--1-2
... good luck!