Commit 49fa25fb authored by Dries's avatar Dries
Browse files

- Rollback of patch #68418: clean up node submit hooks. Needs more thinkering.

  Restores the old node API.
parent c64db1da
......@@ -187,15 +187,18 @@ function book_load($node) {
return db_fetch_object(db_query('SELECT * FROM {book} WHERE vid = %d', $node->vid));
}
function book_form_alter($form_id, &$form) {
if ($form_id == 'node_delete_confirm') {
$form['#submit']['book_node_delete_confirm_submit'] = array();
}
/**
* Implementation of hook_insert().
*/
function book_insert($node) {
db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
}
function book_node_submit($form_id, $node) {
$node = (object)$node;
if ($node->is_new || $node->revision) {
/**
* Implementation of hook_update().
*/
function book_update($node) {
if ($node->revision) {
db_query("INSERT INTO {book} (nid, vid, parent, weight) VALUES (%d, %d, %d, %d)", $node->nid, $node->vid, $node->parent, $node->weight);
}
else {
......@@ -203,16 +206,30 @@ function book_node_submit($form_id, $node) {
}
}
function book_node_delete_confirm_submit($form_id, $form_values) {
db_query('DELETE FROM {book} WHERE nid = %d OR parent = %d', $form_values['node']->nid, $form_values['node']->nid);
/**
* Implementation of hook_delete().
*/
function book_delete(&$node) {
db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
}
/**
* Implementation of hook_form().
* Implementation of hook_submit().
*/
function book_form(&$node) {
function book_submit(&$node) {
global $user;
// Set default values for non-administrators.
if (!user_access('administer nodes')) {
$node->revision = 1;
$book->uid = $user->uid;
$book->name = $user->uid ? $user->name : '';
}
}
/**
* Implementation of hook_form().
*/
function book_form(&$node) {
$type = node_get_types('type', $node);
if ($node->nid && !$node->parent && !user_access('create new books')) {
$form['parent'] = array('#type' => 'value', '#value' => $node->parent);
......@@ -248,23 +265,22 @@ function book_form(&$node) {
'#description' => t('An explanation of the additions or updates being made to help other authors understand your motivations.'),
);
$form['weight'] = array('#type' => 'weight',
'#title' => t('Weight'),
'#access' => user_access('administer nodes'),
'#default_value' => $node->weight,
'#delta' => 15,
'#weight' => 5,
'#description' => t('Pages at a given level are ordered first by weight and then by title.'),
);
if (!user_access('administer nodes')) {
if (user_access('administer nodes')) {
$form['weight'] = array('#type' => 'weight',
'#title' => t('Weight'),
'#default_value' => $node->weight,
'#delta' => 15,
'#weight' => 5,
'#description' => t('Pages at a given level are ordered first by weight and then by title.'),
);
}
else {
// If a regular user updates a book page, we preserve the node weight; otherwise
// we use 0 as the default for new pages
$form['weight'] = array(
'#type' => 'value',
'#value' => isset($node->weight) ? $node->weight : 0,
);
$form['name'] = array('#type' => 'value', '#value' => $user->uid ? $user->name : '');
}
return $form;
......@@ -465,6 +481,9 @@ function book_nodeapi(&$node, $op, $teaser, $page) {
case 'delete revision':
db_query('DELETE FROM {book} WHERE vid = %d', $node->vid);
break;
case 'delete':
db_query('DELETE FROM {book} WHERE nid = %d', $node->nid);
break;
}
}
......
......@@ -278,7 +278,6 @@ function comment_form_alter($form_id, &$form) {
}
elseif (isset($form['type'])) {
if ($form['type']['#value'] .'_node_form' == $form_id) {
$form['#submit']['comment_node_submit'] = array();
$node = $form['#node'];
$form['comment_settings'] = array(
'#type' => 'fieldset',
......@@ -296,10 +295,6 @@ function comment_form_alter($form_id, &$form) {
);
}
}
if ($form_id == 'node_delete_confirm') {
$form['#submit']['comment_node_delete_confirm_submit'] = array();
}
}
/**
......@@ -318,6 +313,15 @@ function comment_nodeapi(&$node, $op, $arg = 0) {
}
break;
case 'insert':
db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->created, $node->uid);
break;
case 'delete':
db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid);
db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid);
break;
case 'update index':
$text = '';
$comments = db_query('SELECT subject, comment, format FROM {comments} WHERE nid = %d AND status = %d', $node->nid, COMMENT_PUBLISHED);
......@@ -340,17 +344,6 @@ function comment_nodeapi(&$node, $op, $arg = 0) {
}
}
function comment_node_delete_confirm_submit($form_id, $form_values) {
db_query('DELETE FROM {comments} WHERE nid = %d', $form_values['node']->nid);
db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $form_values['node']->nid);
}
function comment_node_submit($form_id, $node) {
if ($node->is_new) {
db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->created, $node->uid);
}
}
/**
* Implementation of hook_user().
*
......
......@@ -231,31 +231,6 @@ function forum_form_alter($form_id, &$form) {
unset($form['nodes']['forum']);
}
}
if ($form_id == 'node_delete_confirm' && $form['node']['#value']->type == 'forum') {
$form['#submit']['forum_node_delete_confirm_submit'] = array();
}
}
/**
* Check in particular that only a "leaf" term in the associated taxonomy
* vocabulary is selected, not a "container" term.
*/
function forum_node_validate($form_id, $node) {
$node = (object)$node;
if ($node->taxonomy) {
// Extract the node's proper topic ID.
$vocabulary = variable_get('forum_nav_vocabulary', '');
$containers = variable_get('forum_containers', array());
foreach ($node->taxonomy as $term) {
if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
if (in_array($term, $containers)) {
$term = taxonomy_get_term($term);
form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => $term->name)));
}
}
}
}
}
/**
......@@ -350,15 +325,16 @@ function forum_view(&$node, $teaser = FALSE, $page = FALSE) {
}
/**
* An early submit handler of the forum_node_form. Runs before the node is saved.
* Implementation of hook_submit().
*
* Check in particular that only a "leaf" term in the associated taxonomy
* vocabulary is selected, not a "container" term.
*/
function forum_node_submit_early($form_id, &$node) {
$node = (object)$node;
function forum_submit(&$node) {
// Make sure all fields are set properly:
$node->icon = $node->icon ? $node->icon : '';
if (!empty($node->taxonomy)) {
if ($node->taxonomy) {
// Get the forum terms from the (cached) tree
$tree = taxonomy_get_tree(_forum_get_vid());
if ($tree) {
......@@ -379,13 +355,35 @@ function forum_node_submit_early($form_id, &$node) {
}
}
}
}
$node = (array)$node;
/**
* Implementation of hook_validate().
*
* Check in particular that only a "leaf" term in the associated taxonomy
* vocabulary is selected, not a "container" term.
*/
function forum_validate($node) {
if ($node->taxonomy) {
// Extract the node's proper topic ID.
$vocabulary = variable_get('forum_nav_vocabulary', '');
$containers = variable_get('forum_containers', array());
foreach ($node->taxonomy as $term) {
if (db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $term, $vocabulary))) {
if (in_array($term, $containers)) {
$term = taxonomy_get_term($term);
form_set_error('taxonomy', t('The item %forum is only a container for forums. Please select one of the forums below it.', array('%forum' => $term->name)));
}
}
}
}
}
function forum_node_submit($form_id, $node) {
$node = (object)$node;
if ($node->is_new) {
/**
* Implementation of hook_update().
*/
function forum_update($node) {
if ($node->revision) {
db_query("INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)", $node->nid, $node->vid, $node->tid);
}
else {
......@@ -424,8 +422,18 @@ function forum_prepare(&$node) {
}
}
function forum_node_delete_confirm_submit($form_id, $form_values) {
db_query('DELETE FROM {forum} WHERE nid = %d', $form_values['node']->nid);
/**
* Implementation of hook_insert().
*/
function forum_insert($node) {
db_query('INSERT INTO {forum} (nid, vid, tid) VALUES (%d, %d, %d)', $node->nid, $node->vid, $node->tid);
}
/**
* Implementation of hook_delete().
*/
function forum_delete(&$node) {
db_query('DELETE FROM {forum} WHERE nid = %d', $node->nid);
}
/**
......
......@@ -146,20 +146,31 @@ function menu_block($op = 'list', $delta = 0) {
}
}
function menu_node_delete_confirm_submit($form_id, $form_values) {
menu_node_form_delete($form_values['node']);
menu_rebuild();
}
/**
* Implementation of hook_nodeapi().
*/
function menu_nodeapi(&$node, $op) {
if (user_access('administer menu')) {
switch ($op) {
case 'insert':
case 'update':
if ($node->menu['delete']) {
menu_node_form_delete($node);
menu_rebuild();
}
elseif ($node->menu['title']) {
$node->menu['path'] = ($node->menu['path']) ? $node->menu['path'] : "node/$node->nid";
menu_edit_item_save($node->menu);
menu_rebuild();
}
break;
function menu_node_submit($form_id, $node) {
if ($node->menu['delete']) {
menu_node_form_delete($node);
menu_rebuild();
}
elseif ($node->menu['title']) {
$node->menu['path'] = ($node->menu['path']) ? $node->menu['path'] : "node/$node->nid";
menu_edit_item_save($node->menu);
menu_rebuild();
case 'delete':
menu_node_form_delete($node);
menu_rebuild();
break;
}
}
}
......@@ -187,8 +198,6 @@ function menu_form_alter($form_id, &$form) {
}
}
$form['#submit']['menu_node_submit'] = array();
$form['menu'] = array('#type' => 'fieldset',
'#title' => t('Menu settings'),
'#access' => user_access('administer menu'),
......@@ -249,10 +258,6 @@ function menu_form_alter($form_id, &$form) {
);
}
}
if ($form_id == 'node_delete_confirm') {
$form['#submit']['menu_node_delete_confirm_submit'] = array();
}
}
/**
......
......@@ -600,6 +600,16 @@ function node_save(&$node) {
db_query($node_query, $node_table_values);
db_query($revisions_query, $revisions_table_values);
// Call the node specific callback (if any):
if ($node->is_new) {
node_invoke($node, 'insert');
node_invoke_nodeapi($node, 'insert');
}
else {
node_invoke($node, 'update');
node_invoke_nodeapi($node, 'update');
}
// Update the node access table for this node.
node_access_acquire_grants($node);
......@@ -1061,8 +1071,6 @@ function node_menu($may_cache) {
'path' => 'node/add/'. $type_url_str,
'title' => t($name),
'access' => node_access('create', $type->type),
'callback' => 'drupal_get_form',
'callback arguments' => array($type->type. '_node_form', array('type' => $type->type))
);
}
}
......@@ -1091,7 +1099,7 @@ function node_menu($may_cache) {
'type' => MENU_LOCAL_TASK);
$items[] = array('path' => 'node/'. arg(1) .'/delete', 'title' => t('delete'),
'callback' => 'drupal_get_form',
'callback arguments' => array('node_delete_confirm', $node),
'callback arguments' => array('node_delete_confirm'),
'access' => node_access('delete', $node),
'weight' => 1,
'type' => MENU_CALLBACK);
......@@ -1748,9 +1756,53 @@ function node_feed($nodes = 0, $channel = array()) {
}
/**
* A form validate handler. Perform checks on the given node.
* Prepare node for save and allow modules to make changes.
*/
function node_submit($node) {
global $user;
// Convert the node to an object, if necessary.
$node = (object)$node;
// Auto-generate the teaser, but only if it hasn't been set (e.g. by a
// module-provided 'teaser' form item).
if (!isset($node->teaser)) {
$node->teaser = isset($node->body) ? node_teaser($node->body, isset($node->format) ? $node->format : NULL) : '';
}
$access = user_access('administer nodes');
if ($access) {
// Populate the "authored by" field.
if ($account = user_load(array('name' => $node->name))) {
$node->uid = $account->uid;
}
else {
$node->uid = 0;
}
$node->created = $node->date ? strtotime($node->date) : NULL;
}
// Force defaults in case people modify the form:
$node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
foreach (array('status', 'promote', 'sticky', 'revision') as $key) {
if (!$access || !isset($node->$key)) {
$node->$key = in_array($key, $node_options);
}
}
// Do node-type-specific validation checks.
node_invoke($node, 'submit');
node_invoke_nodeapi($node, 'submit');
$node->validated = TRUE;
return $node;
}
/**
* Perform validation checks on the given node.
*/
function node_form_validate($form_id, $node) {
function node_validate($node, $form = array()) {
// Convert the node to an object, if necessary.
$node = (object)$node;
$type = node_get_types('type', $node);
......@@ -1779,6 +1831,14 @@ function node_form_validate($form_id, $node) {
form_set_error('date', t('You have to specify a valid date.'));
}
}
// Do node-type-specific validation checks.
node_invoke($node, 'validate', $form);
node_invoke_nodeapi($node, 'validate', $form);
}
function node_form_validate($form_id, $form_values, $form) {
node_validate($form_values, $form);
}
function node_object_prepare(&$node) {
......@@ -1825,13 +1885,14 @@ function node_form($node, $form_values = NULL) {
$form['title']['#weight'] = -5;
}
// Populate $node so we can assign it to $form['#node].
$node_options = variable_get('node_options_'. $node->type, array('status', 'promote'));
// If this is a new node, fill in the default values.
if (!isset($node->nid)) {
foreach (array('status', 'promote', 'sticky', 'revision') as $key) {
$node->$key = in_array($key, $node_options);
}
global $user;
$node->uid = $user->uid;
}
else {
// Nodes being edited should always be preset with the default revision setting.
......@@ -1839,17 +1900,39 @@ function node_form($node, $form_values = NULL) {
}
$form['#node'] = $node;
// Node author information is editable only by administrators.
$form['author'] = array('#type' => 'fieldset', '#title' => t('Authoring information'), '#access' => user_access('administer nodes'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => 20);
$form['author']['name'] = array('#type' => 'textfield', '#title' => t('Authored by'), '#maxlength' => 60, '#autocomplete_path' => 'user/autocomplete', '#default_value' => $node->nid ? $node->name : $user->name, '#weight' => -1, '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', 'Anonymous'))));
$form['author']['date'] = array('#type' => 'textfield', '#title' => t('Authored on'), '#maxlength' => 25, '#default_value' => $node->date, '#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => $node->date)));
// Node author information for administrators
$form['author'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Authoring information'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 20,
);
$form['author']['name'] = array('#type' => 'textfield', '#title' => t('Authored by'), '#maxlength' => 60, '#autocomplete_path' => 'user/autocomplete', '#default_value' => $node->name ? $node->name : '', '#weight' => -1, '#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', 'Anonymous'))));
$form['author']['date'] = array('#type' => 'textfield', '#title' => t('Authored on'), '#maxlength' => 25, '#description' => t('Format: %time. Leave blank to use the time of form submission.', array('%time' => $node->date)));
if (isset($node->nid)) {
$form['author']['date']['#default_value'] = $node->date;
}
// Node options are editable only by administrators.
$form['options'] = array('#type' => 'fieldset', '#title' => t('Publishing options'), '#access' => user_access('administer nodes'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#weight' => 25);
// Node options for administrators
$form['options'] = array(
'#type' => 'fieldset',
'#access' => user_access('administer nodes'),
'#title' => t('Publishing options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => 25,
);
$form['options']['status'] = array('#type' => 'checkbox', '#title' => t('Published'), '#default_value' => $node->status);
$form['options']['promote'] = array('#type' => 'checkbox', '#title' => t('Promoted to front page'), '#default_value' => $node->promote);
$form['options']['sticky'] = array('#type' => 'checkbox', '#title' => t('Sticky at top of lists'), '#default_value' => $node->sticky);
$form['options']['revision'] = array('#type' => 'checkbox', '#title' => t('Create new revision'), '#default_value' => $node->revision);
// These values are used when the user has no administrator accesss.
foreach (array('uid', 'created') as $key) {
$form[$key] = array('#type' => 'value', '#value' => $node->$key);
}
// Add the buttons.
$form['preview'] = array('#type' => 'button', '#value' => t('Preview'), '#weight' => 40);
......@@ -1858,15 +1941,6 @@ function node_form($node, $form_values = NULL) {
$form['delete'] = array('#type' => 'button', '#value' => t('Delete'), '#weight' => 50);
}
$form['#after_build'] = array('node_form_add_preview');
$form['#validate'] = array(
'node_form_validate' => array(),
$node->type .'_node_validate' => array(),
);
$form['#submit'] = array(
$node->type .'_node_submit_early' => array(),
'node_form_submit' => array(),
$node->type .'_node_submit' => array(),
);
$form['#base'] = 'node_form';
return $form;
}
......@@ -1930,30 +2004,40 @@ function theme_node_form($form) {
}
/**
* Present set of list of node creation links
* Present a node submission form or a set of links to such forms.
*/
function node_add() {
function node_add($type = NULL) {
global $user;
$types = node_get_types();
$type = isset($type) ? str_replace('-', '_', $type) : NULL;
// If a node type has been specified, validate its existence.
if (isset($types[$type]) && node_access('create', $type)) {
// Initialize settings:
$node = array('uid' => $user->uid, 'name' => $user->name, 'type' => $type);
foreach ($types as $type) {
if (function_exists($type->module .'_form') && node_access('create', $type->type)) {
$type_url_str = str_replace('_', '-', $type->type);
$title = t('Add a new @s.', array('@s' => $type->name));
$out = '<dt>'. l($type->name, "node/add/$type_url_str", array('title' => $title)) .'</dt>';
$out .= '<dd>'. filter_xss_admin($type->description) .'</dd>';
$item[$type->type] = $out;
}
}
if (isset($item)) {
uksort($item, 'strnatcasecmp');
$output = t('Choose the appropriate item from the list:') .'<dl>'. implode('', $item) .'</dl>';
$output = drupal_get_form($type .'_node_form', $node);
drupal_set_title(t('Submit @name', array('@name' => $types[$type]->name)));
}
else {
$output = t('No content types available.');
// If no (valid) node type has been provided, display a node type overview.
foreach ($types as $type) {
if (function_exists($type->module .'_form') && node_access('create', $type->type)) {
$type_url_str = str_replace('_', '-', $type->type);
$title = t('Add a new @s.', array('@s' => $type->name));
$out = '<dt>'. l($type->name, "node/add/$type_url_str", array('title' => $title)) .'</dt>';
$out .= '<dd>'. filter_xss_admin($type->description) .'</dd>';
$item[$type->type] = $out;
}
}
if (isset($item)) {
uksort($item, 'strnatcasecmp');
$output = t('Choose the appropriate item from the list:') .'<dl>'. implode('', $item) .'</dl>';
}
else {
$output = t('No content types available.');
}
}
return $output;
......@@ -2033,27 +2117,31 @@ function theme_node_log_message($log) {
return '<div class="log"><div class="title">'. t('Log') .':</div>'. $log .'</div>';
}
function node_form_submit($form_id, &$node) {
function node_form_submit($form_id, $edit) {
global $user;
$node = (object)$node;
// Auto-generate the teaser, but only if it hasn't been set (e.g. by a
// module-provided 'teaser' form item).
if (!isset($node->teaser)) {
$node->teaser = isset($node->body) ? node_teaser($node->body, isset($node->format) ? $node->format : NULL) : '';
}
// Populate the uid based on name field.
$account = user_load(array('name' => $node->name));
$node->uid = $account->uid;
$node->created = strtotime($node->date);
// Fix up the node when required:
$node = node_submit($edit);
$action = $node->nid ? 'updated' : 'created';
node_save($node);
watchdog('content', t("@type: $action %title.", array('@type' => t($node->type), '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
drupal_set_message(t("The %post was $action.", array ('%post' => node_get_types('name', $node))));
// redirect the submitter as needed
// Prepare the node's body:
if ($node->nid) {
// Check whether the current user has the proper access rights to
// perform this operation:
if (node_access('update', $node)) {
node_save($node);
watchdog('content', t('@type: updated %title.', array('@type' => t($node->type), '%title' => $node->title)), WATCHDOG_NOTICE, l(t('view'), 'node/'. $node->nid));
drupal_set_message(t('The %post was updated.', array ('%post' => node_get_types('name', $node))));
}