Jump to:
| Project: | Content Construction Kit (CCK) |
| Version: | 5.x-1.6-1 |
| Component: | General |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed (fixed) |
Issue Summary
I have a custom node type (ff1_team) which is managed by my custom module and has no CCK fields. I have written a small archiving script which converts each of these nodes into a new node type (old_team), keeping the existing node id. As part of the script, I load each node, recreating the body from all of the exisitng custom fields and then save it using node_save().
On top of that, I also want to populate some CCK fields which exist in the old_team node type. The data for these fields come from a custom table that will be emptied after the archiving process.
The problem I am having is that the CCK fields are not being populated. The node type is changed, and the body is updated, but the CCK fields never get populated. Can anyone point out where I'm going wrong and how to put it right?
My code is shown below.
Many thanks.
Ian
<?php
function ff1_new_season() {
// Get all teams from the node table
$result = db_query("SELECT * FROM {node} WHERE type = 'ff1_team'");
while ($team = db_fetch_object($result)) {
// Move content to body
$node = node_load($team->nid);
$node->body = '<div class="messages status">'. t('This is an archived team from %year.', array('%year' => date('Y')-1)) .'</div>'. theme($node->type, $node);
$order = array("\r\n", "\n", "\r");
$replace = "";
$node->body = str_replace($order, $replace, $node->body);
$node->format = 3; // Full HTML format
// Change node type
$node->type = 'old_team';
$race = variable_get('ff1_last_race', 0); // Get the last race
// Extract the final league information about this team
$team_info = db_result(db_query("SELECT lt.rank, lt.team_score FROM {ff1_league_table} lt WHERE lt.team_nid = %d AND lt.race_nid = %d AND lt.table_type = 'points_so_far'", $node->nid, $race));
$node->field_final_position = $team_info->rank; // Final league position
$node->field_team_points = $team_info->team_score; // Final points
$node->field_year = date('Y')-1; // Season
// Save new node
$node = node_submit($node);
node_save($node);
}
// Empty tables ...
}
?>
Comments
#1
After some digging around in the CCK code and plenty of trial and error, I've managed to work out how to do this. It may not be a best practice solution, but it works for me. There were 3 things that I needed to change in my code:
1. CCK had no record of the original node type, so I needed to create new CCK data, as if it were a brand new node. To do this, I used
content_insert($node);after changing the node type and callingnode_save($node);.2. CCK values need [0]['value'] after the field identifier in the node object.
3. ... and this was a DOH! moment... you can't use db_result to fetch an object from the db. Use db_fetch_object instead! :)
Here is my new code:
<?php...
// Change node type
$node->type = 'old_team';
$race = variable_get('ff1_last_race', 0); // Get the last race
// Extract the final league information about this team
$team_info = db_fetch_object(db_query("SELECT lt.rank, lt.team_score FROM {ff1_league_table} lt WHERE lt.team_nid = %d AND lt.race_nid = %d AND lt.table_type = 'points_so_far'", $node->nid, $race));
$node->field_final_position[0]['value'] = $team_info->rank; // Final league position
$node->field_team_points[0]['value'] = $team_info->team_score; // Final points
$node->field_year[0]['value'] = date('Y')-1; // Season
// Save new node
$node = node_submit($node);
node_save($node);
content_insert($node);
unset($node);
}
// Empty tables
...
?>
#2
The content_insert() call is duplicated. Infact, in your case, node_save will call hook_update which calls content_update() to insert/update field in your type tables.
#3
The above code worked for me just by using the [0]['value'] after the CCK field name. It's pretty neat otherwise. Thanks !
#4
This worked great for me, but what about for saving fields that can have multiple values? I tried doing [0]['value'], [1]['value'], etc., but it's not working that way.
#5
I take that back. It does work!
#6
It took me some time to figure this out. Thought i would share.
You need to use content_insert to make sure cck data is properly saved.
Similarly if you are updating an existing node (especially when you have a cck field that can take unlimited values), then you need to call content_update in order to make sure newly inserted data is properly saved.
This is especially useful if you are keeping drupal database in synch with a master database that changes.
#7
Closing old issues. None of us is using the D5 version any more, so hard to provide any support. Sorry.
#8
Automatically closed -- issue fixed for 2 weeks with no activity.