Change state but only if a function return true

Handy snippit, only change to the next state in the workflow if a function returns true, this creates an action which you'll have to include in your workflow transaction/actions.

Handy if you want todo a whole bunch of tests, or alert something that the state is about to change.

could be hacked to change state-path too, but im not super clear on that

<?php
function action_eval_php($op, $edit = array(), $node) {

  switch(
$op) {
    case
'metadata':
      return array(
       
'description' => t('Execute PHP, optionally move to next state'),
       
'type' => t('PHP Code'),
       
'batchable' => false,
       
'configurable' => true,
      );

    case
'do':
       
// get unique function name so we dont get function collisions
       
eval($edit['evalcode']);
       
$functionID=$edit['functionID'];
       
$_action_eval="_action_do_eval_$functionID";
       
// log
       
watchdog('action', t('Calling PHP eval code function %eval', array('%eval' => $_action_eval)));
       
$ret=$_action_eval($op, $edit, $node);

        if (
function_exists("action_workflow_execute_transition")) {
            if(
$ret==true && $edit['executeTransition']==true) {
               
action_workflow_execute_transition($op, $edit, &$node);
            }
        }
      break;

   
// return an HTML config form for the action
   
case 'form':
     
// default values for form
     
$functionID=$edit["functionID"];
      if (!isset(
$edit['functionID'])) $functionID=md5(microtime());
      if (!isset(
$edit['evalcode'])) $edit['evalcode'] =
"function _action_do_eval_$functionID(\$op, \$edit = array(), \$node) {\n\n \treturn true;\n }";
      if (!isset(
$edit['executeTransition'])) $edit['executeTransition'] = 0;

     
$form['evalcode'] = array(
       
'#type' => 'textarea',
       
'#title' => t('PHP Code'),
       
'#default_value' => $edit['evalcode'],
       
'#cols' => '80',
       
'#rows' => '20',
       
'#required' => true,
       
'#description' => t('The code to be run'),
      );

     
$form['functionID'] = array(
       
'#type' => 'hidden',
       
'#default_value' => $functionID,
       
'#required' => true

     
);

     
$form['executeTransition'] = array(
       
'#type' => 'checkbox',
       
'#title' => t('Execute transition to next state if _action_do_eval_...() returns true?'),
       
'#default_value' => $edit['executeTransition'],
      );

      return
$form;

   
// validate the HTML form
   
case 'validate':
     
$errors = array();

      foreach (
$errors as $name => $message) {
       
form_set_error($name, $message);
      }

      return
count($errors) == 0;

   
// process the HTML form to store configuration
   
case 'submit':
     
$params = array(
       
'evalcode' => $edit['evalcode'],
       
'functionID' => $edit['functionID'],
       
'executeTransition' => $edit['executeTransition']
        );
      return
$params;
  }
}
?>

5.x compatibility

Ninja Overlord - February 20, 2008 - 18:35

Would this work in 5.x? In addition, where would you put said function? And could said function be dependent on the workflow status easily?

(What I want is something like for all nodes of content type Page (actually a custom content type),

if (workflow != "Approved" | "Submitted") {
   unpublish/delete the content (prefer deletion to lessen the back end stuff related to the site)
   unpublish/delete another content of a different type (each one of these is attached to an Organic Group, which have one field in particular in common at least)
   }

if (content_type="(**custom content type**)"){
   workflow = "Out of date"
   }

After I get my dev version of the site up and functional, I shall start to work on the merging of these two content types so upon submission of the custom content type, the Organic Group is automatically formed and thus attached to the original content so then the second line in the first if's actions can be deleted, but thats not something I'm willing to do on a live site.

I havn't had any PHP coding experience, although plenty of C++ and Java, so I cannot write the code myself off the bat.

 
 

Drupal is a registered trademark of Dries Buytaert.