Actions currently are written the following way. We use a naming convention of a function starting with 'action_' to denote an action. Within the action we have various ops, as follows:
<?php
/**
* Implementation of a Drupal action.
*/
function action_block_user($op, $context = array(), &$object) {
switch ($op) {
case 'do':
global $user;
// block user here...
break;
case 'metadata':
return array(
'description' => t('Block current user'),
'type' => 'User',
'batchable' => TRUE,
'configurable' => FALSE,
'supported hooks' => array(
'nodeapi' => array(
'delete' => 1,
'insert' => 1,
'update' => 1,
'view' => 1
),
'comment' => array(
'insert' => 1,
'update' => 1,
'delete' => 1
)
)
);
}
}
?>The advantages to the current system:
-
Actions can appear anywhere (modules, includes, template.php, etc.); as long as the functions are in the PHP namespace the actions will be detected.
-
Actions are portable. There is a single function that can be copy and pasted.
-
They are consistent -- it's easy to understand the various components of an action you've not seen before by looking at the ops.
The disadvantages of the current system are:
-
Now that we have the form API, the 'validate' and 'submit' ops should really be standard validate and submit functions that adhere to normal fapi conventions, such as getting passed $form_id and $form_values.
-
It is slightly slower to pass and evaluate an op than to call an existing function.
-
Programming into deeply nested switch and case statements is just icky.
If we leave the current system and implement a new one, it would probably involve implementing a hook_actions_info() to replace the metadata op, standard validate and submit functions for the validate and submit ops, and a do or execute function for the do op.
The new way would look something like this for a nonconfigurable action.
<?php
function user_action_info() {
return array(
'action_user_block' => array(
'description' => t('Block current user'),
'type' => 'User',
'batchable' => TRUE,
'configurable' => FALSE,
'supported hooks' => array(
'nodeapi' => array(
'delete' => 1,
'insert' => 1,
'update' => 1,
'view' => 1
),
'comment' => array(
'insert' => 1,
'update' => 1,
'delete' => 1
)
)
)
);
}
function action_user_block_do($context, &$object){
global $user;
// block user here;
}
?>The 'configurable' key could probably be dropped because we could test for the existence of action_user_block_form().
The batchable key could be dropped if we pull node_save() out of all the actions and make it a separate action.

Comments
I think that the
I think that the hook_actions_info() would be the better choice - it would result in code which is easier to read and maintain :) Furthermore I think it's more consistent with the rest of drupal's API.
I would also separate the node_save() out of the actions. Ideally it would be invoked only if needed. I have to think more about this.