All pastes #940440 Raw Edit

Someone

public text v1 · immutable
·published 2008-03-12 23:39 UTC
rendered paste body
function cortisol_form( $node, &$form_state ) {

  //
  // Generate the form from a database table -- it's too easy to fuck up
  // and/or flatten the fields accidentally otherwise!  $form_fields works OK,
  // but it doesn't store the attributes of the form elements, whereas with a DB
  // table, it would be trivial to add new fields and/or leave a space at the 
  // end of theme_cortisol_form() to handle ''extra'' misc. fields at the end.
  //
  $form = array();
  $form_fields = _cortisol_inputs();
  $conflict_fields = _cortisol_conflict_fields();

  // CSS: allow jQuery to replace some fields with radios
  $check = array( 'class' => 'checkconflicts' );

+--- 63 lines: $p0: Top of the paper survey on all 3 pages; just enter it once. 
  
+---128 lines: $p1: Page 1.-----------------------------------------------------

+--- 96 lines: $p2: Page 2.-----------------------------------------------------

+--- 30 lines: $p3: Page 3.-----------------------------------------------------

+--- 27 lines: $p4: Page 4.-----------------------------------------------------

  // {{{ assemble the form... at least provisionally...
  foreach( array($p0, $p1, $p2, $p3, $p4) as $page ) {
    foreach( $page as $key => $value ) {
      $form[$key] = $value;
    }
  }
  $form['#submit'][] = 'cortisol_submit';
  $form['#validate'][] = 'cortisol_validate';
  $form['handentered']['#type'] = 'hidden';
  $form['handentered']['#value'] = TRUE;
  $form['checked']['#type'] = 'hidden';
  $form['sid']['#type'] = 'hidden';
  $validation_code =<<<__END_JS

    // JavaScript for jQuery validation hooks should be injected here...

__END_JS;
  drupal_add_js( $validation_code );
  // }}}

  // {{{ If there are conflicts from validation, modify the form to show them.
  if( isset($form_state) ) {

    // Avoid the need to screw around during $node insertion
    $form['sid']['#value'] = $form_state['storage']['sid'];

    // Rebuild the form if instructed to do so
    if( $form_state['rebuild'] ) {
      if( $form_state['storage']['conflicts'] &&
          !$form_state['storage']['resolved']    ) {
        $conflicts = unserialize($form_state['storage']['conflicts']);
        foreach( $conflicts as $field => $conflict ) {
          $new_old = explode('|',$conflict);
          $new = $new_old[0];
          $old = $new_old[1];
          foreach(_cortisol_conflict_radios($new, $old) as $prop => $val) {
            if( $prop == '#title' && isset($form[$field]['#title']) ){
              $form[$field]['#title'] = "Correct value for '".
                                        $form[$field]['#title']."'";
            } else {
              $form[$field][$prop] = $val;
            }
          }
          $form[$field]['#attributes']['class'] .= ' error';
          unset($form_fields[$field]);
        }
        foreach($form_fields as $field) {
          $form[$field]['#default_value'] = $form_state['values'][$field];
        }
        $form_state['storage'] = NULL;
      }
      drupal_set_message("Attempting to unset form_state['storage']...");
      unset($form_state['storage']);
      drupal_set_message("\$form_state['storage'] = ".$form_state['storage']);
      unset($form_state['rebuild']);
      drupal_set_message("\$form_state['rebuild'] = ".$form_state['storage']);
    } else {
      foreach($form_fields as $field) {
        $form[$field]['#default_value'] = $form_state['values'][$field];
      }
    }
  } else {
    $form['conflicts']['#value'] = 0;
    $form['resolved']['#value'] = 0;
    $form['checked']['#value'] = 0;
  }
  // }}}

  return $form;

}

function cortisol_validate( $node, &$form_state ) {
  
  // {{{ check for required (ID) fields
  //
  $values = 'values';
  if( isset($form_state[$values]) ) {
    if ($form_state[$values]['participant'] < 100 ||
        $form_state[$values]['participant'] > 999   ) {
      form_set_error('participant', 
      t("Invalid ID #".$form_state[$values]['participant'].": please check!"));
    } 
    if( !isset($form_state[$values]['phase']) ) {
      form_set_error('phase', 
                   t('The phase of the survey must be selected to proceed.'));
    }
  } else {
    form_set_error('$form_state['.$values.'] is not set!  (This is a bug.)');
  } 
  // }}}
  // {{{ anything jQuery missed: silly stuff like '1 pack a day' etc.
  //
  foreach (_cortisol_conflict_fields(TRUE) as $field => $type) {
    if(!empty($form_state[$values][$field])) {
      switch( $type ) {
        case 'numeric':
          // NA/null should be '' or just NULL...
          if( preg_match('/(N\/?A|none)/i',$form_state[$values][$field]) ){
            $form_state[$values][$field] = 0;
          } 
          // still busted?
          if( !is_numeric($form_state[$values][$field]) ) {
            form_set_error('General badness',"$field must be a $type value");
          } 
          break;
        case 'time':
          if( !preg_match('/\d+:\d+/', $form_state[$values][$field]) ) {
            form_set_error('General badness',"$field must be a $type value");
          }
          break;
        default:
          break;
      }
    }
  }
  // }}}
  // {{{ validation & conflict catching
  //
  if( isset($form_state[$values]['participant']) &&
      isset($form_state[$values]['phase']) &&
     !isset($form_state['storage']['checked']) )  {

    $inputs = _cortisol_inputs();
    $pid = $form_state[$values]['participant'];
    $phase = $form_state[$values]['phase'];
    if( WELLELDERLY_DEBUG ) {
      drupal_set_message("Checking survey for subject $pid, phase $phase...");
    }
    $conflicts = _cortisol_fetch_conflicts($form_state);
    if( $conflicts ) {
      $clist = array();
      foreach( $conflicts as $field => $conflict ) {
        $new_old = explode('|',$conflict);
        $new = $new_old[0];
        $old = $new_old[1];
        if(is_numeric($old) || is_numeric($new)) {
          $clist[] = "$field: existing value is $old, you entered $new";
        } else {
          $clist[] = "$field: existing value is '$old', you entered '$new'";
        }
        $num++;
      }
      unset($inputs[$field]);
      foreach( $inputs as $field ) {
        $values[$field] = $form_state['values'][$field];
      }
      $num = count($clist);
      $s = ($num > 1) ? "s" : "";
      if ($num > 0) {
        form_set_error('conflicts',
                       t("Found $num conflict$s (highlighted in red): ".
                         theme_item_list($clist)));
        form_set_value(array( '#parents' => array('conflicts')),
                       serialize($conflicts),
                       $form_state );
        form_set_value(array('#parents' => array('resolved')), 0, $form_state );
        $form_state['storage']['conflicts'] = serialize($conflicts);
        $form_state['storage']['inputs'] = serialize($values);
        $form_state['rebuild'] = TRUE;
      } else {
        form_set_value(array('#parents' => array('conflicts')), 0, $form_state);
        form_set_value(array('#parents' => array('resolved')), 1, $form_state);
      }
      foreach( $inputs as $input ) {
        $form_state['storage'][$input] = $form_state[$values][$input];
      }
      $form_state['storage']['inputfields'] = serialize($inputs);
      $form_state['storage']['checked'] = TRUE;
    } else {
      form_set_value(array( '#parents' => array('conflicts')), 0, $form_state);
      form_set_value(array( '#parents' => array('resolved')), 1, $form_state );
      unset($form_state['storage']);
      unset($form_state['rebuilt']);
    }
  }
}