diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-06-17 13:44:45 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-06-17 13:44:45 +0000 |
commit | cb043e8c489f033f7435e7fd5d18325155465c77 (patch) | |
tree | 716cdfe743aa99a01a1dce97cc800c00119af896 /modules/node | |
parent | 3620310d7c8a5d487f7b6826a89f8a4816149333 (diff) | |
download | brdo-cb043e8c489f033f7435e7fd5d18325155465c77.tar.gz brdo-cb043e8c489f033f7435e7fd5d18325155465c77.tar.bz2 |
- Patch #735800 by effulgentsia, fago, Frando: node form triggers form level submit functions on button level submits, without validation. Oh yeah.
Diffstat (limited to 'modules/node')
-rw-r--r-- | modules/node/node.api.php | 28 | ||||
-rw-r--r-- | modules/node/node.pages.inc | 77 |
2 files changed, 78 insertions, 27 deletions
diff --git a/modules/node/node.api.php b/modules/node/node.api.php index 95dc3b2b1..690fb9e39 100644 --- a/modules/node/node.api.php +++ b/modules/node/node.api.php @@ -665,6 +665,34 @@ function hook_node_validate($node, $form) { } /** + * Act on a node after validated form values have been copied to it. + * + * This hook is invoked when a node form is submitted with either the "Save" or + * "Preview" button, after form values have been copied to the form state's node + * object, but before the node is saved or previewed. It is a chance for modules + * to adjust the node's properties from what they are simply after a copy from + * $form_state['values']. This hook is intended for adjusting non-field-related + * properties. See hook_field_attach_submit() for customizing field-related + * properties. + * + * @param $node + * The node being updated in response to a form submission. + * @param $form + * The form being used to edit the node. + * @param $form_state + * The form state array. + * + * @ingroup node_api_hooks + */ +function hook_node_submit($node, $form, &$form_state) { + // Decompose the selected menu parent option into 'menu_name' and 'plid', if + // the form used the default parent selection widget. + if (!empty($form_state['values']['menu']['parent'])) { + list($node->menu['menu_name'], $node->menu['plid']) = explode(':', $form_state['values']['menu']['parent']); + } +} + +/** * Act on a node that is being assembled before rendering. * * The module may add elements to $node->content prior to rendering. This hook diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc index 6b9544f17..96a4ebfcb 100644 --- a/modules/node/node.pages.inc +++ b/modules/node/node.pages.inc @@ -76,12 +76,15 @@ function node_add($type) { } function node_form_validate($form, &$form_state) { + // $form_state['node'] contains the actual entity being edited, but we must + // not update it with form values that have not yet been validated, so we + // create a pseudo-entity to use during validation. $node = (object) $form_state['values']; node_validate($node, $form); // Field validation. Requires access to $form_state, so this cannot be // done in node_validate() as it currently exists. - field_attach_form_validate('node', $node, $form, $form_state); + entity_form_field_validate('node', $form, $form_state); } /** @@ -89,28 +92,29 @@ function node_form_validate($form, &$form_state) { */ function node_form($form, &$form_state, $node) { global $user; - // This form has its own multistep persistence. - if ($form_state['rebuild']) { - $form_state['input'] = array(); - } - if (isset($form_state['node'])) { - $node = (object) ($form_state['node'] + (array) $node); - } - if (isset($form_state['node_preview'])) { - $form['#prefix'] = $form_state['node_preview']; - } - foreach (array('title') as $key) { - if (!isset($node->$key)) { - $node->$key = NULL; + // During initial form build, add the node entity to the form state for use + // during form building and processing. During a rebuild, use what is in the + // form state. + if (!isset($form_state['node'])) { + if (!isset($node->title)) { + $node->title = NULL; } - } - if (!isset($form_state['node_preview'])) { node_object_prepare($node); + $form_state['node'] = $node; } else { + $node = $form_state['node']; + } + + // Some special stuff when previewing a node. + if (isset($form_state['node_preview'])) { + $form['#prefix'] = $form_state['node_preview']; $node->in_preview = TRUE; } + else { + unset($node->in_preview); + } // Identify this as a node edit form. $form['#node_edit_form'] = TRUE; @@ -140,7 +144,9 @@ function node_form($form, &$form_state, $node) { if (!isset($form['title']['#weight'])) { $form['title']['#weight'] = -5; } - + // @todo Legacy support. Modules adding form building and processing functions + // to the node form are encouraged to access the node using + // $form_state['node']. Remove in Drupal 8. $form['#node'] = $node; $form['additional_settings'] = array( @@ -299,8 +305,9 @@ function node_form_delete_submit($form, &$form_state) { function node_form_build_preview($form, &$form_state) { - $node = node_form_submit_build_node($form, $form_state); + $node = $form['#builder_function']($form, $form_state); $form_state['node_preview'] = node_preview($node); + $form_state['rebuild'] = TRUE; } /** @@ -382,7 +389,7 @@ function theme_node_preview($variables) { } function node_form_submit($form, &$form_state) { - $node = node_form_submit_build_node($form, $form_state); + $node = $form['#builder_function']($form, $form_state); $insert = empty($node->nid); node_save($node); $node_link = l(t('view'), 'node/' . $node->nid); @@ -398,7 +405,6 @@ function node_form_submit($form, &$form_state) { drupal_set_message(t('@type %title has been updated.', $t_args)); } if ($node->nid) { - unset($form_state['rebuild']); $form_state['values']['nid'] = $node->nid; $form_state['nid'] = $node->nid; $form_state['redirect'] = 'node/' . $node->nid; @@ -407,25 +413,42 @@ function node_form_submit($form, &$form_state) { // In the unlikely case something went wrong on save, the node will be // rebuilt and node form redisplayed the same way as in preview. drupal_set_message(t('The post could not be saved.'), 'error'); + $form_state['rebuild'] = TRUE; } // Clear the page and block caches. cache_clear_all(); } /** - * Build a node by processing submitted form values and prepare for a form rebuild. + * Updates the form state's node entity by processing this submission's values. + * + * This is the default #builder_function for the node form. It is called + * during the "Save" and "Preview" submit handlers to retrieve the entity to + * save or preview. This function can also be called by a "Next" button of a + * wizard to update the form state's entity with the current step's values + * before proceeding to the next step. + * + * @see node_form() */ function node_form_submit_build_node($form, &$form_state) { - // Unset any button-level handlers, execute all the form-level submit - // functions to process the form values into an updated node. + // @todo Legacy support for modules that extend the node form with form-level + // submit handlers that adjust $form_state['values'] prior to those values + // being used to update the entity. Module authors are encouraged to instead + // adjust the node directly within a hook_node_submit() implementation. For + // Drupal 8, evaluate whether the pattern of triggering form-level submit + // handlers during button-level submit processing is worth supporting + // properly, and if so, add a Form API function for doing so. unset($form_state['submit_handlers']); form_execute_handlers('submit', $form, $form_state); - $node = node_submit((object) $form_state['values']); - field_attach_submit('node', $node, $form, $form_state); + $node = $form_state['node']; + entity_form_submit_build_entity('node', $node, $form, $form_state); - $form_state['node'] = (array) $node; - $form_state['rebuild'] = TRUE; + node_submit($node); + foreach (module_implements('node_submit') as $module) { + $function = $module . '_node_submit'; + $function($node, $form, $form_state); + } return $node; } |