When changing the workflow of a node, I would loose all the data stored in a matrix field.

Problem seemed to stem from the update $op using the following code.

case 'update':
      db_query("DELETE FROM {node_field_matrix_data} WHERE vid = %d and field_name= '%s'",$node->vid, $field['field_name']);
break;

 

I'm not sure why we would be deleting here... I read a previous post saying that you had to handle storage of matrix field manually, but perhaps its just a mistype where insert should be delete instead?

Anyway, I changed this around a little to handle things.


**
 * Implementation of hook_field().
 */
function matrix_field($op, &$node, $field, &$node_field, $teaser, $page) {
  dpm($node);
  switch ($op) {
    
    case 'load':
      $result = db_query("SELECT value, row, col FROM {node_field_matrix_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
      $values = array();
      while ($data = db_fetch_array($result)) {
        dpm($data);
        $values[$data["row"]][$data["col"]] = $data['value'];
      }
      $additions = array($field['field_name'] => $values);
      return $additions;
    
    case 'update':
      
      
       for ($i=1; $i<= MATRIX_NUMBER; $i++) {
        if (!empty($field["label_row_$i"])) {
          for ($j=1; $j<= MATRIX_NUMBER; $j++) {
            //lets check and see if this field already exists
            $pre_existing_data = db_result(db_query("SELECT COUNT(*) FROM {node_field_matrix_data} WHERE nid = %d AND vid = %d AND field_name = '%s' AND row = %d AND col = %d", $node->nid, $node->vid, $field['field_name'], $i, $j));
            if($pre_existing_data ) {
              //ok it exists so lets overwrite the data
              db_query("UPDATE {node_field_matrix_data} SET value = '%s' WHERE nid = %d AND vid = %d AND field_name = '%s' AND row = %d AND col = %d", $node_field['matrix'][$i][$j],
                $node->nid, $node->vid, $field['field_name'], $i, $j);
                //drupal_set_message("[$i], [$j] is existing and was updated to " . $node_field['matrix'][$i][$j]); 
            }
            elseif(!empty($node_field['matrix'][$i][$j])) {
              //OK, this field didn't have a value before, but it does now, so lets insert it.
              db_query("INSERT INTO {node_field_matrix_data} 
                SET nid = %d, vid = %d, field_name = '%s', row = %d, col = %d, value = '%s'",
                $node->nid, $node->vid, $field['field_name'], $i, $j, $node_field['matrix'][$i][$j]);
             // drupal_set_message("[$i], [$j] is not existing and " . $node_field['matrix'][$i][$j]. " was inserted") ;
            }
          }
        }
      }
    break;
    
    case 'delete':
      db_query("DELETE FROM {node_field_matrix_data} WHERE nid = %d" ,$node->nid);
    break;  
    
    case 'insert':
      for ($i=1; $i<= MATRIX_NUMBER; $i++) {
        if (!empty($field["label_row_$i"])) {
          for ($j=1; $j<= MATRIX_NUMBER; $j++) {
            if (!empty($node_field['matrix'][$i][$j])) {
              db_query("INSERT INTO {node_field_matrix_data} 
                SET nid = %d, vid = %d, field_name = '%s', row = %d, col = %d, value = '%s'",
                $node->nid, $node->vid, $field['field_name'], $i, $j, $node_field['matrix'][$i][$j]);
            }
          }
        }
      }
      break;
  }
}

Comments

frankcarey’s picture

Status: Active » Needs review

Note: Revisions still will not work correctly. While revision data is stored correctly ( referencing the old versions in the database), reverting to an old version actually creates a copy of the old version, and a new vid. Since matrix.module doesn't know what the new version is, it breaks. Not sure how to fix that, any ideas?
)

aaron1234nz’s picture

Thanks for the code. I"ll take a look

frankcarey’s picture

woh, time warp :)

aaron1234nz’s picture

Status: Needs review » Fixed

Another patch I committed seems to have solved this issue (fixed for both 5.x and 6.x versions)

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.