From 2bc1080e1929559ee6e970378bd5a8175d2d93e8 Mon Sep 17 00:00:00 2001
From: Robert Allerstorfer <roball@405360.no-reply.drupal.org>
Date: Thu, 8 Dec 2011 17:15:51 +0100
Subject: [PATCH] If set, get the number of steps per node (instead of per
 content-type)

---
 multistep.api.php   |    4 +-
 multistep.module    |   58 +++++++++++++++++++++++++++++++++++---------------
 multistep.rules.inc |    4 +-
 3 files changed, 44 insertions(+), 22 deletions(-)

diff --git a/multistep.api.php b/multistep.api.php
index 9034d61..836aea0 100644
--- a/multistep.api.php
+++ b/multistep.api.php
@@ -31,7 +31,7 @@ function hook_multistep_update_status(&$form_state, $status, $step) {
   // Get the node type
   $type = $form_state['node']['type'];
   // Check whether we are on the last step of the form
-  if ($type == 'profile' && $step == variable_get('multistep_steps_' . $type, 0)) {
+  if ($type == 'profile' && $step == _multistep_get_last_step($type, $form_state['values']['nid'])) {
     // Check whether the user entered their Last Name in the proper field
     if (empty($form_state['values']['field_last_name']['value'][0])) {
       // Warn the user
@@ -66,7 +66,7 @@ function hook_multistep_set_step($form_state, $step, $action) {
       }
       break;
     case 'next':
-      $last = variable_get('multistep_steps_' . $form_state['node']['type'], 0);
+      $last = _multistep_get_last_step($form_state['node']['type'], $form_state['values']['nid']);
       if ($step < $last && $form_state['values']['go_to_last_step'][0]['value'] == 'yes') {
         return $last;
       }
diff --git a/multistep.module b/multistep.module
index aa17c84..1ebf1b6 100644
--- a/multistep.module
+++ b/multistep.module
@@ -130,12 +130,14 @@ function multistep_block($op = 'list', $delta = 0, $edit = array()) {
  * Creates a menu of the different groups in a form.
  */
 function _multistep_block($type) {
+  $nid = NULL;
   if (arg(0) == 'node' || arg(0) == 'user') {
     $node_type = '';
     $new = FALSE;
     $context = arg(0);
     if (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'edit') {
-      $node_type = node_load(arg(1))->type;
+      $nid = arg(1);
+      $node_type = node_load($nid)->type;
     }
     elseif (arg(0) == 'node' && arg(1) == 'add' && arg(2) != '') {
       $node_type = strtr(arg(2), array('-' => '_'));
@@ -163,7 +165,7 @@ function _multistep_block($type) {
       //Get design variables
       $show_step_numbers = variable_get('multistep_show_step_numbers', TRUE);
       $workflow_mode = variable_get('multistep_workflow_mode', 'free');
-      $current_step = _multistep_get_current_step($type);
+      $current_step = _multistep_get_current_step($type, $nid);
       // Generate the menu items.
       if (variable_get('multistep_menu_' . $type, 'enabled') == 'enabled') {
         foreach ($groups as $group) {
@@ -197,7 +199,7 @@ function _multistep_block($type) {
       }
       // Generate the progress bar.
       if (variable_get('multistep_progress_' . $type, 'enabled') == 'enabled') {
-        $steps = variable_get('multistep_steps_' . $type, 0);
+        $steps = _multistep_get_last_step($type, $nid);
         $submitted = 0;
         for ($step = 1; $step <= $steps; $step++) {
           $status = _multistep_get_status(arg(1), $step);
@@ -252,7 +254,7 @@ function multistep_field_access($op, $field, $account = NULL, $node = NULL) {
       }
       break;
     case 'edit':
-      $step = _multistep_get_current_step($type);
+      $step = _multistep_get_current_step($type, $node->nid);
       // Render all steps if requested by a user with "toggle multistep" permissions.
       if ($step == 0 && user_access('toggle multistep')) {
         return;
@@ -523,7 +525,7 @@ function multistep_form_alter(&$form, &$form_state, $form_id) {
   if (module_exists('content_profile') && is_content_profile($type)) {
     unset($form['#redirect']);
   }
-  $step = _multistep_get_current_step($type);
+  $step = _multistep_get_current_step($type, $form['nid']['#value']);
   // This hides extra fields for steps they don't belong in.
   $content_type = content_types($type);
   foreach ($content_type['extra'] as $field_name => $field_value) {
@@ -581,7 +583,7 @@ function multistep_form_alter(&$form, &$form_state, $form_id) {
       '#weight' => 102,
     );
   }
-  if ($step < variable_get('multistep_steps_' . $type, 0) && $step != 0) {
+  if ($step < _multistep_get_last_step($type, $form['nid']['#value']) && $step != 0) {
     $form['buttons']['next'] = array(
       '#type' => 'submit',
       '#value' => variable_get('multistep_button_next', t('Next >')),
@@ -589,7 +591,7 @@ function multistep_form_alter(&$form, &$form_state, $form_id) {
       '#weight' => 103,
     );
   }
-  if ($step == variable_get('multistep_steps_' . $type, 0) || $step == 0) {
+  if ($step == _multistep_get_last_step($type, $form['nid']['#value']) || $step == 0) {
     $form['buttons']['done'] = array(
       '#type' => 'submit',
       '#value' => variable_get('multistep_button_done', t('Done')),
@@ -660,7 +662,7 @@ function multistep_validate($form, &$form_state) {
   }
   // Verify if the status checkbox is checked, and the Publishing option is set to Publish
   if ($form_state['values']['status'] && array_search('status', variable_get('node_options_' . $form_state['values']['type'], array())) !== FALSE) {
-    $step = _multistep_get_current_step($form_state['values']['type']);
+    $step = _multistep_get_current_step($form_state['values']['type'], $form['nid']['#value']);
     $complete = _multistep_will_complete($form_state, $step);
     $form_state['values']['status'] = _multistep_publishing($complete);
   }
@@ -673,8 +675,8 @@ function multistep_submit($form, &$form_state, $action) {
   // Submit the actual values.
   node_form_submit($form, $form_state);
   $type = $form_state['values']['type'];
-  $step = _multistep_get_current_step($type);
   $nid = $form_state['nid'];
+  $step = _multistep_get_current_step($type, $nid);
   // Update the multistep table.
   multistep_update_status($form_state, 'submitted', $step);
   // Set next step
@@ -689,7 +691,7 @@ function multistep_submit($form, &$form_state, $action) {
     case 'next':
     case 'done':
       if ($step == 0) {
-        $goto_step[] = variable_get('multistep_steps_' . $form_state['node']['type'], 0);
+        $goto_step[] = _multistep_get_last_step($form_state['node']['type'], $form['nid']['#value']);
       }
       $goto_step[] = $step + 1;
       break;
@@ -705,7 +707,7 @@ function multistep_submit($form, &$form_state, $action) {
   // Only use the value returned by the last module that decided the step
   $goto_step = array_pop($goto_step);
   // If there are steps left, go to the next (or previous) one.
-  if ($goto_step <= variable_get('multistep_steps_' .$type, 0)) {
+  if ($goto_step <= _multistep_get_last_step($type, $form['nid']['#value'])) {
     // Handle redirects for content_profile
     if (module_exists('content_profile') && is_content_profile($type)) {
       $node = node_load($nid);
@@ -783,7 +785,7 @@ function _multistep_publishing($complete) {
  * Get all possible steps as an array.
  */
 function _multistep_get_steps($form_type) {
-  $num_steps = variable_get('multistep_steps_' . $form_type, 0);
+  $num_steps = _multistep_get_last_step($form_type, NULL);
   $steps = array('0' => t('All'));
   for ($step = 1; $step <= $num_steps; $step++) {
     $steps[$step] = $step;
@@ -823,7 +825,7 @@ function _multistep_get_field_step($field_name, $type) {
  * Step 0 will render the entire form and it is reserved with users with
  * "toggle multistep" permissions.
  */
-function _multistep_get_current_step($type) {
+function _multistep_get_current_step($type, $nid) {
   $step = 1;
   // @see http://drupal.org/node/566682 - Added support for hierarchical_select.
   if (arg(0) == 'hierarchical_select_json') {
@@ -872,7 +874,7 @@ function _multistep_get_current_step($type) {
   }
   elseif (arg(0) == 'node' && is_numeric(arg(1)) && arg(2) == 'edit'
   && is_numeric(arg(3)) && arg(3) >= 1
-  && arg(3) <= variable_get('multistep_steps_' . $type, 0)) {
+  && arg(3) <= _multistep_get_last_step($type, $nid)) {
     $step = arg(3);
   }
   // Get the step if it's a content profile
@@ -881,7 +883,7 @@ function _multistep_get_current_step($type) {
   && arg(0) == 'user' && is_numeric(arg(1)) && arg(2) == 'profile'
   && arg(3) == $type
   && is_numeric(arg(4)) && arg(4) >=1
-  && arg(4) <= variable_get('multistep_steps_' . $type, 0)) {
+  && arg(4) <= _multistep_get_last_step($type, $nid)) {
     $step = arg(4);
   }
   elseif (module_exists('content_profile')
@@ -928,7 +930,7 @@ function _multistep_update_status($nid, $status = 'unsubmitted', $step = NULL) {
     if (is_null($step) || $step == 0) {
       $start = 1;
       $node = node_load($nid);
-      $end = variable_get('multistep_steps_' . $node->type, 0);
+      $end = _multistep_get_last_step($node->type, $nid);
     }
     else {
       $start = $end = $step;
@@ -981,7 +983,7 @@ function _multistep_get_status($nid, $step) {
  * Get status of all steps in a specific node and decide whether the form is complete or no.
  */
 function _multistep_is_complete(&$form_state) {
-  $steps = variable_get('multistep_steps_' . $form_state['values']['type'], 0);
+  $steps = _multistep_get_last_step($form_state['values']['type'], $form_state['values']['nid']);
   // Verify if there's at least one step that's not complete.
   for ($step = 1; $step <= $steps; $step++) {
     if (_multistep_get_status($form_state['values']['nid'], $step) != 'submitted') {
@@ -1006,7 +1008,7 @@ function _multistep_will_complete(&$form_state, $current_step) {
   if ($current_step == 0 || _multistep_is_complete($form_state)) {
     return TRUE;
   }
-  $steps = variable_get('multistep_steps_' . $form_state['values']['type'], 0);
+  $steps = _multistep_get_last_step($form_state['values']['type'], $form_state['values']['nid']);
   $unsubmitted = array();
   // Verify which steps are not complete.
   for ($step = 1; $step <= $steps; $step++) {
@@ -1028,6 +1030,26 @@ function _multistep_will_complete(&$form_state, $current_step) {
 }
 
 /**
+ * Get the number of the last step.
+ * Allows another module to set the number of steps per node
+ * See http://drupal.org/node/1363560
+ */
+function _multistep_get_last_step($form_type , $nid) {
+  if (is_numeric($nid)) {
+    $variable_name = 'multistep_steps_' . $form_type . ':' . $nid;
+    if (isset($variable_name)) {
+      // If $nid has been passed as a number, check if variable
+      // "multistep_steps_TYPE:NID" exists. If so, return its value as the last step
+      return variable_get($variable_name, 0);
+    }
+  }
+  // Otherwise, return the value of the content-type scope variable
+  // ("multistep_steps_TYPE") as the last step
+  $variable_name = 'multistep_steps_' . $form_type;
+  return variable_get($variable_name, 0);
+}
+
+/**
  * Implementation of hook_theme().
  */
 function multistep_theme() {
diff --git a/multistep.rules.inc b/multistep.rules.inc
index 2df8395..62a7a2f 100644
--- a/multistep.rules.inc
+++ b/multistep.rules.inc
@@ -32,7 +32,7 @@ function multistep_rules_condition_info() {
  * Check to see if the node is complete.
  */
 function multistep_condition_content_is_complete($node) {
-  $steps = variable_get('multistep_steps_' . $node->type, 0);
+  $steps = _multistep_get_last_step($node->type, $node->nid);
   // Look for a step that is not complete.
   for ($step = 1; $step <= $steps; $step++) {
     if (_multistep_get_status($node->nid, $step) != 'submitted') {
@@ -47,7 +47,7 @@ function multistep_condition_content_is_complete($node) {
  * ever happen once. At least that is the idea anyway.
  */
 function multistep_condition_content_will_complete($node) {
-  $steps = variable_get('multistep_steps_' . $node->type, 0);
+  $steps = _multistep_get_last_step($node->type, $node->nid);
   $current_step = _multistep_get_current_step($node->type);
   $unsubmitted = array();
   // Get all the incomplete steps
-- 
1.7.7

