By ckee on
At one point in development these functions were working, but today the form populates if there's data, but changes don't make it to the database. Similarly new data aren't inserted. hook_insert doesn't even seem to be called, as a message from drupal_set_message in the function doesn't display. All suggestions welcome. These are long functions so I haven't included everything.
function cpo_form($form_state) {
global $user;
if(is_object($form_state) && isset($form_state->nid)) {
$nid = $form_state->nid;
} else {
$query = "select nid from {cpo} where cpo_id = '$user->name'";
$nid = db_result(db_query($query));
}
$node = node_load($nid);
.
.
.
// handle standard fields (conditionally)
$type = node_get_types('type', $node);
if ($type->has_title) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#description' => t("First name, middle initial, last name"),
'#required' => TRUE,
'#weight' => -10,
);
}
if ($type->has_body) {
$form['body_field'] = node_body_field(
$node,
$type->body_label,
$type->min_word_count
);
}
// custom content fields
$form['cpo_id'] = array(
'#type' => 'value',
'#value' => $user->name,
);
$form['cpo_title'] = array(
'#type' => 'textfield',
'#title' => t('Title'),
'#default_value' => isset($node->cpo_title) ? $node->cpo_title : '',
);
$form['cpo_first_name'] = array(
'#type' => 'textfield',
'#title' => t('First name'),
'#default_value' => isset($node->cpo_first_name) ? $node->cpo_first_name : '',
);
$form['cpo_middle_initial'] = array(
'#type' => 'textfield',
'#title' => t('Middle initial'),
'#default_value' => isset($node->cpo_middle_initial) ? $node->cpo_middle_initial : '',
);
$form['cpo_last_name'] = array(
'#type' => 'textfield',
'#title' => t('Last name'),
'#default_value' => isset($node->cpo_last_name) ? $node->cpo_last_name : '',
);
.
.
.
$form['submit'] = array('#type' => 'submit', '#value' => t('Save'));
return $form;
}
function cpo_insert($node) {
drupal_set_message('in insert');
if (!isset($node->cpo_association_memberships_other)) {
$node->cpo_association_memberships_other = '';
}
if (!isset($node->cpo_company_bio)) {
$node->cpo_company_bio = '';
}
db_query(
'INSERT INTO {cpo} (vid, nid, cpo_id, cpo_title, cpo_first_name, cpo_middle_initial, cpo_last_name, cpo_degrees, cpo_company_name, cpo_company_website, cpo_association_memberships_other, cpo_email, cpo_phone_day, cpo_phone_cell, cpo_fax, cpo_annual_maintenance_fee, cpo_paid_through, cpo_certified_since, cpo_address1, cpo_address2, cpo_city, cpo_state, cpo_zip, cpo_country, cpo_company_bio, cpo_approved_directory_display, cpo_is_for_admin_use_only)'
. "VALUES (%d, %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %f, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)",
$node->vid,
$node->nid,
$node->cpo_id,
$node->cpo_title,
$node->cpo_first_name,
$node->cpo_middle_initial,
$node->cpo_last_name,
$node->cpo_degrees,
$node->cpo_company_name,
$node->cpo_company_website,
$node->cpo_association_memberships_other,
$node->cpo_email,
$node->cpo_phone_day,
$node->cpo_phone_cell,
$node->cpo_fax,
$node->cpo_annual_maintenance_fee,
$node->cpo_paid_through,
$node->cpo_certified_since,
$node->cpo_address1,
$node->cpo_address2,
$node->cpo_city,
$node->cpo_state,
$node->cpo_zip,
$node->cpo_country,
$node->cpo_company_bio,
$node->cpo_approved_directory_display,
$node->cpo_is_for_admin_use_only
);
}
Comments
hook_insert works when path in hook_menu changed
Hoping this means something to someone: with hook_insert not working, the path in hook_menu was 'cpo-edit'. Because the node-type is cpo I changed the path in hook_menu to node/add/cpo to see what would happen. (1) The form now had Save and Preview buttons in addition to the module-specific Save (submit) button from the form. (2) The data now inserted to the db, but as a new node, rather than updating.
works with node path but not otherwise
I see now that the form works when invoked via paths referencing the node, e.g. node/999/edit will load the form with the correct node. So I'm guessing that the problem in terms of what I was trying to do -- i.e. invoke the form from a more generic path and populate it programmatically -- might be related to the code at the top of the form:
I read the reference here http://drupal.org/node/158237 to explicit invocations of node_load interfering with hook_insert, although I don't see the direct connection to my issue.
theme_menu_item link to the rescue
I realized that I had a fundamental misunderstanding of the interaction between the menu system and the node system. I thought that because my module implemented a content type, that invoking the form via the path in the module's hook_menu would result in the behavior I'd expect of a node -- specifically, inserting new ones and updating existing ones on submitting the form. Not necessarily true, as I'm sure experienced Drupallers know ....
My solution was to add the following to my theme's template.php file:
The effect is that when a user hits the menu item whose link is cpo-edit (which is the path in the cpo module's hook_menu) the function checks to see if the user has cpo data or not, and inserts the correct path as the menu item's link. If only the add link was needed, the change could be made via the menu admin page, but inserting the nid requires a lookup, hence the function.
Thanks to zeropx on the irc #drupal-support chat for pointing me in the right direction.