I would love to see an action that has a field where you can enter your own PHP code to execute when triggered by Workflow-ng.

An example of where this would be useful to me is the following scenario:
1. I have two node types, one is a parent ("Project") and one is a child ("Project Item").
2. The Project Item node type uses a cck node_reference field to create the relationship.
3. When the child node, called "Project Item" node type is created or updated, a trigger would execute my custom PHP action code.
4. The custom PHP code would update the timestamp of the changed field for my node_referenced parent, "Project" with the current timestamp.

Currently I can't think of a better way to do this.

This would allow really flexible actions without needing to write modules each time. Is this feasible?

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

fago’s picture

yep, that sounds useful. However the question is how we deal with the arguments. One could just pass all available arguments to the code.

Feel free to contribute a patch :)

tanc’s picture

Hi fago, oh how I wish I could contribute a patch. I gave it a shot but my coding simply isn't up to it. If someone can start me off maybe I can figure it out?

peterpoe’s picture

Status: Active » Needs work
FileSize
1.66 KB

Check out this patch. I'm not an expert programmer, so I don't know if I did everything right.

fago’s picture

what's that? include_once("../dBug.php"); :)

Anyway, while the code allows executing code, it doesn't handle arguments. If we add this action, it needs to be able to work with the available arguments. Probably best it would be to let users choose the arguments, that should be available in the php code. E.g. provide a checkbox for each available argument. Then we can handle loading of necessary arguments in the action itself like the token actions do.

webchick’s picture

Title: Execute arbitrary PHP code on trigger » GHOP #73: Execute arbitrary PHP code on trigger

This is now (I believe) a GHOP task. :) If I'm wrong fago, please post another issue and link it at http://code.google.com/p/google-highly-open-participation-drupal/issues/...

fago’s picture

yep, that's it.

corsix’s picture

What did you mean by "it doesn't handle arguments" regarding the patch in post 3? It allowed actions like:

print "Hello [user:user].";

Which, unless I misunderstand, is using the user:user argument.

fago’s picture

This is just a token.. So it gives you back a string value. But e.g. if there is a content node, the $node object should be available in the code too.

Of course, we need to list the available arguments so that the user knows, which arguments can be used. I would suggest to use the internal argument names, as variable names.
-> e.g. the variables of the event "Content is going to be saved" would look like

$node - content, entity: node
$node_unchanged - unchanged content, entity: node
$author - content author, entity: user
$author_unchanged - unchanged content\'s author, entity: user

corsix’s picture

Added a custom PHP action and condition, which allows for actions/conditions like these:

// action:
$node->title = 'I am '. $author->name .', and this is node [node:nid]'

// condition:
return $node->nid > 5 || $node->nid < 2
fago’s picture

wow, that was quick! Here are some notes:

* Your action does return all available arguments, which means every argument would be saved even if it wasn't changed. That's not good. Better leave it up to the people to return arguments to be saved or not. Or, if you like you could provide checkboxes in the configuration form...

* if you use eval($code) instead of eval('?>'. $code); you need not to manually add <?php

@workflow_ng_custom_php_prepend_php_arguments: The function looks fine. Instead of adding the assignments added to the code you could also use extract() to make the variables known before calling eval(). But do it as you prefer.

* #module: Set this to Workflow-ng so that the include file and the given #module matches.

* Comments: Please add some more comments, e.g. comment each Implementation of an hook like
/**
* Implementation of hook_condition_info()
*/

* ob_start() - Interesting idea, but I don't think this is necessary. I think it's better to just let people print stuff - as this is the behaviour that one would expect. If drupal_set_message() is desired, people should use it theirself (or the available action). So better just eval the code as it is.

@For conditions with multiple PHP statements, you must explicitly use "return".
This could be a bit confusing in the first tick, so I think it's better to just require the usage of return (and adding it to your examples). Instead a validation routine, that checks for the existence of return would surely help people.

* I think we need to show the users which arguments are available. I'd suggest to add a "help" theme function - similar to the help provided by the token module. It should just lists all available arguments, with their label and entity type.

corsix’s picture

Status: Needs work » Needs review
FileSize
7.61 KB

Addressed the issues you raised.

fago’s picture

Status: Needs review » Needs work

It already looks fine and works :)

+ $row[] = (isset($argument['#saved']) && $argument['#saved']) ? t('Yes') : t('No');
You got this wrong. This is only true for arguments that are saved automatically for an event - e.g. for the event node submit the node gets saved by the node module, so it sets this to true and workflow-ng knows that it doesn't need to save it. To check wheter workflow-ng supports saving the argument you can do:

<?php
  $entity_info = workflow_ng_gather_data('entity_info', FALSE);
  if (isset($entity_info[$info['#entity']]['#save']) && function_exists($entity_info[$info['#entity']]['#save'])) ..
?>

This should be TRUE for nodes and FALSE for users.

* I think the argument help would fit better above of the code textarea - so it's visible while coding.

* There is an error in the action's description:
drupal_message("This is node $node->nid"); --> drupal_set_message

fago’s picture

another note to the code above: in this case $info['#entity'] is the entity type ('node', 'user', ..)

corsix’s picture

Updated the saveable column, and removed it for conditions (as they shouldn't be saving things, just checking things). Also moved the argument list to the top and fixed the action documentation.

fago’s picture

Status: Needs work » Fixed

ah yes -> committed to 5.x :)
This was great work, thanks!

tanc’s picture

Awesome work corsix, well done! Thanks everyone for making this happen, it is a great additional feature to a superb module.

Anonymous’s picture

Status: Fixed » Closed (fixed)

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