I have created a module that is supposed to add a new node type. Nodes of this type are created using a multistep form. The necessary hooks are called, but they do not get the data from the form: there is node $node->point for example.
I will include the complete source code of the module here. First gastro.info
name = Gastro
description = gastronomy entry with address and marker on a map which is derived from the address
package = Seculogix Custom
core = 6.x
Next ist gastro.install:
/**
* Implementation of hook_schema()
*/
function gastro_schema() {
$schema['gastro_location'] = array(
'description' => t('Stores the address and the calculated coordinates.'),
'fields' => array(
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => t('The {node} this location belongs to.')),
'vid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'description' => t('The {node_revision} for this location.')),
'street' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'description' => t('The street part of the address. Includes house number.')),
'postal' => array('type' => 'varchar', 'length' => 5, 'not null' => TRUE, 'description' => t('The postal code of the address. Note this is not a number.')),
'city' => array('type' => 'varchar', 'length' => 100, 'not null' => TRUE, 'description' => t('This is the city, town, village, or place of the address.')),
'point' => array('type' => 'varchar', 'length' => 40, 'not null' => TRUE, 'description' => t('The pait of coordinates for this address')),
),
'primary key' => array('nid', 'vid'),
'indexes' => array(
'street_index' => array('street'),
'postal_index' => array('postal'),
'city_index' => array('city'),
),
);
dsm($schema);
return $schema;
}
/**
* Implementation of hook_install()
*/
function gastro_install() {
dsm("gastro_install");
drupal_install_schema('gastro');
}
/**
* Implementation of hook_uninstall()
*/
function gastro_uninstall() {
dsm("gastro_uninstall");
drupal_uninstall_schema('gastro');
}
And finally gastro.module:
/**
* Implementation of hook_node_info()
*/
function gastro_node_info() {
return array(
'gastro' => array(
'name' => t('Restaurant'),
'module' => 'gastro',
'has_title' => TRUE,
'title_label' => t('Name of the restaurant'),
'has_body' => FALSE,
'description' => 'foo',
),
);
}
/**
* Implementation of hook_form()
*
* This function will be called twice. The first time $node and $form_state
* will be almost empty. The second tme, $node->step will be set to one, and
* $form_state will contain the $form_state['values']['test1'] element.
*/
function gastro_form(&$node, $form_state) {
if (empty($form_state['values'])) {
return gastro_address_form($node, $form_state);
}
else {
return gastro_map_form($node, $form_state);
}
}
function gastro_address_form(&$node, $form_state) {
$form['title'] = array(
'#type' => 'textfield',
'#title' => t('Name of the restaurant'),
'#default_value' => $node->title,
'#required' => TRUE,
);
$form['address'] = array(
'#type' => 'fieldset',
'#title' => t('Address'),
'#collapsible' => FALSE,
'#weight' => -5,
);
$form['address']['street'] = array(
'#type' => 'textfield',
'#title' => t('Street name and house number'),
'#default_value' => $node->street,
'#description' => t('Provide the street name and house number, just like are used to from letters.'),
'#size' => 40,
'#required' => TRUE,
);
$form['address']['postal'] = array(
'#type' => 'textfield',
'#title' => t('Postal code'),
'#default_value' => $node->postal,
'#description' => t('The postal code for the street above in the city below.'),
'#size' => 6,
'#maxlength' => 5,
'#required' => TRUE,
);
$form['address']['city'] = array(
'#type' => 'textfield',
'#title' => t('City'),
'#default_value' => $node->city,
'#description' => t('The city, town, village, or place where the restaurant is.'),
'#size' => 40,
'#required' => TRUE,
);
return $form;
}
function gastro_map_form(&$node, $form_state) {
$form['map'] = array(
'#type' => 'fieldset',
'#title' => t('Map View'),
'#collapsible' => FALSE,
'#weight' => -5,
);
$form['map']['gmapez'] = array(
'#type' => 'markup',
'#prefix' => '<div class="GMapEZ" id="gastro-gmapez">',
'#suffix' => '</div>',
'#value' => '<a href="http://maps.google.com/maps?ll='. gastro_calculate_point($form_state) .'"></a>',
);
$form['point'] = array(
'#type' => 'item',
'#title' => 'Point',
'#value' => gastro_calculate_point($form_state),
);
return $form;
}
function gastro_calculate_point($form_state) {
$output = 'csv';
$gl = 'de';
$key = variable_get('googlemap_api_key',NULL);
$street = str_replace(' ', '+', $form_state['values']['street']);
$postal = str_replace(' ', '+', $form_state['values']['postal']);
$city = str_replace(' ', '+', $form_state['values']['city']);
$q = "$street,$postal+$city,Germany";
$url = 'http://maps.google.com/maps/geo?gl=de&output='. $output .'&key='. $key .'&q='. $q; // is this secure code?
$result = drupal_http_request($url);
list($status_code, $precision, $p1, $p2) = explode(',', $result->data);
if ($status_code == '200') {
return "$p1,$p2";
}
return '';
}
/**
* Implementation of hook_validate()
*/
function gastro_validate($node, &$form) {
}
/**
* Implementation of hook_form_alter()
*/
function gastro_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'gastro_node_form') {
if (empty($form_state['values'])) {
$form['#rebuild'] = TRUE;
unset($form['buttons']['submit']);
$form['buttons']['preview']['#value'] = t('Next');
}
else {
$form['#rebuild'] = FALSE;
$form['#redirect'] = TRUE;
unset($form['buttons']['preview']);
}
}
}
/**
* Implementation of hook_insert()
*/
function gastro_insert($node) {
$query = "
INSERT
INTO {gastro_location} (nid, vid, street, postal, city, point)
VALUES (%d, %d, '%s', '%s', '%s', '%s')";
dsm($node);
db_query($query, $node->nid, $node->vid, $node->street, $node->postal, $node->city, $node->point);
}
/**
* Implementation of hook_update()
*/
function gastro_update($node) {
if ($node->revision) {
gastro_insert($node);
}
else {
$query = "
UPDATE {gastro_location}
SET street = '%s', postal = '%s', city = '%s', point = '%s'
WHERE vid = %d";
db_query($query, $node->street, $node->postal, $node->city, $node->point);
}
}
/**
* Implementation of hook_load()
*/
function gastro_load($node) {
$query = "
SELECT street, postal, city, point
FROM {gastro_location}
WHERE vid = %d";
$result = db_query($query, $node->vid);
$object = db_fetch_object($result);
dsm($object);
return $object;
}
/**
* Implementation of hook_nodeapi()
*
* When a node revision is deleted, we need to remove the corresponding record
* from our table. The only way to handle revision deletion is by implementing
* hook_nodeapi().
*/
function gastro_nodeapi(&$node, $op, $teaser=NULL, $page=NULL) {
dsm("op=$op");
dsm($node);
switch ($op) {
case 'delete revision':
$query = "
DELETE
FROM {gastro_location}
WHERE vid = %d";
db_query($query, $node->vid);
break;
}
}
/**
* Implementation of hook_delete()
*
* When a node is deleted, we need to remove all related records from our table
*/
function gastro_delete($node) {
$query = "
DELETE
FROM {gastro_location}
WHERE nid = %d";
db_query($query, $node->nid);
}
The multistep form seems to work, but somewhere between clicking "Submit" and gastro_insert() being called, some things are lost.
I have marked this as support request because I assume I have forgotten something. I am willing to try everything, as I am at my wit's end now.
Comments
Comment #1
housetier commentedIt's been over a week with no response, only wild guesses on IRC. I guess I have hit a wall and will have to find a way to do it differently.
Going to close it now...