I have a content type containing lots of required and conditional fields. Because it can take a bit of time to properly create these nodes, and not all information will always be available to the end-user, I've implemented the ability for the user to "Save as Draft" while on this node's edit form.
Here's my form alter:
function mymodule_form_node_form_alter(&$form, &$form_state) {
if ($form['#bundle'] == 'content_type') {
// If node already exists and is not published, show "Draft" markup.
if (isset($form['#node']->nid) && $form['#node']->status == 0) {
$form['draft_markup']['#markup'] = '<div id="node-draft">Draft</div>';
}
// Add a new validate function to disable error checking on required fields.
if (empty($form['#validate'])) {
$form['#validate'] = array();
}
array_unshift($form['#validate'], 'mymodule_save_draft_validate');
// Add 'Save as Draft' button
$form['actions']['draft'] = array(
'#type' => 'submit',
'#class' => 'form-submit',
'#value' => t('Save as Draft'),
'#weight' => '0',
'#submit' => array('mymodule_save_draft_submit'),
);
// Change submit button's text.
$form['actions']['submit']['#value'] = t('Save & Publish');
}
}
Custom validate function – the magic lies in &drupal_static('form_set_error', NULL, TRUE)
, where TRUE resets the static form_set_error
variable:
function mymodule_save_draft_validate($form, &$form_state) {
if ($form_state['triggering_element']['#value'] == $form['actions']['draft']['#value']) {
// Set as unpublished.
$form_state['values']['status'] = 0;
// Force validation.
$errors = &drupal_static('form_set_error', NULL, TRUE);
} else {
// Set as published.
$form_state['values']['status'] = 1;
}
}
Custom submit function – drupal_get_messages()
stops "required" field errors from displaying when a user saves as draft, while a user doing the normal 'submit' will see the errors:
function mymodule_save_draft_submit($form, &$form_state) {
drupal_get_messages();
node_form_submit($form, $form_state);
}
Outside of obviously missing field data (which I'm not worried about since status = 0 and I can filter to never display unpublished nodes to the public) does anything stand out as dangerous here for a long-term, production site? Maybe the answer is simply "no", but forcing validation via &drupal_static('form_set_error', NULL, TRUE)
makes me wonder if I'm opening the door to bigger security vulnerabilities. Because fields still run their validation, I am unable to get data to save that shouldn't be saved (i.e. if I try and put PHP code in a number input, the integer "0" is saved into the database - cool). Looking for a bit of peer review here...