I have a field that generates 10 values and stores them as $node_field[0], $node_field[1], $node_field[2], etc.. this is fine for the first Submit/Save, but on subsequent Edits, the function only has access to $node_field[0]. Thus it regenerates the remaining 9 values again and I effectively lose them.

The fix for this is simple, we take the existing function that generates the pass-through variable and throw it into a loop. Now when someone edits a node that uses this computed field, the computed field has access to all $node_field[*] values and does not need to recalculate.

This seems to work fine, but I would prefer someone else to test and confirm also.


--- computed_field.module	2007-05-15 23:45:34.000000000 -0400
+++ computed_field.module	2008-04-27 17:23:20.000000000 -0400
@@ -175,11 +175,14 @@ function computed_field_widget($op, &$no
 
       $form[$field['field_name']] = array('#tree' => true);
 
-      $form[$field['field_name']][0]['value'] = array(
-        '#type' => 'value',
-        '#title' => t($field['widget']['label']),
-        '#default_value' => isset($node_field[0]['value']) ? $node_field[0]['value'] : '',
-      );
+      foreach($node_field AS $key => $value) {
+        $form[$field['field_name']][$key]['value'] = array(
+          '#type' => 'value',
+          '#title' => t($field['widget']['label']),
+          '#default_value' => isset($value['value']) ? $value['value'] : '',
+        );
+      }
+
       return $form;
   }
 }


Comments

clivesj’s picture

Do I understand it well that you want the computed field to only compute on initial creation of the node? And that during subsequent editing the values of the first creation are retained?
I think that it is by design that the computed field re-computes all the time.
If i understand it well yor patch will change this behaviour.

I have a few fields of which I only want them to calculate upon initial creation. I did add some code -within the computed field- that loads the node data. If the value is already set it will be retained otherwise it will be computed.

jason.fisher’s picture

That is incorrect. I can handle the field computing on subsequent editing -- I want to, in fact, so I can verify the values computed before and change them if necessary. The form is being changed, and my computed value relies on other fields, so being able to execute on edit is a necessity.

The problem is this morsel of code.




/**
 * Implementation of cck hook_widget
 */
function computed_field_widget($op, &$node, $field, &$node_field) {
  switch ($op) {
    case 'form':
      $form = array();

      $form[$field['field_name']] = array('#tree' => true);

      $form[$field['field_name']][0]['value'] = array(
        '#type' => 'value',
        '#title' => t($field['widget']['label']),
        '#default_value' => isset($node_field[0]['value']) ? $node_field[0]['value'] : '',
      );
      return $form;
  }
}

.. because of this:

$form[$field['field_name']][0]['value'] = array( ..trunc.. )

.. my computed_field code only has access to $node_field[0].

I need access to the complete array $node_field ([ 0, 1, 2, 3, .. etc ]) .. ['value'].

Here is my computed_field code to demonstrate (still a revision or two from final):


srand((double)microtime()*1000000);

$chars = 'ABCDEFGHJKLMNPRSTUVWXYZ23456789';
$clen = 8;
$spos = 4;
$schar = '-';
$fname = 'field_code_generator';

if (!$node_field[0]['value']) $node_field = array();

while (sizeof($node_field) < $node->field_total_codes[0]['value']) {
  $code .= substr($chars, rand()%33, 1);
 
  if (strlen($code) >= $clen):     
    $code = trim(chunk_split($code, 
                  floor($clen/ceil($clen/$spos)), $schar), $schar);

    if ( !in_array( array('value' => $code), $node_field ) &&
         !db_result(db_query("SELECT COUNT(*) FROM {content_%s} WHERE %s = '%s'", $fname, $fname, $code)) ): 
      $node_field[] = array('value' => $code);
    endif;

    $code = '';
  endif;
}

As you can see, I am growing $node_field until it reaches a length set in a Text input field.

The inner code is of little consequence, but we are basically generating a unique hyphen-split 8 character code (thus the SELECT). Once we are certain it's unique, we tack it on the end of $node_field.

If someone were to edit the node and raise field_total_codes by 10 and save, this will add the additional entries onto the end. Because these codes cannot be taken back once they are generated -- they are forever, we do not account for a reduction in field_total_codes.

My patch wraps that single $form[$field['field_name']][0]['value'] = array( ..trunc.. ) into a loop, that iterates through the entirety of $node_field to construct the true value:


      foreach($node_field AS $key => $value) {
        $form[$field['field_name']][$key]['value'] = array(

.. and it seems to work in the old case also. I don't see an ill effect yet, but would like someone else to test.

Thanks,
Jason

clivesj’s picture

Thanks for the explenation Jason,
the intention of the patch is now clear to me.
Indeed it will not change the intended behaviour of Comp fields.
Your patch might be usefull for me in some circumstances.
As soon as I'm able to test it I will and report back here.
Thanks

jason.fisher’s picture

Excellent, thank you.

deekayen’s picture

Status: Needs review » Patch (to be ported)

applies against 5.x, which isn't supported anymore

Moonshine’s picture

Status: Patch (to be ported) » Closed (fixed)

This was fixed in the 6.x version.